--- a/.hgtags Fri Jul 27 16:53:15 2012 -0700
+++ b/.hgtags Fri Jul 27 22:26:19 2012 -0700
@@ -169,3 +169,5 @@
9b19b2302c28f4da6d4078f66234abecfed5688a jdk8-b45
600c9a1feb01633cbcf2341a43d1d21e6497ecd0 jdk8-b46
b820143a6f1ce993c6e6f31db4d64de990f42654 jdk8-b47
+086271e35b0a419b38e8bda9bebd70693811df0a jdk8-b48
+cecd7026f30cbd83b0601925a7a5e059aec98138 jdk8-b49
--- a/.hgtags-top-repo Fri Jul 27 16:53:15 2012 -0700
+++ b/.hgtags-top-repo Fri Jul 27 22:26:19 2012 -0700
@@ -169,3 +169,5 @@
633f2378c904c92bb922a6e19e9f62fe8eac14af jdk8-b45
27fa766a2298ba8347dc198f0cf85ba6618e17db jdk8-b46
1dcb4b7b9373e64e135c12fe1f8699f1f80e51e8 jdk8-b47
+3f6c72d1c2a6e5c9e7d81c3dc984886678a128ad jdk8-b48
+c97b99424815c43818e3cc3ffcdd1a60f3198b52 jdk8-b49
--- a/THIRD_PARTY_README Fri Jul 27 16:53:15 2012 -0700
+++ b/THIRD_PARTY_README Fri Jul 27 22:26:19 2012 -0700
@@ -3383,3 +3383,397 @@
-------------------------------------------------------------------------------
+%% This notice is provided with respect to Mozilla Network Security
+Services (NSS), which is supplied with the JDK test suite in the OpenJDK
+source code repository. It is licensed under Mozilla Public License (MPL),
+version 2.0.
+
+The NSS libraries are supplied in executable form, built from unmodified
+NSS source code labeled with the "NSS_3.13.1_RTM" release tag.
+
+The NSS source code is available in the OpenJDK source code repository at:
+ jdk/test/sun/security/pkcs11/nss/src
+
+The NSS libraries are available in the OpenJDK source code repository at:
+ jdk/test/sun/security/pkcs11/nss/lib
+
+--- begin of LICENSE ---
+
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+ means each individual or legal entity that creates, contributes to
+ the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+ means the combination of the Contributions of others (if any) used
+ by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+ means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+ means Source Code Form to which the initial Contributor has attached
+ the notice in Exhibit A, the Executable Form of such Source Code
+ Form, and Modifications of such Source Code Form, in each case
+ including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+ means
+
+ (a) that the initial Contributor has attached the notice described
+ in Exhibit B to the Covered Software; or
+
+ (b) that the Covered Software was made available under the terms of
+ version 1.1 or earlier of the License, but not also under the
+ terms of a Secondary License.
+
+1.6. "Executable Form"
+ means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+ means a work that combines Covered Software with other material, in
+ a separate file or files, that is not Covered Software.
+
+1.8. "License"
+ means this document.
+
+1.9. "Licensable"
+ means having the right to grant, to the maximum extent possible,
+ whether at the time of the initial grant or subsequently, any and
+ all of the rights conveyed by this License.
+
+1.10. "Modifications"
+ means any of the following:
+
+ (a) any file in Source Code Form that results from an addition to,
+ deletion from, or modification of the contents of Covered
+ Software; or
+
+ (b) any new file in Source Code Form that contains any Covered
+ Software.
+
+1.11. "Patent Claims" of a Contributor
+ means any patent claim(s), including without limitation, method,
+ process, and apparatus claims, in any patent Licensable by such
+ Contributor that would be infringed, but for the grant of the
+ License, by the making, using, selling, offering for sale, having
+ made, import, or transfer of either its Contributions or its
+ Contributor Version.
+
+1.12. "Secondary License"
+ means either the GNU General Public License, Version 2.0, the GNU
+ Lesser General Public License, Version 2.1, the GNU Affero General
+ Public License, Version 3.0, or any later versions of those
+ licenses.
+
+1.13. "Source Code Form"
+ means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+ means an individual or a legal entity exercising rights under this
+ License. For legal entities, "You" includes any entity that
+ controls, is controlled by, or is under common control with You. For
+ purposes of this definition, "control" means (a) the power, direct
+ or indirect, to cause the direction or management of such entity,
+ whether by contract or otherwise, or (b) ownership of more than
+ fifty percent (50%) of the outstanding shares or beneficial
+ ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+ Licensable by such Contributor to use, reproduce, make available,
+ modify, display, perform, distribute, and otherwise exploit its
+ Contributions, either on an unmodified basis, with Modifications, or
+ as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+ for sale, have made, import, and otherwise transfer either its
+ Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+ or
+
+(b) for infringements caused by: (i) Your and any other third party's
+ modifications of Covered Software, or (ii) the combination of its
+ Contributions with other software (except as part of its Contributor
+ Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+ its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+ Form, as described in Section 3.1, and You must inform recipients of
+ the Executable Form how they can obtain a copy of such Source Code
+ Form by reasonable means in a timely manner, at a charge no more
+ than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+ License, or sublicense it under different terms, provided that the
+ license for the Executable Form does not attempt to limit or alter
+ the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+* *
+* 6. Disclaimer of Warranty *
+* ------------------------- *
+* *
+* Covered Software is provided under this License on an "as is" *
+* basis, without warranty of any kind, either expressed, implied, or *
+* statutory, including, without limitation, warranties that the *
+* Covered Software is free of defects, merchantable, fit for a *
+* particular purpose or non-infringing. The entire risk as to the *
+* quality and performance of the Covered Software is with You. *
+* Should any Covered Software prove defective in any respect, You *
+* (not any Contributor) assume the cost of any necessary servicing, *
+* repair, or correction. This disclaimer of warranty constitutes an *
+* essential part of this License. No use of any Covered Software is *
+* authorized under this License except under this disclaimer. *
+* *
+************************************************************************
+
+************************************************************************
+* *
+* 7. Limitation of Liability *
+* -------------------------- *
+* *
+* Under no circumstances and under no legal theory, whether tort *
+* (including negligence), contract, or otherwise, shall any *
+* Contributor, or anyone who distributes Covered Software as *
+* permitted above, be liable to You for any direct, indirect, *
+* special, incidental, or consequential damages of any character *
+* including, without limitation, damages for lost profits, loss of *
+* goodwill, work stoppage, computer failure or malfunction, or any *
+* and all other commercial damages or losses, even if such party *
+* shall have been informed of the possibility of such damages. This *
+* limitation of liability shall not apply to liability for death or *
+* personal injury resulting from such party's negligence to the *
+* extent applicable law prohibits such limitation. Some *
+* jurisdictions do not allow the exclusion or limitation of *
+* incidental or consequential damages, so this exclusion and *
+* limitation may not apply to You. *
+* *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ License, v. 2.0. If a copy of the MPL was not distributed with this
+ file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+ This Source Code Form is "Incompatible With Secondary Licenses", as
+ defined by the Mozilla Public License, v. 2.0.
+
+--- end of LICENSE ---
+
+-------------------------------------------------------------------------------
+
--- a/corba/.hgtags Fri Jul 27 16:53:15 2012 -0700
+++ b/corba/.hgtags Fri Jul 27 22:26:19 2012 -0700
@@ -169,3 +169,5 @@
747dad9e9d37d244a5c765a1afe9194f7ddae118 jdk8-b45
30141e598d72a6146126cb86b034ed6d0bd191b3 jdk8-b46
21e46ea21c6a26246fb7a1926ac7fe8d580d0518 jdk8-b47
+7e2b179a5b4dbd3f097e28daa00abfcc72ba3e0b jdk8-b48
+fe44e58a6bdbeae350ce96aafb49770a5dca5d8a jdk8-b49
--- a/hotspot/.hgtags Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/.hgtags Fri Jul 27 22:26:19 2012 -0700
@@ -261,3 +261,7 @@
cf37a594c38db2ea926954154636f9f81da2e032 jdk8-b46
0c7bb1f4f9c8062b5c5bfa56b3bdca44839b4109 jdk8-b47
66b0450071c1534e014b131892cc86b63f1d009c hs24-b16
+1e26f61bbb521642639f56fae11326f1932f5a7d jdk8-b48
+bd54fe36b5e50f9ef1e30a5047b27fee5297e268 hs24-b17
+e3619706a7253540a2d94e9e841acaab8ace7038 jdk8-b49
+72e0362c3f0cfacbbac8af8a5b9d2e182f21c17b hs24-b18
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java Fri Jul 27 22:26:19 2012 -0700
@@ -47,14 +47,11 @@
private static int HAS_LINENUMBER_TABLE;
private static int HAS_CHECKED_EXCEPTIONS;
private static int HAS_LOCALVARIABLE_TABLE;
+ private static int HAS_EXCEPTION_TABLE;
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("constMethodOopDesc");
constants = new OopField(type.getOopField("_constants"), 0);
- // The exception handler table. 4-tuples of ints [start_pc, end_pc,
- // handler_pc, catch_type index] For methods with no exceptions the
- // table is pointing to Universe::the_empty_int_array
- exceptionTable = new OopField(type.getOopField("_exception_table"), 0);
constMethodSize = new CIntField(type.getCIntegerField("_constMethod_size"), 0);
flags = new ByteField(type.getJByteField("_flags"), 0);
@@ -62,6 +59,7 @@
HAS_LINENUMBER_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_linenumber_table").intValue();
HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("constMethodOopDesc::_has_checked_exceptions").intValue();
HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_localvariable_table").intValue();
+ HAS_EXCEPTION_TABLE = db.lookupIntConstant("constMethodOopDesc::_has_exception_table").intValue();
// Size of Java bytecodes allocated immediately after constMethodOop.
codeSize = new CIntField(type.getCIntegerField("_code_size"), 0);
@@ -78,6 +76,9 @@
type = db.lookupType("LocalVariableTableElement");
localVariableTableElementSize = type.getSize();
+
+ type = db.lookupType("ExceptionTableElement");
+ exceptionTableElementSize = type.getSize();
}
ConstMethod(OopHandle handle, ObjectHeap heap) {
@@ -86,7 +87,6 @@
// Fields
private static OopField constants;
- private static OopField exceptionTable;
private static CIntField constMethodSize;
private static ByteField flags;
private static CIntField codeSize;
@@ -100,6 +100,7 @@
private static long checkedExceptionElementSize;
private static long localVariableTableElementSize;
+ private static long exceptionTableElementSize;
public Method getMethod() {
InstanceKlass ik = (InstanceKlass)getConstants().getPoolHolder();
@@ -112,10 +113,6 @@
return (ConstantPool) constants.getValue(this);
}
- public TypeArray getExceptionTable() {
- return (TypeArray) exceptionTable.getValue(this);
- }
-
public long getConstMethodSize() {
return constMethodSize.getValue(this);
}
@@ -235,7 +232,6 @@
super.iterateFields(visitor, doVMFields);
if (doVMFields) {
visitor.doOop(constants, true);
- visitor.doOop(exceptionTable, true);
visitor.doCInt(constMethodSize, true);
visitor.doByte(flags, true);
visitor.doCInt(codeSize, true);
@@ -326,6 +322,23 @@
return ret;
}
+ public boolean hasExceptionTable() {
+ return (getFlags() & HAS_EXCEPTION_TABLE) != 0;
+ }
+
+ public ExceptionTableElement[] getExceptionTable() {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(hasExceptionTable(), "should only be called if table is present");
+ }
+ ExceptionTableElement[] ret = new ExceptionTableElement[getExceptionTableLength()];
+ long offset = offsetOfExceptionTable();
+ for (int i = 0; i < ret.length; i++) {
+ ret[i] = new ExceptionTableElement(getHandle(), offset);
+ offset += exceptionTableElementSize;
+ }
+ return ret;
+ }
+
public boolean hasCheckedExceptions() {
return (getFlags() & HAS_CHECKED_EXCEPTIONS) != 0;
}
@@ -415,7 +428,10 @@
if (Assert.ASSERTS_ENABLED) {
Assert.that(hasLocalVariableTable(), "should only be called if table is present");
}
- if (hasCheckedExceptions()) {
+
+ if (hasExceptionTable()) {
+ return offsetOfExceptionTable() - 2;
+ } else if (hasCheckedExceptions()) {
return offsetOfCheckedExceptions() - 2;
} else {
return offsetOfLastU2Element();
@@ -432,4 +448,33 @@
return offset;
}
+ private int getExceptionTableLength() {
+ if (hasExceptionTable()) {
+ return (int) getHandle().getCIntegerAt(offsetOfExceptionTableLength(), 2, true);
+ } else {
+ return 0;
+ }
+ }
+
+ private long offsetOfExceptionTableLength() {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(hasExceptionTable(), "should only be called if table is present");
+ }
+ if (hasCheckedExceptions()) {
+ return offsetOfCheckedExceptions() - 2;
+ } else {
+ return offsetOfLastU2Element();
+ }
+ }
+
+ private long offsetOfExceptionTable() {
+ long offset = offsetOfExceptionTableLength();
+ long length = getExceptionTableLength();
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(length > 0, "should only be called if table is present");
+ }
+ offset -= length * exceptionTableElementSize;
+ return offset;
+ }
+
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ExceptionTableElement.java Fri Jul 27 22:26:19 2012 -0700
@@ -0,0 +1,81 @@
+/*
+ * 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.
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.interpreter.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class ExceptionTableElement {
+ static {
+ VM.registerVMInitializedObserver(new Observer() {
+ public void update(Observable o, Object data) {
+ initialize(VM.getVM().getTypeDataBase());
+ }
+ });
+ }
+
+ private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+ Type type = db.lookupType("ExceptionTableElement");
+ offsetOfStartPC = type.getCIntegerField("start_pc").getOffset();
+ offsetOfEndPC = type.getCIntegerField("end_pc").getOffset();
+ offsetOfHandlerPC = type.getCIntegerField("handler_pc").getOffset();
+ offsetOfCatchTypeIndex = type.getCIntegerField("catch_type_index").getOffset();
+ }
+
+ private static long offsetOfStartPC;
+ private static long offsetOfEndPC;
+ private static long offsetOfHandlerPC;
+ private static long offsetOfCatchTypeIndex;
+
+ private OopHandle handle;
+ private long offset;
+
+ public ExceptionTableElement(OopHandle handle, long offset) {
+ this.handle = handle;
+ this.offset = offset;
+ }
+
+ public int getStartPC() {
+ return (int) handle.getCIntegerAt(offset + offsetOfStartPC, 2, true);
+ }
+
+ public int getEndPC() {
+ return (int) handle.getCIntegerAt(offset + offsetOfEndPC, 2, true);
+ }
+
+ public int getHandlerPC() {
+ return (int) handle.getCIntegerAt(offset + offsetOfHandlerPC, 2, true);
+ }
+
+ public int getCatchTypeIndex() {
+ return (int) handle.getCIntegerAt(offset + offsetOfCatchTypeIndex, 2, true);
+ }
+}
+
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java Fri Jul 27 22:26:19 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -651,10 +651,11 @@
boolean fellThrough = false; // False to get first BB marked.
// First mark all exception handlers as start of a basic-block
- TypeArray excps = method().getExceptionTable();
- for(int i = 0; i < excps.getLength(); i += 4) {
- int handler_pc_idx = i+2;
- markBB(excps.getIntAt(handler_pc_idx), null);
+ if (method().hasExceptionTable()) {
+ ExceptionTableElement[] excps = method().getExceptionTable();
+ for(int i = 0; i < excps.length; i++) {
+ markBB(excps[i].getHandlerPC(), null);
+ }
}
// Then iterate through the code
@@ -891,14 +892,15 @@
// Mark entry basic block as alive and all exception handlers
_basic_blocks[0].markAsAlive();
- TypeArray excps = method().getExceptionTable();
- for(int i = 0; i < excps.getLength(); i += 4) {
- int handler_pc_idx = i+2;
- BasicBlock bb = getBasicBlockAt(excps.getIntAt(handler_pc_idx));
- // If block is not already alive (due to multiple exception handlers to same bb), then
- // make it alive
- if (bb.isDead())
- bb.markAsAlive();
+ if (method().hasExceptionTable()) {
+ ExceptionTableElement[] excps = method().getExceptionTable();
+ for(int i = 0; i < excps.length; i ++) {
+ BasicBlock bb = getBasicBlockAt(excps[i].getHandlerPC());
+ // If block is not already alive (due to multiple exception handlers to same bb), then
+ // make it alive
+ if (bb.isDead())
+ bb.markAsAlive();
+ }
}
BytecodeStream bcs = new BytecodeStream(_method);
@@ -1468,12 +1470,12 @@
if (_has_exceptions) {
int bci = itr.bci();
- TypeArray exct = method().getExceptionTable();
- for(int i = 0; i< exct.getLength(); i+=4) {
- int start_pc = exct.getIntAt(i);
- int end_pc = exct.getIntAt(i+1);
- int handler_pc = exct.getIntAt(i+2);
- int catch_type = exct.getIntAt(i+3);
+ ExceptionTableElement[] exct = method().getExceptionTable();
+ for(int i = 0; i< exct.length; i++) {
+ int start_pc = exct[i].getStartPC();
+ int end_pc = exct[i].getEndPC();
+ int handler_pc = exct[i].getHandlerPC();
+ int catch_type = exct[i].getCatchTypeIndex();
if (start_pc <= bci && bci < end_pc) {
BasicBlock excBB = getBasicBlockAt(handler_pc);
@@ -2151,7 +2153,7 @@
_conflict = false;
_max_locals = (int) method().getMaxLocals();
_max_stack = (int) method().getMaxStack();
- _has_exceptions = (method().getExceptionTable().getLength() > 0);
+ _has_exceptions = (method().hasExceptionTable());
_nof_refval_conflicts = 0;
_init_vars = new ArrayList(5); // There are seldom more than 5 init_vars
_report_result = false;
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Fri Jul 27 22:26:19 2012 -0700
@@ -127,7 +127,6 @@
return getConstMethod().getConstants();
}
public MethodData getMethodData() { return (MethodData) methodData.getValue(this); }
- public TypeArray getExceptionTable() { return getConstMethod().getExceptionTable(); }
/** WARNING: this is in words, not useful in this system; use getObjectSize() instead */
public long getMethodSize() { return methodSize.getValue(this); }
public long getMaxStack() { return maxStack.getValue(this); }
@@ -328,6 +327,14 @@
return null;
}
+ public boolean hasExceptionTable() {
+ return getConstMethod().hasExceptionTable();
+ }
+
+ public ExceptionTableElement[] getExceptionTable() {
+ return getConstMethod().getExceptionTable();
+ }
+
public boolean hasCheckedExceptions() {
return getConstMethod().hasCheckedExceptions();
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java Fri Jul 27 22:26:19 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -504,11 +504,14 @@
2 /* exp. table len. */ +
2 /* code attr. count */;
- TypeArray exceptionTable = m.getExceptionTable();
- final int exceptionTableLen = (int) exceptionTable.getLength();
- if (exceptionTableLen != 0) {
+ boolean hasExceptionTable = m.hasExceptionTable();
+ ExceptionTableElement[] exceptionTable = null;
+ int exceptionTableLen = 0;
+ if (hasExceptionTable) {
+ exceptionTable = m.getExceptionTable();
+ exceptionTableLen = exceptionTable.length;
if (DEBUG) debugMessage("\tmethod has exception table");
- codeSize += (exceptionTableLen / 4) /* exception table is 4-tuple array */
+ codeSize += exceptionTableLen /* exception table is 4-tuple array */
* (2 /* start_pc */ +
2 /* end_pc */ +
2 /* handler_pc */ +
@@ -586,15 +589,15 @@
dos.write(code);
// write exception table size
- dos.writeShort((short) (exceptionTableLen / 4));
- if (DEBUG) debugMessage("\texception table length = " + (exceptionTableLen / 4));
+ dos.writeShort((short) exceptionTableLen);
+ if (DEBUG) debugMessage("\texception table length = " + exceptionTableLen);
if (exceptionTableLen != 0) {
- for (int e = 0; e < exceptionTableLen; e += 4) {
- dos.writeShort((short) exceptionTable.getIntAt(e));
- dos.writeShort((short) exceptionTable.getIntAt(e + 1));
- dos.writeShort((short) exceptionTable.getIntAt(e + 2));
- dos.writeShort((short) exceptionTable.getIntAt(e + 3));
+ for (int e = 0; e < exceptionTableLen; e++) {
+ dos.writeShort((short) exceptionTable[e].getStartPC());
+ dos.writeShort((short) exceptionTable[e].getEndPC());
+ dos.writeShort((short) exceptionTable[e].getHandlerPC());
+ dos.writeShort((short) exceptionTable[e].getCatchTypeIndex());
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Fri Jul 27 22:26:19 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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
@@ -783,37 +783,39 @@
});
// display exception table for this method
- TypeArray exceptionTable = method.getExceptionTable();
- // exception table is 4 tuple array of shorts
- int numEntries = (int)exceptionTable.getLength() / 4;
- if (numEntries != 0) {
- buf.h4("Exception Table");
- buf.beginTable(1);
- buf.beginTag("tr");
- buf.headerCell("start bci");
- buf.headerCell("end bci");
- buf.headerCell("handler bci");
- buf.headerCell("catch type");
- buf.endTag("tr");
-
- for (int e = 0; e < numEntries; e += 4) {
+ boolean hasException = method.hasExceptionTable();
+ if (hasException) {
+ ExceptionTableElement[] exceptionTable = method.getExceptionTable();
+ int numEntries = exceptionTable.length;
+ if (numEntries != 0) {
+ buf.h4("Exception Table");
+ buf.beginTable(1);
buf.beginTag("tr");
- buf.cell(Integer.toString(exceptionTable.getIntAt(e)));
- buf.cell(Integer.toString(exceptionTable.getIntAt(e + 1)));
- buf.cell(Integer.toString(exceptionTable.getIntAt(e + 2)));
- short cpIndex = (short) exceptionTable.getIntAt(e + 3);
- ConstantPool.CPSlot obj = cpIndex == 0? null : cpool.getSlotAt(cpIndex);
- if (obj == null) {
- buf.cell("Any");
- } else if (obj.isMetaData()) {
- buf.cell(obj.getSymbol().asString().replace('/', '.'));
- } else {
- buf.cell(genKlassLink((InstanceKlass)obj.getOop()));
+ buf.headerCell("start bci");
+ buf.headerCell("end bci");
+ buf.headerCell("handler bci");
+ buf.headerCell("catch type");
+ buf.endTag("tr");
+
+ for (int e = 0; e < numEntries; e ++) {
+ buf.beginTag("tr");
+ buf.cell(Integer.toString(exceptionTable[e].getStartPC()));
+ buf.cell(Integer.toString(exceptionTable[e].getEndPC()));
+ buf.cell(Integer.toString(exceptionTable[e].getHandlerPC()));
+ short cpIndex = (short) exceptionTable[e].getCatchTypeIndex();
+ ConstantPool.CPSlot obj = cpIndex == 0? null : cpool.getSlotAt(cpIndex);
+ if (obj == null) {
+ buf.cell("Any");
+ } else if (obj.isMetaData()) {
+ buf.cell(obj.getSymbol().asString().replace('/', '.'));
+ } else {
+ buf.cell(genKlassLink((InstanceKlass)obj.getOop()));
+ }
+ buf.endTag("tr");
}
- buf.endTag("tr");
+
+ buf.endTable();
}
-
- buf.endTable();
}
// display constant pool hyperlink
--- a/hotspot/make/hotspot_version Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/make/hotspot_version Fri Jul 27 22:26:19 2012 -0700
@@ -35,7 +35,7 @@
HS_MAJOR_VER=24
HS_MINOR_VER=0
-HS_BUILD_NUMBER=16
+HS_BUILD_NUMBER=18
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
--- a/hotspot/make/solaris/makefiles/fastdebug.make Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/make/solaris/makefiles/fastdebug.make Fri Jul 27 22:26:19 2012 -0700
@@ -36,6 +36,11 @@
ifeq ("${Platform_compiler}", "sparcWorks")
OPT_CFLAGS/SLOWER = -xO2
+ifeq ($(COMPILER_REV_NUMERIC), 510)
+# CC 5.10 has bug XXXXX with -xO4
+OPT_CFLAGS/jvmtiClassFileReconstituter.o = $(OPT_CFLAGS/SLOWER)
+endif # COMPILER_REV_NUMERIC == 510
+
ifeq ($(COMPILER_REV_NUMERIC), 509)
# To avoid jvm98 crash
OPT_CFLAGS/instanceKlass.o = $(OPT_CFLAGS/SLOWER)
--- a/hotspot/make/solaris/makefiles/optimized.make Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/make/solaris/makefiles/optimized.make Fri Jul 27 22:26:19 2012 -0700
@@ -32,6 +32,11 @@
# (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
ifeq ("${Platform_compiler}", "sparcWorks")
+ifeq ($(COMPILER_REV_NUMERIC), 510)
+# CC 5.10 has bug XXXXX with -xO4
+OPT_CFLAGS/jvmtiClassFileReconstituter.o = $(OPT_CFLAGS/O2)
+endif # COMPILER_REV_NUMERIC == 510
+
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
# dtrace cannot handle tail call optimization (6672627, 6693876)
OPT_CFLAGS/jni.o = $(OPT_CFLAGS/DEFAULT) $(OPT_CCFLAGS/NO_TAIL_CALL_OPT)
--- a/hotspot/make/solaris/makefiles/product.make Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/make/solaris/makefiles/product.make Fri Jul 27 22:26:19 2012 -0700
@@ -40,6 +40,11 @@
# (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
ifeq ("${Platform_compiler}", "sparcWorks")
+ifeq ($(COMPILER_REV_NUMERIC), 510)
+# CC 5.10 has bug XXXXX with -xO4
+OPT_CFLAGS/jvmtiClassFileReconstituter.o = $(OPT_CFLAGS/O2)
+endif # COMPILER_REV_NUMERIC == 510
+
ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
# dtrace cannot handle tail call optimization (6672627, 6693876)
OPT_CFLAGS/jni.o = $(OPT_CFLAGS/DEFAULT) $(OPT_CCFLAGS/NO_TAIL_CALL_OPT)
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -2573,6 +2573,13 @@
emit_byte(0xC0 | encode);
}
+void Assembler::punpcklqdq(XMMRegister dst, XMMRegister src) {
+ NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+ int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66);
+ emit_byte(0x6C);
+ emit_byte(0xC0 | encode);
+}
+
void Assembler::push(int32_t imm32) {
// in 64bits we push 64bits onto the stack but only
// take a 32bit immediate
@@ -3178,6 +3185,13 @@
emit_byte(0xC0 | encode);
}
+void Assembler::vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+ assert(VM_Version::supports_avx2() || (!vector256) && VM_Version::supports_avx(), "");
+ int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256);
+ emit_byte(0xEF);
+ emit_byte(0xC0 | encode);
+}
+
void Assembler::vinsertf128h(XMMRegister dst, XMMRegister nds, XMMRegister src) {
assert(VM_Version::supports_avx(), "");
bool vector256 = true;
@@ -3189,6 +3203,17 @@
emit_byte(0x01);
}
+void Assembler::vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src) {
+ assert(VM_Version::supports_avx2(), "");
+ bool vector256 = true;
+ int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_3A);
+ emit_byte(0x38);
+ emit_byte(0xC0 | encode);
+ // 0x00 - insert into lower 128 bits
+ // 0x01 - insert into upper 128 bits
+ emit_byte(0x01);
+}
+
void Assembler::vzeroupper() {
assert(VM_Version::supports_avx(), "");
(void)vex_prefix_and_encode(xmm0, xmm0, xmm0, VEX_SIMD_NONE);
@@ -7480,6 +7505,24 @@
movb(as_Address(dst), src);
}
+void MacroAssembler::movdl(XMMRegister dst, AddressLiteral src) {
+ if (reachable(src)) {
+ movdl(dst, as_Address(src));
+ } else {
+ lea(rscratch1, src);
+ movdl(dst, Address(rscratch1, 0));
+ }
+}
+
+void MacroAssembler::movq(XMMRegister dst, AddressLiteral src) {
+ if (reachable(src)) {
+ movq(dst, as_Address(src));
+ } else {
+ lea(rscratch1, src);
+ movq(dst, Address(rscratch1, 0));
+ }
+}
+
void MacroAssembler::movdbl(XMMRegister dst, AddressLiteral src) {
if (reachable(src)) {
if (UseXmmLoadAndClearUpper) {
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -1466,6 +1466,9 @@
void punpckldq(XMMRegister dst, XMMRegister src);
void punpckldq(XMMRegister dst, Address src);
+ // Interleave Low Quadwords
+ void punpcklqdq(XMMRegister dst, XMMRegister src);
+
#ifndef _LP64 // no 32bit push/pop on amd64
void pushl(Address src);
#endif
@@ -1606,13 +1609,11 @@
void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0
- // AVX 3-operands instructions (encoded with VEX prefix)
+ // AVX 3-operands scalar instructions (encoded with VEX prefix)
void vaddsd(XMMRegister dst, XMMRegister nds, Address src);
void vaddsd(XMMRegister dst, XMMRegister nds, XMMRegister src);
void vaddss(XMMRegister dst, XMMRegister nds, Address src);
void vaddss(XMMRegister dst, XMMRegister nds, XMMRegister src);
- void vandpd(XMMRegister dst, XMMRegister nds, Address src);
- void vandps(XMMRegister dst, XMMRegister nds, Address src);
void vdivsd(XMMRegister dst, XMMRegister nds, Address src);
void vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src);
void vdivss(XMMRegister dst, XMMRegister nds, Address src);
@@ -1625,13 +1626,17 @@
void vsubsd(XMMRegister dst, XMMRegister nds, XMMRegister src);
void vsubss(XMMRegister dst, XMMRegister nds, Address src);
void vsubss(XMMRegister dst, XMMRegister nds, XMMRegister src);
- void vxorpd(XMMRegister dst, XMMRegister nds, Address src);
- void vxorps(XMMRegister dst, XMMRegister nds, Address src);
// AVX Vector instrucitons.
+ void vandpd(XMMRegister dst, XMMRegister nds, Address src);
+ void vandps(XMMRegister dst, XMMRegister nds, Address src);
+ void vxorpd(XMMRegister dst, XMMRegister nds, Address src);
+ void vxorps(XMMRegister dst, XMMRegister nds, Address src);
void vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
void vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+ void vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
void vinsertf128h(XMMRegister dst, XMMRegister nds, XMMRegister src);
+ void vinserti128h(XMMRegister dst, XMMRegister nds, 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
@@ -2563,6 +2568,20 @@
void vxorps(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vxorps(dst, nds, src); }
void vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src);
+ void vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+ if (UseAVX > 1 || !vector256) // vpxor 256 bit is available only in AVX2
+ Assembler::vpxor(dst, nds, src, vector256);
+ else
+ Assembler::vxorpd(dst, nds, src, vector256);
+ }
+
+ // 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
+ Assembler::vinserti128h(dst, nds, src);
+ else
+ Assembler::vinsertf128h(dst, nds, src);
+ }
// Data
@@ -2615,6 +2634,13 @@
// to avoid hiding movb
void movbyte(ArrayAddress dst, int src);
+ // Import other mov() methods from the parent class or else
+ // they will be hidden by the following overriding declaration.
+ using Assembler::movdl;
+ using Assembler::movq;
+ void movdl(XMMRegister dst, AddressLiteral src);
+ void movq(XMMRegister dst, AddressLiteral src);
+
// Can push value or effective address
void pushptr(AddressLiteral src);
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -562,7 +562,7 @@
AllocatePrefetchInstr = 3;
}
// On family 15h processors use XMM and UnalignedLoadStores for Array Copy
- if( FLAG_IS_DEFAULT(UseXMMForArrayCopy) ) {
+ if( supports_sse2() && FLAG_IS_DEFAULT(UseXMMForArrayCopy) ) {
UseXMMForArrayCopy = true;
}
if( FLAG_IS_DEFAULT(UseUnalignedLoadStores) && UseXMMForArrayCopy ) {
--- a/hotspot/src/cpu/x86/vm/x86.ad Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/cpu/x86/vm/x86.ad Fri Jul 27 22:26:19 2012 -0700
@@ -71,244 +71,244 @@
// XMM0-XMM3 might hold parameters
reg_def XMM0 ( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg());
-reg_def XMM0b( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next());
-reg_def XMM0c( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next()->next());
-reg_def XMM0d( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next()->next()->next());
-reg_def XMM0e( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next()->next()->next()->next());
-reg_def XMM0f( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM0g( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM0h( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM0b( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(1));
+reg_def XMM0c( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(2));
+reg_def XMM0d( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(3));
+reg_def XMM0e( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(4));
+reg_def XMM0f( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(5));
+reg_def XMM0g( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(6));
+reg_def XMM0h( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(7));
reg_def XMM1 ( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg());
-reg_def XMM1b( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next());
-reg_def XMM1c( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next()->next());
-reg_def XMM1d( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next()->next()->next());
-reg_def XMM1e( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next()->next()->next()->next());
-reg_def XMM1f( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM1g( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM1h( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM1b( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(1));
+reg_def XMM1c( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(2));
+reg_def XMM1d( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(3));
+reg_def XMM1e( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(4));
+reg_def XMM1f( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(5));
+reg_def XMM1g( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(6));
+reg_def XMM1h( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(7));
reg_def XMM2 ( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg());
-reg_def XMM2b( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next());
-reg_def XMM2c( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next()->next());
-reg_def XMM2d( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next()->next()->next());
-reg_def XMM2e( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next()->next()->next()->next());
-reg_def XMM2f( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM2g( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM2h( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM2b( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(1));
+reg_def XMM2c( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(2));
+reg_def XMM2d( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(3));
+reg_def XMM2e( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(4));
+reg_def XMM2f( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(5));
+reg_def XMM2g( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(6));
+reg_def XMM2h( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(7));
reg_def XMM3 ( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg());
-reg_def XMM3b( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next());
-reg_def XMM3c( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next()->next());
-reg_def XMM3d( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next()->next()->next());
-reg_def XMM3e( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next()->next()->next()->next());
-reg_def XMM3f( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM3g( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM3h( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM3b( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(1));
+reg_def XMM3c( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(2));
+reg_def XMM3d( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(3));
+reg_def XMM3e( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(4));
+reg_def XMM3f( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(5));
+reg_def XMM3g( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(6));
+reg_def XMM3h( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(7));
reg_def XMM4 ( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg());
-reg_def XMM4b( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next());
-reg_def XMM4c( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next()->next());
-reg_def XMM4d( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next()->next()->next());
-reg_def XMM4e( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next()->next()->next()->next());
-reg_def XMM4f( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM4g( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM4h( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM4b( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(1));
+reg_def XMM4c( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(2));
+reg_def XMM4d( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(3));
+reg_def XMM4e( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(4));
+reg_def XMM4f( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(5));
+reg_def XMM4g( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(6));
+reg_def XMM4h( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(7));
reg_def XMM5 ( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg());
-reg_def XMM5b( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next());
-reg_def XMM5c( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next()->next());
-reg_def XMM5d( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next()->next()->next());
-reg_def XMM5e( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next()->next()->next()->next());
-reg_def XMM5f( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM5g( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM5h( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM5b( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(1));
+reg_def XMM5c( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(2));
+reg_def XMM5d( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(3));
+reg_def XMM5e( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(4));
+reg_def XMM5f( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(5));
+reg_def XMM5g( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(6));
+reg_def XMM5h( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(7));
#ifdef _WIN64
reg_def XMM6 ( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg());
-reg_def XMM6b( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next());
-reg_def XMM6c( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next()->next());
-reg_def XMM6d( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next()->next()->next());
-reg_def XMM6e( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next()->next()->next()->next());
-reg_def XMM6f( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM6g( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM6h( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM6b( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(1));
+reg_def XMM6c( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(2));
+reg_def XMM6d( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(3));
+reg_def XMM6e( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(4));
+reg_def XMM6f( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(5));
+reg_def XMM6g( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(6));
+reg_def XMM6h( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(7));
reg_def XMM7 ( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg());
-reg_def XMM7b( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next());
-reg_def XMM7c( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next()->next());
-reg_def XMM7d( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next()->next()->next());
-reg_def XMM7e( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next()->next()->next()->next());
-reg_def XMM7f( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM7g( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM7h( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM7b( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(1));
+reg_def XMM7c( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(2));
+reg_def XMM7d( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(3));
+reg_def XMM7e( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(4));
+reg_def XMM7f( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(5));
+reg_def XMM7g( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(6));
+reg_def XMM7h( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(7));
reg_def XMM8 ( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg());
-reg_def XMM8b( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next());
-reg_def XMM8c( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next()->next());
-reg_def XMM8d( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next()->next()->next());
-reg_def XMM8e( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next()->next()->next()->next());
-reg_def XMM8f( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM8g( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM8h( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM8b( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(1));
+reg_def XMM8c( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(2));
+reg_def XMM8d( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(3));
+reg_def XMM8e( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(4));
+reg_def XMM8f( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(5));
+reg_def XMM8g( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(6));
+reg_def XMM8h( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(7));
reg_def XMM9 ( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg());
-reg_def XMM9b( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next());
-reg_def XMM9c( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next()->next());
-reg_def XMM9d( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next()->next()->next());
-reg_def XMM9e( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next()->next()->next()->next());
-reg_def XMM9f( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM9g( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM9h( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM9b( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(1));
+reg_def XMM9c( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(2));
+reg_def XMM9d( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(3));
+reg_def XMM9e( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(4));
+reg_def XMM9f( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(5));
+reg_def XMM9g( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(6));
+reg_def XMM9h( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(7));
reg_def XMM10 ( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg());
-reg_def XMM10b( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next());
-reg_def XMM10c( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next()->next());
-reg_def XMM10d( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next()->next()->next());
-reg_def XMM10e( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next()->next()->next()->next());
-reg_def XMM10f( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM10g( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM10h( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM10b( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(1));
+reg_def XMM10c( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(2));
+reg_def XMM10d( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(3));
+reg_def XMM10e( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(4));
+reg_def XMM10f( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(5));
+reg_def XMM10g( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(6));
+reg_def XMM10h( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(7));
reg_def XMM11 ( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg());
-reg_def XMM11b( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next());
-reg_def XMM11c( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next()->next());
-reg_def XMM11d( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next()->next()->next());
-reg_def XMM11e( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next()->next()->next()->next());
-reg_def XMM11f( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM11g( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM11h( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM11b( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(1));
+reg_def XMM11c( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(2));
+reg_def XMM11d( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(3));
+reg_def XMM11e( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(4));
+reg_def XMM11f( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(5));
+reg_def XMM11g( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(6));
+reg_def XMM11h( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(7));
reg_def XMM12 ( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg());
-reg_def XMM12b( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next());
-reg_def XMM12c( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next()->next());
-reg_def XMM12d( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next()->next()->next());
-reg_def XMM12e( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next()->next()->next()->next());
-reg_def XMM12f( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM12g( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM12h( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM12b( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(1));
+reg_def XMM12c( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(2));
+reg_def XMM12d( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(3));
+reg_def XMM12e( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(4));
+reg_def XMM12f( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(5));
+reg_def XMM12g( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(6));
+reg_def XMM12h( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(7));
reg_def XMM13 ( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg());
-reg_def XMM13b( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next());
-reg_def XMM13c( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next()->next());
-reg_def XMM13d( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next()->next()->next());
-reg_def XMM13e( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next()->next()->next()->next());
-reg_def XMM13f( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM13g( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM13h( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM13b( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(1));
+reg_def XMM13c( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(2));
+reg_def XMM13d( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(3));
+reg_def XMM13e( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(4));
+reg_def XMM13f( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(5));
+reg_def XMM13g( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(6));
+reg_def XMM13h( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(7));
reg_def XMM14 ( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg());
-reg_def XMM14b( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next());
-reg_def XMM14c( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next()->next());
-reg_def XMM14d( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next()->next()->next());
-reg_def XMM14e( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next()->next()->next()->next());
-reg_def XMM14f( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM14g( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM14h( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM14b( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(1));
+reg_def XMM14c( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(2));
+reg_def XMM14d( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(3));
+reg_def XMM14e( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(4));
+reg_def XMM14f( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(5));
+reg_def XMM14g( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(6));
+reg_def XMM14h( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(7));
reg_def XMM15 ( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg());
-reg_def XMM15b( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next());
-reg_def XMM15c( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next()->next());
-reg_def XMM15d( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next()->next()->next());
-reg_def XMM15e( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next()->next()->next()->next());
-reg_def XMM15f( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM15g( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM15h( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM15b( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(1));
+reg_def XMM15c( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(2));
+reg_def XMM15d( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(3));
+reg_def XMM15e( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(4));
+reg_def XMM15f( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(5));
+reg_def XMM15g( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(6));
+reg_def XMM15h( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(7));
#else // _WIN64
reg_def XMM6 ( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg());
-reg_def XMM6b( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next());
-reg_def XMM6c( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next()->next());
-reg_def XMM6d( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next()->next()->next());
-reg_def XMM6e( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next()->next()->next()->next());
-reg_def XMM6f( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM6g( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM6h( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM6b( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(1));
+reg_def XMM6c( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(2));
+reg_def XMM6d( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(3));
+reg_def XMM6e( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(4));
+reg_def XMM6f( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(5));
+reg_def XMM6g( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(6));
+reg_def XMM6h( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(7));
reg_def XMM7 ( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg());
-reg_def XMM7b( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next());
-reg_def XMM7c( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next()->next());
-reg_def XMM7d( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next()->next()->next());
-reg_def XMM7e( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next()->next()->next()->next());
-reg_def XMM7f( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM7g( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM7h( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM7b( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(1));
+reg_def XMM7c( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(2));
+reg_def XMM7d( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(3));
+reg_def XMM7e( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(4));
+reg_def XMM7f( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(5));
+reg_def XMM7g( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(6));
+reg_def XMM7h( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(7));
#ifdef _LP64
reg_def XMM8 ( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg());
-reg_def XMM8b( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next());
-reg_def XMM8c( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next()->next());
-reg_def XMM8d( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next()->next()->next());
-reg_def XMM8e( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next()->next()->next()->next());
-reg_def XMM8f( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM8g( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM8h( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM8b( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(1));
+reg_def XMM8c( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(2));
+reg_def XMM8d( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(3));
+reg_def XMM8e( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(4));
+reg_def XMM8f( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(5));
+reg_def XMM8g( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(6));
+reg_def XMM8h( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(7));
reg_def XMM9 ( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg());
-reg_def XMM9b( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next());
-reg_def XMM9c( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next()->next());
-reg_def XMM9d( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next()->next()->next());
-reg_def XMM9e( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next()->next()->next()->next());
-reg_def XMM9f( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM9g( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM9h( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM9b( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(1));
+reg_def XMM9c( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(2));
+reg_def XMM9d( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(3));
+reg_def XMM9e( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(4));
+reg_def XMM9f( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(5));
+reg_def XMM9g( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(6));
+reg_def XMM9h( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(7));
reg_def XMM10 ( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg());
-reg_def XMM10b( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next());
-reg_def XMM10c( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next()->next());
-reg_def XMM10d( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next()->next()->next());
-reg_def XMM10e( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next()->next()->next()->next());
-reg_def XMM10f( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM10g( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM10h( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM10b( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(1));
+reg_def XMM10c( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(2));
+reg_def XMM10d( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(3));
+reg_def XMM10e( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(4));
+reg_def XMM10f( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(5));
+reg_def XMM10g( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(6));
+reg_def XMM10h( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(7));
reg_def XMM11 ( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg());
-reg_def XMM11b( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next());
-reg_def XMM11c( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next()->next());
-reg_def XMM11d( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next()->next()->next());
-reg_def XMM11e( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next()->next()->next()->next());
-reg_def XMM11f( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM11g( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM11h( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM11b( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(1));
+reg_def XMM11c( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(2));
+reg_def XMM11d( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(3));
+reg_def XMM11e( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(4));
+reg_def XMM11f( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(5));
+reg_def XMM11g( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(6));
+reg_def XMM11h( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(7));
reg_def XMM12 ( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg());
-reg_def XMM12b( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next());
-reg_def XMM12c( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next()->next());
-reg_def XMM12d( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next()->next()->next());
-reg_def XMM12e( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next()->next()->next()->next());
-reg_def XMM12f( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM12g( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM12h( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM12b( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(1));
+reg_def XMM12c( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(2));
+reg_def XMM12d( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(3));
+reg_def XMM12e( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(4));
+reg_def XMM12f( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(5));
+reg_def XMM12g( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(6));
+reg_def XMM12h( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(7));
reg_def XMM13 ( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg());
-reg_def XMM13b( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next());
-reg_def XMM13c( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next()->next());
-reg_def XMM13d( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next()->next()->next());
-reg_def XMM13e( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next()->next()->next()->next());
-reg_def XMM13f( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM13g( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM13h( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM13b( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(1));
+reg_def XMM13c( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(2));
+reg_def XMM13d( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(3));
+reg_def XMM13e( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(4));
+reg_def XMM13f( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(5));
+reg_def XMM13g( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(6));
+reg_def XMM13h( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(7));
reg_def XMM14 ( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg());
-reg_def XMM14b( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next());
-reg_def XMM14c( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next()->next());
-reg_def XMM14d( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next()->next()->next());
-reg_def XMM14e( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next()->next()->next()->next());
-reg_def XMM14f( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM14g( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM14h( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM14b( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(1));
+reg_def XMM14c( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(2));
+reg_def XMM14d( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(3));
+reg_def XMM14e( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(4));
+reg_def XMM14f( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(5));
+reg_def XMM14g( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(6));
+reg_def XMM14h( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(7));
reg_def XMM15 ( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg());
-reg_def XMM15b( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next());
-reg_def XMM15c( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next()->next());
-reg_def XMM15d( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next()->next()->next());
-reg_def XMM15e( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next()->next()->next()->next());
-reg_def XMM15f( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next()->next()->next()->next()->next());
-reg_def XMM15g( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next()->next()->next()->next()->next()->next());
-reg_def XMM15h( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next()->next()->next()->next()->next()->next()->next());
+reg_def XMM15b( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(1));
+reg_def XMM15c( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(2));
+reg_def XMM15d( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(3));
+reg_def XMM15e( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(4));
+reg_def XMM15f( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(5));
+reg_def XMM15g( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(6));
+reg_def XMM15h( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(7));
#endif // _LP64
@@ -889,7 +889,7 @@
ins_pipe(pipe_slow);
%}
-instruct vaddF_reg(regF dst, regF src1, regF src2) %{
+instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
predicate(UseAVX > 0);
match(Set dst (AddF src1 src2));
@@ -901,7 +901,7 @@
ins_pipe(pipe_slow);
%}
-instruct vaddF_mem(regF dst, regF src1, memory src2) %{
+instruct addF_reg_mem(regF dst, regF src1, memory src2) %{
predicate(UseAVX > 0);
match(Set dst (AddF src1 (LoadF src2)));
@@ -913,7 +913,7 @@
ins_pipe(pipe_slow);
%}
-instruct vaddF_imm(regF dst, regF src, immF con) %{
+instruct addF_reg_imm(regF dst, regF src, immF con) %{
predicate(UseAVX > 0);
match(Set dst (AddF src con));
@@ -960,7 +960,7 @@
ins_pipe(pipe_slow);
%}
-instruct vaddD_reg(regD dst, regD src1, regD src2) %{
+instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
predicate(UseAVX > 0);
match(Set dst (AddD src1 src2));
@@ -972,7 +972,7 @@
ins_pipe(pipe_slow);
%}
-instruct vaddD_mem(regD dst, regD src1, memory src2) %{
+instruct addD_reg_mem(regD dst, regD src1, memory src2) %{
predicate(UseAVX > 0);
match(Set dst (AddD src1 (LoadD src2)));
@@ -984,7 +984,7 @@
ins_pipe(pipe_slow);
%}
-instruct vaddD_imm(regD dst, regD src, immD con) %{
+instruct addD_reg_imm(regD dst, regD src, immD con) %{
predicate(UseAVX > 0);
match(Set dst (AddD src con));
@@ -1031,7 +1031,7 @@
ins_pipe(pipe_slow);
%}
-instruct vsubF_reg(regF dst, regF src1, regF src2) %{
+instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
predicate(UseAVX > 0);
match(Set dst (SubF src1 src2));
@@ -1043,7 +1043,7 @@
ins_pipe(pipe_slow);
%}
-instruct vsubF_mem(regF dst, regF src1, memory src2) %{
+instruct subF_reg_mem(regF dst, regF src1, memory src2) %{
predicate(UseAVX > 0);
match(Set dst (SubF src1 (LoadF src2)));
@@ -1055,7 +1055,7 @@
ins_pipe(pipe_slow);
%}
-instruct vsubF_imm(regF dst, regF src, immF con) %{
+instruct subF_reg_imm(regF dst, regF src, immF con) %{
predicate(UseAVX > 0);
match(Set dst (SubF src con));
@@ -1102,7 +1102,7 @@
ins_pipe(pipe_slow);
%}
-instruct vsubD_reg(regD dst, regD src1, regD src2) %{
+instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
predicate(UseAVX > 0);
match(Set dst (SubD src1 src2));
@@ -1114,7 +1114,7 @@
ins_pipe(pipe_slow);
%}
-instruct vsubD_mem(regD dst, regD src1, memory src2) %{
+instruct subD_reg_mem(regD dst, regD src1, memory src2) %{
predicate(UseAVX > 0);
match(Set dst (SubD src1 (LoadD src2)));
@@ -1126,7 +1126,7 @@
ins_pipe(pipe_slow);
%}
-instruct vsubD_imm(regD dst, regD src, immD con) %{
+instruct subD_reg_imm(regD dst, regD src, immD con) %{
predicate(UseAVX > 0);
match(Set dst (SubD src con));
@@ -1173,7 +1173,7 @@
ins_pipe(pipe_slow);
%}
-instruct vmulF_reg(regF dst, regF src1, regF src2) %{
+instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
predicate(UseAVX > 0);
match(Set dst (MulF src1 src2));
@@ -1185,7 +1185,7 @@
ins_pipe(pipe_slow);
%}
-instruct vmulF_mem(regF dst, regF src1, memory src2) %{
+instruct mulF_reg_mem(regF dst, regF src1, memory src2) %{
predicate(UseAVX > 0);
match(Set dst (MulF src1 (LoadF src2)));
@@ -1197,7 +1197,7 @@
ins_pipe(pipe_slow);
%}
-instruct vmulF_imm(regF dst, regF src, immF con) %{
+instruct mulF_reg_imm(regF dst, regF src, immF con) %{
predicate(UseAVX > 0);
match(Set dst (MulF src con));
@@ -1244,7 +1244,7 @@
ins_pipe(pipe_slow);
%}
-instruct vmulD_reg(regD dst, regD src1, regD src2) %{
+instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
predicate(UseAVX > 0);
match(Set dst (MulD src1 src2));
@@ -1256,7 +1256,7 @@
ins_pipe(pipe_slow);
%}
-instruct vmulD_mem(regD dst, regD src1, memory src2) %{
+instruct mulD_reg_mem(regD dst, regD src1, memory src2) %{
predicate(UseAVX > 0);
match(Set dst (MulD src1 (LoadD src2)));
@@ -1268,7 +1268,7 @@
ins_pipe(pipe_slow);
%}
-instruct vmulD_imm(regD dst, regD src, immD con) %{
+instruct mulD_reg_imm(regD dst, regD src, immD con) %{
predicate(UseAVX > 0);
match(Set dst (MulD src con));
@@ -1315,7 +1315,7 @@
ins_pipe(pipe_slow);
%}
-instruct vdivF_reg(regF dst, regF src1, regF src2) %{
+instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
predicate(UseAVX > 0);
match(Set dst (DivF src1 src2));
@@ -1327,7 +1327,7 @@
ins_pipe(pipe_slow);
%}
-instruct vdivF_mem(regF dst, regF src1, memory src2) %{
+instruct divF_reg_mem(regF dst, regF src1, memory src2) %{
predicate(UseAVX > 0);
match(Set dst (DivF src1 (LoadF src2)));
@@ -1339,7 +1339,7 @@
ins_pipe(pipe_slow);
%}
-instruct vdivF_imm(regF dst, regF src, immF con) %{
+instruct divF_reg_imm(regF dst, regF src, immF con) %{
predicate(UseAVX > 0);
match(Set dst (DivF src con));
@@ -1386,7 +1386,7 @@
ins_pipe(pipe_slow);
%}
-instruct vdivD_reg(regD dst, regD src1, regD src2) %{
+instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
predicate(UseAVX > 0);
match(Set dst (DivD src1 src2));
@@ -1398,7 +1398,7 @@
ins_pipe(pipe_slow);
%}
-instruct vdivD_mem(regD dst, regD src1, memory src2) %{
+instruct divD_reg_mem(regD dst, regD src1, memory src2) %{
predicate(UseAVX > 0);
match(Set dst (DivD src1 (LoadD src2)));
@@ -1410,7 +1410,7 @@
ins_pipe(pipe_slow);
%}
-instruct vdivD_imm(regD dst, regD src, immD con) %{
+instruct divD_reg_imm(regD dst, regD src, immD con) %{
predicate(UseAVX > 0);
match(Set dst (DivD src con));
@@ -1433,7 +1433,7 @@
ins_pipe(pipe_slow);
%}
-instruct vabsF_reg(regF dst, regF src) %{
+instruct absF_reg_reg(regF dst, regF src) %{
predicate(UseAVX > 0);
match(Set dst (AbsF src));
ins_cost(150);
@@ -1457,7 +1457,7 @@
ins_pipe(pipe_slow);
%}
-instruct vabsD_reg(regD dst, regD src) %{
+instruct absD_reg_reg(regD dst, regD src) %{
predicate(UseAVX > 0);
match(Set dst (AbsD src));
ins_cost(150);
@@ -1481,7 +1481,7 @@
ins_pipe(pipe_slow);
%}
-instruct vnegF_reg(regF dst, regF src) %{
+instruct negF_reg_reg(regF dst, regF src) %{
predicate(UseAVX > 0);
match(Set dst (NegF src));
ins_cost(150);
@@ -1505,7 +1505,7 @@
ins_pipe(pipe_slow);
%}
-instruct vnegD_reg(regD dst, regD src) %{
+instruct negD_reg_reg(regD dst, regD src) %{
predicate(UseAVX > 0);
match(Set dst (NegD src));
ins_cost(150);
@@ -1719,12 +1719,12 @@
format %{ "movd $dst,$src\n\t"
"punpcklbw $dst,$dst\n\t"
"pshuflw $dst,$dst,0x00\n\t"
- "movlhps $dst,$dst\t! replicate16B" %}
+ "punpcklqdq $dst,$dst\t! replicate16B" %}
ins_encode %{
__ movdl($dst$$XMMRegister, $src$$Register);
__ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
__ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -1735,14 +1735,14 @@
format %{ "movd $dst,$src\n\t"
"punpcklbw $dst,$dst\n\t"
"pshuflw $dst,$dst,0x00\n\t"
- "movlhps $dst,$dst\n\t"
- "vinsertf128h $dst,$dst,$dst\t! replicate32B" %}
+ "punpcklqdq $dst,$dst\n\t"
+ "vinserti128h $dst,$dst,$dst\t! replicate32B" %}
ins_encode %{
__ movdl($dst$$XMMRegister, $src$$Register);
__ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
__ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
- __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+ __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -1751,9 +1751,9 @@
instruct Repl4B_imm(vecS dst, immI con) %{
predicate(n->as_Vector()->length() == 4);
match(Set dst (ReplicateB con));
- format %{ "movss $dst,[$constantaddress]\t! replicate4B($con)" %}
+ format %{ "movdl $dst,[$constantaddress]\t! replicate4B($con)" %}
ins_encode %{
- __ movflt($dst$$XMMRegister, $constantaddress(replicate4_imm($con$$constant, 1)));
+ __ movdl($dst$$XMMRegister, $constantaddress(replicate4_imm($con$$constant, 1)));
%}
ins_pipe( pipe_slow );
%}
@@ -1761,9 +1761,9 @@
instruct Repl8B_imm(vecD dst, immI con) %{
predicate(n->as_Vector()->length() == 8);
match(Set dst (ReplicateB con));
- format %{ "movsd $dst,[$constantaddress]\t! replicate8B($con)" %}
+ format %{ "movq $dst,[$constantaddress]\t! replicate8B($con)" %}
ins_encode %{
- __ movdbl($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 1)));
+ __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 1)));
%}
ins_pipe( pipe_slow );
%}
@@ -1771,11 +1771,11 @@
instruct Repl16B_imm(vecX dst, immI con) %{
predicate(n->as_Vector()->length() == 16);
match(Set dst (ReplicateB con));
- format %{ "movsd $dst,[$constantaddress]\t! replicate16B($con)\n\t"
- "movlhps $dst,$dst" %}
+ format %{ "movq $dst,[$constantaddress]\n\t"
+ "punpcklqdq $dst,$dst\t! replicate16B($con)" %}
ins_encode %{
- __ movdbl($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 1)));
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
+ __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 1)));
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -1783,13 +1783,13 @@
instruct Repl32B_imm(vecY dst, immI con) %{
predicate(n->as_Vector()->length() == 32);
match(Set dst (ReplicateB con));
- format %{ "movsd $dst,[$constantaddress]\t! lreplicate32B($con)\n\t"
- "movlhps $dst,$dst\n\t"
- "vinsertf128h $dst,$dst,$dst" %}
+ format %{ "movq $dst,[$constantaddress]\n\t"
+ "punpcklqdq $dst,$dst\n\t"
+ "vinserti128h $dst,$dst,$dst\t! lreplicate32B($con)" %}
ins_encode %{
- __ movdbl($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 1)));
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
- __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+ __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 1)));
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+ __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -1828,11 +1828,11 @@
instruct Repl32B_zero(vecY dst, immI0 zero) %{
predicate(n->as_Vector()->length() == 32);
match(Set dst (ReplicateB zero));
- format %{ "vxorpd $dst,$dst,$dst\t! replicate32B zero" %}
+ format %{ "vpxor $dst,$dst,$dst\t! replicate32B zero" %}
ins_encode %{
// Use vxorpd since AVX does not have vpxor for 256-bit (AVX2 will have it).
bool vector256 = true;
- __ vxorpd($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
+ __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
%}
ins_pipe( fpu_reg_reg );
%}
@@ -1867,11 +1867,11 @@
match(Set dst (ReplicateS src));
format %{ "movd $dst,$src\n\t"
"pshuflw $dst,$dst,0x00\n\t"
- "movlhps $dst,$dst\t! replicate8S" %}
+ "punpcklqdq $dst,$dst\t! replicate8S" %}
ins_encode %{
__ movdl($dst$$XMMRegister, $src$$Register);
__ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -1881,13 +1881,13 @@
match(Set dst (ReplicateS src));
format %{ "movd $dst,$src\n\t"
"pshuflw $dst,$dst,0x00\n\t"
- "movlhps $dst,$dst\n\t"
- "vinsertf128h $dst,$dst,$dst\t! replicate16S" %}
+ "punpcklqdq $dst,$dst\n\t"
+ "vinserti128h $dst,$dst,$dst\t! replicate16S" %}
ins_encode %{
__ movdl($dst$$XMMRegister, $src$$Register);
__ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
- __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+ __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -1896,9 +1896,9 @@
instruct Repl2S_imm(vecS dst, immI con) %{
predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateS con));
- format %{ "movss $dst,[$constantaddress]\t! replicate2S($con)" %}
+ format %{ "movdl $dst,[$constantaddress]\t! replicate2S($con)" %}
ins_encode %{
- __ movflt($dst$$XMMRegister, $constantaddress(replicate4_imm($con$$constant, 2)));
+ __ movdl($dst$$XMMRegister, $constantaddress(replicate4_imm($con$$constant, 2)));
%}
ins_pipe( fpu_reg_reg );
%}
@@ -1906,9 +1906,9 @@
instruct Repl4S_imm(vecD dst, immI con) %{
predicate(n->as_Vector()->length() == 4);
match(Set dst (ReplicateS con));
- format %{ "movsd $dst,[$constantaddress]\t! replicate4S($con)" %}
+ format %{ "movq $dst,[$constantaddress]\t! replicate4S($con)" %}
ins_encode %{
- __ movdbl($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 2)));
+ __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 2)));
%}
ins_pipe( fpu_reg_reg );
%}
@@ -1916,11 +1916,11 @@
instruct Repl8S_imm(vecX dst, immI con) %{
predicate(n->as_Vector()->length() == 8);
match(Set dst (ReplicateS con));
- format %{ "movsd $dst,[$constantaddress]\t! replicate8S($con)\n\t"
- "movlhps $dst,$dst" %}
+ format %{ "movq $dst,[$constantaddress]\n\t"
+ "punpcklqdq $dst,$dst\t! replicate8S($con)" %}
ins_encode %{
- __ movdbl($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 2)));
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
+ __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 2)));
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -1928,13 +1928,13 @@
instruct Repl16S_imm(vecY dst, immI con) %{
predicate(n->as_Vector()->length() == 16);
match(Set dst (ReplicateS con));
- format %{ "movsd $dst,[$constantaddress]\t! replicate16S($con)\n\t"
- "movlhps $dst,$dst\n\t"
- "vinsertf128h $dst,$dst,$dst" %}
+ format %{ "movq $dst,[$constantaddress]\n\t"
+ "punpcklqdq $dst,$dst\n\t"
+ "vinserti128h $dst,$dst,$dst\t! replicate16S($con)" %}
ins_encode %{
- __ movdbl($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 2)));
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
- __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+ __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 2)));
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+ __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -1973,11 +1973,11 @@
instruct Repl16S_zero(vecY dst, immI0 zero) %{
predicate(n->as_Vector()->length() == 16);
match(Set dst (ReplicateS zero));
- format %{ "vxorpd $dst,$dst,$dst\t! replicate16S zero" %}
+ format %{ "vpxor $dst,$dst,$dst\t! replicate16S zero" %}
ins_encode %{
// Use vxorpd since AVX does not have vpxor for 256-bit (AVX2 will have it).
bool vector256 = true;
- __ vxorpd($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
+ __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
%}
ins_pipe( fpu_reg_reg );
%}
@@ -2012,11 +2012,11 @@
match(Set dst (ReplicateI src));
format %{ "movd $dst,$src\n\t"
"pshufd $dst,$dst,0x00\n\t"
- "vinsertf128h $dst,$dst,$dst\t! replicate8I" %}
+ "vinserti128h $dst,$dst,$dst\t! replicate8I" %}
ins_encode %{
__ movdl($dst$$XMMRegister, $src$$Register);
__ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
- __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+ __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -2025,9 +2025,9 @@
instruct Repl2I_imm(vecD dst, immI con) %{
predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateI con));
- format %{ "movsd $dst,[$constantaddress]\t! replicate2I($con)" %}
+ format %{ "movq $dst,[$constantaddress]\t! replicate2I($con)" %}
ins_encode %{
- __ movdbl($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 4)));
+ __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 4)));
%}
ins_pipe( fpu_reg_reg );
%}
@@ -2035,11 +2035,11 @@
instruct Repl4I_imm(vecX dst, immI con) %{
predicate(n->as_Vector()->length() == 4);
match(Set dst (ReplicateI con));
- format %{ "movsd $dst,[$constantaddress]\t! replicate4I($con)\n\t"
- "movlhps $dst,$dst" %}
+ format %{ "movq $dst,[$constantaddress]\t! replicate4I($con)\n\t"
+ "punpcklqdq $dst,$dst" %}
ins_encode %{
- __ movdbl($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 4)));
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
+ __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 4)));
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -2047,13 +2047,13 @@
instruct Repl8I_imm(vecY dst, immI con) %{
predicate(n->as_Vector()->length() == 8);
match(Set dst (ReplicateI con));
- format %{ "movsd $dst,[$constantaddress]\t! replicate8I($con)\n\t"
- "movlhps $dst,$dst\n\t"
- "vinsertf128h $dst,$dst,$dst" %}
+ format %{ "movq $dst,[$constantaddress]\t! replicate8I($con)\n\t"
+ "punpcklqdq $dst,$dst\n\t"
+ "vinserti128h $dst,$dst,$dst" %}
ins_encode %{
- __ movdbl($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 4)));
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
- __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+ __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 4)));
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+ __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -2061,7 +2061,7 @@
// Integer could be loaded into xmm register directly from memory.
instruct Repl2I_mem(vecD dst, memory mem) %{
predicate(n->as_Vector()->length() == 2);
- match(Set dst (ReplicateI (LoadVector mem)));
+ match(Set dst (ReplicateI (LoadI mem)));
format %{ "movd $dst,$mem\n\t"
"pshufd $dst,$dst,0x00\t! replicate2I" %}
ins_encode %{
@@ -2073,7 +2073,7 @@
instruct Repl4I_mem(vecX dst, memory mem) %{
predicate(n->as_Vector()->length() == 4);
- match(Set dst (ReplicateI (LoadVector mem)));
+ match(Set dst (ReplicateI (LoadI mem)));
format %{ "movd $dst,$mem\n\t"
"pshufd $dst,$dst,0x00\t! replicate4I" %}
ins_encode %{
@@ -2085,14 +2085,14 @@
instruct Repl8I_mem(vecY dst, memory mem) %{
predicate(n->as_Vector()->length() == 8);
- match(Set dst (ReplicateI (LoadVector mem)));
+ match(Set dst (ReplicateI (LoadI mem)));
format %{ "movd $dst,$mem\n\t"
"pshufd $dst,$dst,0x00\n\t"
- "vinsertf128h $dst,$dst,$dst\t! replicate8I" %}
+ "vinserti128h $dst,$dst,$dst\t! replicate8I" %}
ins_encode %{
__ movdl($dst$$XMMRegister, $mem$$Address);
__ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
- __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+ __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -2121,11 +2121,11 @@
instruct Repl8I_zero(vecY dst, immI0 zero) %{
predicate(n->as_Vector()->length() == 8);
match(Set dst (ReplicateI zero));
- format %{ "vxorpd $dst,$dst,$dst\t! replicate8I zero" %}
+ format %{ "vpxor $dst,$dst,$dst\t! replicate8I zero" %}
ins_encode %{
// Use vxorpd since AVX does not have vpxor for 256-bit (AVX2 will have it).
bool vector256 = true;
- __ vxorpd($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
+ __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
%}
ins_pipe( fpu_reg_reg );
%}
@@ -2136,10 +2136,10 @@
predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateL src));
format %{ "movdq $dst,$src\n\t"
- "movlhps $dst,$dst\t! replicate2L" %}
+ "punpcklqdq $dst,$dst\t! replicate2L" %}
ins_encode %{
__ movdq($dst$$XMMRegister, $src$$Register);
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -2148,12 +2148,12 @@
predicate(n->as_Vector()->length() == 4);
match(Set dst (ReplicateL src));
format %{ "movdq $dst,$src\n\t"
- "movlhps $dst,$dst\n\t"
- "vinsertf128h $dst,$dst,$dst\t! replicate4L" %}
+ "punpcklqdq $dst,$dst\n\t"
+ "vinserti128h $dst,$dst,$dst\t! replicate4L" %}
ins_encode %{
__ movdq($dst$$XMMRegister, $src$$Register);
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
- __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+ __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -2165,12 +2165,12 @@
format %{ "movdl $dst,$src.lo\n\t"
"movdl $tmp,$src.hi\n\t"
"punpckldq $dst,$tmp\n\t"
- "movlhps $dst,$dst\t! replicate2L"%}
+ "punpcklqdq $dst,$dst\t! replicate2L"%}
ins_encode %{
__ movdl($dst$$XMMRegister, $src$$Register);
__ movdl($tmp$$XMMRegister, HIGH_FROM_LOW($src$$Register));
__ punpckldq($dst$$XMMRegister, $tmp$$XMMRegister);
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -2182,14 +2182,14 @@
format %{ "movdl $dst,$src.lo\n\t"
"movdl $tmp,$src.hi\n\t"
"punpckldq $dst,$tmp\n\t"
- "movlhps $dst,$dst\n\t"
- "vinsertf128h $dst,$dst,$dst\t! replicate4L" %}
+ "punpcklqdq $dst,$dst\n\t"
+ "vinserti128h $dst,$dst,$dst\t! replicate4L" %}
ins_encode %{
__ movdl($dst$$XMMRegister, $src$$Register);
__ movdl($tmp$$XMMRegister, HIGH_FROM_LOW($src$$Register));
__ punpckldq($dst$$XMMRegister, $tmp$$XMMRegister);
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
- __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+ __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -2199,11 +2199,11 @@
instruct Repl2L_imm(vecX dst, immL con) %{
predicate(n->as_Vector()->length() == 2);
match(Set dst (ReplicateL con));
- format %{ "movsd $dst,[$constantaddress]\t! replicate2L($con)\n\t"
- "movlhps $dst,$dst" %}
+ format %{ "movq $dst,[$constantaddress]\n\t"
+ "punpcklqdq $dst,$dst\t! replicate2L($con)" %}
ins_encode %{
- __ movdbl($dst$$XMMRegister, $constantaddress($con));
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
+ __ movq($dst$$XMMRegister, $constantaddress($con));
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -2211,13 +2211,13 @@
instruct Repl4L_imm(vecY dst, immL con) %{
predicate(n->as_Vector()->length() == 4);
match(Set dst (ReplicateL con));
- format %{ "movsd $dst,[$constantaddress]\t! replicate4L($con)\n\t"
- "movlhps $dst,$dst\n\t"
- "vinsertf128h $dst,$dst,$dst" %}
+ format %{ "movq $dst,[$constantaddress]\n\t"
+ "punpcklqdq $dst,$dst\n\t"
+ "vinserti128h $dst,$dst,$dst\t! replicate4L($con)" %}
ins_encode %{
- __ movdbl($dst$$XMMRegister, $constantaddress($con));
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
- __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+ __ movq($dst$$XMMRegister, $constantaddress($con));
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+ __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -2225,26 +2225,26 @@
// Long could be loaded into xmm register directly from memory.
instruct Repl2L_mem(vecX dst, memory mem) %{
predicate(n->as_Vector()->length() == 2);
- match(Set dst (ReplicateL (LoadVector mem)));
+ match(Set dst (ReplicateL (LoadL mem)));
format %{ "movq $dst,$mem\n\t"
- "movlhps $dst,$dst\t! replicate2L" %}
+ "punpcklqdq $dst,$dst\t! replicate2L" %}
ins_encode %{
__ movq($dst$$XMMRegister, $mem$$Address);
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
instruct Repl4L_mem(vecY dst, memory mem) %{
predicate(n->as_Vector()->length() == 4);
- match(Set dst (ReplicateL (LoadVector mem)));
+ match(Set dst (ReplicateL (LoadL mem)));
format %{ "movq $dst,$mem\n\t"
- "movlhps $dst,$dst\n\t"
- "vinsertf128h $dst,$dst,$dst\t! replicate4L" %}
+ "punpcklqdq $dst,$dst\n\t"
+ "vinserti128h $dst,$dst,$dst\t! replicate4L" %}
ins_encode %{
__ movq($dst$$XMMRegister, $mem$$Address);
- __ movlhps($dst$$XMMRegister, $dst$$XMMRegister);
- __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+ __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+ __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
%}
ins_pipe( pipe_slow );
%}
@@ -2263,11 +2263,11 @@
instruct Repl4L_zero(vecY dst, immL0 zero) %{
predicate(n->as_Vector()->length() == 4);
match(Set dst (ReplicateL zero));
- format %{ "vxorpd $dst,$dst,$dst\t! replicate4L zero" %}
+ format %{ "vpxor $dst,$dst,$dst\t! replicate4L zero" %}
ins_encode %{
// Use vxorpd since AVX does not have vpxor for 256-bit (AVX2 will have it).
bool vector256 = true;
- __ vxorpd($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
+ __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
%}
ins_pipe( fpu_reg_reg );
%}
--- a/hotspot/src/os/solaris/dtrace/libjvm_db.c Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/os/solaris/dtrace/libjvm_db.c Fri Jul 27 22:26:19 2012 -0700
@@ -516,7 +516,7 @@
err = read_pointer(J, methodOopPtr + OFFSET_methodOopDesc_constMethod, &constMethod);
CHECK_FAIL(err);
- err = read_pointer(J->P, constMethod + OFFSET_constMethodOopDesc_constants, &constantPool);
+ err = read_pointer(J, constMethod + OFFSET_constMethodOopDesc_constants, &constantPool);
CHECK_FAIL(err);
/* To get name string */
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -3505,8 +3505,10 @@
}
// now perform tests that are based on flag settings
- if (callee->should_inline()) {
+ if (callee->force_inline() || callee->should_inline()) {
// ignore heuristic controls on inlining
+ if (callee->force_inline())
+ CompileTask::print_inlining(callee, scope()->level(), bci(), "force inline by annotation");
} else {
if (inline_level() > MaxInlineLevel ) INLINE_BAILOUT("too-deep inlining");
if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining");
@@ -3531,7 +3533,7 @@
}
#ifndef PRODUCT
- // printing
+ // printing
if (PrintInlining) {
print_inline_result(callee, true);
}
--- a/hotspot/src/share/vm/ci/ciMethod.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -79,7 +79,7 @@
_max_locals = h_m()->max_locals();
_code_size = h_m()->code_size();
_intrinsic_id = h_m()->intrinsic_id();
- _handler_count = h_m()->exception_table()->length() / 4;
+ _handler_count = h_m()->exception_table_length();
_uses_monitors = h_m()->access_flags().has_monitor_bytecodes();
_balanced_monitors = !_uses_monitors || h_m()->access_flags().is_monitor_matching();
_is_c1_compilable = !h_m()->is_not_c1_compilable();
@@ -198,7 +198,7 @@
}
// And load the exception table.
- typeArrayOop exc_table = me->exception_table();
+ ExceptionTable exc_table(me);
// Allocate one extra spot in our list of exceptions. This
// last entry will be used to represent the possibility that
@@ -209,13 +209,12 @@
* (_handler_count + 1));
if (_handler_count > 0) {
for (int i=0; i<_handler_count; i++) {
- int base = i*4;
_exception_handlers[i] = new (arena) ciExceptionHandler(
holder(),
- /* start */ exc_table->int_at(base),
- /* limit */ exc_table->int_at(base+1),
- /* goto pc */ exc_table->int_at(base+2),
- /* cp index */ exc_table->int_at(base+3));
+ /* start */ exc_table.start_pc(i),
+ /* limit */ exc_table.end_pc(i),
+ /* goto pc */ exc_table.handler_pc(i),
+ /* cp index */ exc_table.catch_type_index(i));
}
}
--- a/hotspot/src/share/vm/ci/ciMethod.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -160,6 +160,8 @@
// Code size for inlining decisions.
int code_size_for_inlining();
+ bool force_inline() { return get_methodOop()->force_inline(); }
+
int comp_level();
int highest_osr_comp_level();
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -318,6 +318,13 @@
bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); }
+inline Symbol* check_symbol_at(constantPoolHandle cp, int index) {
+ if (valid_cp_range(index, cp->length()) && cp->tag_at(index).is_utf8())
+ return cp->symbol_at(index);
+ else
+ return NULL;
+}
+
constantPoolHandle ClassFileParser::parse_constant_pool(Handle class_loader, TRAPS) {
ClassFileStream* cfs = stream();
constantPoolHandle nullHandle;
@@ -902,6 +909,7 @@
bool* is_synthetic_addr,
u2* generic_signature_index_addr,
typeArrayHandle* field_annotations,
+ ClassFileParser::FieldAnnotationCollector* parsed_annotations,
TRAPS) {
ClassFileStream* cfs = stream();
assert(attributes_count > 0, "length should be greater than 0");
@@ -1142,12 +1150,14 @@
bool is_synthetic = false;
u2 generic_signature_index = 0;
bool is_static = access_flags.is_static();
+ FieldAnnotationCollector parsed_annotations;
u2 attributes_count = cfs->get_u2_fast();
if (attributes_count > 0) {
parse_field_attributes(cp, attributes_count, is_static, signature_index,
&constantvalue_index, &is_synthetic,
&generic_signature_index, &field_annotations,
+ &parsed_annotations,
CHECK_(nullHandle));
if (field_annotations.not_null()) {
if (fields_annotations->is_null()) {
@@ -1173,6 +1183,8 @@
signature_index,
constantvalue_index,
0);
+ if (parsed_annotations.has_any_annotations())
+ parsed_annotations.apply_to(field);
BasicType type = cp->basic_type_for_signature_at(signature_index);
@@ -1284,42 +1296,38 @@
}
-typeArrayHandle ClassFileParser::parse_exception_table(u4 code_length,
- u4 exception_table_length,
- constantPoolHandle cp,
- TRAPS) {
+u2* ClassFileParser::parse_exception_table(u4 code_length,
+ u4 exception_table_length,
+ constantPoolHandle cp,
+ TRAPS) {
ClassFileStream* cfs = stream();
- typeArrayHandle nullHandle;
-
- // 4-tuples of ints [start_pc, end_pc, handler_pc, catch_type index]
- typeArrayOop eh = oopFactory::new_permanent_intArray(exception_table_length*4, CHECK_(nullHandle));
- typeArrayHandle exception_handlers = typeArrayHandle(THREAD, eh);
-
- int index = 0;
- cfs->guarantee_more(8 * exception_table_length, CHECK_(nullHandle)); // start_pc, end_pc, handler_pc, catch_type_index
- for (unsigned int i = 0; i < exception_table_length; i++) {
- u2 start_pc = cfs->get_u2_fast();
- u2 end_pc = cfs->get_u2_fast();
- u2 handler_pc = cfs->get_u2_fast();
- u2 catch_type_index = cfs->get_u2_fast();
- // Will check legal target after parsing code array in verifier.
- if (_need_verify) {
+
+ u2* exception_table_start = cfs->get_u2_buffer();
+ assert(exception_table_start != NULL, "null exception table");
+ cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc, end_pc, handler_pc, catch_type_index
+ // Will check legal target after parsing code array in verifier.
+ if (_need_verify) {
+ for (unsigned int i = 0; i < exception_table_length; i++) {
+ u2 start_pc = cfs->get_u2_fast();
+ u2 end_pc = cfs->get_u2_fast();
+ u2 handler_pc = cfs->get_u2_fast();
+ u2 catch_type_index = cfs->get_u2_fast();
guarantee_property((start_pc < end_pc) && (end_pc <= code_length),
- "Illegal exception table range in class file %s", CHECK_(nullHandle));
+ "Illegal exception table range in class file %s",
+ CHECK_NULL);
guarantee_property(handler_pc < code_length,
- "Illegal exception table handler in class file %s", CHECK_(nullHandle));
+ "Illegal exception table handler in class file %s",
+ CHECK_NULL);
if (catch_type_index != 0) {
guarantee_property(valid_cp_range(catch_type_index, cp->length()) &&
is_klass_reference(cp, catch_type_index),
- "Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle));
+ "Catch type in exception table has bad constant type in class file %s", CHECK_NULL);
}
}
- exception_handlers->int_at_put(index++, start_pc);
- exception_handlers->int_at_put(index++, end_pc);
- exception_handlers->int_at_put(index++, handler_pc);
- exception_handlers->int_at_put(index++, catch_type_index);
+ } else {
+ cfs->skip_u2_fast(exception_table_length * 4);
}
- return exception_handlers;
+ return exception_table_start;
}
void ClassFileParser::parse_linenumber_table(
@@ -1638,12 +1646,158 @@
name->as_C_string(), _class_name->as_C_string(), sig->as_C_string());
}
+// Skip an annotation. Return >=limit if there is any problem.
+int ClassFileParser::skip_annotation(u1* buffer, int limit, int index) {
+ // annotation := atype:u2 do(nmem:u2) {member:u2 value}
+ // value := switch (tag:u1) { ... }
+ index += 2; // skip atype
+ if ((index += 2) >= limit) return limit; // read nmem
+ int nmem = Bytes::get_Java_u2(buffer+index-2);
+ while (--nmem >= 0 && index < limit) {
+ index += 2; // skip member
+ index = skip_annotation_value(buffer, limit, index);
+ }
+ return index;
+}
+
+// Skip an annotation value. Return >=limit if there is any problem.
+int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) {
+ // value := switch (tag:u1) {
+ // case B, C, I, S, Z, D, F, J, c: con:u2;
+ // case e: e_class:u2 e_name:u2;
+ // case s: s_con:u2;
+ // case [: do(nval:u2) {value};
+ // case @: annotation;
+ // case s: s_con:u2;
+ // }
+ if ((index += 1) >= limit) return limit; // read tag
+ u1 tag = buffer[index-1];
+ switch (tag) {
+ case 'B': case 'C': case 'I': case 'S': case 'Z':
+ case 'D': case 'F': case 'J': case 'c': case 's':
+ index += 2; // skip con or s_con
+ break;
+ case 'e':
+ index += 4; // skip e_class, e_name
+ break;
+ case '[':
+ {
+ if ((index += 2) >= limit) return limit; // read nval
+ int nval = Bytes::get_Java_u2(buffer+index-2);
+ while (--nval >= 0 && index < limit) {
+ index = skip_annotation_value(buffer, limit, index);
+ }
+ }
+ break;
+ case '@':
+ index = skip_annotation(buffer, limit, index);
+ break;
+ default:
+ assert(false, "annotation tag");
+ return limit; // bad tag byte
+ }
+ return index;
+}
+
+// Sift through annotations, looking for those significant to the VM:
+void ClassFileParser::parse_annotations(u1* buffer, int limit,
+ constantPoolHandle cp,
+ ClassFileParser::AnnotationCollector* coll,
+ TRAPS) {
+ // annotations := do(nann:u2) {annotation}
+ int index = 0;
+ if ((index += 2) >= limit) return; // read nann
+ int nann = Bytes::get_Java_u2(buffer+index-2);
+ enum { // initial annotation layout
+ atype_off = 0, // utf8 such as 'Ljava/lang/annotation/Retention;'
+ count_off = 2, // u2 such as 1 (one value)
+ member_off = 4, // utf8 such as 'value'
+ tag_off = 6, // u1 such as 'c' (type) or 'e' (enum)
+ e_tag_val = 'e',
+ e_type_off = 7, // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;'
+ e_con_off = 9, // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME'
+ e_size = 11, // end of 'e' annotation
+ c_tag_val = 'c',
+ c_con_off = 7, // utf8 payload, such as 'I' or 'Ljava/lang/String;'
+ c_size = 9, // end of 'c' annotation
+ min_size = 6 // smallest possible size (zero members)
+ };
+ while ((--nann) >= 0 && (index-2 + min_size <= limit)) {
+ int index0 = index;
+ index = skip_annotation(buffer, limit, index);
+ u1* abase = buffer + index0;
+ int atype = Bytes::get_Java_u2(abase + atype_off);
+ int count = Bytes::get_Java_u2(abase + count_off);
+ Symbol* aname = check_symbol_at(cp, atype);
+ if (aname == NULL) break; // invalid annotation name
+ Symbol* member = NULL;
+ if (count >= 1) {
+ int member_index = Bytes::get_Java_u2(abase + member_off);
+ member = check_symbol_at(cp, member_index);
+ if (member == NULL) break; // invalid member name
+ }
+
+ // Here is where parsing particular annotations will take place.
+ AnnotationCollector::ID id = coll->annotation_index(aname);
+ if (id == AnnotationCollector::_unknown) continue;
+ coll->set_annotation(id);
+ // If there are no values, just set the bit and move on:
+ if (count == 0) continue;
+
+ // For the record, here is how annotation payloads can be collected.
+ // Suppose we want to capture @Retention.value. Here is how:
+ //if (id == AnnotationCollector::_class_Retention) {
+ // Symbol* payload = NULL;
+ // if (count == 1
+ // && e_size == (index0 - index) // match size
+ // && e_tag_val == *(abase + tag_off)
+ // && (check_symbol_at(cp, Bytes::get_Java_u2(abase + e_type_off))
+ // == vmSymbols::RetentionPolicy_signature())
+ // && member == vmSymbols::value_name()) {
+ // payload = check_symbol_at(cp, Bytes::get_Java_u2(abase + e_con_off));
+ // }
+ // check_property(payload != NULL,
+ // "Invalid @Retention annotation at offset %u in class file %s",
+ // index0, CHECK);
+ // if (payload != NULL) {
+ // payload->increment_refcount();
+ // coll->_class_RetentionPolicy = payload;
+ // }
+ //}
+ }
+}
+
+ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Symbol* name) {
+ vmSymbols::SID sid = vmSymbols::find_sid(name);
+ switch (sid) {
+ case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature):
+ if (_location != _in_method) break; // only allow for methods
+ return _method_ForceInline;
+ default: break;
+ }
+ return AnnotationCollector::_unknown;
+}
+
+void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) {
+ fatal("no field annotations yet");
+}
+
+void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) {
+ if (has_annotation(_method_ForceInline))
+ m->set_force_inline(true);
+}
+
+void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) {
+ fatal("no class annotations yet");
+}
+
+
#define MAX_ARGS_SIZE 255
#define MAX_CODE_SIZE 65535
#define INITIAL_MAX_LVT_NUMBER 256
// Note: the parse_method below is big and clunky because all parsing of the code and exceptions
-// attribute is inlined. This is curbersome to avoid since we inline most of the parts in the
+// attribute is inlined. This is cumbersome to avoid since we inline most of the parts in the
// methodOop to save footprint, so we only know the size of the resulting methodOop when the
// entire method attribute is parsed.
//
@@ -1712,6 +1866,7 @@
u4 code_length = 0;
u1* code_start = 0;
u2 exception_table_length = 0;
+ u2* exception_table_start = NULL;
typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
u2 checked_exceptions_length = 0;
u2* checked_exceptions_start = NULL;
@@ -1733,6 +1888,7 @@
// stackmap attribute - JDK1.5
typeArrayHandle stackmap_data;
u2 generic_signature_index = 0;
+ MethodAnnotationCollector parsed_annotations;
u1* runtime_visible_annotations = NULL;
int runtime_visible_annotations_length = 0;
u1* runtime_invisible_annotations = NULL;
@@ -1798,7 +1954,7 @@
cfs->guarantee_more(2, CHECK_(nullHandle)); // exception_table_length
exception_table_length = cfs->get_u2_fast();
if (exception_table_length > 0) {
- exception_handlers =
+ exception_table_start =
parse_exception_table(code_length, exception_table_length, cp, CHECK_(nullHandle));
}
@@ -1959,6 +2115,7 @@
runtime_visible_annotations_length = method_attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
+ parse_annotations(runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle));
cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle));
} else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
runtime_invisible_annotations_length = method_attribute_length;
@@ -2002,9 +2159,13 @@
}
// All sizing information for a methodOop is finally available, now create it
- methodOop m_oop = oopFactory::new_method(code_length, access_flags, linenumber_table_length,
- total_lvt_length, checked_exceptions_length,
- oopDesc::IsSafeConc, CHECK_(nullHandle));
+ methodOop m_oop = oopFactory::new_method(code_length, access_flags,
+ linenumber_table_length,
+ total_lvt_length,
+ exception_table_length,
+ checked_exceptions_length,
+ oopDesc::IsSafeConc,
+ CHECK_(nullHandle));
methodHandle m (THREAD, m_oop);
ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize);
@@ -2035,16 +2196,15 @@
// Fill in code attribute information
m->set_max_stack(max_stack);
m->set_max_locals(max_locals);
- m->constMethod()->set_stackmap_data(stackmap_data());
/**
- * The exception_table field is the flag used to indicate
+ * The stackmap_data field is the flag used to indicate
* that the methodOop and it's associated constMethodOop are partially
* initialized and thus are exempt from pre/post GC verification. Once
* the field is set, the oops are considered fully initialized so make
* sure that the oops can pass verification when this field is set.
*/
- m->set_exception_table(exception_handlers());
+ m->constMethod()->set_stackmap_data(stackmap_data());
// Copy byte codes
m->set_code(code_start);
@@ -2055,6 +2215,14 @@
linenumber_table->buffer(), linenumber_table_length);
}
+ // Copy exception table
+ if (exception_table_length > 0) {
+ int size =
+ exception_table_length * sizeof(ExceptionTableElement) / sizeof(u2);
+ copy_u2_with_conversion((u2*) m->exception_table_start(),
+ exception_table_start, size);
+ }
+
// Copy checked exceptions
if (checked_exceptions_length > 0) {
int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2);
@@ -2136,6 +2304,8 @@
clear_hashtable(lvt_Hash);
}
+ if (parsed_annotations.has_any_annotations())
+ parsed_annotations.apply_to(m);
*method_annotations = assemble_annotations(runtime_visible_annotations,
runtime_visible_annotations_length,
runtime_invisible_annotations,
@@ -2314,7 +2484,7 @@
}
-void ClassFileParser::parse_classfile_sourcefile_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
+void ClassFileParser::parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS) {
ClassFileStream* cfs = stream();
cfs->guarantee_more(2, CHECK); // sourcefile_index
u2 sourcefile_index = cfs->get_u2_fast();
@@ -2323,13 +2493,12 @@
cp->tag_at(sourcefile_index).is_utf8(),
"Invalid SourceFile attribute at constant pool index %u in class file %s",
sourcefile_index, CHECK);
- k->set_source_file_name(cp->symbol_at(sourcefile_index));
+ set_class_sourcefile(cp->symbol_at(sourcefile_index));
}
void ClassFileParser::parse_classfile_source_debug_extension_attribute(constantPoolHandle cp,
- instanceKlassHandle k,
int length, TRAPS) {
ClassFileStream* cfs = stream();
u1* sde_buffer = cfs->get_u1_buffer();
@@ -2337,7 +2506,13 @@
// Don't bother storing it if there is no way to retrieve it
if (JvmtiExport::can_get_source_debug_extension()) {
- k->set_source_debug_extension((char*)sde_buffer, length);
+ assert((length+1) > length, "Overflow checking");
+ u1* sde = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, u1, length+1);
+ for (int i = 0; i < length; i++) {
+ sde[i] = sde_buffer[i];
+ }
+ sde[length] = '\0';
+ set_class_sde_buffer((char*)sde, length);
}
// Got utf8 string, set stream position forward
cfs->skip_u1(length, CHECK);
@@ -2353,7 +2528,7 @@
u2 enclosing_method_class_index,
u2 enclosing_method_method_index,
constantPoolHandle cp,
- instanceKlassHandle k, TRAPS) {
+ TRAPS) {
ClassFileStream* cfs = stream();
u1* current_mark = cfs->current();
u2 length = 0;
@@ -2444,7 +2619,7 @@
assert(index == size, "wrong size");
// Update instanceKlass with inner class info.
- k->set_inner_classes(inner_classes());
+ set_class_inner_classes(inner_classes);
// Restore buffer's current position.
cfs->set_current(current_mark);
@@ -2452,11 +2627,11 @@
return length;
}
-void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
- k->set_is_synthetic();
+void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS) {
+ set_class_synthetic_flag(true);
}
-void ClassFileParser::parse_classfile_signature_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
+void ClassFileParser::parse_classfile_signature_attribute(constantPoolHandle cp, TRAPS) {
ClassFileStream* cfs = stream();
u2 signature_index = cfs->get_u2(CHECK);
check_property(
@@ -2464,10 +2639,10 @@
cp->tag_at(signature_index).is_utf8(),
"Invalid constant pool index %u in Signature attribute in class file %s",
signature_index, CHECK);
- k->set_generic_signature(cp->symbol_at(signature_index));
+ set_class_generic_signature(cp->symbol_at(signature_index));
}
-void ClassFileParser::parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k,
+void ClassFileParser::parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp,
u4 attribute_byte_length, TRAPS) {
ClassFileStream* cfs = stream();
u1* current_start = cfs->current();
@@ -2539,10 +2714,12 @@
}
-void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
+void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp,
+ ClassFileParser::ClassAnnotationCollector* parsed_annotations,
+ TRAPS) {
ClassFileStream* cfs = stream();
// Set inner classes attribute to default sentinel
- k->set_inner_classes(Universe::the_empty_short_array());
+ set_class_inner_classes(typeArrayHandle(THREAD, Universe::the_empty_short_array()));
cfs->guarantee_more(2, CHECK); // attributes_count
u2 attributes_count = cfs->get_u2_fast();
bool parsed_sourcefile_attribute = false;
@@ -2578,10 +2755,10 @@
} else {
parsed_sourcefile_attribute = true;
}
- parse_classfile_sourcefile_attribute(cp, k, CHECK);
+ parse_classfile_sourcefile_attribute(cp, CHECK);
} else if (tag == vmSymbols::tag_source_debug_extension()) {
// Check for SourceDebugExtension tag
- parse_classfile_source_debug_extension_attribute(cp, k, (int)attribute_length, CHECK);
+ parse_classfile_source_debug_extension_attribute(cp, (int)attribute_length, CHECK);
} else if (tag == vmSymbols::tag_inner_classes()) {
// Check for InnerClasses tag
if (parsed_innerclasses_attribute) {
@@ -2600,7 +2777,7 @@
"Invalid Synthetic classfile attribute length %u in class file %s",
attribute_length, CHECK);
}
- parse_classfile_synthetic_attribute(cp, k, CHECK);
+ parse_classfile_synthetic_attribute(cp, CHECK);
} else if (tag == vmSymbols::tag_deprecated()) {
// Check for Deprecatd tag - 4276120
if (attribute_length != 0) {
@@ -2615,11 +2792,16 @@
"Wrong Signature attribute length %u in class file %s",
attribute_length, CHECK);
}
- parse_classfile_signature_attribute(cp, k, CHECK);
+ parse_classfile_signature_attribute(cp, CHECK);
} else if (tag == vmSymbols::tag_runtime_visible_annotations()) {
runtime_visible_annotations_length = attribute_length;
runtime_visible_annotations = cfs->get_u1_buffer();
assert(runtime_visible_annotations != NULL, "null visible annotations");
+ parse_annotations(runtime_visible_annotations,
+ runtime_visible_annotations_length,
+ cp,
+ parsed_annotations,
+ CHECK);
cfs->skip_u1(runtime_visible_annotations_length, CHECK);
} else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) {
runtime_invisible_annotations_length = attribute_length;
@@ -2653,7 +2835,7 @@
if (parsed_bootstrap_methods_attribute)
classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
parsed_bootstrap_methods_attribute = true;
- parse_classfile_bootstrap_methods_attribute(cp, k, attribute_length, CHECK);
+ parse_classfile_bootstrap_methods_attribute(cp, attribute_length, CHECK);
} else {
// Unknown attribute
cfs->skip_u1(attribute_length, CHECK);
@@ -2668,7 +2850,7 @@
runtime_invisible_annotations,
runtime_invisible_annotations_length,
CHECK);
- k->set_class_annotations(annotations());
+ set_class_annotations(annotations);
if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
u2 num_of_classes = parse_classfile_inner_classes_attribute(
@@ -2676,7 +2858,7 @@
parsed_innerclasses_attribute,
enclosing_method_class_index,
enclosing_method_method_index,
- cp, k, CHECK);
+ cp, CHECK);
if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) {
guarantee_property(
inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
@@ -2690,6 +2872,23 @@
}
}
+void ClassFileParser::apply_parsed_class_attributes(instanceKlassHandle k) {
+ if (_synthetic_flag)
+ k->set_is_synthetic();
+ if (_sourcefile != NULL) {
+ _sourcefile->increment_refcount();
+ k->set_source_file_name(_sourcefile);
+ }
+ if (_generic_signature != NULL) {
+ _generic_signature->increment_refcount();
+ k->set_generic_signature(_generic_signature);
+ }
+ if (_sde_buffer != NULL) {
+ k->set_source_debug_extension(_sde_buffer, _sde_length);
+ }
+ k->set_inner_classes(_inner_classes());
+ k->set_class_annotations(_annotations());
+}
typeArrayHandle ClassFileParser::assemble_annotations(u1* runtime_visible_annotations,
int runtime_visible_annotations_length,
@@ -2740,8 +2939,7 @@
jt->get_thread_stat()->perf_timers_addr(),
PerfClassTraceTime::PARSE_CLASS);
- _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
- _max_bootstrap_specifier_index = -1;
+ init_parsed_class_attributes();
if (JvmtiExport::should_post_class_file_load_hook()) {
// Get the cached class file bytes (if any) from the class that
@@ -2974,6 +3172,13 @@
objArrayHandle methods_parameter_annotations(THREAD, methods_parameter_annotations_oop);
objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);
+ // Additional attributes
+ ClassAnnotationCollector parsed_annotations;
+ parse_classfile_attributes(cp, &parsed_annotations, CHECK_(nullHandle));
+
+ // Make sure this is the end of class file stream
+ guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
+
// We check super class after class file is parsed and format is checked
if (super_class_index > 0 && super_klass.is_null()) {
Symbol* sk = cp->klass_name_at(super_class_index);
@@ -3462,11 +3667,10 @@
this_klass->set_has_miranda_methods(); // then set a flag
}
- // Additional attributes
- parse_classfile_attributes(cp, this_klass, CHECK_(nullHandle));
-
- // Make sure this is the end of class file stream
- guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
+ // Fill in field values obtained by parse_classfile_attributes
+ if (parsed_annotations.has_any_annotations())
+ parsed_annotations.apply_to(this_klass);
+ apply_parsed_class_attributes(this_klass);
// VerifyOops believes that once this has been set, the object is completely loaded.
// Compute transitive closure of interfaces this class implements
@@ -3481,6 +3685,7 @@
// Do final class setup
fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_counts);
+ // Fill in has_finalizer, has_vanilla_constructor, and layout_helper
set_precomputed_flags(this_klass);
// reinitialize modifiers, using the InnerClasses attribute
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -31,8 +31,8 @@
#include "oops/typeArrayOop.hpp"
#include "runtime/handles.inline.hpp"
#include "utilities/accessFlags.hpp"
+#include "classfile/symbolTable.hpp"
-class TempNewSymbol;
class FieldAllocationCount;
@@ -50,11 +50,80 @@
KlassHandle _host_klass;
GrowableArray<Handle>* _cp_patches; // overrides for CP entries
+ // precomputed flags
bool _has_finalizer;
bool _has_empty_finalizer;
bool _has_vanilla_constructor;
+ int _max_bootstrap_specifier_index; // detects BSS values
- int _max_bootstrap_specifier_index;
+ // class attributes parsed before the instance klass is created:
+ bool _synthetic_flag;
+ Symbol* _sourcefile;
+ Symbol* _generic_signature;
+ char* _sde_buffer;
+ int _sde_length;
+ typeArrayHandle _inner_classes;
+ typeArrayHandle _annotations;
+
+ void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }
+ void set_class_sourcefile(Symbol* x) { _sourcefile = x; }
+ void set_class_generic_signature(Symbol* x) { _generic_signature = x; }
+ void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }
+ void set_class_inner_classes(typeArrayHandle x) { _inner_classes = x; }
+ void set_class_annotations(typeArrayHandle x) { _annotations = x; }
+ void init_parsed_class_attributes() {
+ _synthetic_flag = false;
+ _sourcefile = NULL;
+ _generic_signature = NULL;
+ _sde_buffer = NULL;
+ _sde_length = 0;
+ // initialize the other flags too:
+ _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
+ _max_bootstrap_specifier_index = -1;
+ }
+ void apply_parsed_class_attributes(instanceKlassHandle k); // update k
+
+ class AnnotationCollector {
+ public:
+ enum Location { _in_field, _in_method, _in_class };
+ enum ID {
+ _unknown = 0,
+ _method_ForceInline,
+ _annotation_LIMIT
+ };
+ const Location _location;
+ int _annotations_present;
+ AnnotationCollector(Location location)
+ : _location(location), _annotations_present(0)
+ {
+ assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");
+ }
+ // If this annotation name has an ID, report it (or _none).
+ ID annotation_index(Symbol* name);
+ // Set the annotation name:
+ void set_annotation(ID id) {
+ assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
+ _annotations_present |= nth_bit((int)id);
+ }
+ // Report if the annotation is present.
+ bool has_any_annotations() { return _annotations_present != 0; }
+ bool has_annotation(ID id) { return (nth_bit((int)id) & _annotations_present) != 0; }
+ };
+ class FieldAnnotationCollector: public AnnotationCollector {
+ public:
+ FieldAnnotationCollector() : AnnotationCollector(_in_field) { }
+ void apply_to(FieldInfo* f);
+ };
+ class MethodAnnotationCollector: public AnnotationCollector {
+ public:
+ MethodAnnotationCollector() : AnnotationCollector(_in_method) { }
+ void apply_to(methodHandle m);
+ };
+ class ClassAnnotationCollector: public AnnotationCollector {
+ public:
+ ClassAnnotationCollector() : AnnotationCollector(_in_class) { }
+ void apply_to(instanceKlassHandle k);
+ };
enum { fixed_buffer_size = 128 };
u_char linenumbertable_buffer[fixed_buffer_size];
@@ -87,7 +156,9 @@
u2* constantvalue_index_addr,
bool* is_synthetic_addr,
u2* generic_signature_index_addr,
- typeArrayHandle* field_annotations, TRAPS);
+ typeArrayHandle* field_annotations,
+ FieldAnnotationCollector* parsed_annotations,
+ TRAPS);
typeArrayHandle parse_fields(Symbol* class_name,
constantPoolHandle cp, bool is_interface,
FieldAllocationCount *fac,
@@ -113,8 +184,8 @@
objArrayHandle methods_parameter_annotations,
objArrayHandle methods_default_annotations,
TRAPS);
- typeArrayHandle parse_exception_table(u4 code_length, u4 exception_table_length,
- constantPoolHandle cp, TRAPS);
+ u2* parse_exception_table(u4 code_length, u4 exception_table_length,
+ constantPoolHandle cp, TRAPS);
void parse_linenumber_table(
u4 code_attribute_length, u4 code_length,
CompressedLineNumberWriteStream** write_stream, TRAPS);
@@ -128,25 +199,32 @@
typeArrayOop parse_stackmap_table(u4 code_attribute_length, TRAPS);
// Classfile attribute parsing
- void parse_classfile_sourcefile_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
- void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp,
- instanceKlassHandle k, int length, TRAPS);
+ void parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS);
+ void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp, int length, TRAPS);
u2 parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
bool parsed_enclosingmethod_attribute,
u2 enclosing_method_class_index,
u2 enclosing_method_method_index,
constantPoolHandle cp,
- instanceKlassHandle k, TRAPS);
- void parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
- void parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
- void parse_classfile_signature_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
- void parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k, u4 attribute_length, TRAPS);
+ TRAPS);
+ void parse_classfile_attributes(constantPoolHandle cp,
+ ClassAnnotationCollector* parsed_annotations,
+ TRAPS);
+ void parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS);
+ void parse_classfile_signature_attribute(constantPoolHandle cp, TRAPS);
+ void parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, u4 attribute_length, TRAPS);
// Annotations handling
typeArrayHandle assemble_annotations(u1* runtime_visible_annotations,
int runtime_visible_annotations_length,
u1* runtime_invisible_annotations,
int runtime_invisible_annotations_length, TRAPS);
+ int skip_annotation(u1* buffer, int limit, int index);
+ int skip_annotation_value(u1* buffer, int limit, int index);
+ void parse_annotations(u1* buffer, int limit, constantPoolHandle cp,
+ /* Results (currently, only one result is supported): */
+ AnnotationCollector* result,
+ TRAPS);
// Final setup
unsigned int compute_oop_map_count(instanceKlassHandle super,
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -2738,17 +2738,6 @@
if (k != NULL) {
compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature());
}
-
- // Disallow compilation of CallSite.setTargetNormal and CallSite.setTargetVolatile
- // (For C2: keep this until we have throttling logic for uncommon traps.)
- if (k != NULL) {
- instanceKlass* ik = instanceKlass::cast(k);
- methodOop m_normal = ik->lookup_method(vmSymbols::setTargetNormal_name(), vmSymbols::setTarget_signature());
- methodOop m_volatile = ik->lookup_method(vmSymbols::setTargetVolatile_name(), vmSymbols::setTarget_signature());
- guarantee(m_normal != NULL && m_volatile != NULL, "must exist");
- m_normal->set_not_compilable_quietly();
- m_volatile->set_not_compilable_quietly();
- }
}
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -2771,7 +2771,6 @@
nmethods++;
method_size += m->size();
// class loader uses same objArray for empty vectors, so don't count these
- if (m->exception_table()->length() != 0) method_size += m->exception_table()->size();
if (m->has_stackmap_table()) {
method_size += m->stackmap_data()->size();
}
--- a/hotspot/src/share/vm/classfile/verifier.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/classfile/verifier.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 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
@@ -1368,47 +1368,48 @@
}
void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) {
- typeArrayHandle exhandlers (THREAD, _method->exception_table());
+ ExceptionTable exhandlers(_method());
+ int exlength = exhandlers.length();
constantPoolHandle cp (THREAD, _method->constants());
- if (exhandlers() != NULL) {
- for(int i = 0; i < exhandlers->length();) {
- u2 start_pc = exhandlers->int_at(i++);
- u2 end_pc = exhandlers->int_at(i++);
- u2 handler_pc = exhandlers->int_at(i++);
- if (start_pc >= code_length || code_data[start_pc] == 0) {
- class_format_error("Illegal exception table start_pc %d", start_pc);
+ for(int i = 0; i < exlength; i++) {
+ //reacquire the table in case a GC happened
+ ExceptionTable exhandlers(_method());
+ u2 start_pc = exhandlers.start_pc(i);
+ u2 end_pc = exhandlers.end_pc(i);
+ u2 handler_pc = exhandlers.handler_pc(i);
+ if (start_pc >= code_length || code_data[start_pc] == 0) {
+ class_format_error("Illegal exception table start_pc %d", start_pc);
+ return;
+ }
+ if (end_pc != code_length) { // special case: end_pc == code_length
+ if (end_pc > code_length || code_data[end_pc] == 0) {
+ class_format_error("Illegal exception table end_pc %d", end_pc);
return;
}
- if (end_pc != code_length) { // special case: end_pc == code_length
- if (end_pc > code_length || code_data[end_pc] == 0) {
- class_format_error("Illegal exception table end_pc %d", end_pc);
- return;
- }
- }
- if (handler_pc >= code_length || code_data[handler_pc] == 0) {
- class_format_error("Illegal exception table handler_pc %d", handler_pc);
+ }
+ if (handler_pc >= code_length || code_data[handler_pc] == 0) {
+ class_format_error("Illegal exception table handler_pc %d", handler_pc);
+ return;
+ }
+ int catch_type_index = exhandlers.catch_type_index(i);
+ if (catch_type_index != 0) {
+ VerificationType catch_type = cp_index_to_type(
+ catch_type_index, cp, CHECK_VERIFY(this));
+ VerificationType throwable =
+ VerificationType::reference_type(vmSymbols::java_lang_Throwable());
+ bool is_subclass = throwable.is_assignable_from(
+ catch_type, this, CHECK_VERIFY(this));
+ if (!is_subclass) {
+ // 4286534: should throw VerifyError according to recent spec change
+ verify_error(
+ "Catch type is not a subclass of Throwable in handler %d",
+ handler_pc);
return;
}
- int catch_type_index = exhandlers->int_at(i++);
- if (catch_type_index != 0) {
- VerificationType catch_type = cp_index_to_type(
- catch_type_index, cp, CHECK_VERIFY(this));
- VerificationType throwable =
- VerificationType::reference_type(vmSymbols::java_lang_Throwable());
- bool is_subclass = throwable.is_assignable_from(
- catch_type, this, CHECK_VERIFY(this));
- if (!is_subclass) {
- // 4286534: should throw VerifyError according to recent spec change
- verify_error(
- "Catch type is not a subclass of Throwable in handler %d",
- handler_pc);
- return;
- }
- }
- if (start_pc < min) min = start_pc;
- if (end_pc > max) max = end_pc;
}
+ if (start_pc < min) min = start_pc;
+ if (end_pc > max) max = end_pc;
}
}
@@ -1474,35 +1475,36 @@
void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame,
StackMapTable* stackmap_table, TRAPS) {
constantPoolHandle cp (THREAD, _method->constants());
- typeArrayHandle exhandlers (THREAD, _method->exception_table());
- if (exhandlers() != NULL) {
- for(int i = 0; i < exhandlers->length();) {
- u2 start_pc = exhandlers->int_at(i++);
- u2 end_pc = exhandlers->int_at(i++);
- u2 handler_pc = exhandlers->int_at(i++);
- int catch_type_index = exhandlers->int_at(i++);
- if(bci >= start_pc && bci < end_pc) {
- u1 flags = current_frame->flags();
- if (this_uninit) { flags |= FLAG_THIS_UNINIT; }
- StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags);
- if (catch_type_index != 0) {
- // We know that this index refers to a subclass of Throwable
- VerificationType catch_type = cp_index_to_type(
- catch_type_index, cp, CHECK_VERIFY(this));
- new_frame->push_stack(catch_type, CHECK_VERIFY(this));
- } else {
- VerificationType throwable =
- VerificationType::reference_type(vmSymbols::java_lang_Throwable());
- new_frame->push_stack(throwable, CHECK_VERIFY(this));
- }
- bool match = stackmap_table->match_stackmap(
- new_frame, handler_pc, true, false, CHECK_VERIFY(this));
- if (!match) {
- verify_error(bci,
- "Stack map does not match the one at exception handler %d",
- handler_pc);
- return;
- }
+ ExceptionTable exhandlers(_method());
+ int exlength = exhandlers.length();
+ for(int i = 0; i < exlength; i++) {
+ //reacquire the table in case a GC happened
+ ExceptionTable exhandlers(_method());
+ u2 start_pc = exhandlers.start_pc(i);
+ u2 end_pc = exhandlers.end_pc(i);
+ u2 handler_pc = exhandlers.handler_pc(i);
+ int catch_type_index = exhandlers.catch_type_index(i);
+ if(bci >= start_pc && bci < end_pc) {
+ u1 flags = current_frame->flags();
+ if (this_uninit) { flags |= FLAG_THIS_UNINIT; }
+ StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags);
+ if (catch_type_index != 0) {
+ // We know that this index refers to a subclass of Throwable
+ VerificationType catch_type = cp_index_to_type(
+ catch_type_index, cp, CHECK_VERIFY(this));
+ new_frame->push_stack(catch_type, CHECK_VERIFY(this));
+ } else {
+ VerificationType throwable =
+ VerificationType::reference_type(vmSymbols::java_lang_Throwable());
+ new_frame->push_stack(throwable, CHECK_VERIFY(this));
+ }
+ bool match = stackmap_table->match_stackmap(
+ new_frame, handler_pc, true, false, CHECK_VERIFY(this));
+ if (!match) {
+ verify_error(bci,
+ "Stack map does not match the one at exception handler %d",
+ handler_pc);
+ return;
}
}
}
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -257,6 +257,7 @@
template(java_lang_invoke_BoundMethodHandle, "java/lang/invoke/BoundMethodHandle") \
template(java_lang_invoke_DirectMethodHandle, "java/lang/invoke/DirectMethodHandle") \
template(java_lang_invoke_CountingMethodHandle, "java/lang/invoke/CountingMethodHandle") \
+ template(java_lang_invoke_ForceInline_signature, "Ljava/lang/invoke/ForceInline;") \
/* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \
template(findMethodHandleType_name, "findMethodHandleType") \
template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \
--- a/hotspot/src/share/vm/code/vmreg.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/code/vmreg.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -131,6 +131,10 @@
assert((is_reg() && value() < stack0->value() - 1) || is_stack(), "must be");
return (VMReg)(intptr_t)(value() + 1);
}
+ VMReg next(int i) {
+ assert((is_reg() && value() < stack0->value() - i) || is_stack(), "must be");
+ return (VMReg)(intptr_t)(value() + i);
+ }
VMReg prev() {
assert((is_stack() && value() > stack0->value()) || (is_reg() && value() != 0), "must be");
return (VMReg)(intptr_t)(value() - 1);
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -27,6 +27,7 @@
#include "gc_implementation/g1/concurrentG1RefineThread.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1CollectorPolicy.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
#include "gc_implementation/g1/g1RemSet.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
#include "memory/space.inline.hpp"
@@ -500,11 +501,11 @@
}
void ConcurrentG1Refine::clear_and_record_card_counts() {
- if (G1ConcRSLogCacheSize == 0) return;
+ if (G1ConcRSLogCacheSize == 0) {
+ return;
+ }
-#ifndef PRODUCT
double start = os::elapsedTime();
-#endif
if (_expand_card_counts) {
int new_idx = _cache_size_index + 1;
@@ -523,11 +524,8 @@
assert((this_epoch+1) <= max_jint, "to many periods");
// Update epoch
_n_periods++;
-
-#ifndef PRODUCT
- double elapsed = os::elapsedTime() - start;
- _g1h->g1_policy()->record_cc_clear_time(elapsed * 1000.0);
-#endif
+ double cc_clear_time_ms = (os::elapsedTime() - start) * 1000;
+ _g1h->g1_policy()->phase_times()->record_cc_clear_time_ms(cc_clear_time_ms);
}
void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -3156,9 +3156,6 @@
_g1h->g1_policy()->record_concurrent_pause();
}
cmThread()->yield();
- if (worker_id == 0) {
- _g1h->g1_policy()->record_concurrent_pause_end();
- }
return true;
} else {
return false;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -33,6 +33,7 @@
#include "gc_implementation/g1/g1CollectorPolicy.hpp"
#include "gc_implementation/g1/g1ErgoVerbose.hpp"
#include "gc_implementation/g1/g1EvacFailure.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
#include "gc_implementation/g1/g1Log.hpp"
#include "gc_implementation/g1/g1MarkSweep.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
@@ -2274,7 +2275,7 @@
while (dcqs.apply_closure_to_completed_buffer(cl, worker_i, 0, true)) {
n_completed_buffers++;
}
- g1_policy()->record_update_rs_processed_buffers(worker_i,
+ g1_policy()->phase_times()->record_update_rs_processed_buffers(worker_i,
(double) n_completed_buffers);
dcqs.clear_n_completed_buffers();
assert(!dcqs.completed_buffers_exist_dirty(), "Completed buffers exist!");
@@ -3633,10 +3634,10 @@
gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
- GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause())
- .append(g1_policy()->gcs_are_young() ? " (young)" : " (mixed)")
- .append(g1_policy()->during_initial_mark_pause() ? " (initial-mark)" : "");
- TraceTime t(gc_cause_str, G1Log::fine() && !G1Log::finer(), true, gclog_or_tty);
+ int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
+ workers()->active_workers() : 1);
+ g1_policy()->phase_times()->note_gc_start(os::elapsedTime(), active_workers,
+ g1_policy()->gcs_are_young(), g1_policy()->during_initial_mark_pause(), gc_cause());
TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
TraceMemoryManagerStats tms(false /* fullGC */, gc_cause());
@@ -3699,9 +3700,15 @@
// before the start GC event.
_hr_printer.start_gc(false /* full */, (size_t) total_collections());
+ // This timing is only used by the ergonomics to handle our pause target.
+ // It is unclear why this should not include the full pause. We will
+ // investigate this in CR 7178365.
+ //
+ // Preserving the old comment here if that helps the investigation:
+ //
// The elapsed time induced by the start time below deliberately elides
// the possible verification above.
- double start_time_sec = os::elapsedTime();
+ double sample_start_time_sec = os::elapsedTime();
size_t start_used_bytes = used();
#if YOUNG_LIST_VERBOSE
@@ -3710,7 +3717,7 @@
g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty);
#endif // YOUNG_LIST_VERBOSE
- g1_policy()->record_collection_pause_start(start_time_sec,
+ g1_policy()->record_collection_pause_start(sample_start_time_sec,
start_used_bytes);
double scan_wait_start = os::elapsedTime();
@@ -3719,11 +3726,12 @@
// objects on them have been correctly scanned before we start
// moving them during the GC.
bool waited = _cm->root_regions()->wait_until_scan_finished();
+ double wait_time_ms = 0.0;
if (waited) {
double scan_wait_end = os::elapsedTime();
- double wait_time_ms = (scan_wait_end - scan_wait_start) * 1000.0;
- g1_policy()->record_root_region_scan_wait_time(wait_time_ms);
+ wait_time_ms = (scan_wait_end - scan_wait_start) * 1000.0;
}
+ g1_policy()->phase_times()->record_root_region_scan_wait_time(wait_time_ms);
#if YOUNG_LIST_VERBOSE
gclog_or_tty->print_cr("\nAfter recording pause start.\nYoung_list:");
@@ -3877,12 +3885,16 @@
true /* verify_fingers */);
_cm->note_end_of_gc();
- double end_time_sec = os::elapsedTime();
- double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
- g1_policy()->record_pause_time_ms(pause_time_ms);
- int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
- workers()->active_workers() : 1);
- g1_policy()->record_collection_pause_end(active_workers);
+ // Collect thread local data to allow the ergonomics to use
+ // the collected information
+ g1_policy()->phase_times()->collapse_par_times();
+
+ // This timing is only used by the ergonomics to handle our pause target.
+ // It is unclear why this should not include the full pause. We will
+ // investigate this in CR 7178365.
+ double sample_end_time_sec = os::elapsedTime();
+ double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS;
+ g1_policy()->record_collection_pause_end(pause_time_ms);
MemoryService::track_memory_usage();
@@ -3929,9 +3941,6 @@
// RETIRE events are generated before the end GC event.
_hr_printer.end_gc(false /* full */, (size_t) total_collections());
- // We have to do this after we decide whether to expand the heap or not.
- g1_policy()->print_heap_transition();
-
if (mark_in_progress()) {
concurrent_mark()->update_g1_committed();
}
@@ -3941,13 +3950,14 @@
#endif
gc_epilogue(false);
+
+ g1_policy()->phase_times()->note_gc_end(os::elapsedTime());
+
+ // We have to do this after we decide whether to expand the heap or not.
+ g1_policy()->print_heap_transition();
}
- // The closing of the inner scope, immediately above, will complete
- // logging at the "fine" level. The record_collection_pause_end() call
- // above will complete logging at the "finer" level.
- //
- // It is not yet to safe, however, to tell the concurrent mark to
+ // It is not yet to safe to tell the concurrent mark to
// start as we have some optional output below. We don't want the
// output from the concurrent mark thread interfering with this
// logging output either.
@@ -4695,7 +4705,7 @@
if (worker_id >= _n_workers) return; // no work needed this round
double start_time_ms = os::elapsedTime() * 1000.0;
- _g1h->g1_policy()->record_gc_worker_start_time(worker_id, start_time_ms);
+ _g1h->g1_policy()->phase_times()->record_gc_worker_start_time(worker_id, start_time_ms);
{
ResourceMark rm;
@@ -4744,8 +4754,8 @@
evac.do_void();
double elapsed_ms = (os::elapsedTime()-start)*1000.0;
double term_ms = pss.term_time()*1000.0;
- _g1h->g1_policy()->record_obj_copy_time(worker_id, elapsed_ms-term_ms);
- _g1h->g1_policy()->record_termination(worker_id, term_ms, pss.term_attempts());
+ _g1h->g1_policy()->phase_times()->record_obj_copy_time(worker_id, elapsed_ms-term_ms);
+ _g1h->g1_policy()->phase_times()->record_termination(worker_id, term_ms, pss.term_attempts());
}
_g1h->g1_policy()->record_thread_age_table(pss.age_table());
_g1h->update_surviving_young_words(pss.surviving_young_words()+1);
@@ -4763,7 +4773,7 @@
}
double end_time_ms = os::elapsedTime() * 1000.0;
- _g1h->g1_policy()->record_gc_worker_end_time(worker_id, end_time_ms);
+ _g1h->g1_policy()->phase_times()->record_gc_worker_end_time(worker_id, end_time_ms);
}
};
@@ -4874,15 +4884,15 @@
double ext_roots_end = os::elapsedTime();
- g1_policy()->reset_obj_copy_time(worker_i);
+ g1_policy()->phase_times()->reset_obj_copy_time(worker_i);
double obj_copy_time_sec = buf_scan_perm.closure_app_seconds() +
buf_scan_non_heap_roots.closure_app_seconds();
- g1_policy()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
+ g1_policy()->phase_times()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
double ext_root_time_ms =
((ext_roots_end - ext_roots_start) - obj_copy_time_sec) * 1000.0;
- g1_policy()->record_ext_root_scan_time(worker_i, ext_root_time_ms);
+ g1_policy()->phase_times()->record_ext_root_scan_time(worker_i, ext_root_time_ms);
// During conc marking we have to filter the per-thread SATB buffers
// to make sure we remove any oops into the CSet (which will show up
@@ -4893,7 +4903,7 @@
}
}
double satb_filtering_ms = (os::elapsedTime() - ext_roots_end) * 1000.0;
- g1_policy()->record_satb_filtering_time(worker_i, satb_filtering_ms);
+ g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms);
// Now scan the complement of the collection set.
if (scan_rs != NULL) {
@@ -5393,7 +5403,7 @@
assert(pss.refs()->is_empty(), "both queue and overflow should be empty");
double ref_proc_time = os::elapsedTime() - ref_proc_start;
- g1_policy()->record_ref_proc_time(ref_proc_time * 1000.0);
+ g1_policy()->phase_times()->record_ref_proc_time(ref_proc_time * 1000.0);
}
// Weak Reference processing during an evacuation pause (part 2).
@@ -5430,7 +5440,7 @@
// and could signicantly increase the pause time.
double ref_enq_time = os::elapsedTime() - ref_enq_start;
- g1_policy()->record_ref_enq_time(ref_enq_time * 1000.0);
+ g1_policy()->phase_times()->record_ref_enq_time(ref_enq_time * 1000.0);
}
void G1CollectedHeap::evacuate_collection_set() {
@@ -5493,11 +5503,11 @@
}
double par_time_ms = (end_par_time_sec - start_par_time_sec) * 1000.0;
- g1_policy()->record_par_time(par_time_ms);
+ g1_policy()->phase_times()->record_par_time(par_time_ms);
double code_root_fixup_time_ms =
(os::elapsedTime() - end_par_time_sec) * 1000.0;
- g1_policy()->record_code_root_fixup_time(code_root_fixup_time_ms);
+ g1_policy()->phase_times()->record_code_root_fixup_time(code_root_fixup_time_ms);
set_par_threads(0);
@@ -5759,7 +5769,7 @@
}
double elapsed = os::elapsedTime() - start;
- g1_policy()->record_clear_ct_time(elapsed * 1000.0);
+ g1_policy()->phase_times()->record_clear_ct_time(elapsed * 1000.0);
}
void G1CollectedHeap::free_collection_set(HeapRegion* cs_head) {
@@ -5868,8 +5878,8 @@
NULL /* old_proxy_set */,
NULL /* humongous_proxy_set */,
false /* par */);
- policy->record_young_free_cset_time_ms(young_time_ms);
- policy->record_non_young_free_cset_time_ms(non_young_time_ms);
+ policy->phase_times()->record_young_free_cset_time_ms(young_time_ms);
+ policy->phase_times()->record_non_young_free_cset_time_ms(non_young_time_ms);
}
// This routine is similar to the above but does not record
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -29,6 +29,7 @@
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1CollectorPolicy.hpp"
#include "gc_implementation/g1/g1ErgoVerbose.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
#include "gc_implementation/g1/g1Log.hpp"
#include "gc_implementation/g1/heapRegionRemSet.hpp"
#include "gc_implementation/shared/gcPolicyCounters.hpp"
@@ -77,57 +78,6 @@
1.0, 0.7, 0.7, 0.5, 0.5, 0.42, 0.42, 0.30
};
-// Help class for avoiding interleaved logging
-class LineBuffer: public StackObj {
-
-private:
- static const int BUFFER_LEN = 1024;
- static const int INDENT_CHARS = 3;
- char _buffer[BUFFER_LEN];
- int _indent_level;
- int _cur;
-
- void vappend(const char* format, va_list ap) {
- int res = vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap);
- if (res != -1) {
- _cur += res;
- } else {
- DEBUG_ONLY(warning("buffer too small in LineBuffer");)
- _buffer[BUFFER_LEN -1] = 0;
- _cur = BUFFER_LEN; // vsnprintf above should not add to _buffer if we are called again
- }
- }
-
-public:
- explicit LineBuffer(int indent_level): _indent_level(indent_level), _cur(0) {
- for (; (_cur < BUFFER_LEN && _cur < (_indent_level * INDENT_CHARS)); _cur++) {
- _buffer[_cur] = ' ';
- }
- }
-
-#ifndef PRODUCT
- ~LineBuffer() {
- assert(_cur == _indent_level * INDENT_CHARS, "pending data in buffer - append_and_print_cr() not called?");
- }
-#endif
-
- void append(const char* format, ...) {
- va_list ap;
- va_start(ap, format);
- vappend(format, ap);
- va_end(ap);
- }
-
- void append_and_print_cr(const char* format, ...) {
- va_list ap;
- va_start(ap, format);
- vappend(format, ap);
- va_end(ap);
- gclog_or_tty->print_cr("%s", _buffer);
- _cur = _indent_level * INDENT_CHARS;
- }
-};
-
G1CollectorPolicy::G1CollectorPolicy() :
_parallel_gc_threads(G1CollectedHeap::use_parallel_gc_threads()
? ParallelGCThreads : 1),
@@ -135,20 +85,6 @@
_recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
_stop_world_start(0.0),
- _cur_clear_ct_time_ms(0.0),
- _root_region_scan_wait_time_ms(0.0),
-
- _cur_ref_proc_time_ms(0.0),
- _cur_ref_enq_time_ms(0.0),
-
-#ifndef PRODUCT
- _min_clear_cc_time_ms(-1.0),
- _max_clear_cc_time_ms(-1.0),
- _cur_clear_cc_time_ms(0.0),
- _cum_clear_cc_time_ms(0.0),
- _num_cc_clears(0L),
-#endif
-
_concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
_concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
@@ -257,30 +193,9 @@
_recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime());
_prev_collection_pause_end_ms = os::elapsedTime() * 1000.0;
- _par_last_gc_worker_start_times_ms = new double[_parallel_gc_threads];
- _par_last_ext_root_scan_times_ms = new double[_parallel_gc_threads];
- _par_last_satb_filtering_times_ms = new double[_parallel_gc_threads];
-
- _par_last_update_rs_times_ms = new double[_parallel_gc_threads];
- _par_last_update_rs_processed_buffers = new double[_parallel_gc_threads];
-
- _par_last_scan_rs_times_ms = new double[_parallel_gc_threads];
-
- _par_last_obj_copy_times_ms = new double[_parallel_gc_threads];
+ _phase_times = new G1GCPhaseTimes(_parallel_gc_threads);
- _par_last_termination_times_ms = new double[_parallel_gc_threads];
- _par_last_termination_attempts = new double[_parallel_gc_threads];
- _par_last_gc_worker_end_times_ms = new double[_parallel_gc_threads];
- _par_last_gc_worker_times_ms = new double[_parallel_gc_threads];
- _par_last_gc_worker_other_times_ms = new double[_parallel_gc_threads];
-
- int index;
- if (ParallelGCThreads == 0)
- index = 0;
- else if (ParallelGCThreads > 8)
- index = 7;
- else
- index = ParallelGCThreads - 1;
+ int index = MIN2(_parallel_gc_threads - 1, 7);
_pending_card_diff_seq->add(0.0);
_rs_length_diff_seq->add(rs_length_diff_defaults[index]);
@@ -824,7 +739,7 @@
#endif // PRODUCT
void G1CollectorPolicy::record_full_collection_start() {
- _cur_collection_start_sec = os::elapsedTime();
+ _full_collection_start_sec = os::elapsedTime();
// Release the future to-space so that it is available for compaction into.
_g1->set_full_collection();
}
@@ -833,7 +748,7 @@
// Consider this like a collection pause for the purposes of allocation
// since last pause.
double end_sec = os::elapsedTime();
- double full_gc_time_sec = end_sec - _cur_collection_start_sec;
+ double full_gc_time_sec = end_sec - _full_collection_start_sec;
double full_gc_time_ms = full_gc_time_sec * 1000.0;
_trace_gen1_time_data.record_full_collection(full_gc_time_ms);
@@ -869,12 +784,6 @@
void G1CollectorPolicy::record_collection_pause_start(double start_time_sec,
size_t start_used) {
- if (G1Log::finer()) {
- gclog_or_tty->stamp(PrintGCTimeStamps);
- gclog_or_tty->print("[%s", (const char*)GCCauseString("GC pause", _g1->gc_cause())
- .append(gcs_are_young() ? " (young)" : " (mixed)"));
- }
-
// We only need to do this here as the policy will only be applied
// to the GC we're about to start. so, no point is calculating this
// every time we calculate / recalculate the target young length.
@@ -888,7 +797,7 @@
_trace_gen0_time_data.record_start_collection(s_w_t_ms);
_stop_world_start = 0.0;
- _cur_collection_start_sec = start_time_sec;
+ phase_times()->_cur_collection_start_sec = start_time_sec;
_cur_collection_pause_used_at_start_bytes = start_used;
_cur_collection_pause_used_regions_at_start = _g1->used_regions();
_pending_cards = _g1->pending_card_num();
@@ -902,30 +811,6 @@
_survivor_bytes_before_gc = young_list->survivor_used_bytes();
_capacity_before_gc = _g1->capacity();
-#ifdef DEBUG
- // initialise these to something well known so that we can spot
- // if they are not set properly
-
- for (int i = 0; i < _parallel_gc_threads; ++i) {
- _par_last_gc_worker_start_times_ms[i] = -1234.0;
- _par_last_ext_root_scan_times_ms[i] = -1234.0;
- _par_last_satb_filtering_times_ms[i] = -1234.0;
- _par_last_update_rs_times_ms[i] = -1234.0;
- _par_last_update_rs_processed_buffers[i] = -1234.0;
- _par_last_scan_rs_times_ms[i] = -1234.0;
- _par_last_obj_copy_times_ms[i] = -1234.0;
- _par_last_termination_times_ms[i] = -1234.0;
- _par_last_termination_attempts[i] = -1234.0;
- _par_last_gc_worker_end_times_ms[i] = -1234.0;
- _par_last_gc_worker_times_ms[i] = -1234.0;
- _par_last_gc_worker_other_times_ms[i] = -1234.0;
- }
-#endif
-
- // This is initialized to zero here and is set during the evacuation
- // pause if we actually waited for the root region scanning to finish.
- _root_region_scan_wait_time_ms = 0.0;
-
_last_gc_was_young = false;
// do that for any other surv rate groups
@@ -974,127 +859,6 @@
}
}
-void G1CollectorPolicy::record_concurrent_pause_end() {
-}
-
-template<class T>
-T sum_of(T* sum_arr, int start, int n, int N) {
- T sum = (T)0;
- for (int i = 0; i < n; i++) {
- int j = (start + i) % N;
- sum += sum_arr[j];
- }
- return sum;
-}
-
-void G1CollectorPolicy::print_par_stats(int level,
- const char* str,
- double* data,
- bool showDecimals) {
- double min = data[0], max = data[0];
- double total = 0.0;
- LineBuffer buf(level);
- buf.append("[%s (ms):", str);
- for (uint i = 0; i < no_of_gc_threads(); ++i) {
- double val = data[i];
- if (val < min)
- min = val;
- if (val > max)
- max = val;
- total += val;
- if (G1Log::finest()) {
- if (showDecimals) {
- buf.append(" %.1lf", val);
- } else {
- buf.append(" %d", (int)val);
- }
- }
- }
-
- if (G1Log::finest()) {
- buf.append_and_print_cr("");
- }
- double avg = total / (double) no_of_gc_threads();
- if (showDecimals) {
- buf.append_and_print_cr(" Min: %.1lf, Avg: %.1lf, Max: %.1lf, Diff: %.1lf, Sum: %.1lf]",
- min, avg, max, max - min, total);
- } else {
- buf.append_and_print_cr(" Min: %d, Avg: %d, Max: %d, Diff: %d, Sum: %d]",
- (int)min, (int)avg, (int)max, (int)max - (int)min, (int)total);
- }
-}
-
-void G1CollectorPolicy::print_stats(int level,
- const char* str,
- double value) {
- LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value);
-}
-
-void G1CollectorPolicy::print_stats(int level,
- const char* str,
- double value,
- int workers) {
- LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: %d]", str, value, workers);
-}
-
-void G1CollectorPolicy::print_stats(int level,
- const char* str,
- int value) {
- LineBuffer(level).append_and_print_cr("[%s: %d]", str, value);
-}
-
-double G1CollectorPolicy::avg_value(double* data) {
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- double ret = 0.0;
- for (uint i = 0; i < no_of_gc_threads(); ++i) {
- ret += data[i];
- }
- return ret / (double) no_of_gc_threads();
- } else {
- return data[0];
- }
-}
-
-double G1CollectorPolicy::max_value(double* data) {
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- double ret = data[0];
- for (uint i = 1; i < no_of_gc_threads(); ++i) {
- if (data[i] > ret) {
- ret = data[i];
- }
- }
- return ret;
- } else {
- return data[0];
- }
-}
-
-double G1CollectorPolicy::sum_of_values(double* data) {
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- double sum = 0.0;
- for (uint i = 0; i < no_of_gc_threads(); i++) {
- sum += data[i];
- }
- return sum;
- } else {
- return data[0];
- }
-}
-
-double G1CollectorPolicy::max_sum(double* data1, double* data2) {
- double ret = data1[0] + data2[0];
-
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- for (uint i = 1; i < no_of_gc_threads(); ++i) {
- double data = data1[i] + data2[i];
- if (data > ret) {
- ret = data;
- }
- }
- }
- return ret;
-}
-
bool G1CollectorPolicy::need_to_start_conc_mark(const char* source, size_t alloc_word_size) {
if (_g1->concurrent_mark()->cmThread()->during_cycle()) {
return false;
@@ -1142,10 +906,8 @@
// Anything below that is considered to be zero
#define MIN_TIMER_GRANULARITY 0.0000001
-void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
+void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms) {
double end_time_sec = os::elapsedTime();
- double elapsed_ms = _last_pause_time_ms;
- bool parallel = G1CollectedHeap::use_parallel_gc_threads();
assert(_cur_collection_pause_used_regions_at_start >= cset_region_length(),
"otherwise, the subtraction below does not make sense");
size_t rs_size =
@@ -1154,7 +916,6 @@
assert(cur_used_bytes == _g1->recalculate_used(), "It should!");
bool last_pause_included_initial_mark = false;
bool update_stats = !_g1->evacuation_failed();
- set_no_of_gc_threads(no_of_gc_threads);
#ifndef PRODUCT
if (G1YoungSurvRateVerbose) {
@@ -1174,7 +935,7 @@
set_initiate_conc_mark_if_possible();
}
- _mmu_tracker->add_pause(end_time_sec - elapsed_ms/1000.0,
+ _mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0,
end_time_sec, false);
size_t freed_bytes =
@@ -1185,58 +946,11 @@
(double)surviving_bytes/
(double)_collection_set_bytes_used_before;
- // These values are used to update the summary information that is
- // displayed when TraceGen0Time is enabled, and are output as part
- // of the "finer" output, in the non-parallel case.
-
- double ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms);
- double satb_filtering_time = avg_value(_par_last_satb_filtering_times_ms);
- double update_rs_time = avg_value(_par_last_update_rs_times_ms);
- double update_rs_processed_buffers =
- sum_of_values(_par_last_update_rs_processed_buffers);
- double scan_rs_time = avg_value(_par_last_scan_rs_times_ms);
- double obj_copy_time = avg_value(_par_last_obj_copy_times_ms);
- double termination_time = avg_value(_par_last_termination_times_ms);
-
- double known_time = ext_root_scan_time +
- satb_filtering_time +
- update_rs_time +
- scan_rs_time +
- obj_copy_time;
-
- double other_time_ms = elapsed_ms;
-
- // Subtract the root region scanning wait time. It's initialized to
- // zero at the start of the pause.
- other_time_ms -= _root_region_scan_wait_time_ms;
-
- if (parallel) {
- other_time_ms -= _cur_collection_par_time_ms;
- } else {
- other_time_ms -= known_time;
- }
-
- // Now subtract the time taken to fix up roots in generated code
- other_time_ms -= _cur_collection_code_root_fixup_time_ms;
-
- // Subtract the time taken to clean the card table from the
- // current value of "other time"
- other_time_ms -= _cur_clear_ct_time_ms;
-
- // TraceGen0Time and TraceGen1Time summary info updating.
-
if (update_stats) {
- double parallel_known_time = known_time + termination_time;
- double parallel_other_time = _cur_collection_par_time_ms - parallel_known_time;
-
- _trace_gen0_time_data.record_end_collection(
- elapsed_ms, other_time_ms, _root_region_scan_wait_time_ms, _cur_collection_par_time_ms,
- ext_root_scan_time, satb_filtering_time, update_rs_time, scan_rs_time, obj_copy_time,
- termination_time, parallel_other_time, _cur_clear_ct_time_ms);
-
+ _trace_gen0_time_data.record_end_collection(pause_time_ms, phase_times());
// this is where we update the allocation rate of the application
double app_time_ms =
- (_cur_collection_start_sec * 1000.0 - _prev_collection_pause_end_ms);
+ (phase_times()->_cur_collection_start_sec * 1000.0 - _prev_collection_pause_end_ms);
if (app_time_ms < MIN_TIMER_GRANULARITY) {
// This usually happens due to the timer not having the required
// granularity. Some Linuxes are the usual culprits.
@@ -1257,7 +971,7 @@
double interval_ms =
(end_time_sec - _recent_prev_end_times_for_all_gcs_sec->oldest()) * 1000.0;
- update_recent_gc_times(end_time_sec, elapsed_ms);
+ update_recent_gc_times(end_time_sec, pause_time_ms);
_recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms;
if (recent_avg_pause_time_ratio() < 0.0 ||
(recent_avg_pause_time_ratio() - 1.0 > 0.0)) {
@@ -1284,90 +998,6 @@
}
}
}
-
- if (G1Log::finer()) {
- bool print_marking_info =
- _g1->mark_in_progress() && !last_pause_included_initial_mark;
-
- gclog_or_tty->print_cr("%s, %1.8lf secs]",
- (last_pause_included_initial_mark) ? " (initial-mark)" : "",
- elapsed_ms / 1000.0);
-
- if (_root_region_scan_wait_time_ms > 0.0) {
- print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
- }
- if (parallel) {
- print_stats(1, "Parallel Time", _cur_collection_par_time_ms, no_of_gc_threads);
- print_par_stats(2, "GC Worker Start", _par_last_gc_worker_start_times_ms);
- print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms);
- if (print_marking_info) {
- print_par_stats(2, "SATB Filtering", _par_last_satb_filtering_times_ms);
- }
- print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
- if (G1Log::finest()) {
- print_par_stats(3, "Processed Buffers", _par_last_update_rs_processed_buffers,
- false /* showDecimals */);
- }
- print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms);
- print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms);
- print_par_stats(2, "Termination", _par_last_termination_times_ms);
- if (G1Log::finest()) {
- print_par_stats(3, "Termination Attempts", _par_last_termination_attempts,
- false /* showDecimals */);
- }
-
- for (int i = 0; i < _parallel_gc_threads; i++) {
- _par_last_gc_worker_times_ms[i] = _par_last_gc_worker_end_times_ms[i] -
- _par_last_gc_worker_start_times_ms[i];
-
- double worker_known_time = _par_last_ext_root_scan_times_ms[i] +
- _par_last_satb_filtering_times_ms[i] +
- _par_last_update_rs_times_ms[i] +
- _par_last_scan_rs_times_ms[i] +
- _par_last_obj_copy_times_ms[i] +
- _par_last_termination_times_ms[i];
-
- _par_last_gc_worker_other_times_ms[i] = _par_last_gc_worker_times_ms[i] -
- worker_known_time;
- }
-
- print_par_stats(2, "GC Worker Other", _par_last_gc_worker_other_times_ms);
- print_par_stats(2, "GC Worker Total", _par_last_gc_worker_times_ms);
- print_par_stats(2, "GC Worker End", _par_last_gc_worker_end_times_ms);
- } else {
- print_stats(1, "Ext Root Scanning", ext_root_scan_time);
- if (print_marking_info) {
- print_stats(1, "SATB Filtering", satb_filtering_time);
- }
- print_stats(1, "Update RS", update_rs_time);
- if (G1Log::finest()) {
- print_stats(2, "Processed Buffers", (int)update_rs_processed_buffers);
- }
- print_stats(1, "Scan RS", scan_rs_time);
- print_stats(1, "Object Copying", obj_copy_time);
- }
- print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
- print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
-#ifndef PRODUCT
- print_stats(1, "Cur Clear CC", _cur_clear_cc_time_ms);
- print_stats(1, "Cum Clear CC", _cum_clear_cc_time_ms);
- print_stats(1, "Min Clear CC", _min_clear_cc_time_ms);
- print_stats(1, "Max Clear CC", _max_clear_cc_time_ms);
- if (_num_cc_clears > 0) {
- print_stats(1, "Avg Clear CC", _cum_clear_cc_time_ms / ((double)_num_cc_clears));
- }
-#endif
- print_stats(1, "Other", other_time_ms);
- print_stats(2, "Choose CSet",
- (_recorded_young_cset_choice_time_ms +
- _recorded_non_young_cset_choice_time_ms));
- print_stats(2, "Ref Proc", _cur_ref_proc_time_ms);
- print_stats(2, "Ref Enq", _cur_ref_enq_time_ms);
- print_stats(2, "Free CSet",
- (_recorded_young_free_cset_time_ms +
- _recorded_non_young_free_cset_time_ms));
- }
-
bool new_in_marking_window = _in_marking_window;
bool new_in_marking_window_im = false;
if (during_initial_mark_pause()) {
@@ -1406,8 +1036,6 @@
// do that for any other surv rate groupsx
if (update_stats) {
- double pause_time_ms = elapsed_ms;
-
size_t diff = 0;
if (_max_pending_cards >= _pending_cards) {
diff = _max_pending_cards - _pending_cards;
@@ -1416,7 +1044,7 @@
double cost_per_card_ms = 0.0;
if (_pending_cards > 0) {
- cost_per_card_ms = update_rs_time / (double) _pending_cards;
+ cost_per_card_ms = phase_times()->_update_rs_time / (double) _pending_cards;
_cost_per_card_ms_seq->add(cost_per_card_ms);
}
@@ -1424,7 +1052,7 @@
double cost_per_entry_ms = 0.0;
if (cards_scanned > 10) {
- cost_per_entry_ms = scan_rs_time / (double) cards_scanned;
+ cost_per_entry_ms = phase_times()->_scan_rs_time / (double) cards_scanned;
if (_last_gc_was_young) {
_cost_per_entry_ms_seq->add(cost_per_entry_ms);
} else {
@@ -1464,7 +1092,7 @@
size_t copied_bytes = surviving_bytes;
double cost_per_byte_ms = 0.0;
if (copied_bytes > 0) {
- cost_per_byte_ms = obj_copy_time / (double) copied_bytes;
+ cost_per_byte_ms = phase_times()->_obj_copy_time / (double) copied_bytes;
if (_in_marking_window) {
_cost_per_byte_ms_during_cm_seq->add(cost_per_byte_ms);
} else {
@@ -1473,21 +1101,21 @@
}
double all_other_time_ms = pause_time_ms -
- (update_rs_time + scan_rs_time + obj_copy_time + termination_time);
+ (phase_times()->_update_rs_time + phase_times()->_scan_rs_time + phase_times()->_obj_copy_time + phase_times()->_termination_time);
double young_other_time_ms = 0.0;
if (young_cset_region_length() > 0) {
young_other_time_ms =
- _recorded_young_cset_choice_time_ms +
- _recorded_young_free_cset_time_ms;
+ phase_times()->_recorded_young_cset_choice_time_ms +
+ phase_times()->_recorded_young_free_cset_time_ms;
_young_other_cost_per_region_ms_seq->add(young_other_time_ms /
(double) young_cset_region_length());
}
double non_young_other_time_ms = 0.0;
if (old_cset_region_length() > 0) {
non_young_other_time_ms =
- _recorded_non_young_cset_choice_time_ms +
- _recorded_non_young_free_cset_time_ms;
+ phase_times()->_recorded_non_young_cset_choice_time_ms +
+ phase_times()->_recorded_non_young_free_cset_time_ms;
_non_young_other_cost_per_region_ms_seq->add(non_young_other_time_ms /
(double) old_cset_region_length());
@@ -1514,7 +1142,7 @@
// Note that _mmu_tracker->max_gc_time() returns the time in seconds.
double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
- adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms);
+ adjust_concurrent_refinement(phase_times()->_update_rs_time, phase_times()->_update_rs_processed_buffers, update_rs_time_goal_ms);
_collectionSetChooser->verify();
}
@@ -2323,7 +1951,7 @@
set_recorded_rs_lengths(_inc_cset_recorded_rs_lengths);
double young_end_time_sec = os::elapsedTime();
- _recorded_young_cset_choice_time_ms =
+ phase_times()->_recorded_young_cset_choice_time_ms =
(young_end_time_sec - young_start_time_sec) * 1000.0;
// We are doing young collections so reset this.
@@ -2439,7 +2067,7 @@
predicted_pause_time_ms, target_pause_time_ms);
double non_young_end_time_sec = os::elapsedTime();
- _recorded_non_young_cset_choice_time_ms =
+ phase_times()->_recorded_non_young_cset_choice_time_ms =
(non_young_end_time_sec - non_young_start_time_sec) * 1000.0;
}
@@ -2455,33 +2083,29 @@
}
}
-void TraceGen0TimeData::record_end_collection(
- double total_ms,
- double other_ms,
- double root_region_scan_wait_ms,
- double parallel_ms,
- double ext_root_scan_ms,
- double satb_filtering_ms,
- double update_rs_ms,
- double scan_rs_ms,
- double obj_copy_ms,
- double termination_ms,
- double parallel_other_ms,
- double clear_ct_ms)
-{
+void TraceGen0TimeData::record_end_collection(double pause_time_ms, G1GCPhaseTimes* phase_times) {
if(TraceGen0Time) {
- _total.add(total_ms);
- _other.add(other_ms);
- _root_region_scan_wait.add(root_region_scan_wait_ms);
- _parallel.add(parallel_ms);
- _ext_root_scan.add(ext_root_scan_ms);
- _satb_filtering.add(satb_filtering_ms);
- _update_rs.add(update_rs_ms);
- _scan_rs.add(scan_rs_ms);
- _obj_copy.add(obj_copy_ms);
- _termination.add(termination_ms);
- _parallel_other.add(parallel_other_ms);
- _clear_ct.add(clear_ct_ms);
+ _total.add(pause_time_ms);
+ _other.add(pause_time_ms - phase_times->accounted_time_ms());
+ _root_region_scan_wait.add(phase_times->_root_region_scan_wait_time_ms);
+ _parallel.add(phase_times->_cur_collection_par_time_ms);
+ _ext_root_scan.add(phase_times->_ext_root_scan_time);
+ _satb_filtering.add(phase_times->_satb_filtering_time);
+ _update_rs.add(phase_times->_update_rs_time);
+ _scan_rs.add(phase_times->_scan_rs_time);
+ _obj_copy.add(phase_times->_obj_copy_time);
+ _termination.add(phase_times->_termination_time);
+
+ double parallel_known_time = phase_times->_ext_root_scan_time +
+ phase_times->_satb_filtering_time +
+ phase_times->_update_rs_time +
+ phase_times->_scan_rs_time +
+ phase_times->_obj_copy_time +
+ + phase_times->_termination_time;
+
+ double parallel_other_time = phase_times->_cur_collection_par_time_ms - parallel_known_time;
+ _parallel_other.add(parallel_other_time);
+ _clear_ct.add(phase_times->_cur_clear_ct_time_ms);
}
}
@@ -2497,20 +2121,18 @@
}
}
-void TraceGen0TimeData::print_summary(int level,
- const char* str,
+void TraceGen0TimeData::print_summary(const char* str,
const NumberSeq* seq) const {
double sum = seq->sum();
- LineBuffer(level + 1).append_and_print_cr("%-24s = %8.2lf s (avg = %8.2lf ms)",
+ gclog_or_tty->print_cr("%-27s = %8.2lf s (avg = %8.2lf ms)",
str, sum / 1000.0, seq->avg());
}
-void TraceGen0TimeData::print_summary_sd(int level,
- const char* str,
+void TraceGen0TimeData::print_summary_sd(const char* str,
const NumberSeq* seq) const {
- print_summary(level, str, seq);
- LineBuffer(level + 6).append_and_print_cr("(num = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
- seq->num(), seq->sd(), seq->maximum());
+ print_summary(str, seq);
+ gclog_or_tty->print_cr("%+45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
+ "(num", seq->num(), seq->sd(), seq->maximum());
}
void TraceGen0TimeData::print() const {
@@ -2519,7 +2141,7 @@
}
gclog_or_tty->print_cr("ALL PAUSES");
- print_summary_sd(0, "Total", &_total);
+ print_summary_sd(" Total", &_total);
gclog_or_tty->print_cr("");
gclog_or_tty->print_cr("");
gclog_or_tty->print_cr(" Young GC Pauses: %8d", _young_pause_num);
@@ -2531,24 +2153,24 @@
if (_young_pause_num == 0 && _mixed_pause_num == 0) {
gclog_or_tty->print_cr("none");
} else {
- print_summary_sd(0, "Evacuation Pauses", &_total);
- print_summary(1, "Root Region Scan Wait", &_root_region_scan_wait);
- print_summary(1, "Parallel Time", &_parallel);
- print_summary(2, "Ext Root Scanning", &_ext_root_scan);
- print_summary(2, "SATB Filtering", &_satb_filtering);
- print_summary(2, "Update RS", &_update_rs);
- print_summary(2, "Scan RS", &_scan_rs);
- print_summary(2, "Object Copy", &_obj_copy);
- print_summary(2, "Termination", &_termination);
- print_summary(2, "Parallel Other", &_parallel_other);
- print_summary(1, "Clear CT", &_clear_ct);
- print_summary(1, "Other", &_other);
+ print_summary_sd(" Evacuation Pauses", &_total);
+ print_summary(" Root Region Scan Wait", &_root_region_scan_wait);
+ print_summary(" Parallel Time", &_parallel);
+ print_summary(" Ext Root Scanning", &_ext_root_scan);
+ print_summary(" SATB Filtering", &_satb_filtering);
+ print_summary(" Update RS", &_update_rs);
+ print_summary(" Scan RS", &_scan_rs);
+ print_summary(" Object Copy", &_obj_copy);
+ print_summary(" Termination", &_termination);
+ print_summary(" Parallel Other", &_parallel_other);
+ print_summary(" Clear CT", &_clear_ct);
+ print_summary(" Other", &_other);
}
gclog_or_tty->print_cr("");
gclog_or_tty->print_cr("MISC");
- print_summary_sd(0, "Stop World", &_all_stop_world_times_ms);
- print_summary_sd(0, "Yields", &_all_yield_times_ms);
+ print_summary_sd(" Stop World", &_all_stop_world_times_ms);
+ print_summary_sd(" Yields", &_all_yield_times_ms);
}
void TraceGen1TimeData::record_full_collection(double full_gc_time_ms) {
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -36,6 +36,7 @@
class HeapRegion;
class CollectionSetChooser;
+class G1GCPhaseTimes;
// TraceGen0Time collects data on _both_ young and mixed evacuation pauses
// (the latter may contain non-young regions - i.e. regions that are
@@ -61,26 +62,14 @@
NumberSeq _parallel_other;
NumberSeq _clear_ct;
- void print_summary (int level, const char* str, const NumberSeq* seq) const;
- void print_summary_sd (int level, const char* str, const NumberSeq* seq) const;
+ void print_summary(const char* str, const NumberSeq* seq) const;
+ void print_summary_sd(const char* str, const NumberSeq* seq) const;
public:
TraceGen0TimeData() : _young_pause_num(0), _mixed_pause_num(0) {};
void record_start_collection(double time_to_stop_the_world_ms);
void record_yield_time(double yield_time_ms);
- void record_end_collection(
- double total_ms,
- double other_ms,
- double root_region_scan_wait_ms,
- double parallel_ms,
- double ext_root_scan_ms,
- double satb_filtering_ms,
- double update_rs_ms,
- double scan_rs_ms,
- double obj_copy_ms,
- double termination_ms,
- double parallel_other_ms,
- double clear_ct_ms);
+ void record_end_collection(double pause_time_ms, G1GCPhaseTimes* phase_times);
void increment_young_collection_count();
void increment_mixed_collection_count();
void print() const;
@@ -186,25 +175,9 @@
CollectionSetChooser* _collectionSetChooser;
- double _cur_collection_start_sec;
+ double _full_collection_start_sec;
size_t _cur_collection_pause_used_at_start_bytes;
uint _cur_collection_pause_used_regions_at_start;
- double _cur_collection_par_time_ms;
-
- double _cur_collection_code_root_fixup_time_ms;
-
- double _cur_clear_ct_time_ms;
- double _cur_ref_proc_time_ms;
- double _cur_ref_enq_time_ms;
-
-#ifndef PRODUCT
- // Card Table Count Cache stats
- double _min_clear_cc_time_ms; // min
- double _max_clear_cc_time_ms; // max
- double _cur_clear_cc_time_ms; // clearing time during current pause
- double _cum_clear_cc_time_ms; // cummulative clearing time
- jlong _num_cc_clears; // number of times the card count cache has been cleared
-#endif
// These exclude marking times.
TruncatedSeq* _recent_gc_times_ms;
@@ -217,23 +190,6 @@
double _stop_world_start;
- double* _par_last_gc_worker_start_times_ms;
- double* _par_last_ext_root_scan_times_ms;
- double* _par_last_satb_filtering_times_ms;
- double* _par_last_update_rs_times_ms;
- double* _par_last_update_rs_processed_buffers;
- double* _par_last_scan_rs_times_ms;
- double* _par_last_obj_copy_times_ms;
- double* _par_last_termination_times_ms;
- double* _par_last_termination_attempts;
- double* _par_last_gc_worker_end_times_ms;
- double* _par_last_gc_worker_times_ms;
-
- // Each workers 'other' time i.e. the elapsed time of the parallel
- // code executed by a worker minus the sum of the individual sub-phase
- // times for that worker thread.
- double* _par_last_gc_worker_other_times_ms;
-
// indicates whether we are in young or mixed GC mode
bool _gcs_are_young;
@@ -306,10 +262,6 @@
size_t _recorded_rs_lengths;
size_t _max_rs_lengths;
-
- double _recorded_young_free_cset_time_ms;
- double _recorded_non_young_free_cset_time_ms;
-
double _sigma;
size_t _rs_lengths_prediction;
@@ -341,8 +293,7 @@
void set_no_of_gc_threads(uintx v) { _no_of_gc_threads = v; }
double _pause_time_target_ms;
- double _recorded_young_cset_choice_time_ms;
- double _recorded_non_young_cset_choice_time_ms;
+
size_t _pending_cards;
size_t _max_pending_cards;
@@ -497,14 +448,6 @@
uint young_cset_region_length() { return eden_cset_region_length() +
survivor_cset_region_length(); }
- void record_young_free_cset_time_ms(double time_ms) {
- _recorded_young_free_cset_time_ms = time_ms;
- }
-
- void record_non_young_free_cset_time_ms(double time_ms) {
- _recorded_non_young_free_cset_time_ms = time_ms;
- }
-
double predict_survivor_regions_evac_time();
void cset_regions_freed() {
@@ -552,19 +495,6 @@
}
private:
- void print_stats(int level, const char* str, double value);
- void print_stats(int level, const char* str, double value, int workers);
- void print_stats(int level, const char* str, int value);
-
- void print_par_stats(int level, const char* str, double* data, bool showDecimals = true);
-
- double avg_value (double* data);
- double max_value (double* data);
- double sum_of_values (double* data);
- double max_sum (double* data1, double* data2);
-
- double _last_pause_time_ms;
-
size_t _bytes_in_collection_set_before_gc;
size_t _bytes_copied_during_gc;
@@ -638,6 +568,8 @@
// Stash a pointer to the g1 heap.
G1CollectedHeap* _g1;
+ G1GCPhaseTimes* _phase_times;
+
// The ratio of gc time to elapsed time, computed over recent pauses.
double _recent_avg_pause_time_ratio;
@@ -677,7 +609,6 @@
double _cur_mark_stop_world_time_ms;
double _mark_remark_start_sec;
double _mark_cleanup_start_sec;
- double _root_region_scan_wait_time_ms;
// Update the young list target length either by setting it to the
// desired fixed value or by calculating it using G1's pause
@@ -728,6 +659,8 @@
return CollectorPolicy::G1CollectorPolicyKind;
}
+ G1GCPhaseTimes* phase_times() const { return _phase_times; }
+
// Check the current value of the young list RSet lengths and
// compare it against the last prediction. If the current value is
// higher, recalculate the young list target length prediction.
@@ -772,10 +705,6 @@
void record_concurrent_mark_init_end(double
mark_init_elapsed_time_ms);
- void record_root_region_scan_wait_time(double time_ms) {
- _root_region_scan_wait_time_ms = time_ms;
- }
-
void record_concurrent_mark_remark_start();
void record_concurrent_mark_remark_end();
@@ -784,97 +713,14 @@
void record_concurrent_mark_cleanup_completed();
void record_concurrent_pause();
- void record_concurrent_pause_end();
- void record_collection_pause_end(int no_of_gc_threads);
+ void record_collection_pause_end(double pause_time);
void print_heap_transition();
// Record the fact that a full collection occurred.
void record_full_collection_start();
void record_full_collection_end();
- void record_gc_worker_start_time(int worker_i, double ms) {
- _par_last_gc_worker_start_times_ms[worker_i] = ms;
- }
-
- void record_ext_root_scan_time(int worker_i, double ms) {
- _par_last_ext_root_scan_times_ms[worker_i] = ms;
- }
-
- void record_satb_filtering_time(int worker_i, double ms) {
- _par_last_satb_filtering_times_ms[worker_i] = ms;
- }
-
- void record_update_rs_time(int thread, double ms) {
- _par_last_update_rs_times_ms[thread] = ms;
- }
-
- void record_update_rs_processed_buffers (int thread,
- double processed_buffers) {
- _par_last_update_rs_processed_buffers[thread] = processed_buffers;
- }
-
- void record_scan_rs_time(int thread, double ms) {
- _par_last_scan_rs_times_ms[thread] = ms;
- }
-
- void reset_obj_copy_time(int thread) {
- _par_last_obj_copy_times_ms[thread] = 0.0;
- }
-
- void reset_obj_copy_time() {
- reset_obj_copy_time(0);
- }
-
- void record_obj_copy_time(int thread, double ms) {
- _par_last_obj_copy_times_ms[thread] += ms;
- }
-
- void record_termination(int thread, double ms, size_t attempts) {
- _par_last_termination_times_ms[thread] = ms;
- _par_last_termination_attempts[thread] = (double) attempts;
- }
-
- void record_gc_worker_end_time(int worker_i, double ms) {
- _par_last_gc_worker_end_times_ms[worker_i] = ms;
- }
-
- void record_pause_time_ms(double ms) {
- _last_pause_time_ms = ms;
- }
-
- void record_clear_ct_time(double ms) {
- _cur_clear_ct_time_ms = ms;
- }
-
- void record_par_time(double ms) {
- _cur_collection_par_time_ms = ms;
- }
-
- void record_code_root_fixup_time(double ms) {
- _cur_collection_code_root_fixup_time_ms = ms;
- }
-
- void record_ref_proc_time(double ms) {
- _cur_ref_proc_time_ms = ms;
- }
-
- void record_ref_enq_time(double ms) {
- _cur_ref_enq_time_ms = ms;
- }
-
-#ifndef PRODUCT
- void record_cc_clear_time(double ms) {
- if (_min_clear_cc_time_ms < 0.0 || ms <= _min_clear_cc_time_ms)
- _min_clear_cc_time_ms = ms;
- if (_max_clear_cc_time_ms < 0.0 || ms >= _max_clear_cc_time_ms)
- _max_clear_cc_time_ms = ms;
- _cur_clear_cc_time_ms = ms;
- _cum_clear_cc_time_ms += ms;
- _num_cc_clears++;
- }
-#endif
-
// Record how much space we copied during a GC. This is typically
// called when a GC alloc region is being retired.
void record_bytes_copied_during_gc(size_t bytes) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -0,0 +1,379 @@
+/*
+ * 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.
+ *
+ */
+
+
+#include "precompiled.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
+#include "gc_implementation/g1/g1Log.hpp"
+
+// Helper class for avoiding interleaved logging
+class LineBuffer: public StackObj {
+
+private:
+ static const int BUFFER_LEN = 1024;
+ static const int INDENT_CHARS = 3;
+ char _buffer[BUFFER_LEN];
+ int _indent_level;
+ int _cur;
+
+ void vappend(const char* format, va_list ap) {
+ int res = vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap);
+ if (res != -1) {
+ _cur += res;
+ } else {
+ DEBUG_ONLY(warning("buffer too small in LineBuffer");)
+ _buffer[BUFFER_LEN -1] = 0;
+ _cur = BUFFER_LEN; // vsnprintf above should not add to _buffer if we are called again
+ }
+ }
+
+public:
+ explicit LineBuffer(int indent_level): _indent_level(indent_level), _cur(0) {
+ for (; (_cur < BUFFER_LEN && _cur < (_indent_level * INDENT_CHARS)); _cur++) {
+ _buffer[_cur] = ' ';
+ }
+ }
+
+#ifndef PRODUCT
+ ~LineBuffer() {
+ assert(_cur == _indent_level * INDENT_CHARS, "pending data in buffer - append_and_print_cr() not called?");
+ }
+#endif
+
+ void append(const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ vappend(format, ap);
+ va_end(ap);
+ }
+
+ void append_and_print_cr(const char* format, ...) {
+ va_list ap;
+ va_start(ap, format);
+ vappend(format, ap);
+ va_end(ap);
+ gclog_or_tty->print_cr("%s", _buffer);
+ _cur = _indent_level * INDENT_CHARS;
+ }
+};
+
+G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
+ _max_gc_threads(max_gc_threads),
+ _min_clear_cc_time_ms(-1.0),
+ _max_clear_cc_time_ms(-1.0),
+ _cur_clear_cc_time_ms(0.0),
+ _cum_clear_cc_time_ms(0.0),
+ _num_cc_clears(0L)
+{
+ assert(max_gc_threads > 0, "Must have some GC threads");
+ _par_last_gc_worker_start_times_ms = new double[_max_gc_threads];
+ _par_last_ext_root_scan_times_ms = new double[_max_gc_threads];
+ _par_last_satb_filtering_times_ms = new double[_max_gc_threads];
+ _par_last_update_rs_times_ms = new double[_max_gc_threads];
+ _par_last_update_rs_processed_buffers = new double[_max_gc_threads];
+ _par_last_scan_rs_times_ms = new double[_max_gc_threads];
+ _par_last_obj_copy_times_ms = new double[_max_gc_threads];
+ _par_last_termination_times_ms = new double[_max_gc_threads];
+ _par_last_termination_attempts = new double[_max_gc_threads];
+ _par_last_gc_worker_end_times_ms = new double[_max_gc_threads];
+ _par_last_gc_worker_times_ms = new double[_max_gc_threads];
+ _par_last_gc_worker_other_times_ms = new double[_max_gc_threads];
+}
+
+void G1GCPhaseTimes::note_gc_start(double pause_start_time_sec, uint active_gc_threads,
+ bool is_young_gc, bool is_initial_mark_gc, GCCause::Cause gc_cause) {
+ assert(active_gc_threads > 0, "The number of threads must be > 0");
+ assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max nubmer of threads");
+ _active_gc_threads = active_gc_threads;
+ _pause_start_time_sec = pause_start_time_sec;
+ _is_young_gc = is_young_gc;
+ _is_initial_mark_gc = is_initial_mark_gc;
+ _gc_cause = gc_cause;
+
+#ifdef ASSERT
+ // initialise the timing data to something well known so that we can spot
+ // if something is not set properly
+
+ for (uint i = 0; i < _max_gc_threads; ++i) {
+ _par_last_gc_worker_start_times_ms[i] = -1234.0;
+ _par_last_ext_root_scan_times_ms[i] = -1234.0;
+ _par_last_satb_filtering_times_ms[i] = -1234.0;
+ _par_last_update_rs_times_ms[i] = -1234.0;
+ _par_last_update_rs_processed_buffers[i] = -1234.0;
+ _par_last_scan_rs_times_ms[i] = -1234.0;
+ _par_last_obj_copy_times_ms[i] = -1234.0;
+ _par_last_termination_times_ms[i] = -1234.0;
+ _par_last_termination_attempts[i] = -1234.0;
+ _par_last_gc_worker_end_times_ms[i] = -1234.0;
+ _par_last_gc_worker_times_ms[i] = -1234.0;
+ _par_last_gc_worker_other_times_ms[i] = -1234.0;
+ }
+#endif
+}
+
+void G1GCPhaseTimes::note_gc_end(double pause_end_time_sec) {
+ if (G1Log::fine()) {
+ double pause_time_ms = (pause_end_time_sec - _pause_start_time_sec) * MILLIUNITS;
+
+ for (uint i = 0; i < _active_gc_threads; i++) {
+ _par_last_gc_worker_times_ms[i] = _par_last_gc_worker_end_times_ms[i] -
+ _par_last_gc_worker_start_times_ms[i];
+
+ double worker_known_time = _par_last_ext_root_scan_times_ms[i] +
+ _par_last_satb_filtering_times_ms[i] +
+ _par_last_update_rs_times_ms[i] +
+ _par_last_scan_rs_times_ms[i] +
+ _par_last_obj_copy_times_ms[i] +
+ _par_last_termination_times_ms[i];
+
+ _par_last_gc_worker_other_times_ms[i] = _par_last_gc_worker_times_ms[i] -
+ worker_known_time;
+ }
+
+ print(pause_time_ms);
+ }
+
+}
+
+void G1GCPhaseTimes::print_par_stats(int level,
+ const char* str,
+ double* data,
+ bool showDecimals) {
+ double min = data[0], max = data[0];
+ double total = 0.0;
+ LineBuffer buf(level);
+ buf.append("[%s (ms):", str);
+ for (uint i = 0; i < _active_gc_threads; ++i) {
+ double val = data[i];
+ if (val < min)
+ min = val;
+ if (val > max)
+ max = val;
+ total += val;
+ if (G1Log::finest()) {
+ if (showDecimals) {
+ buf.append(" %.1lf", val);
+ } else {
+ buf.append(" %d", (int)val);
+ }
+ }
+ }
+
+ if (G1Log::finest()) {
+ buf.append_and_print_cr("");
+ }
+ double avg = total / (double) _active_gc_threads;
+ if (showDecimals) {
+ buf.append_and_print_cr(" Min: %.1lf, Avg: %.1lf, Max: %.1lf, Diff: %.1lf, Sum: %.1lf]",
+ min, avg, max, max - min, total);
+ } else {
+ buf.append_and_print_cr(" Min: %d, Avg: %d, Max: %d, Diff: %d, Sum: %d]",
+ (int)min, (int)avg, (int)max, (int)max - (int)min, (int)total);
+ }
+}
+
+void G1GCPhaseTimes::print_stats(int level, const char* str, double value) {
+ LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value);
+}
+
+void G1GCPhaseTimes::print_stats(int level, const char* str, double value, int workers) {
+ LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: %d]", str, value, workers);
+}
+
+void G1GCPhaseTimes::print_stats(int level, const char* str, int value) {
+ LineBuffer(level).append_and_print_cr("[%s: %d]", str, value);
+}
+
+double G1GCPhaseTimes::avg_value(double* data) {
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ double ret = 0.0;
+ for (uint i = 0; i < _active_gc_threads; ++i) {
+ ret += data[i];
+ }
+ return ret / (double) _active_gc_threads;
+ } else {
+ return data[0];
+ }
+}
+
+double G1GCPhaseTimes::max_value(double* data) {
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ double ret = data[0];
+ for (uint i = 1; i < _active_gc_threads; ++i) {
+ if (data[i] > ret) {
+ ret = data[i];
+ }
+ }
+ return ret;
+ } else {
+ return data[0];
+ }
+}
+
+double G1GCPhaseTimes::sum_of_values(double* data) {
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ double sum = 0.0;
+ for (uint i = 0; i < _active_gc_threads; i++) {
+ sum += data[i];
+ }
+ return sum;
+ } else {
+ return data[0];
+ }
+}
+
+double G1GCPhaseTimes::max_sum(double* data1, double* data2) {
+ double ret = data1[0] + data2[0];
+
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ for (uint i = 1; i < _active_gc_threads; ++i) {
+ double data = data1[i] + data2[i];
+ if (data > ret) {
+ ret = data;
+ }
+ }
+ }
+ return ret;
+}
+
+void G1GCPhaseTimes::collapse_par_times() {
+ _ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms);
+ _satb_filtering_time = avg_value(_par_last_satb_filtering_times_ms);
+ _update_rs_time = avg_value(_par_last_update_rs_times_ms);
+ _update_rs_processed_buffers =
+ sum_of_values(_par_last_update_rs_processed_buffers);
+ _scan_rs_time = avg_value(_par_last_scan_rs_times_ms);
+ _obj_copy_time = avg_value(_par_last_obj_copy_times_ms);
+ _termination_time = avg_value(_par_last_termination_times_ms);
+}
+
+double G1GCPhaseTimes::accounted_time_ms() {
+ // Subtract the root region scanning wait time. It's initialized to
+ // zero at the start of the pause.
+ double misc_time_ms = _root_region_scan_wait_time_ms;
+
+ misc_time_ms += _cur_collection_par_time_ms;
+
+ // Now subtract the time taken to fix up roots in generated code
+ misc_time_ms += _cur_collection_code_root_fixup_time_ms;
+
+ // Subtract the time taken to clean the card table from the
+ // current value of "other time"
+ misc_time_ms += _cur_clear_ct_time_ms;
+
+ return misc_time_ms;
+}
+
+void G1GCPhaseTimes::print(double pause_time_ms) {
+
+ if (PrintGCTimeStamps) {
+ gclog_or_tty->stamp();
+ gclog_or_tty->print(": ");
+ }
+
+ GCCauseString gc_cause_str = GCCauseString("GC pause", _gc_cause)
+ .append(_is_young_gc ? " (young)" : " (mixed)")
+ .append(_is_initial_mark_gc ? " (initial-mark)" : "");
+ gclog_or_tty->print_cr("[%s, %3.7f secs]", (const char*)gc_cause_str, pause_time_ms / 1000.0);
+
+ if (!G1Log::finer()) {
+ return;
+ }
+
+ if (_root_region_scan_wait_time_ms > 0.0) {
+ print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
+ }
+ if (G1CollectedHeap::use_parallel_gc_threads()) {
+ print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
+ print_par_stats(2, "GC Worker Start", _par_last_gc_worker_start_times_ms);
+ print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms);
+ if (_satb_filtering_time > 0.0) {
+ print_par_stats(2, "SATB Filtering", _par_last_satb_filtering_times_ms);
+ }
+ print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
+ if (G1Log::finest()) {
+ print_par_stats(3, "Processed Buffers", _par_last_update_rs_processed_buffers,
+ false /* showDecimals */);
+ }
+ print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms);
+ print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms);
+ print_par_stats(2, "Termination", _par_last_termination_times_ms);
+ if (G1Log::finest()) {
+ print_par_stats(3, "Termination Attempts", _par_last_termination_attempts,
+ false /* showDecimals */);
+ }
+ print_par_stats(2, "GC Worker Other", _par_last_gc_worker_other_times_ms);
+ print_par_stats(2, "GC Worker Total", _par_last_gc_worker_times_ms);
+ print_par_stats(2, "GC Worker End", _par_last_gc_worker_end_times_ms);
+ } else {
+ print_stats(1, "Ext Root Scanning", _ext_root_scan_time);
+ if (_satb_filtering_time > 0.0) {
+ print_stats(1, "SATB Filtering", _satb_filtering_time);
+ }
+ print_stats(1, "Update RS", _update_rs_time);
+ if (G1Log::finest()) {
+ print_stats(2, "Processed Buffers", (int)_update_rs_processed_buffers);
+ }
+ print_stats(1, "Scan RS", _scan_rs_time);
+ print_stats(1, "Object Copying", _obj_copy_time);
+ }
+ print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
+ print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
+ if (Verbose && G1Log::finest()) {
+ print_stats(1, "Cur Clear CC", _cur_clear_cc_time_ms);
+ print_stats(1, "Cum Clear CC", _cum_clear_cc_time_ms);
+ print_stats(1, "Min Clear CC", _min_clear_cc_time_ms);
+ print_stats(1, "Max Clear CC", _max_clear_cc_time_ms);
+ if (_num_cc_clears > 0) {
+ print_stats(1, "Avg Clear CC", _cum_clear_cc_time_ms / ((double)_num_cc_clears));
+ }
+ }
+ double misc_time_ms = pause_time_ms - accounted_time_ms();
+ print_stats(1, "Other", misc_time_ms);
+ print_stats(2, "Choose CSet",
+ (_recorded_young_cset_choice_time_ms +
+ _recorded_non_young_cset_choice_time_ms));
+ print_stats(2, "Ref Proc", _cur_ref_proc_time_ms);
+ print_stats(2, "Ref Enq", _cur_ref_enq_time_ms);
+ print_stats(2, "Free CSet",
+ (_recorded_young_free_cset_time_ms +
+ _recorded_non_young_free_cset_time_ms));
+}
+
+void G1GCPhaseTimes::record_cc_clear_time_ms(double ms) {
+ if (!(Verbose && G1Log::finest())) {
+ return;
+ }
+
+ if (_min_clear_cc_time_ms < 0.0 || ms <= _min_clear_cc_time_ms) {
+ _min_clear_cc_time_ms = ms;
+ }
+ if (_max_clear_cc_time_ms < 0.0 || ms >= _max_clear_cc_time_ms) {
+ _max_clear_cc_time_ms = ms;
+ }
+ _cur_clear_cc_time_ms = ms;
+ _cum_clear_cc_time_ms += ms;
+ _num_cc_clears++;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -0,0 +1,216 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
+
+#include "memory/allocation.hpp"
+#include "gc_interface/gcCause.hpp"
+
+class G1GCPhaseTimes : public CHeapObj<mtGC> {
+ friend class G1CollectorPolicy;
+ friend class TraceGen0TimeData;
+
+ private:
+ uint _active_gc_threads;
+ uint _max_gc_threads;
+
+ GCCause::Cause _gc_cause;
+ bool _is_young_gc;
+ bool _is_initial_mark_gc;
+
+ double _pause_start_time_sec;
+
+ double* _par_last_gc_worker_start_times_ms;
+ double* _par_last_ext_root_scan_times_ms;
+ double* _par_last_satb_filtering_times_ms;
+ double* _par_last_update_rs_times_ms;
+ double* _par_last_update_rs_processed_buffers;
+ double* _par_last_scan_rs_times_ms;
+ double* _par_last_obj_copy_times_ms;
+ double* _par_last_termination_times_ms;
+ double* _par_last_termination_attempts;
+ double* _par_last_gc_worker_end_times_ms;
+ double* _par_last_gc_worker_times_ms;
+ double* _par_last_gc_worker_other_times_ms;
+
+ double _cur_collection_par_time_ms;
+
+ double _cur_collection_code_root_fixup_time_ms;
+
+ double _cur_clear_ct_time_ms;
+ double _cur_ref_proc_time_ms;
+ double _cur_ref_enq_time_ms;
+
+ // Helper methods for detailed logging
+ void print_par_stats(int level, const char* str, double* data, bool showDecimals = true);
+ void print_stats(int level, const char* str, double value);
+ void print_stats(int level, const char* str, double value, int workers);
+ void print_stats(int level, const char* str, int value);
+ double avg_value(double* data);
+ double max_value(double* data);
+ double sum_of_values(double* data);
+ double max_sum(double* data1, double* data2);
+ double accounted_time_ms();
+
+ // Card Table Count Cache stats
+ double _min_clear_cc_time_ms; // min
+ double _max_clear_cc_time_ms; // max
+ double _cur_clear_cc_time_ms; // clearing time during current pause
+ double _cum_clear_cc_time_ms; // cummulative clearing time
+ jlong _num_cc_clears; // number of times the card count cache has been cleared
+
+ // The following insance variables are directly accessed by G1CollectorPolicy
+ // and TraceGen0TimeData. This is why those classes are declared friends.
+ // An alternative is to add getters and setters for all of these fields.
+ // It might also be possible to restructure the code to reduce these
+ // dependencies.
+ double _ext_root_scan_time;
+ double _satb_filtering_time;
+ double _update_rs_time;
+ double _update_rs_processed_buffers;
+ double _scan_rs_time;
+ double _obj_copy_time;
+ double _termination_time;
+
+ double _cur_collection_start_sec;
+ double _root_region_scan_wait_time_ms;
+
+ double _recorded_young_cset_choice_time_ms;
+ double _recorded_non_young_cset_choice_time_ms;
+
+ double _recorded_young_free_cset_time_ms;
+ double _recorded_non_young_free_cset_time_ms;
+
+ void print(double pause_time_ms);
+
+ public:
+ G1GCPhaseTimes(uint max_gc_threads);
+ void note_gc_start(double pause_start_time_sec, uint active_gc_threads,
+ bool is_young_gc, bool is_initial_mark_gc, GCCause::Cause gc_cause);
+ void note_gc_end(double pause_end_time_sec);
+ void collapse_par_times();
+
+ void record_gc_worker_start_time(uint worker_i, double ms) {
+ assert(worker_i >= 0, "worker index must be > 0");
+ assert(worker_i < _active_gc_threads, "worker index out of bounds");
+ _par_last_gc_worker_start_times_ms[worker_i] = ms;
+ }
+
+ void record_ext_root_scan_time(uint worker_i, double ms) {
+ assert(worker_i >= 0, "worker index must be > 0");
+ assert(worker_i < _active_gc_threads, "worker index out of bounds");
+ _par_last_ext_root_scan_times_ms[worker_i] = ms;
+ }
+
+ void record_satb_filtering_time(uint worker_i, double ms) {
+ assert(worker_i >= 0, "worker index must be > 0");
+ assert(worker_i < _active_gc_threads, "worker index out of bounds");
+ _par_last_satb_filtering_times_ms[worker_i] = ms;
+ }
+
+ void record_update_rs_time(uint worker_i, double ms) {
+ assert(worker_i >= 0, "worker index must be > 0");
+ assert(worker_i < _active_gc_threads, "worker index out of bounds");
+ _par_last_update_rs_times_ms[worker_i] = ms;
+ }
+
+ void record_update_rs_processed_buffers (uint worker_i,
+ double processed_buffers) {
+ assert(worker_i >= 0, "worker index must be > 0");
+ assert(worker_i < _active_gc_threads, "worker index out of bounds");
+ _par_last_update_rs_processed_buffers[worker_i] = processed_buffers;
+ }
+
+ void record_scan_rs_time(uint worker_i, double ms) {
+ assert(worker_i >= 0, "worker index must be > 0");
+ assert(worker_i < _active_gc_threads, "worker index out of bounds");
+ _par_last_scan_rs_times_ms[worker_i] = ms;
+ }
+
+ void reset_obj_copy_time(uint worker_i) {
+ assert(worker_i >= 0, "worker index must be > 0");
+ assert(worker_i < _active_gc_threads, "worker index out of bounds");
+ _par_last_obj_copy_times_ms[worker_i] = 0.0;
+ }
+
+ void reset_obj_copy_time() {
+ reset_obj_copy_time(0);
+ }
+
+ void record_obj_copy_time(uint worker_i, double ms) {
+ assert(worker_i >= 0, "worker index must be > 0");
+ assert(worker_i < _active_gc_threads, "worker index out of bounds");
+ _par_last_obj_copy_times_ms[worker_i] += ms;
+ }
+
+ void record_termination(uint worker_i, double ms, size_t attempts) {
+ assert(worker_i >= 0, "worker index must be > 0");
+ assert(worker_i < _active_gc_threads, "worker index out of bounds");
+ _par_last_termination_times_ms[worker_i] = ms;
+ _par_last_termination_attempts[worker_i] = (double) attempts;
+ }
+
+ void record_gc_worker_end_time(uint worker_i, double ms) {
+ assert(worker_i >= 0, "worker index must be > 0");
+ assert(worker_i < _active_gc_threads, "worker index out of bounds");
+ _par_last_gc_worker_end_times_ms[worker_i] = ms;
+ }
+
+ void record_clear_ct_time(double ms) {
+ _cur_clear_ct_time_ms = ms;
+ }
+
+ void record_par_time(double ms) {
+ _cur_collection_par_time_ms = ms;
+ }
+
+ void record_code_root_fixup_time(double ms) {
+ _cur_collection_code_root_fixup_time_ms = ms;
+ }
+
+ void record_ref_proc_time(double ms) {
+ _cur_ref_proc_time_ms = ms;
+ }
+
+ void record_ref_enq_time(double ms) {
+ _cur_ref_enq_time_ms = ms;
+ }
+
+ void record_root_region_scan_wait_time(double time_ms) {
+ _root_region_scan_wait_time_ms = time_ms;
+ }
+
+ void record_cc_clear_time_ms(double ms);
+
+ void record_young_free_cset_time_ms(double time_ms) {
+ _recorded_young_free_cset_time_ms = time_ms;
+ }
+
+ void record_non_young_free_cset_time_ms(double time_ms) {
+ _recorded_non_young_free_cset_time_ms = time_ms;
+ }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -29,6 +29,7 @@
#include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
#include "gc_implementation/g1/g1CollectorPolicy.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
@@ -224,7 +225,7 @@
assert( _cards_scanned != NULL, "invariant" );
_cards_scanned[worker_i] = scanRScl.cards_done();
- _g1p->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
+ _g1p->phase_times()->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
}
// Closure used for updating RSets and recording references that
@@ -276,7 +277,7 @@
guarantee(cl.n() == 0, "Card table should be clean.");
}
- _g1p->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0);
+ _g1p->phase_times()->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0);
}
class CountRSSizeClosure: public HeapRegionClosure {
@@ -390,13 +391,13 @@
if (G1UseParallelRSetUpdating || (worker_i == 0)) {
updateRS(&into_cset_dcq, worker_i);
} else {
- _g1p->record_update_rs_processed_buffers(worker_i, 0.0);
- _g1p->record_update_rs_time(worker_i, 0.0);
+ _g1p->phase_times()->record_update_rs_processed_buffers(worker_i, 0.0);
+ _g1p->phase_times()->record_update_rs_time(worker_i, 0.0);
}
if (G1UseParallelRSetScanning || (worker_i == 0)) {
scanRS(oc, worker_i);
} else {
- _g1p->record_scan_rs_time(worker_i, 0.0);
+ _g1p->phase_times()->record_scan_rs_time(worker_i, 0.0);
}
// We now clear the cached values of _cset_rs_update_cl for this worker
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -375,7 +375,6 @@
Handle h_exception(thread, exception);
methodHandle h_method (thread, method(thread));
constantPoolHandle h_constants(thread, h_method->constants());
- typeArrayHandle h_extable (thread, h_method->exception_table());
bool should_repeat;
int handler_bci;
int current_bci = bci(thread);
@@ -547,23 +546,6 @@
}
}
- if (is_put && !is_static && klass->is_subclass_of(SystemDictionary::CallSite_klass()) && (info.name() == vmSymbols::target_name())) {
- const jint direction = frame::interpreter_frame_expression_stack_direction();
- Handle call_site (THREAD, *((oop*) thread->last_frame().interpreter_frame_tos_at(-1 * direction)));
- Handle method_handle(THREAD, *((oop*) thread->last_frame().interpreter_frame_tos_at( 0 * direction)));
- assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "must be");
- assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be");
-
- {
- // Walk all nmethods depending on this call site.
- MutexLocker mu(Compile_lock, thread);
- Universe::flush_dependents_on(call_site, method_handle);
- }
-
- // Don't allow fast path for setting CallSite.target and sub-classes.
- put_code = (Bytecodes::Code) 0;
- }
-
cache_entry(thread)->set_field(
get_code,
put_code,
--- a/hotspot/src/share/vm/memory/dump.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/memory/dump.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -231,8 +231,6 @@
if (obj->is_constMethod()) {
mark_object(obj);
mark_object(constMethodOop(obj)->stackmap_data());
- // Exception tables are needed by ci code during compilation.
- mark_object(constMethodOop(obj)->exception_table());
}
// Mark objects referenced by klass objects which are read-only.
@@ -513,7 +511,6 @@
for(i = 0; i < methods->length(); i++) {
methodOop m = methodOop(methods->obj_at(i));
mark_and_move_for_policy(OP_favor_startup, m->constMethod(), _move_ro);
- mark_and_move_for_policy(OP_favor_runtime, m->constMethod()->exception_table(), _move_ro);
mark_and_move_for_policy(OP_favor_runtime, m->constMethod()->stackmap_data(), _move_ro);
}
--- a/hotspot/src/share/vm/memory/oopFactory.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/memory/oopFactory.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -140,14 +140,15 @@
constMethodOop oopFactory::new_constMethod(int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS) {
klassOop cmkObj = Universe::constMethodKlassObj();
constMethodKlass* cmk = constMethodKlass::cast(cmkObj);
return cmk->allocate(byte_code_size, compressed_line_number_size,
- localvariable_table_length, checked_exceptions_length,
- is_conc_safe,
+ localvariable_table_length, exception_table_length,
+ checked_exceptions_length, is_conc_safe,
CHECK_NULL);
}
@@ -155,6 +156,7 @@
methodOop oopFactory::new_method(int byte_code_size, AccessFlags access_flags,
int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS) {
@@ -164,6 +166,7 @@
constMethodOop cm = new_constMethod(byte_code_size,
compressed_line_number_size,
localvariable_table_length,
+ exception_table_length,
checked_exceptions_length,
is_conc_safe, CHECK_NULL);
constMethodHandle rw(THREAD, cm);
--- a/hotspot/src/share/vm/memory/oopFactory.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/memory/oopFactory.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -86,6 +86,7 @@
static constMethodOop new_constMethod(int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS);
@@ -97,6 +98,7 @@
AccessFlags access_flags,
int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS);
--- a/hotspot/src/share/vm/oops/constMethodKlass.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/oops/constMethodKlass.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -65,6 +65,7 @@
constMethodOop constMethodKlass::allocate(int byte_code_size,
int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS) {
@@ -72,6 +73,7 @@
int size = constMethodOopDesc::object_size(byte_code_size,
compressed_line_number_size,
localvariable_table_length,
+ exception_table_length,
checked_exceptions_length);
KlassHandle h_k(THREAD, as_klassOop());
constMethodOop cm = (constMethodOop)
@@ -82,12 +84,12 @@
cm->init_fingerprint();
cm->set_constants(NULL);
cm->set_stackmap_data(NULL);
- cm->set_exception_table(NULL);
cm->set_code_size(byte_code_size);
cm->set_constMethod_size(size);
cm->set_inlined_tables_length(checked_exceptions_length,
compressed_line_number_size,
- localvariable_table_length);
+ localvariable_table_length,
+ exception_table_length);
assert(cm->size() == size, "wrong size for object");
cm->set_is_conc_safe(is_conc_safe);
cm->set_partially_loaded();
@@ -100,7 +102,6 @@
constMethodOop cm = constMethodOop(obj);
MarkSweep::mark_and_push(cm->adr_constants());
MarkSweep::mark_and_push(cm->adr_stackmap_data());
- MarkSweep::mark_and_push(cm->adr_exception_table());
// Performance tweak: We skip iterating over the klass pointer since we
// know that Universe::constMethodKlassObj never moves.
}
@@ -112,7 +113,6 @@
constMethodOop cm_oop = constMethodOop(obj);
PSParallelCompact::mark_and_push(cm, cm_oop->adr_constants());
PSParallelCompact::mark_and_push(cm, cm_oop->adr_stackmap_data());
- PSParallelCompact::mark_and_push(cm, cm_oop->adr_exception_table());
// Performance tweak: We skip iterating over the klass pointer since we
// know that Universe::constMethodKlassObj never moves.
}
@@ -123,7 +123,6 @@
constMethodOop cm = constMethodOop(obj);
blk->do_oop(cm->adr_constants());
blk->do_oop(cm->adr_stackmap_data());
- blk->do_oop(cm->adr_exception_table());
// Get size before changing pointers.
// Don't call size() or oop_size() since that is a virtual call.
int size = cm->object_size();
@@ -139,8 +138,6 @@
if (mr.contains(adr)) blk->do_oop(adr);
adr = cm->adr_stackmap_data();
if (mr.contains(adr)) blk->do_oop(adr);
- adr = cm->adr_exception_table();
- if (mr.contains(adr)) blk->do_oop(adr);
// Get size before changing pointers.
// Don't call size() or oop_size() since that is a virtual call.
int size = cm->object_size();
@@ -155,7 +152,6 @@
constMethodOop cm = constMethodOop(obj);
MarkSweep::adjust_pointer(cm->adr_constants());
MarkSweep::adjust_pointer(cm->adr_stackmap_data());
- MarkSweep::adjust_pointer(cm->adr_exception_table());
// Get size before changing pointers.
// Don't call size() or oop_size() since that is a virtual call.
int size = cm->object_size();
@@ -190,7 +186,6 @@
constMethodOop m = constMethodOop(obj);
st->print(" - constants: " INTPTR_FORMAT " ", (address)m->constants());
m->constants()->print_value_on(st); st->cr();
- st->print(" - exceptions: " INTPTR_FORMAT "\n", (address)m->exception_table());
if (m->has_stackmap_table()) {
st->print(" - stackmap data: ");
m->stackmap_data()->print_value_on(st);
@@ -228,8 +223,6 @@
typeArrayOop stackmap_data = m->stackmap_data();
guarantee(stackmap_data == NULL ||
stackmap_data->is_perm(), "should be in permspace");
- guarantee(m->exception_table()->is_perm(), "should be in permspace");
- guarantee(m->exception_table()->is_typeArray(), "should be type array");
address m_end = (address)((oop*) m + m->size());
address compressed_table_start = m->code_end();
@@ -244,11 +237,15 @@
compressed_table_end += stream.position();
}
guarantee(compressed_table_end <= m_end, "invalid method layout");
- // Verify checked exceptions and local variable tables
+ // Verify checked exceptions, exception table and local variable tables
if (m->has_checked_exceptions()) {
u2* addr = m->checked_exceptions_length_addr();
guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
}
+ if (m->has_exception_handler()) {
+ u2* addr = m->exception_table_length_addr();
+ guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
+ }
if (m->has_localvariable_table()) {
u2* addr = m->localvariable_table_length_addr();
guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
@@ -257,12 +254,12 @@
u2* uncompressed_table_start;
if (m->has_localvariable_table()) {
uncompressed_table_start = (u2*) m->localvariable_table_start();
- } else {
- if (m->has_checked_exceptions()) {
+ } else if (m->has_exception_handler()) {
+ uncompressed_table_start = (u2*) m->exception_table_start();
+ } else if (m->has_checked_exceptions()) {
uncompressed_table_start = (u2*) m->checked_exceptions_start();
- } else {
+ } else {
uncompressed_table_start = (u2*) m_end;
- }
}
int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end;
int max_gap = align_object_size(1)*BytesPerWord;
@@ -273,8 +270,8 @@
bool constMethodKlass::oop_partially_loaded(oop obj) const {
assert(obj->is_constMethod(), "object must be klass");
constMethodOop m = constMethodOop(obj);
- // check whether exception_table points to self (flag for partially loaded)
- return m->exception_table() == (typeArrayOop)obj;
+ // check whether stackmap_data points to self (flag for partially loaded)
+ return m->stackmap_data() == (typeArrayOop)obj;
}
@@ -282,6 +279,6 @@
void constMethodKlass::oop_set_partially_loaded(oop obj) {
assert(obj->is_constMethod(), "object must be klass");
constMethodOop m = constMethodOop(obj);
- // Temporarily set exception_table to point to self
- m->set_exception_table((typeArrayOop)obj);
+ // Temporarily set stackmap_data to point to self
+ m->set_stackmap_data((typeArrayOop)obj);
}
--- a/hotspot/src/share/vm/oops/constMethodKlass.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/oops/constMethodKlass.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, 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
@@ -46,6 +46,7 @@
DEFINE_ALLOCATE_PERMANENT(constMethodKlass);
constMethodOop allocate(int byte_code_size, int compressed_line_number_size,
int localvariable_table_length,
+ int exception_table_length,
int checked_exceptions_length,
bool is_conc_safe,
TRAPS);
--- a/hotspot/src/share/vm/oops/constMethodOop.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/oops/constMethodOop.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -35,6 +35,7 @@
int constMethodOopDesc::object_size(int code_size,
int compressed_line_number_size,
int local_variable_table_length,
+ int exception_table_length,
int checked_exceptions_length) {
int extra_bytes = code_size;
if (compressed_line_number_size > 0) {
@@ -49,6 +50,10 @@
extra_bytes +=
local_variable_table_length * sizeof(LocalVariableTableElement);
}
+ if (exception_table_length > 0) {
+ extra_bytes += sizeof(u2);
+ extra_bytes += exception_table_length * sizeof(ExceptionTableElement);
+ }
int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
return align_object_size(header_size() + extra_words);
}
@@ -73,23 +78,40 @@
return last_u2_element();
}
-u2* constMethodOopDesc::localvariable_table_length_addr() const {
- assert(has_localvariable_table(), "called only if table is present");
+u2* constMethodOopDesc::exception_table_length_addr() const {
+ assert(has_exception_handler(), "called only if table is present");
if (has_checked_exceptions()) {
// If checked_exception present, locate immediately before them.
return (u2*) checked_exceptions_start() - 1;
} else {
- // Else, the linenumber table is at the end of the constMethod.
+ // Else, the exception table is at the end of the constMethod.
return last_u2_element();
}
}
+u2* constMethodOopDesc::localvariable_table_length_addr() const {
+ assert(has_localvariable_table(), "called only if table is present");
+ if (has_exception_handler()) {
+ // If exception_table present, locate immediately before them.
+ return (u2*) exception_table_start() - 1;
+ } else {
+ if (has_checked_exceptions()) {
+ // If checked_exception present, locate immediately before them.
+ return (u2*) checked_exceptions_start() - 1;
+ } else {
+ // Else, the linenumber table is at the end of the constMethod.
+ return last_u2_element();
+ }
+ }
+}
+
// Update the flags to indicate the presence of these optional fields.
void constMethodOopDesc::set_inlined_tables_length(
int checked_exceptions_len,
int compressed_line_number_size,
- int localvariable_table_len) {
+ int localvariable_table_len,
+ int exception_table_len) {
// Must be done in the order below, otherwise length_addr accessors
// will not work. Only set bit in header if length is positive.
assert(_flags == 0, "Error");
@@ -100,6 +122,10 @@
_flags |= _has_checked_exceptions;
*(checked_exceptions_length_addr()) = checked_exceptions_len;
}
+ if (exception_table_len > 0) {
+ _flags |= _has_exception_table;
+ *(exception_table_length_addr()) = exception_table_len;
+ }
if (localvariable_table_len > 0) {
_flags |= _has_localvariable_table;
*(localvariable_table_length_addr()) = localvariable_table_len;
@@ -133,3 +159,15 @@
addr -= length * sizeof(LocalVariableTableElement) / sizeof(u2);
return (LocalVariableTableElement*) addr;
}
+
+int constMethodOopDesc::exception_table_length() const {
+ return has_exception_handler() ? *(exception_table_length_addr()) : 0;
+}
+
+ExceptionTableElement* constMethodOopDesc::exception_table_start() const {
+ u2* addr = exception_table_length_addr();
+ u2 length = *addr;
+ assert(length > 0, "should only be called if table is present");
+ addr -= length * sizeof(ExceptionTableElement) / sizeof(u2);
+ return (ExceptionTableElement*)addr;
+}
--- a/hotspot/src/share/vm/oops/constMethodOop.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/oops/constMethodOop.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -43,7 +43,6 @@
// | fingerprint 2 |
// | constants (oop) |
// | stackmap_data (oop) |
-// | exception_table (oop) |
// | constMethod_size |
// | interp_kind | flags | code_size |
// | name index | signature index |
@@ -64,7 +63,13 @@
// | (length is u2, elements are 6-tuples of u2) |
// | (see class LocalVariableTableElement) |
// | (access flags bit tells whether table is present) |
-// | (indexed from end of contMethodOop) |
+// | (indexed from end of constMethodOop) |
+// |------------------------------------------------------|
+// | exception table + length (length last) |
+// | (length is u2, elements are 4-tuples of u2) |
+// | (see class ExceptionTableElement) |
+// | (access flags bit tells whether table is present) |
+// | (indexed from end of constMethodOop) |
// |------------------------------------------------------|
// | checked exceptions elements + length (length last) |
// | (length is u2, elements are u2) |
@@ -93,6 +98,15 @@
};
+// Utitily class describing elements in exception table
+class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
+ public:
+ u2 start_pc;
+ u2 end_pc;
+ u2 handler_pc;
+ u2 catch_type_index;
+};
+
class constMethodOopDesc : public oopDesc {
friend class constMethodKlass;
friend class VMStructs;
@@ -100,7 +114,8 @@
enum {
_has_linenumber_table = 1,
_has_checked_exceptions = 2,
- _has_localvariable_table = 4
+ _has_localvariable_table = 4,
+ _has_exception_table = 8
};
// Bit vector of signature
@@ -114,7 +129,7 @@
public:
oop* oop_block_beg() const { return adr_constants(); }
- oop* oop_block_end() const { return adr_exception_table() + 1; }
+ oop* oop_block_end() const { return adr_stackmap_data() + 1; }
private:
//
@@ -126,11 +141,6 @@
// Raw stackmap data for the method
typeArrayOop _stackmap_data;
- // The exception handler table. 4-tuples of ints [start_pc, end_pc,
- // handler_pc, catch_type index] For methods with no exceptions the
- // table is pointing to Universe::the_empty_int_array
- typeArrayOop _exception_table;
-
//
// End of the oop block.
//
@@ -152,7 +162,8 @@
// Inlined tables
void set_inlined_tables_length(int checked_exceptions_len,
int compressed_line_number_size,
- int localvariable_table_len);
+ int localvariable_table_len,
+ int exception_table_len);
bool has_linenumber_table() const
{ return (_flags & _has_linenumber_table) != 0; }
@@ -163,6 +174,9 @@
bool has_localvariable_table() const
{ return (_flags & _has_localvariable_table) != 0; }
+ bool has_exception_handler() const
+ { return (_flags & _has_exception_table) != 0; }
+
void set_interpreter_kind(int kind) { _interpreter_kind = kind; }
int interpreter_kind(void) const { return _interpreter_kind; }
@@ -181,11 +195,6 @@
}
bool has_stackmap_table() const { return _stackmap_data != NULL; }
- // exception handler table
- typeArrayOop exception_table() const { return _exception_table; }
- void set_exception_table(typeArrayOop e) { oop_store_without_check((oop*) &_exception_table, (oop) e); }
- bool has_exception_handler() const { return exception_table() != NULL && exception_table()->length() > 0; }
-
void init_fingerprint() {
const uint64_t initval = CONST64(0x8000000000000000);
_fingerprint = initval;
@@ -235,6 +244,7 @@
// Object size needed
static int object_size(int code_size, int compressed_line_number_size,
int local_variable_table_length,
+ int exception_table_length,
int checked_exceptions_length);
int object_size() const { return _constMethod_size; }
@@ -256,6 +266,7 @@
u_char* compressed_linenumber_table() const; // not preserved by gc
u2* checked_exceptions_length_addr() const;
u2* localvariable_table_length_addr() const;
+ u2* exception_table_length_addr() const;
// checked exceptions
int checked_exceptions_length() const;
@@ -265,6 +276,10 @@
int localvariable_table_length() const;
LocalVariableTableElement* localvariable_table_start() const;
+ // exception table
+ int exception_table_length() const;
+ ExceptionTableElement* exception_table_start() const;
+
// byte codes
void set_code(address code) {
if (code_size() > 0) {
@@ -282,13 +297,10 @@
// interpreter support
static ByteSize constants_offset()
{ return byte_offset_of(constMethodOopDesc, _constants); }
- static ByteSize exception_table_offset()
- { return byte_offset_of(constMethodOopDesc, _exception_table); }
// Garbage collection support
oop* adr_constants() const { return (oop*)&_constants; }
oop* adr_stackmap_data() const { return (oop*)&_stackmap_data; }
- oop* adr_exception_table() const { return (oop*)&_exception_table; }
bool is_conc_safe() { return _is_conc_safe; }
void set_is_conc_safe(bool v) { _is_conc_safe = v; }
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/oops/generateOopMap.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -400,10 +400,9 @@
bool fellThrough = false; // False to get first BB marked.
// First mark all exception handlers as start of a basic-block
- typeArrayOop excps = method()->exception_table();
- for(int i = 0; i < excps->length(); i += 4) {
- int handler_pc_idx = i+2;
- bb_mark_fct(this, excps->int_at(handler_pc_idx), NULL);
+ ExceptionTable excps(method());
+ for(int i = 0; i < excps.length(); i ++) {
+ bb_mark_fct(this, excps.handler_pc(i), NULL);
}
// Then iterate through the code
@@ -450,10 +449,9 @@
// Mark entry basic block as alive and all exception handlers
_basic_blocks[0].mark_as_alive();
- typeArrayOop excps = method()->exception_table();
- for(int i = 0; i < excps->length(); i += 4) {
- int handler_pc_idx = i+2;
- BasicBlock *bb = get_basic_block_at(excps->int_at(handler_pc_idx));
+ ExceptionTable excps(method());
+ for(int i = 0; i < excps.length(); i++) {
+ BasicBlock *bb = get_basic_block_at(excps.handler_pc(i));
// If block is not already alive (due to multiple exception handlers to same bb), then
// make it alive
if (bb->is_dead()) bb->mark_as_alive();
@@ -1181,12 +1179,12 @@
if (_has_exceptions) {
int bci = itr->bci();
- typeArrayOop exct = method()->exception_table();
- for(int i = 0; i< exct->length(); i+=4) {
- int start_pc = exct->int_at(i);
- int end_pc = exct->int_at(i+1);
- int handler_pc = exct->int_at(i+2);
- int catch_type = exct->int_at(i+3);
+ ExceptionTable exct(method());
+ for(int i = 0; i< exct.length(); i++) {
+ int start_pc = exct.start_pc(i);
+ int end_pc = exct.end_pc(i);
+ int handler_pc = exct.handler_pc(i);
+ int catch_type = exct.catch_type_index(i);
if (start_pc <= bci && bci < end_pc) {
BasicBlock *excBB = get_basic_block_at(handler_pc);
@@ -2055,7 +2053,7 @@
_conflict = false;
_max_locals = method()->max_locals();
_max_stack = method()->max_stack();
- _has_exceptions = (method()->exception_table()->length() > 0);
+ _has_exceptions = (method()->has_exception_handler());
_nof_refval_conflicts = 0;
_init_vars = new GrowableArray<intptr_t>(5); // There are seldom more than 5 init_vars
_report_result = false;
@@ -2070,9 +2068,10 @@
if (Verbose) {
_method->print_codes();
tty->print_cr("Exception table:");
- typeArrayOop excps = method()->exception_table();
- for(int i = 0; i < excps->length(); i += 4) {
- tty->print_cr("[%d - %d] -> %d", excps->int_at(i + 0), excps->int_at(i + 1), excps->int_at(i + 2));
+ ExceptionTable excps(method());
+ for(int i = 0; i < excps.length(); i ++) {
+ tty->print_cr("[%d - %d] -> %d",
+ excps.start_pc(i), excps.end_pc(i), excps.handler_pc(i));
}
}
}
--- a/hotspot/src/share/vm/oops/methodOop.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/oops/methodOop.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -111,25 +111,21 @@
int methodOopDesc::fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS) {
// exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index)
- const int beg_bci_offset = 0;
- const int end_bci_offset = 1;
- const int handler_bci_offset = 2;
- const int klass_index_offset = 3;
- const int entry_size = 4;
// access exception table
- typeArrayHandle table (THREAD, constMethod()->exception_table());
- int length = table->length();
- assert(length % entry_size == 0, "exception table format has changed");
+ ExceptionTable table(this);
+ int length = table.length();
// iterate through all entries sequentially
constantPoolHandle pool(THREAD, constants());
- for (int i = 0; i < length; i += entry_size) {
- int beg_bci = table->int_at(i + beg_bci_offset);
- int end_bci = table->int_at(i + end_bci_offset);
+ for (int i = 0; i < length; i ++) {
+ //reacquire the table in case a GC happened
+ ExceptionTable table(this);
+ int beg_bci = table.start_pc(i);
+ int end_bci = table.end_pc(i);
assert(beg_bci <= end_bci, "inconsistent exception table");
if (beg_bci <= throw_bci && throw_bci < end_bci) {
// exception handler bci range covers throw_bci => investigate further
- int handler_bci = table->int_at(i + handler_bci_offset);
- int klass_index = table->int_at(i + klass_index_offset);
+ int handler_bci = table.handler_pc(i);
+ int klass_index = table.catch_type_index(i);
if (klass_index == 0) {
return handler_bci;
} else if (ex_klass.is_null()) {
@@ -980,7 +976,7 @@
{
int flags_bits = (JVM_MH_INVOKE_BITS | JVM_ACC_PUBLIC | JVM_ACC_FINAL);
methodOop m_oop = oopFactory::new_method(0, accessFlags_from(flags_bits),
- 0, 0, 0, IsSafeConc, CHECK_(empty));
+ 0, 0, 0, 0, IsSafeConc, CHECK_(empty));
m = methodHandle(THREAD, m_oop);
}
m->set_constants(cp());
@@ -994,7 +990,6 @@
m->set_result_index(rtf.type());
#endif
m->compute_size_of_parameters(THREAD);
- m->set_exception_table(Universe::the_empty_int_array());
m->init_intrinsic_id();
assert(m->intrinsic_id() == vmIntrinsics::_invokeExact ||
m->intrinsic_id() == vmIntrinsics::_invokeGeneric, "must be an invoker");
@@ -1038,6 +1033,7 @@
AccessFlags flags = m->access_flags();
int checked_exceptions_len = m->checked_exceptions_length();
int localvariable_len = m->localvariable_table_length();
+ int exception_table_len = m->exception_table_length();
// Allocate newm_oop with the is_conc_safe parameter set
// to IsUnsafeConc to indicate that newm_oop is not yet
// safe for concurrent processing by a GC.
@@ -1045,6 +1041,7 @@
flags,
new_compressed_linenumber_size,
localvariable_len,
+ exception_table_len,
checked_exceptions_len,
IsUnsafeConc,
CHECK_(methodHandle()));
@@ -1085,6 +1082,7 @@
newm->set_method_size(new_method_size);
assert(newm->code_size() == new_code_length, "check");
assert(newm->checked_exceptions_length() == checked_exceptions_len, "check");
+ assert(newm->exception_table_length() == exception_table_len, "check");
assert(newm->localvariable_table_length() == localvariable_len, "check");
// Copy new byte codes
memcpy(newm->code_base(), new_code, new_code_length);
@@ -1100,6 +1098,12 @@
m->checked_exceptions_start(),
checked_exceptions_len * sizeof(CheckedExceptionElement));
}
+ // Copy exception table
+ if (exception_table_len > 0) {
+ memcpy(newm->exception_table_start(),
+ m->exception_table_start(),
+ exception_table_len * sizeof(ExceptionTableElement));
+ }
// Copy local variable number table
if (localvariable_len > 0) {
memcpy(newm->localvariable_table_start(),
--- a/hotspot/src/share/vm/oops/methodOop.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/oops/methodOop.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -122,8 +122,9 @@
u2 _max_locals; // Number of local variables used by this method
u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words
u1 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none)
- u1 _jfr_towrite : 1, // Flags
- : 7;
+ u1 _jfr_towrite : 1, // Flags
+ _force_inline : 1,
+ : 6;
u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
u2 _number_of_breakpoints; // fullspeed debugging support
InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations
@@ -282,12 +283,12 @@
}
// exception handler table
- typeArrayOop exception_table() const
- { return constMethod()->exception_table(); }
- void set_exception_table(typeArrayOop e)
- { constMethod()->set_exception_table(e); }
bool has_exception_handler() const
{ return constMethod()->has_exception_handler(); }
+ int exception_table_length() const
+ { return constMethod()->exception_table_length(); }
+ ExceptionTableElement* exception_table_start() const
+ { return constMethod()->exception_table_start(); }
// Finds the first entry point bci of an exception handler for an
// exception of klass ex_klass thrown at throw_bci. A value of NULL
@@ -655,6 +656,9 @@
bool jfr_towrite() { return _jfr_towrite; }
void set_jfr_towrite(bool towrite) { _jfr_towrite = towrite; }
+ bool force_inline() { return _force_inline; }
+ void set_force_inline(bool fi) { _force_inline = fi; }
+
// On-stack replacement support
bool has_osr_nmethod(int level, bool match_level) {
return instanceKlass::cast(method_holder())->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL;
@@ -835,4 +839,66 @@
void clear(methodOop method);
};
+// Utility class for access exception handlers
+class ExceptionTable : public StackObj {
+ private:
+ ExceptionTableElement* _table;
+ u2 _length;
+
+ public:
+ ExceptionTable(methodOop m) {
+ if (m->has_exception_handler()) {
+ _table = m->exception_table_start();
+ _length = m->exception_table_length();
+ } else {
+ _table = NULL;
+ _length = 0;
+ }
+ }
+
+ int length() const {
+ return _length;
+ }
+
+ u2 start_pc(int idx) const {
+ assert(idx < _length, "out of bounds");
+ return _table[idx].start_pc;
+ }
+
+ void set_start_pc(int idx, u2 value) {
+ assert(idx < _length, "out of bounds");
+ _table[idx].start_pc = value;
+ }
+
+ u2 end_pc(int idx) const {
+ assert(idx < _length, "out of bounds");
+ return _table[idx].end_pc;
+ }
+
+ void set_end_pc(int idx, u2 value) {
+ assert(idx < _length, "out of bounds");
+ _table[idx].end_pc = value;
+ }
+
+ u2 handler_pc(int idx) const {
+ assert(idx < _length, "out of bounds");
+ return _table[idx].handler_pc;
+ }
+
+ void set_handler_pc(int idx, u2 value) {
+ assert(idx < _length, "out of bounds");
+ _table[idx].handler_pc = value;
+ }
+
+ u2 catch_type_index(int idx) const {
+ assert(idx < _length, "out of bounds");
+ return _table[idx].catch_type_index;
+ }
+
+ void set_catch_type_index(int idx, u2 value) {
+ assert(idx < _length, "out of bounds");
+ _table[idx].catch_type_index = value;
+ }
+};
+
#endif // SHARE_VM_OOPS_METHODOOP_HPP
--- a/hotspot/src/share/vm/opto/phaseX.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/opto/phaseX.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -757,6 +757,7 @@
//------------------------------PhaseIterGVN-----------------------------------
// Initialize hash table to fresh and clean for +VerifyOpto
PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn, const char *dummy ) : PhaseGVN(igvn,dummy), _worklist( ),
+ _stack(C->unique() >> 1),
_delay_transform(false) {
}
@@ -764,6 +765,7 @@
// Initialize with previous PhaseIterGVN info; used by PhaseCCP
PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn ) : PhaseGVN(igvn),
_worklist( igvn->_worklist ),
+ _stack( igvn->_stack ),
_delay_transform(igvn->_delay_transform)
{
}
@@ -772,6 +774,7 @@
// Initialize with previous PhaseGVN info from Parser
PhaseIterGVN::PhaseIterGVN( PhaseGVN *gvn ) : PhaseGVN(gvn),
_worklist(*C->for_igvn()),
+ _stack(C->unique() >> 1),
_delay_transform(false)
{
uint max;
@@ -1138,51 +1141,77 @@
// Kill a globally dead Node. All uses are also globally dead and are
// aggressively trimmed.
void PhaseIterGVN::remove_globally_dead_node( Node *dead ) {
- assert(dead != C->root(), "killing root, eh?");
- if (dead->is_top()) return;
- NOT_PRODUCT( set_progress(); )
- // Remove from iterative worklist
- _worklist.remove(dead);
- if (!dead->is_Con()) { // Don't kill cons but uses
- // Remove from hash table
- _table.hash_delete( dead );
- // Smash all inputs to 'dead', isolating him completely
- for( uint i = 0; i < dead->req(); i++ ) {
- Node *in = dead->in(i);
- if( in ) { // Points to something?
- dead->set_req(i,NULL); // Kill the edge
- if (in->outcnt() == 0 && in != C->top()) {// Made input go dead?
- remove_dead_node(in); // Recursively remove
- } else if (in->outcnt() == 1 &&
- in->has_special_unique_user()) {
- _worklist.push(in->unique_out());
- } else if (in->outcnt() <= 2 && dead->is_Phi()) {
- if( in->Opcode() == Op_Region )
- _worklist.push(in);
- else if( in->is_Store() ) {
- DUIterator_Fast imax, i = in->fast_outs(imax);
- _worklist.push(in->fast_out(i));
- i++;
- if(in->outcnt() == 2) {
- _worklist.push(in->fast_out(i));
- i++;
+ enum DeleteProgress {
+ PROCESS_INPUTS,
+ PROCESS_OUTPUTS
+ };
+ assert(_stack.is_empty(), "not empty");
+ _stack.push(dead, PROCESS_INPUTS);
+
+ while (_stack.is_nonempty()) {
+ dead = _stack.node();
+ uint progress_state = _stack.index();
+ assert(dead != C->root(), "killing root, eh?");
+ assert(!dead->is_top(), "add check for top when pushing");
+ NOT_PRODUCT( set_progress(); )
+ if (progress_state == PROCESS_INPUTS) {
+ // After following inputs, continue to outputs
+ _stack.set_index(PROCESS_OUTPUTS);
+ // Remove from iterative worklist
+ _worklist.remove(dead);
+ if (!dead->is_Con()) { // Don't kill cons but uses
+ bool recurse = false;
+ // Remove from hash table
+ _table.hash_delete( dead );
+ // Smash all inputs to 'dead', isolating him completely
+ for( uint i = 0; i < dead->req(); i++ ) {
+ Node *in = dead->in(i);
+ if( in ) { // Points to something?
+ dead->set_req(i,NULL); // Kill the edge
+ if (in->outcnt() == 0 && in != C->top()) {// Made input go dead?
+ _stack.push(in, PROCESS_INPUTS); // Recursively remove
+ recurse = true;
+ } else if (in->outcnt() == 1 &&
+ in->has_special_unique_user()) {
+ _worklist.push(in->unique_out());
+ } else if (in->outcnt() <= 2 && dead->is_Phi()) {
+ if( in->Opcode() == Op_Region )
+ _worklist.push(in);
+ else if( in->is_Store() ) {
+ DUIterator_Fast imax, i = in->fast_outs(imax);
+ _worklist.push(in->fast_out(i));
+ i++;
+ if(in->outcnt() == 2) {
+ _worklist.push(in->fast_out(i));
+ i++;
+ }
+ assert(!(i < imax), "sanity");
+ }
}
- assert(!(i < imax), "sanity");
}
}
+
+ if (dead->is_macro()) {
+ C->remove_macro_node(dead);
+ }
+
+ if (recurse) {
+ continue;
+ }
}
}
- if (dead->is_macro()) {
- C->remove_macro_node(dead);
+ // Aggressively kill globally dead uses
+ // (Rather than pushing all the outs at once, we push one at a time,
+ // plus the parent to resume later, because of the indefinite number
+ // of edge deletions per loop trip.)
+ if (dead->outcnt() > 0) {
+ // Recursively remove
+ _stack.push(dead->raw_out(0), PROCESS_INPUTS);
+ } else {
+ _stack.pop();
}
}
- // Aggressively kill globally dead uses
- // (Cannot use DUIterator_Last because of the indefinite number
- // of edge deletions per loop trip.)
- while (dead->outcnt() > 0) {
- remove_globally_dead_node(dead->raw_out(0));
- }
}
//------------------------------subsume_node-----------------------------------
--- a/hotspot/src/share/vm/opto/phaseX.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/opto/phaseX.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -403,6 +403,8 @@
// Subsume users of node 'old' into node 'nn'
void subsume_node( Node *old, Node *nn );
+ Node_Stack _stack; // Stack used to avoid recursion
+
protected:
// Idealize new Node 'n' with respect to its inputs and its value
@@ -438,8 +440,8 @@
// It is significant only for debugging and profiling.
Node* register_new_node_with_optimizer(Node* n, Node* orig = NULL);
- // Kill a globally dead Node. It is allowed to have uses which are
- // assumed dead and left 'in limbo'.
+ // Kill a globally dead Node. All uses are also globally dead and are
+ // aggressively trimmed.
void remove_globally_dead_node( Node *dead );
// Kill all inputs to a dead node, recursively making more dead nodes.
--- a/hotspot/src/share/vm/opto/stringopts.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/opto/stringopts.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -533,7 +533,17 @@
if (arg->is_Proj() && arg->in(0)->is_CallStaticJava()) {
CallStaticJavaNode* csj = arg->in(0)->as_CallStaticJava();
if (csj->method() != NULL &&
- csj->method()->intrinsic_id() == vmIntrinsics::_Integer_toString) {
+ csj->method()->intrinsic_id() == vmIntrinsics::_Integer_toString &&
+ arg->outcnt() == 1) {
+ // _control is the list of StringBuilder calls nodes which
+ // will be replaced by new String code after this optimization.
+ // Integer::toString() call is not part of StringBuilder calls
+ // chain. It could be eliminated only if its result is used
+ // only by this SB calls chain.
+ // Another limitation: it should be used only once because
+ // it is unknown that it is used only by this SB calls chain
+ // until all related SB calls nodes are collected.
+ assert(arg->unique_out() == cnode, "sanity");
sc->add_control(csj);
sc->push_int(csj->in(TypeFunc::Parms));
continue;
--- a/hotspot/src/share/vm/prims/jvm.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -35,6 +35,7 @@
#include "oops/fieldStreams.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/objArrayKlass.hpp"
+#include "oops/methodOop.hpp"
#include "prims/jvm.h"
#include "prims/jvm_misc.hpp"
#include "prims/jvmtiExport.hpp"
@@ -2183,11 +2184,11 @@
klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
oop method = instanceKlass::cast(k)->methods()->obj_at(method_index);
- typeArrayOop extable = methodOop(method)->exception_table();
- entry->start_pc = extable->int_at(entry_index * 4);
- entry->end_pc = extable->int_at(entry_index * 4 + 1);
- entry->handler_pc = extable->int_at(entry_index * 4 + 2);
- entry->catchType = extable->int_at(entry_index * 4 + 3);
+ ExceptionTable extable((methodOop(method)));
+ entry->start_pc = extable.start_pc(entry_index);
+ entry->end_pc = extable.end_pc(entry_index);
+ entry->handler_pc = extable.handler_pc(entry_index);
+ entry->catchType = extable.catch_type_index(entry_index);
JVM_END
@@ -2196,7 +2197,7 @@
klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
oop method = instanceKlass::cast(k)->methods()->obj_at(method_index);
- return methodOop(method)->exception_table()->length() / 4;
+ return methodOop(method)->exception_table_length();
JVM_END
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -191,15 +191,14 @@
}
}
- typeArrayHandle exception_table(thread(), const_method->exception_table());
- int exception_table_length = exception_table->length();
- int exception_table_entries = exception_table_length / 4;
+ ExceptionTable exception_table(method());
+ int exception_table_length = exception_table.length();
int code_size = const_method->code_size();
int size =
2+2+4 + // max_stack, max_locals, code_length
code_size + // code
2 + // exception_table_length
- (2+2+2+2) * exception_table_entries + // exception_table
+ (2+2+2+2) * exception_table_length + // exception_table
2 + // attributes_count
attr_size; // attributes
@@ -209,12 +208,12 @@
write_u2(method->max_locals());
write_u4(code_size);
copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
- write_u2(exception_table_entries);
- for (int index = 0; index < exception_table_length; ) {
- write_u2(exception_table->int_at(index++));
- write_u2(exception_table->int_at(index++));
- write_u2(exception_table->int_at(index++));
- write_u2(exception_table->int_at(index++));
+ write_u2(exception_table_length);
+ for (int index = 0; index < exception_table_length; index++) {
+ write_u2(exception_table.start_pc(index));
+ write_u2(exception_table.end_pc(index));
+ write_u2(exception_table.handler_pc(index));
+ write_u2(exception_table.catch_type_index(index));
}
write_u2(attr_count);
if (line_num_cnt != 0) {
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -2478,23 +2478,17 @@
// to use new constant pool indices as needed. The exception table
// holds quadruple entries of the form:
// (beg_bci, end_bci, handler_bci, klass_index)
- const int beg_bci_offset = 0;
- const int end_bci_offset = 1;
- const int handler_bci_offset = 2;
- const int klass_index_offset = 3;
- const int entry_size = 4;
-
- typeArrayHandle ex_table (THREAD, method->exception_table());
- int ext_length = ex_table->length();
- assert(ext_length % entry_size == 0, "exception table format has changed");
-
- for (int j = 0; j < ext_length; j += entry_size) {
- int cur_index = ex_table->int_at(j + klass_index_offset);
+
+ ExceptionTable ex_table(method());
+ int ext_length = ex_table.length();
+
+ for (int j = 0; j < ext_length; j ++) {
+ int cur_index = ex_table.catch_type_index(j);
int new_index = find_new_index(cur_index);
if (new_index != 0) {
RC_TRACE_WITH_THREAD(0x00080000, THREAD,
("ext-klass_index change: %d to %d", cur_index, new_index));
- ex_table->int_at_put(j + klass_index_offset, new_index);
+ ex_table.set_catch_type_index(j, new_index);
}
} // end for each exception table entry
--- a/hotspot/src/share/vm/prims/methodHandleWalk.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/prims/methodHandleWalk.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -1796,7 +1796,7 @@
{
methodOop m_oop = oopFactory::new_method(bytecode_length(),
accessFlags_from(flags_bits),
- 0, 0, 0, oopDesc::IsSafeConc, CHECK_(empty));
+ 0, 0, 0, 0, oopDesc::IsSafeConc, CHECK_(empty));
m = methodHandle(THREAD, m_oop);
}
@@ -1812,9 +1812,6 @@
m->set_max_locals(max_locals());
m->set_size_of_parameters(_num_params);
- typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
- m->set_exception_table(exception_handlers());
-
// Rewrite the method and set up the constant pool cache.
objArrayOop m_array = oopFactory::new_system_objArray(1, CHECK_(empty));
objArrayHandle methods(THREAD, m_array);
--- a/hotspot/src/share/vm/prims/methodHandles.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -3180,17 +3180,15 @@
jclass MH_class = env->FindClass(MH_name);
status = env->RegisterNatives(MH_class, invoke_methods, sizeof(invoke_methods)/sizeof(JNINativeMethod));
}
+ if (!env->ExceptionOccurred()) {
+ status = env->RegisterNatives(MHN_class, call_site_methods, sizeof(call_site_methods)/sizeof(JNINativeMethod));
+ }
if (env->ExceptionOccurred()) {
warning("JSR 292 method handle code is mismatched to this JVM. Disabling support.");
enable_MH = false;
env->ExceptionClear();
}
- status = env->RegisterNatives(MHN_class, call_site_methods, sizeof(call_site_methods)/sizeof(JNINativeMethod));
- if (env->ExceptionOccurred()) {
- // Exception is okay until 7087357
- env->ExceptionClear();
- }
}
if (enable_MH) {
--- a/hotspot/src/share/vm/prims/unsafe.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/prims/unsafe.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -178,17 +178,6 @@
v = *(oop*)index_oop_from_field_offset_long(p, offset); \
}
-#define GET_OOP_FIELD_VOLATILE(obj, offset, v) \
- oop p = JNIHandles::resolve(obj); \
- volatile oop v; \
- if (UseCompressedOops) { \
- volatile narrowOop n = *(volatile narrowOop*)index_oop_from_field_offset_long(p, offset); \
- v = oopDesc::decode_heap_oop(n); \
- } else { \
- v = *(volatile oop*)index_oop_from_field_offset_long(p, offset); \
- } \
- OrderAccess::acquire();
-
// Get/SetObject must be special-cased, since it works with handles.
@@ -296,28 +285,21 @@
UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
UnsafeWrapper("Unsafe_GetObjectVolatile");
- GET_OOP_FIELD_VOLATILE(obj, offset, v)
+ oop p = JNIHandles::resolve(obj);
+ void* addr = index_oop_from_field_offset_long(p, offset);
+ volatile oop v;
+ if (UseCompressedOops) {
+ volatile narrowOop n = *(volatile narrowOop*) addr;
+ v = oopDesc::decode_heap_oop(n);
+ } else {
+ v = *(volatile oop*) addr;
+ }
+ OrderAccess::acquire();
return JNIHandles::make_local(env, v);
UNSAFE_END
UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
UnsafeWrapper("Unsafe_SetObjectVolatile");
- {
- // Catch VolatileCallSite.target stores (via
- // CallSite.setTargetVolatile) and check call site dependencies.
- oop p = JNIHandles::resolve(obj);
- if ((offset == java_lang_invoke_CallSite::target_offset_in_bytes()) && p->is_a(SystemDictionary::CallSite_klass())) {
- Handle call_site (THREAD, p);
- Handle method_handle(THREAD, JNIHandles::resolve(x_h));
- assert(call_site ->is_a(SystemDictionary::CallSite_klass()), "must be");
- assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be");
- {
- // Walk all nmethods depending on this call site.
- MutexLocker mu(Compile_lock, thread);
- Universe::flush_dependents_on(call_site(), method_handle());
- }
- }
- }
oop x = JNIHandles::resolve(x_h);
oop p = JNIHandles::resolve(obj);
void* addr = index_oop_from_field_offset_long(p, offset);
--- a/hotspot/src/share/vm/runtime/relocator.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/runtime/relocator.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -392,16 +392,16 @@
// The width of instruction at "pc" is changing by "delta". Adjust the
// exception table, if any, of "rc->mb".
void Relocator::adjust_exception_table(int bci, int delta) {
- typeArrayOop table = method()->exception_table();
- for (int index = 0; index < table->length(); index +=4) {
- if (table->int_at(index) > bci) {
- table->int_at_put(index+0, table->int_at(index+0) + delta);
- table->int_at_put(index+1, table->int_at(index+1) + delta);
- } else if (bci < table->int_at(index+1)) {
- table->int_at_put(index+1, table->int_at(index+1) + delta);
+ ExceptionTable table(_method());
+ for (int index = 0; index < table.length(); index ++) {
+ if (table.start_pc(index) > bci) {
+ table.set_start_pc(index, table.start_pc(index) + delta);
+ table.set_end_pc(index, table.end_pc(index) + delta);
+ } else if (bci < table.end_pc(index)) {
+ table.set_end_pc(index, table.end_pc(index) + delta);
}
- if (table->int_at(index+2) > bci)
- table->int_at_put(index+2, table->int_at(index+2) + delta);
+ if (table.handler_pc(index) > bci)
+ table.set_handler_pc(index, table.handler_pc(index) + delta);
}
}
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -388,7 +388,6 @@
volatile_nonstatic_field(constMethodOopDesc, _fingerprint, uint64_t) \
nonstatic_field(constMethodOopDesc, _constants, constantPoolOop) \
nonstatic_field(constMethodOopDesc, _stackmap_data, typeArrayOop) \
- nonstatic_field(constMethodOopDesc, _exception_table, typeArrayOop) \
nonstatic_field(constMethodOopDesc, _constMethod_size, int) \
nonstatic_field(constMethodOopDesc, _interpreter_kind, jbyte) \
nonstatic_field(constMethodOopDesc, _flags, jbyte) \
@@ -425,6 +424,10 @@
nonstatic_field(LocalVariableTableElement, descriptor_cp_index, u2) \
nonstatic_field(LocalVariableTableElement, signature_cp_index, u2) \
nonstatic_field(LocalVariableTableElement, slot, u2) \
+ nonstatic_field(ExceptionTableElement, start_pc, u2) \
+ nonstatic_field(ExceptionTableElement, end_pc, u2) \
+ nonstatic_field(ExceptionTableElement, handler_pc, u2) \
+ nonstatic_field(ExceptionTableElement, catch_type_index, u2) \
nonstatic_field(BreakpointInfo, _orig_bytecode, Bytecodes::Code) \
nonstatic_field(BreakpointInfo, _bci, int) \
nonstatic_field(BreakpointInfo, _name_index, u2) \
@@ -1460,6 +1463,7 @@
\
declare_toplevel_type(CheckedExceptionElement) \
declare_toplevel_type(LocalVariableTableElement) \
+ declare_toplevel_type(ExceptionTableElement) \
\
/******************************************/ \
/* Generation and space hierarchies */ \
@@ -2301,6 +2305,7 @@
declare_constant(constMethodOopDesc::_has_linenumber_table) \
declare_constant(constMethodOopDesc::_has_checked_exceptions) \
declare_constant(constMethodOopDesc::_has_localvariable_table) \
+ declare_constant(constMethodOopDesc::_has_exception_table) \
\
/*************************************/ \
/* instanceKlass enum */ \
--- a/hotspot/src/share/vm/services/memRecorder.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/services/memRecorder.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -45,11 +45,11 @@
}
-debug_only(volatile jint MemRecorder::_instance_count = 0;)
+volatile jint MemRecorder::_instance_count = 0;
MemRecorder::MemRecorder() {
assert(MemTracker::is_on(), "Native memory tracking is off");
- debug_only(Atomic::inc(&_instance_count);)
+ Atomic::inc(&_instance_count);
debug_only(set_generation();)
if (MemTracker::track_callsite()) {
@@ -83,9 +83,7 @@
delete _next;
}
-#ifdef ASSERT
Atomic::dec(&_instance_count);
-#endif
}
// Sorting order:
--- a/hotspot/src/share/vm/services/memRecorder.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/services/memRecorder.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -249,9 +249,9 @@
SequencedRecordIterator pointer_itr();
- public:
+ protected:
// number of MemRecorder instance
- debug_only(static volatile jint _instance_count;)
+ static volatile jint _instance_count;
private:
// sorting function, sort records into following order
--- a/hotspot/src/share/vm/services/memSnapshot.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/services/memSnapshot.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -173,7 +173,7 @@
_staging_area = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>();
}
- _lock = new (std::nothrow) Mutex(Monitor::native, "memSnapshotLock");
+ _lock = new (std::nothrow) Mutex(Monitor::max_nonleaf - 1, "memSnapshotLock");
NOT_PRODUCT(_untracked_count = 0;)
}
--- a/hotspot/src/share/vm/services/memTrackWorker.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/services/memTrackWorker.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -67,7 +67,7 @@
NOT_PRODUCT(int _last_gen_in_use;)
inline int generations_in_use() const {
- return (_tail <= _head ? (_head - _tail + 1) : (MAX_GENERATIONS - (_tail - _head) + 1));
+ return (_tail >= _head ? (_tail - _head + 1) : (MAX_GENERATIONS - (_head - _tail) + 1));
}
};
--- a/hotspot/src/share/vm/services/memTracker.cpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/services/memTracker.cpp Fri Jul 27 22:26:19 2012 -0700
@@ -54,7 +54,7 @@
MemRecorder* MemTracker::_global_recorder = NULL;
MemSnapshot* MemTracker::_snapshot = NULL;
MemBaseline MemTracker::_baseline;
-Mutex MemTracker::_query_lock(Monitor::native, "NMT_queryLock");
+Mutex* MemTracker::_query_lock = NULL;
volatile MemRecorder* MemTracker::_merge_pending_queue = NULL;
volatile MemRecorder* MemTracker::_pooled_recorders = NULL;
MemTrackWorker* MemTracker::_worker_thread = NULL;
@@ -89,6 +89,12 @@
return;
}
+ _query_lock = new (std::nothrow) Mutex(Monitor::max_nonleaf, "NMT_queryLock");
+ if (_query_lock == NULL) {
+ shutdown(NMT_out_of_memory);
+ return;
+ }
+
debug_only(_main_thread_tid = os::current_thread_id();)
_state = NMT_bootstrapping_single_thread;
NMT_track_callsite = (_tracking_level == NMT_detail && can_walk_stack());
@@ -164,7 +170,7 @@
{
// shared baseline and snapshot are the only objects needed to
// create query results
- MutexLockerEx locker(&_query_lock, true);
+ MutexLockerEx locker(_query_lock, true);
// cleanup baseline data and snapshot
_baseline.clear();
delete _snapshot;
@@ -351,21 +357,17 @@
}
if (thread != NULL) {
-#ifdef ASSERT
- // cause assertion on stack base. This ensures that threads call
- // Thread::record_stack_base_and_size() method, which will create
- // thread native stack records.
- thread->stack_base();
-#endif
- // for a JavaThread, if it is running in native state, we need to transition it to
- // VM state, so it can stop at safepoint. JavaThread running in VM state does not
- // need lock to write records.
if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) {
- if (((JavaThread*)thread)->thread_state() == _thread_in_native) {
- ThreadInVMfromNative trans((JavaThread*)thread);
- create_record_in_recorder(addr, flags, size, pc, thread);
+ JavaThread* java_thread = static_cast<JavaThread*>(thread);
+ JavaThreadState state = java_thread->thread_state();
+ if (SafepointSynchronize::safepoint_safe(java_thread, state)) {
+ // JavaThreads that are safepoint safe, can run through safepoint,
+ // so ThreadCritical is needed to ensure no threads at safepoint create
+ // new records while the records are being gathered and the sequence number is changing
+ ThreadCritical tc;
+ create_record_in_recorder(addr, flags, size, pc, java_thread);
} else {
- create_record_in_recorder(addr, flags, size, pc, thread);
+ create_record_in_recorder(addr, flags, size, pc, java_thread);
}
} else {
// other threads, such as worker and watcher threads, etc. need to
@@ -390,10 +392,9 @@
// write a record to proper recorder. No lock can be taken from this method
// down.
void MemTracker::create_record_in_recorder(address addr, MEMFLAGS flags,
- size_t size, address pc, Thread* thread) {
- assert(thread == NULL || thread->is_Java_thread(), "wrong thread");
+ size_t size, address pc, JavaThread* thread) {
- MemRecorder* rc = get_thread_recorder((JavaThread*)thread);
+ MemRecorder* rc = get_thread_recorder(thread);
if (rc != NULL) {
rc->record(addr, flags, size, pc);
}
@@ -460,17 +461,18 @@
}
}
_sync_point_skip_count = 0;
- // walk all JavaThreads to collect recorders
- SyncThreadRecorderClosure stc;
- Threads::threads_do(&stc);
-
- _thread_count = stc.get_thread_count();
- MemRecorder* pending_recorders = get_pending_recorders();
-
{
// This method is running at safepoint, with ThreadCritical lock,
// it should guarantee that NMT is fully sync-ed.
ThreadCritical tc;
+
+ // walk all JavaThreads to collect recorders
+ SyncThreadRecorderClosure stc;
+ Threads::threads_do(&stc);
+
+ _thread_count = stc.get_thread_count();
+ MemRecorder* pending_recorders = get_pending_recorders();
+
if (_global_recorder != NULL) {
_global_recorder->set_next(pending_recorders);
pending_recorders = _global_recorder;
@@ -486,8 +488,6 @@
// now, it is the time to shut whole things off
if (_state == NMT_final_shutdown) {
- _tracking_level = NMT_off;
-
// walk all JavaThreads to delete all recorders
SyncThreadRecorderClosure stc;
Threads::threads_do(&stc);
@@ -499,8 +499,16 @@
_global_recorder = NULL;
}
}
-
- _state = NMT_shutdown;
+ MemRecorder* pending_recorders = get_pending_recorders();
+ if (pending_recorders != NULL) {
+ delete pending_recorders;
+ }
+ // try at a later sync point to ensure MemRecorder instance drops to zero to
+ // completely shutdown NMT
+ if (MemRecorder::_instance_count == 0) {
+ _state = NMT_shutdown;
+ _tracking_level = NMT_off;
+ }
}
}
@@ -534,7 +542,7 @@
// baseline current memory snapshot
bool MemTracker::baseline() {
- MutexLockerEx lock(&_query_lock, true);
+ MutexLockerEx lock(_query_lock, true);
MemSnapshot* snapshot = get_snapshot();
if (snapshot != NULL) {
return _baseline.baseline(*snapshot, false);
@@ -545,7 +553,7 @@
// print memory usage from current snapshot
bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
MemBaseline baseline;
- MutexLockerEx lock(&_query_lock, true);
+ MutexLockerEx lock(_query_lock, true);
MemSnapshot* snapshot = get_snapshot();
if (snapshot != NULL && baseline.baseline(*snapshot, summary_only)) {
BaselineReporter reporter(out, unit);
@@ -557,7 +565,7 @@
// compare memory usage between current snapshot and baseline
bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
- MutexLockerEx lock(&_query_lock, true);
+ MutexLockerEx lock(_query_lock, true);
if (_baseline.baselined()) {
MemBaseline baseline;
MemSnapshot* snapshot = get_snapshot();
--- a/hotspot/src/share/vm/services/memTracker.hpp Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/src/share/vm/services/memTracker.hpp Fri Jul 27 22:26:19 2012 -0700
@@ -126,6 +126,8 @@
return "Native memory tracking has been shutdown by user";
case NMT_normal:
return "Native memory tracking has been shutdown due to process exiting";
+ case NMT_out_of_memory:
+ return "Native memory tracking has been shutdown due to out of native memory";
case NMT_initialization:
return "Native memory tracking failed to initialize";
case NMT_error_reporting:
@@ -326,7 +328,7 @@
static void create_memory_record(address addr, MEMFLAGS type,
size_t size, address pc, Thread* thread);
static void create_record_in_recorder(address addr, MEMFLAGS type,
- size_t size, address pc, Thread* thread);
+ size_t size, address pc, JavaThread* thread);
private:
// global memory snapshot
@@ -336,7 +338,7 @@
static MemBaseline _baseline;
// query lock
- static Mutex _query_lock;
+ static Mutex* _query_lock;
// a thread can start to allocate memory before it is attached
// to VM 'Thread', those memory activities are recorded here.
--- a/hotspot/test/runtime/6294277/SourceDebugExtension.java Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/test/runtime/6294277/SourceDebugExtension.java Fri Jul 27 22:26:19 2012 -0700
@@ -25,6 +25,7 @@
* @test
* @bug 6294277
* @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
+ * @run main/othervm -Xdebug -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n SourceDebugExtension
*/
import java.io.*;
--- a/hotspot/test/runtime/6294277/Test6294277.sh Fri Jul 27 16:53:15 2012 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-#
-# 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 Test6294277.sh
-# @bug 6294277
-# @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
-# @run shell Test6294277.sh
-#
-
-
-if [ "${TESTSRC}" = "" ]
-then TESTSRC=.
-fi
-
-if [ "${TESTJAVA}" = "" ]
-then
- PARENT=`dirname \`which java\``
- TESTJAVA=`dirname ${PARENT}`
- echo "TESTJAVA not set, selecting " ${TESTJAVA}
- echo "If this is incorrect, try setting the variable manually."
-fi
-
-BIT_FLAG=""
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
- SunOS | Linux )
- NULL=/dev/null
- PS=":"
- FS="/"
- ## for solaris, linux it's HOME
- FILE_LOCATION=$HOME
- if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" -a `uname -p`='sparc' ]
- then
- BIT_FLAG="-d64"
- fi
- ;;
- Windows_* | Darwin )
- NULL=NUL
- PS=";"
- FS="\\"
- echo "Test skipped"
- exit 0
- ;;
- * )
- echo "Unrecognized system!"
- exit 1;
- ;;
-esac
-
-cp ${TESTSRC}${FS}*.java .
-
-${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -fullversion
-
-${TESTJAVA}${FS}bin${FS}javac *.java
-
-${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -classpath . -Xdebug -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n SourceDebugExtension > test.out 2>&1 &
-
-P_PID=$!
-
-sleep 60
-STATUS=1
-
-grep "Test PASSES" test.out > ${NULL}
-if [ $? = 0 ]; then
- cat test.out
- STATUS=0
-fi
-
-exit $STATUS
--- a/hotspot/test/runtime/7020373/Test7020373.sh Fri Jul 27 16:53:15 2012 -0700
+++ b/hotspot/test/runtime/7020373/Test7020373.sh Fri Jul 27 22:26:19 2012 -0700
@@ -2,10 +2,10 @@
##
## @test
-## @bug 7020373 7055247
+## @bug 7020373 7055247 7053586 7185550
## @key cte_test
## @summary JSR rewriting can overflow memory address size variables
-## @ignore Ignore it until 7053586 fixed
+## @ignore Ignore it as 7053586 test uses lots of memory. See bug report for detail.
## @run shell Test7020373.sh
##
@@ -30,7 +30,7 @@
# set platform-dependent variables
OS=`uname -s`
case "$OS" in
- SunOS | Linux )
+ SunOS | Linux | Darwin )
NULL=/dev/null
PS=":"
FS="/"
@@ -66,7 +66,7 @@
echo "Test Failed"
exit 1
else
- grep "java.lang.LinkageError" test.out
+ egrep "java.lang.LinkageError|java.lang.NoSuchMethodError|Main method not found in class OOMCrashClass4000_1|insufficient memory" test.out
if [ $? = 0 ]
then
echo "Test Passed"
Binary file hotspot/test/runtime/7020373/testcase.jar has changed
--- a/jaxp/.hgtags Fri Jul 27 16:53:15 2012 -0700
+++ b/jaxp/.hgtags Fri Jul 27 22:26:19 2012 -0700
@@ -169,3 +169,5 @@
57476f66e13c55eea2f2fe2b858369a4c64b9936 jdk8-b45
300f45e990643af230d6cca39477ff62c44a9a54 jdk8-b46
404521944ac9383afda7d55d60713b212c730646 jdk8-b47
+1c88da9a1365797e49be77ae42c34bbc0a3c3f0c jdk8-b48
+f81e981eca7b63316cf9d778f93903a4fc62161d jdk8-b49
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Fri Jul 27 22:26:19 2012 -0700
@@ -602,7 +602,7 @@
if (reader == null) {
stream = xmlInputSource.getByteStream();
if (stream == null) {
- URL location = new URL(escapeNonUSAscii(expandedSystemId));
+ URL location = new URL(expandedSystemId);
URLConnection connect = location.openConnection();
if (!(connect instanceof HttpURLConnection)) {
stream = connect.getInputStream();
@@ -2586,76 +2586,6 @@
} // fixURI(String):String
- /**
- * Escape invalid URI characters.
- *
- * Passed a URI that contains invalid characters (like spaces, non-ASCII Unicode characters, and the like),
- * this function percent encodes the invalid characters per the URI specification (i.e., as a sequence of
- * %-encoded UTF-8 octets).
- *
- * N.B. There are two problems. If the URI contains a '%' character, that might be an indication that
- * the URI has already been escaped by the author, or it might be an invalid '%'. In the former case,
- * it's important not to escape it, or we'll wind up with invalid, doubly-escaped '%'s. In the latter,
- * the URI is broken if we don't encode it. Similarly, a '#' character might be the start of a fragment
- * identifier or it might be an invalid '#'.
- *
- * Given that the former is vastly more likely than the latter in each case (most users are familiar with
- * the magic status of '%' and '#' and they occur relatively infrequently in filenames, and if the user parses
- * a proper Java File, we will already have %-escaped the URI), we simply assume that %'s and #'s are legit.
- *
- * Very rarely, we may be wrong. If so, tell the user to fix the clearly broken URI.
- */
- protected static String escapeNonUSAscii(String str) {
- if (str == null) {
- return str;
- }
- int len = str.length(), i=0, ch;
- for (; i < len; i++) {
- ch = str.charAt(i);
- // if it's not an ASCII 7 character, break here, and use UTF-8 encoding
- if (ch >= 128)
- break;
- }
-
- // we saw no non-ascii-7 character
- if (i == len) {
- return str;
- }
-
- // get UTF-8 bytes for the string
- StringBuffer buffer = new StringBuffer();
- byte[] bytes = null;
- byte b;
- try {
- bytes = str.getBytes("UTF-8");
- } catch (java.io.UnsupportedEncodingException e) {
- // should never happen
- return str;
- }
-
- len = bytes.length;
-
- // for each byte
- for (i = 0; i < len; i++) {
- b = bytes[i];
- // for non-ascii character: make it positive, then escape
- if (b < 0) {
- ch = b + 256;
- buffer.append('%');
- buffer.append(gHexChs[ch >> 4]);
- buffer.append(gHexChs[ch & 0xf]);
- }
- else if (b != '%' && b != '#' && gNeedEscaping[b]) {
- buffer.append('%');
- buffer.append(gAfterEscaping1[b]);
- buffer.append(gAfterEscaping2[b]);
- }
- else {
- buffer.append((char)b);
- }
- }
- return buffer.toString();
- }
//
// Package visible methods
--- a/jaxws/.hgtags Fri Jul 27 16:53:15 2012 -0700
+++ b/jaxws/.hgtags Fri Jul 27 22:26:19 2012 -0700
@@ -169,3 +169,5 @@
e80ac58b5ba904f24e125c742c30d0d740f05f86 jdk8-b45
ae368a83c2404b65c9e38c65e2aa081f2201ca74 jdk8-b46
fe6a060afc404dcf0921708a740de770666b781f jdk8-b47
+efb564de8a8ee397a65fab77d45cb20200f6ddd8 jdk8-b48
+b48865af8ac559ba6f60fb86fa3fe0ebdd22746c jdk8-b49
--- a/jdk/.hgtags Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/.hgtags Fri Jul 27 22:26:19 2012 -0700
@@ -169,3 +169,5 @@
b92353a01aa049bc508fc56f0347d5934b7c4390 jdk8-b45
8d2ed9d58453c8049715a72a6d26b6b66b37a94c jdk8-b46
00b22b23269a57d0bb46c57753be2fe9a9d2c1a3 jdk8-b47
+3e4ab821f46166fcf63e8fe5c8046216003c941f jdk8-b48
+51707c3b75c0f521794d9ab425f4e5b2351c70c1 jdk8-b49
--- a/jdk/src/macosx/classes/com/apple/laf/AquaPanelUI.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaPanelUI.java Fri Jul 27 22:26:19 2012 -0700
@@ -32,10 +32,20 @@
import com.apple.laf.AquaUtils.RecyclableSingleton;
import com.apple.laf.AquaUtils.RecyclableSingletonFromDefaultConstructor;
+import java.awt.Graphics;
+
public class AquaPanelUI extends BasicPanelUI {
static RecyclableSingleton<AquaPanelUI> instance = new RecyclableSingletonFromDefaultConstructor<AquaPanelUI>(AquaPanelUI.class);
public static ComponentUI createUI(final JComponent c) {
return instance.get();
}
+
+ @Override
+ public final void update(final Graphics g, final JComponent c) {
+ if (c.isOpaque()) {
+ AquaUtils.fillRect(g, c);
+ }
+ paint(g, c);
+ }
}
--- a/jdk/src/macosx/classes/com/apple/laf/AquaRootPaneUI.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaRootPaneUI.java Fri Jul 27 22:26:19 2012 -0700
@@ -319,4 +319,12 @@
updateComponentTreeUIActivation(element, active);
}
}
+
+ @Override
+ public final void update(final Graphics g, final JComponent c) {
+ if (c.isOpaque()) {
+ AquaUtils.fillRect(g, c);
+ }
+ paint(g, c);
+ }
}
--- a/jdk/src/macosx/classes/com/apple/laf/AquaToolBarUI.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaToolBarUI.java Fri Jul 27 22:26:19 2012 -0700
@@ -73,9 +73,7 @@
g.translate(x, y);
if (c.isOpaque()) {
- final Color background = c.getBackground();
- g.setColor(background);
- g.fillRect(0, 0, w - 1, h - 1);
+ AquaUtils.fillRect(g, c, c.getBackground(), 0, 0, w - 1, h - 1);
}
final Color oldColor = g.getColor();
@@ -137,4 +135,12 @@
return true;
}
}
+
+ @Override
+ public final void update(final Graphics g, final JComponent c) {
+ if (c.isOpaque()) {
+ AquaUtils.fillRect(g, c);
+ }
+ paint(g, c);
+ }
}
--- a/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java Fri Jul 27 22:26:19 2012 -0700
@@ -28,18 +28,19 @@
import java.awt.*;
import java.awt.image.*;
import java.lang.ref.SoftReference;
-import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.security.PrivilegedAction;
import java.util.*;
import javax.swing.*;
import javax.swing.border.Border;
+import javax.swing.plaf.UIResource;
import sun.awt.AppContext;
import sun.lwawt.macosx.CImage;
import sun.lwawt.macosx.CImage.Creator;
+import sun.lwawt.macosx.CPlatformWindow;
import sun.swing.SwingUtilities2;
import com.apple.laf.AquaImageFactory.SlicedImageControl;
@@ -389,4 +390,51 @@
return false;
}
}
+
+ protected static boolean isWindowTextured(final Component c) {
+ if (!(c instanceof JComponent)) {
+ return false;
+ }
+ final JRootPane pane = ((JComponent) c).getRootPane();
+ if (pane == null) {
+ return false;
+ }
+ Object prop = pane.getClientProperty(
+ CPlatformWindow.WINDOW_BRUSH_METAL_LOOK);
+ if (prop != null) {
+ return Boolean.parseBoolean(prop.toString());
+ }
+ prop = pane.getClientProperty(CPlatformWindow.WINDOW_STYLE);
+ return prop != null && "textured".equals(prop);
+ }
+
+ private static Color resetAlpha(final Color color) {
+ return new Color(color.getRed(), color.getGreen(), color.getBlue(), 0);
+ }
+
+ protected static void fillRect(final Graphics g, final Component c) {
+ fillRect(g, c, c.getBackground(), 0, 0, c.getWidth(), c.getHeight());
+ }
+
+ protected static void fillRect(final Graphics g, final Component c,
+ final Color color, final int x, final int y,
+ final int w, final int h) {
+ if (!(g instanceof Graphics2D)) {
+ return;
+ }
+ final Graphics2D cg = (Graphics2D) g.create();
+ try {
+ if (color instanceof UIResource && isWindowTextured(c)
+ && color.equals(SystemColor.window)) {
+ cg.setComposite(AlphaComposite.Src);
+ cg.setColor(resetAlpha(color));
+ } else {
+ cg.setColor(color);
+ }
+ cg.fillRect(x, y, w, h);
+ } finally {
+ cg.dispose();
+ }
+ }
}
+
--- a/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/sun/awt/CGraphicsDevice.java Fri Jul 27 22:26:19 2012 -0700
@@ -48,6 +48,9 @@
private static AWTPermission fullScreenExclusivePermission;
+ // Save/restore DisplayMode for the Full Screen mode
+ private DisplayMode originalMode;
+
public CGraphicsDevice(int displayID) {
this.displayID = displayID;
configs = new GraphicsConfiguration[] {
@@ -124,18 +127,22 @@
}
boolean fsSupported = isFullScreenSupported();
+
if (fsSupported && old != null) {
// enter windowed mode (and restore original display mode)
exitFullScreenExclusive(old);
-
- // TODO: restore display mode
+ if (originalMode != null) {
+ setDisplayMode(originalMode);
+ originalMode = null;
+ }
}
super.setFullScreenWindow(w);
if (fsSupported && w != null) {
- // TODO: save current display mode
-
+ if (isDisplayChangeSupported()) {
+ originalMode = getDisplayMode();
+ }
// enter fullscreen mode
enterFullScreenExclusive(w);
}
--- a/jdk/src/macosx/classes/sun/java2d/opengl/CGLLayer.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/sun/java2d/opengl/CGLLayer.java Fri Jul 27 22:26:19 2012 -0700
@@ -68,11 +68,12 @@
}
public boolean isOpaque() {
- return peer.isOpaque();
+ return !peer.isTranslucent();
}
public int getTransparency() {
- return (peer.isOpaque() ? Transparency.OPAQUE : Transparency.TRANSLUCENT);
+ return peer.isTranslucent() ? Transparency.TRANSLUCENT :
+ Transparency.OPAQUE;
}
public Object getDestination() {
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java Fri Jul 27 22:26:19 2012 -0700
@@ -424,8 +424,7 @@
@Override
public final Graphics getGraphics() {
- Graphics g = getWindowPeerOrSelf().isOpaque() ? getOnscreenGraphics()
- : getOffscreenGraphics();
+ final Graphics g = getOnscreenGraphics();
if (g != null) {
synchronized (getPeerTreeLock()){
applyConstrain(g);
@@ -443,13 +442,7 @@
final LWWindowPeer wp = getWindowPeerOrSelf();
return wp.getOnscreenGraphics(getForeground(), getBackground(),
getFont());
- }
- public final Graphics getOffscreenGraphics() {
- final LWWindowPeer wp = getWindowPeerOrSelf();
-
- return wp.getOffscreenGraphics(getForeground(), getBackground(),
- getFont());
}
private void applyConstrain(final Graphics g) {
@@ -463,7 +456,7 @@
}
//TODO Move this method to SG2D?
- private void SG2DConstraint(final SunGraphics2D sg2d, Region r) {
+ void SG2DConstraint(final SunGraphics2D sg2d, Region r) {
sg2d.constrainX = sg2d.transX;
sg2d.constrainY = sg2d.transY;
@@ -710,7 +703,7 @@
// Obtain the metrics from the offscreen window where this peer is
// mostly drawn to.
// TODO: check for "use platform metrics" settings
- Graphics g = getWindowPeer().getOffscreenGraphics();
+ Graphics g = getWindowPeer().getGraphics();
try {
if (g != null) {
return g.getFontMetrics(f);
@@ -1011,14 +1004,33 @@
@Override
public final void applyShape(final Region shape) {
synchronized (getStateLock()) {
- region = shape;
+ if (region == shape || (region != null && region.equals(shape))) {
+ return;
+ }
+ }
+ applyShapeImpl(shape);
+ }
+
+ void applyShapeImpl(final Region shape) {
+ synchronized (getStateLock()) {
+ if (shape != null) {
+ region = Region.WHOLE_REGION.getIntersection(shape);
+ } else {
+ region = null;
+ }
}
repaintParent(getBounds());
}
protected final Region getRegion() {
synchronized (getStateLock()) {
- return region == null ? Region.getInstance(getSize()) : region;
+ return isShaped() ? region : Region.getInstance(getSize());
+ }
+ }
+
+ public boolean isShaped() {
+ synchronized (getStateLock()) {
+ return region != null;
}
}
@@ -1386,11 +1398,6 @@
}
}
- // Just a helper method, thus final
- protected final void flushOffscreenGraphics() {
- flushOffscreenGraphics(getSize());
- }
-
protected static final void flushOnscreenGraphics(){
final OGLRenderQueue rq = OGLRenderQueue.getInstance();
rq.lock();
@@ -1401,36 +1408,6 @@
}
}
- /*
- * Flushes the given rectangle from the back buffer to the screen.
- */
- protected void flushOffscreenGraphics(Rectangle r) {
- flushOffscreenGraphics(r.x, r.y, r.width, r.height);
- }
-
- private void flushOffscreenGraphics(int x, int y, int width, int height) {
- Image bb = getWindowPeerOrSelf().getBackBuffer();
- if (bb != null) {
- // g is a screen Graphics from the delegate
- final Graphics g = getOnscreenGraphics();
-
- if (g != null && g instanceof Graphics2D) {
- try {
- Graphics2D g2d = (Graphics2D)g;
- Point p = localToWindow(new Point(0, 0));
- Composite composite = g2d.getComposite();
- g2d.setComposite(AlphaComposite.Src);
- g.drawImage(bb, x, y, x + width, y + height, p.x + x,
- p.y + y, p.x + x + width, p.y + y + height,
- null);
- g2d.setComposite(composite);
- } finally {
- g.dispose();
- }
- }
- }
- }
-
/**
* Used by ContainerPeer to skip all the paint events during layout.
*
--- a/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java Fri Jul 27 22:26:19 2012 -0700
@@ -58,9 +58,6 @@
private static void flushBuffers(final LWComponentPeer peer) {
if (peer != null) {
- if (!peer.getWindowPeerOrSelf().isOpaque()) {
- peer.flushOffscreenGraphics();
- }
peer.flushOnscreenGraphics();
}
}
--- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java Fri Jul 27 22:26:19 2012 -0700
@@ -522,12 +522,6 @@
postEvent(targetToAppContext(event.getSource()), event);
}
- // use peer's back buffer to implement non-opaque windows.
- @Override
- public boolean needUpdateWindow() {
- return true;
- }
-
@Override
public void grab(Window w) {
if (w.getPeer() != null) {
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java Fri Jul 27 22:26:19 2012 -0700
@@ -37,6 +37,7 @@
import sun.java2d.*;
import sun.java2d.loops.Blit;
import sun.java2d.loops.CompositeType;
+import sun.java2d.pipe.Region;
import sun.util.logging.PlatformLogger;
public class LWWindowPeer
@@ -109,6 +110,10 @@
private volatile boolean skipNextFocusChange;
+ private static final Color nonOpaqueBackground = new Color(0, 0, 0, 0);
+
+ private volatile boolean textured;
+
/**
* Current modal blocker or null.
*
@@ -169,6 +174,11 @@
setAlwaysOnTop(getTarget().isAlwaysOnTop());
updateMinimumSize();
+ final Shape shape = getTarget().getShape();
+ if (shape != null) {
+ applyShape(Region.getInstance(shape, null));
+ }
+
final float opacity = getTarget().getOpacity();
if (opacity < 1.0f) {
setOpacity(opacity);
@@ -178,7 +188,7 @@
updateInsets(platformWindow.getInsets());
if (getSurfaceData() == null) {
- replaceSurfaceData();
+ replaceSurfaceData(false);
}
}
@@ -280,7 +290,7 @@
// "buffer", that's why numBuffers - 1
assert numBuffers > 1;
- replaceSurfaceData(numBuffers - 1, caps);
+ replaceSurfaceData(numBuffers - 1, caps, false);
} catch (InvalidPipeException z) {
throw new AWTException(z.toString());
}
@@ -420,19 +430,44 @@
public final void setOpaque(final boolean isOpaque) {
if (this.isOpaque != isOpaque) {
this.isOpaque = isOpaque;
- getPlatformWindow().setOpaque(isOpaque);
- replaceSurfaceData();
- repaintPeer();
+ updateOpaque();
}
}
- public final boolean isOpaque() {
- return isOpaque;
+ private void updateOpaque() {
+ getPlatformWindow().setOpaque(!isTranslucent());
+ replaceSurfaceData(false);
+ repaintPeer();
}
@Override
public void updateWindow() {
- flushOffscreenGraphics();
+ }
+
+ public final boolean isTextured() {
+ return textured;
+ }
+
+ public final void setTextured(final boolean isTextured) {
+ textured = isTextured;
+ }
+
+ public final boolean isTranslucent() {
+ synchronized (getStateLock()) {
+ /*
+ * Textured window is a special case of translucent window.
+ * The difference is only in nswindow background. So when we set
+ * texture property our peer became fully translucent. It doesn't
+ * fill background, create non opaque backbuffers and layer etc.
+ */
+ return !isOpaque || isShaped() || isTextured();
+ }
+ }
+
+ @Override
+ final void applyShapeImpl(final Region shape) {
+ super.applyShapeImpl(shape);
+ updateOpaque();
}
@Override
@@ -587,7 +622,20 @@
getFont());
if (g != null) {
try {
- g.clearRect(0, 0, w, h);
+ if (g instanceof Graphics2D) {
+ ((Graphics2D) g).setComposite(AlphaComposite.Src);
+ }
+ if (isTranslucent()) {
+ g.setColor(nonOpaqueBackground);
+ g.fillRect(0, 0, w, h);
+ }
+ if (!isTextured()) {
+ if (g instanceof SunGraphics2D) {
+ SG2DConstraint((SunGraphics2D) g, getRegion());
+ }
+ g.setColor(getBackground());
+ g.fillRect(0, 0, w, h);
+ }
} finally {
g.dispose();
}
@@ -894,35 +942,6 @@
});
}
- /**
- * This method returns a back buffer Graphics to render all the
- * peers to. After the peer is painted, the back buffer contents
- * should be flushed to the screen. All the target painting
- * (Component.paint() method) should be done directly to the screen.
- */
- protected final Graphics getOffscreenGraphics(Color fg, Color bg, Font f) {
- final Image bb = getBackBuffer();
- if (bb == null) {
- return null;
- }
- if (fg == null) {
- fg = SystemColor.windowText;
- }
- if (bg == null) {
- bg = SystemColor.window;
- }
- if (f == null) {
- f = DEFAULT_FONT;
- }
- final Graphics2D g = (Graphics2D) bb.getGraphics();
- if (g != null) {
- g.setColor(fg);
- g.setBackground(bg);
- g.setFont(f);
- }
- return g;
- }
-
/*
* May be called by delegate to provide SD to Java2D code.
*/
@@ -933,11 +952,16 @@
}
private void replaceSurfaceData() {
- replaceSurfaceData(backBufferCount, backBufferCaps);
+ replaceSurfaceData(true);
+ }
+
+ private void replaceSurfaceData(boolean blit) {
+ replaceSurfaceData(backBufferCount, backBufferCaps, blit);
}
private void replaceSurfaceData(int newBackBufferCount,
- BufferCapabilities newBackBufferCaps) {
+ BufferCapabilities newBackBufferCaps,
+ boolean blit) {
synchronized (surfaceDataLock) {
final SurfaceData oldData = getSurfaceData();
surfaceData = platformWindow.replaceSurfaceData();
@@ -950,7 +974,10 @@
if (getSurfaceData() != null && oldData != getSurfaceData()) {
clearBackground(size.width, size.height);
}
- blitSurfaceData(oldData, getSurfaceData());
+
+ if (blit) {
+ blitSurfaceData(oldData, getSurfaceData());
+ }
if (oldData != null && oldData != getSurfaceData()) {
// TODO: drop oldData for D3D/WGL pipelines
@@ -965,11 +992,18 @@
Graphics g = backBuffer.getGraphics();
try {
Rectangle r = getBounds();
- g.setColor(getBackground());
if (g instanceof Graphics2D) {
((Graphics2D) g).setComposite(AlphaComposite.Src);
}
+ g.setColor(nonOpaqueBackground);
g.fillRect(0, 0, r.width, r.height);
+ if (g instanceof SunGraphics2D) {
+ SG2DConstraint((SunGraphics2D) g, getRegion());
+ }
+ if (!isTextured()) {
+ g.setColor(getBackground());
+ g.fillRect(0, 0, r.width, r.height);
+ }
if (oldBB != null) {
// Draw the old back buffer to the new one
g.drawImage(oldBB, 0, 0, null);
@@ -993,7 +1027,7 @@
CompositeType.Src,
dst.getSurfaceType());
if (blit != null) {
- blit.Blit(src, dst, ((Graphics2D) getGraphics()).getComposite(),
+ blit.Blit(src, dst, AlphaComposite.Src,
getRegion(), 0, 0, 0, 0, size.width, size.height);
}
}
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java Fri Jul 27 22:26:19 2012 -0700
@@ -117,7 +117,7 @@
Rectangle r = peer.getBounds();
Image im = null;
if (!r.isEmpty()) {
- int transparency = (peer.isOpaque() ? Transparency.OPAQUE : Transparency.TRANSLUCENT);
+ int transparency = peer.isTranslucent() ? Transparency.TRANSLUCENT : Transparency.OPAQUE;
im = peer.getGraphicsConfiguration().createCompatibleImage(r.width, r.height, transparency);
}
return im;
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java Fri Jul 27 22:26:19 2012 -0700
@@ -64,7 +64,7 @@
}
public boolean isOpaque() {
- return peer.isOpaque();
+ return !peer.isTranslucent();
}
/*
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java Fri Jul 27 22:26:19 2012 -0700
@@ -209,6 +209,7 @@
private boolean undecorated; // initialized in getInitialStyleBits()
private Rectangle normalBounds = null; // not-null only for undecorated maximized windows
private CPlatformResponder responder;
+ private volatile boolean zoomed = false; // from native perspective
public CPlatformWindow(final PeerType peerType) {
super(0, true);
@@ -298,7 +299,7 @@
// If the target is a dialog, popup or tooltip we want it to ignore the brushed metal look.
if (isPopup) {
- styleBits = SET(styleBits, TEXTURED, true);
+ styleBits = SET(styleBits, TEXTURED, false);
// Popups in applets don't activate applet's process
styleBits = SET(styleBits, NONACTIVATING, true);
}
@@ -372,6 +373,8 @@
}
}
+ peer.setTextured(IS(TEXTURED, styleBits));
+
return styleBits;
}
@@ -467,26 +470,42 @@
nativeSetNSWindowBounds(getNSWindowPtr(), x, y, w, h);
}
- private void zoom() {
+ private boolean isMaximized() {
+ return undecorated ? this.normalBounds != null : zoomed;
+ }
+
+ private void maximize() {
+ if (isMaximized()) {
+ return;
+ }
if (!undecorated) {
+ zoomed = true;
CWrapper.NSWindow.zoom(getNSWindowPtr());
} else {
- // OS X handles -zoom incorrectly for undecorated windows
- final boolean isZoomed = this.normalBounds == null;
- deliverZoom(isZoomed);
+ deliverZoom(true);
+
+ this.normalBounds = peer.getBounds();
+ long screen = CWrapper.NSWindow.screen(getNSWindowPtr());
+ Rectangle toBounds = CWrapper.NSScreen.visibleFrame(screen).getBounds();
+ // Flip the y coordinate
+ Rectangle frame = CWrapper.NSScreen.frame(screen).getBounds();
+ toBounds.y = frame.height - toBounds.y - toBounds.height;
+ setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height);
+ }
+ }
- Rectangle toBounds;
- if (isZoomed) {
- this.normalBounds = peer.getBounds();
- long screen = CWrapper.NSWindow.screen(getNSWindowPtr());
- toBounds = CWrapper.NSScreen.visibleFrame(screen).getBounds();
- // Flip the y coordinate
- Rectangle frame = CWrapper.NSScreen.frame(screen).getBounds();
- toBounds.y = frame.height - toBounds.y - toBounds.height;
- } else {
- toBounds = normalBounds;
- this.normalBounds = null;
- }
+ private void unmaximize() {
+ if (!isMaximized()) {
+ return;
+ }
+ if (!undecorated) {
+ zoomed = false;
+ CWrapper.NSWindow.zoom(getNSWindowPtr());
+ } else {
+ deliverZoom(false);
+
+ Rectangle toBounds = this.normalBounds;
+ this.normalBounds = null;
setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height);
}
}
@@ -499,9 +518,9 @@
public void setVisible(boolean visible) {
final long nsWindowPtr = getNSWindowPtr();
- // 1. Process parent-child relationship when hiding
+ // Process parent-child relationship when hiding
if (!visible) {
- // 1a. Unparent my children
+ // Unparent my children
for (Window w : target.getOwnedWindows()) {
WindowPeer p = (WindowPeer)w.getPeer();
if (p instanceof LWWindowPeer) {
@@ -512,30 +531,17 @@
}
}
- // 1b. Unparent myself
+ // Unparent myself
if (owner != null && owner.isVisible()) {
CWrapper.NSWindow.removeChildWindow(owner.getNSWindowPtr(), nsWindowPtr);
}
}
- // 2. Configure stuff
+ // Configure stuff
updateIconImages();
updateFocusabilityForAutoRequestFocus(false);
- // 3. Manage the extended state when hiding
- if (!visible) {
- // Cancel out the current native state of the window
- switch (peer.getState()) {
- case Frame.ICONIFIED:
- CWrapper.NSWindow.deminiaturize(nsWindowPtr);
- break;
- case Frame.MAXIMIZED_BOTH:
- zoom();
- break;
- }
- }
-
- // 4. Actually show or hide the window
+ // Actually show or hide the window
LWWindowPeer blocker = peer.getBlocker();
if (blocker == null || !visible) {
// If it ain't blocked, or is being hidden, go regular way
@@ -564,16 +570,19 @@
}
this.visible = visible;
- // 5. Manage the extended state when showing
+ // Manage the extended state when showing
if (visible) {
- // Re-apply the extended state as expected in shared code
+ // Apply the extended state as expected in shared code
if (target instanceof Frame) {
switch (((Frame)target).getExtendedState()) {
case Frame.ICONIFIED:
CWrapper.NSWindow.miniaturize(nsWindowPtr);
break;
case Frame.MAXIMIZED_BOTH:
- zoom();
+ maximize();
+ break;
+ default: // NORMAL
+ unmaximize(); // in case it was maximized, otherwise this is a no-op
break;
}
}
@@ -581,12 +590,12 @@
nativeSynthesizeMouseEnteredExitedEvents(nsWindowPtr);
- // 6. Configure stuff #2
+ // Configure stuff #2
updateFocusabilityForAutoRequestFocus(true);
- // 7. Manage parent-child relationship when showing
+ // Manage parent-child relationship when showing
if (visible) {
- // 7a. Add myself as a child
+ // Add myself as a child
if (owner != null && owner.isVisible()) {
CWrapper.NSWindow.addChildWindow(owner.getNSWindowPtr(), nsWindowPtr, CWrapper.NSWindow.NSWindowAbove);
if (target.isAlwaysOnTop()) {
@@ -594,7 +603,7 @@
}
}
- // 7b. Add my own children to myself
+ // Add my own children to myself
for (Window w : target.getOwnedWindows()) {
WindowPeer p = (WindowPeer)w.getPeer();
if (p instanceof LWWindowPeer) {
@@ -609,7 +618,7 @@
}
}
- // 8. Deal with the blocker of the window being shown
+ // Deal with the blocker of the window being shown
if (blocker != null && visible) {
// Make sure the blocker is above its siblings
((CPlatformWindow)blocker.getPlatformWindow()).orderAboveSiblings();
@@ -733,10 +742,19 @@
@Override
public void setOpaque(boolean isOpaque) {
CWrapper.NSWindow.setOpaque(getNSWindowPtr(), isOpaque);
- if (!isOpaque) {
+ if (!isOpaque && !peer.isTextured()) {
long clearColor = CWrapper.NSColor.clearColor();
CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), clearColor);
}
+
+ //This is a temporary workaround. Looks like after 7124236 will be fixed
+ //the correct place for invalidateShadow() is CGLayer.drawInCGLContext.
+ SwingUtilities.invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ invalidateShadow();
+ }
+ });
}
@Override
@@ -767,7 +785,7 @@
if (prevWindowState == Frame.MAXIMIZED_BOTH) {
// let's return into the normal states first
// the zoom call toggles between the normal and the max states
- zoom();
+ unmaximize();
}
CWrapper.NSWindow.miniaturize(nsWindowPtr);
break;
@@ -776,14 +794,14 @@
// let's return into the normal states first
CWrapper.NSWindow.deminiaturize(nsWindowPtr);
}
- zoom();
+ maximize();
break;
case Frame.NORMAL:
if (prevWindowState == Frame.ICONIFIED) {
CWrapper.NSWindow.deminiaturize(nsWindowPtr);
} else if (prevWindowState == Frame.MAXIMIZED_BOTH) {
// the zoom call toggles between the normal and the max states
- zoom();
+ unmaximize();
}
break;
default:
@@ -805,6 +823,10 @@
nativeSetEnabled(getNSWindowPtr(), !blocked);
}
+ public final void invalidateShadow(){
+ nativeRevalidateNSWindowShadow(getNSWindowPtr());
+ }
+
// ----------------------------------------------------------------------
// UTILITY METHODS
// ----------------------------------------------------------------------
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Fri Jul 27 22:26:19 2012 -0700
@@ -750,6 +750,11 @@
}
@Override
+ public boolean isWindowShapingSupported() {
+ return true;
+ }
+
+ @Override
public boolean isWindowTranslucencySupported() {
return true;
}
@@ -759,6 +764,10 @@
return true;
}
+ public boolean isSwingBackbufferTranslucencySupported() {
+ return true;
+ }
+
@Override
public boolean enableInputMethodsForTextComponent() {
return true;
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m Fri Jul 27 22:26:19 2012 -0700
@@ -941,14 +941,17 @@
(JNIEnv *env, jclass clazz, jlong windowPtr)
{
JNF_COCOA_ENTER(env);
-AWT_ASSERT_NOT_APPKIT_THREAD;
NSWindow *nsWindow = OBJC(windowPtr);
- [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
- AWT_ASSERT_APPKIT_THREAD;
+ if ([NSThread isMainThread]) {
+ [nsWindow invalidateShadow];
+ } else {
+ [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+ AWT_ASSERT_APPKIT_THREAD;
- [nsWindow invalidateShadow];
- }];
+ [nsWindow invalidateShadow];
+ }];
+ }
JNF_COCOA_EXIT(env);
}
--- a/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/macosx/native/sun/awt/CGraphicsDevice.m Fri Jul 27 22:26:19 2012 -0700
@@ -28,7 +28,7 @@
/*
* Convert the mode string to the more convinient bits per pixel value
*/
-static int getBPPFromModeString(CFStringRef mode)
+static int getBPPFromModeString(CFStringRef mode)
{
if ((CFStringCompare(mode, CFSTR(kIO30BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo)) {
// This is a strange mode, where we using 10 bits per RGB component and pack it into 32 bits
@@ -44,7 +44,7 @@
else if (CFStringCompare(mode, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
return 8;
}
-
+
return 0;
}
@@ -68,6 +68,11 @@
// One of the key parameters does not match
continue;
}
+
+ if (refrate == 0) { // REFRESH_RATE_UNKNOWN
+ return cRef;
+ }
+
// Refresh rate might be 0 in display mode and we ask for specific display rate
// but if we do not find exact match then 0 refresh rate might be just Ok
if (CGDisplayModeGetRefreshRate(cRef) == refrate) {
@@ -165,7 +170,10 @@
}
}
}];
+ } else {
+ [JNFException raise:env as:kIllegalArgumentException reason:"Invalid display mode"];
}
+
CFRelease(allModes);
JNF_COCOA_EXIT(env);
}
--- a/jdk/src/share/classes/javax/swing/JViewport.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/share/classes/javax/swing/JViewport.java Fri Jul 27 22:26:19 2012 -0700
@@ -1586,10 +1586,18 @@
int bdx = blitToX - blitFromX;
int bdy = blitToY - blitFromY;
+ Composite oldComposite = null;
// Shift the scrolled region
+ if (g instanceof Graphics2D) {
+ Graphics2D g2d = (Graphics2D) g;
+ oldComposite = g2d.getComposite();
+ g2d.setComposite(AlphaComposite.Src);
+ }
rm.copyArea(this, g, blitFromX, blitFromY, blitW, blitH, bdx, bdy,
false);
-
+ if (oldComposite != null) {
+ ((Graphics2D) g).setComposite(oldComposite);
+ }
// Paint the newly exposed region.
int x = view.getX();
int y = view.getY();
--- a/jdk/src/share/classes/javax/swing/RepaintManager.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/share/classes/javax/swing/RepaintManager.java Fri Jul 27 22:26:19 2012 -0700
@@ -119,6 +119,11 @@
// Whether or not a VolatileImage should be used for double-buffered painting
static boolean volatileImageBufferEnabled = true;
/**
+ * Type of VolatileImage which should be used for double-buffered
+ * painting.
+ */
+ private static final int volatileBufferType;
+ /**
* Value of the system property awt.nativeDoubleBuffering.
*/
private static boolean nativeDoubleBuffering;
@@ -204,6 +209,13 @@
((SunGraphicsEnvironment)ge).addDisplayChangedListener(
new DisplayChangedHandler());
}
+ Toolkit tk = Toolkit.getDefaultToolkit();
+ if ((tk instanceof SunToolkit)
+ && ((SunToolkit) tk).isSwingBackbufferTranslucencySupported()) {
+ volatileBufferType = Transparency.TRANSLUCENT;
+ } else {
+ volatileBufferType = Transparency.OPAQUE;
+ }
}
/**
@@ -989,7 +1001,8 @@
if (image != null) {
image.flush();
}
- image = config.createCompatibleVolatileImage(width, height);
+ image = config.createCompatibleVolatileImage(width, height,
+ volatileBufferType);
volatileMap.put(config, image);
}
return image;
@@ -1483,9 +1496,26 @@
for(y=clipY, maxy = clipY + clipH; y < maxy ; y += bh) {
osg.translate(-x, -y);
osg.setClip(x,y,bw,bh);
+ if (volatileBufferType != Transparency.OPAQUE
+ && osg instanceof Graphics2D) {
+ final Graphics2D g2d = (Graphics2D) osg;
+ final Color oldBg = g2d.getBackground();
+ g2d.setBackground(c.getBackground());
+ g2d.clearRect(x, y, bw, bh);
+ g2d.setBackground(oldBg);
+ }
c.paintToOffscreen(osg, x, y, bw, bh, maxx, maxy);
g.setClip(x, y, bw, bh);
- g.drawImage(image, x, y, c);
+ if (volatileBufferType != Transparency.OPAQUE
+ && g instanceof Graphics2D) {
+ final Graphics2D g2d = (Graphics2D) g;
+ final Composite oldComposite = g2d.getComposite();
+ g2d.setComposite(AlphaComposite.Src);
+ g2d.drawImage(image, x, y, c);
+ g2d.setComposite(oldComposite);
+ } else {
+ g.drawImage(image, x, y, c);
+ }
osg.translate(x, y);
}
}
--- a/jdk/src/share/classes/javax/swing/SwingUtilities.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/share/classes/javax/swing/SwingUtilities.java Fri Jul 27 22:26:19 2012 -0700
@@ -319,7 +319,8 @@
newEvent = new MouseWheelEvent(newSource,
sourceWheelEvent.getID(),
sourceWheelEvent.getWhen(),
- sourceWheelEvent.getModifiers(),
+ sourceWheelEvent.getModifiers()
+ | sourceWheelEvent.getModifiersEx(),
p.x,p.y,
sourceWheelEvent.getXOnScreen(),
sourceWheelEvent.getYOnScreen(),
@@ -334,7 +335,8 @@
newEvent = new MenuDragMouseEvent(newSource,
sourceMenuDragEvent.getID(),
sourceMenuDragEvent.getWhen(),
- sourceMenuDragEvent.getModifiers(),
+ sourceMenuDragEvent.getModifiers()
+ | sourceMenuDragEvent.getModifiersEx(),
p.x,p.y,
sourceMenuDragEvent.getXOnScreen(),
sourceMenuDragEvent.getYOnScreen(),
@@ -347,7 +349,8 @@
newEvent = new MouseEvent(newSource,
sourceEvent.getID(),
sourceEvent.getWhen(),
- sourceEvent.getModifiers(),
+ sourceEvent.getModifiers()
+ | sourceEvent.getModifiersEx(),
p.x,p.y,
sourceEvent.getXOnScreen(),
sourceEvent.getYOnScreen(),
--- a/jdk/src/share/classes/javax/swing/border/TitledBorder.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/share/classes/javax/swing/border/TitledBorder.java Fri Jul 27 22:26:19 2012 -0700
@@ -440,7 +440,7 @@
* @return the title-font of the titled border
*/
public Font getTitleFont() {
- return titleFont;
+ return titleFont == null ? UIManager.getFont("TitledBorder.font") : titleFont;
}
/**
@@ -449,7 +449,7 @@
* @return the title-color of the titled border
*/
public Color getTitleColor() {
- return titleColor;
+ return titleColor == null ? UIManager.getColor("TitledBorder.titleColor") : titleColor;
}
@@ -681,10 +681,6 @@
if (font != null) {
return font;
}
- font = UIManager.getFont("TitledBorder.font");
- if (font != null) {
- return font;
- }
if (c != null) {
font = c.getFont();
if (font != null) {
@@ -699,10 +695,6 @@
if (color != null) {
return color;
}
- color = UIManager.getColor("TitledBorder.titleColor");
- if (color != null) {
- return color;
- }
return (c != null)
? c.getForeground()
: null;
--- a/jdk/src/share/classes/sun/awt/SunToolkit.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/share/classes/sun/awt/SunToolkit.java Fri Jul 27 22:26:19 2012 -0700
@@ -1985,6 +1985,13 @@
}
/**
+ * Returns true if swing backbuffer should be translucent.
+ */
+ public boolean isSwingBackbufferTranslucencySupported() {
+ return false;
+ }
+
+ /**
* Returns whether or not a containing top level window for the passed
* component is
* {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT PERPIXEL_TRANSLUCENT}.
@@ -2105,25 +2112,41 @@
private EventQueueItem queueTail = null;
private final EventQueue eventQueue;
+ // For the case when queue is cleared but events are not posted
+ private volatile boolean isFlushing = false;
+
PostEventQueue(EventQueue eq) {
eventQueue = eq;
}
public synchronized boolean noEvents() {
- return queueHead == null;
+ return queueHead == null && !isFlushing;
}
/*
* Continually post pending AWTEvents to the Java EventQueue. The method
* is synchronized to ensure the flush is completed before a new event
* can be posted to this queue.
+ *
+ * 7177040: The method couldn't be wholly synchronized because of calls
+ * of EventQueue.postEvent() that uses pushPopLock, otherwise it could
+ * potentially lead to deadlock
*/
- public synchronized void flush() {
- EventQueueItem tempQueue = queueHead;
- queueHead = queueTail = null;
- while (tempQueue != null) {
- eventQueue.postEvent(tempQueue.event);
- tempQueue = tempQueue.next;
+ public void flush() {
+ EventQueueItem tempQueue;
+ synchronized (this) {
+ tempQueue = queueHead;
+ queueHead = queueTail = null;
+ isFlushing = true;
+ }
+ try {
+ while (tempQueue != null) {
+ eventQueue.postEvent(tempQueue.event);
+ tempQueue = tempQueue.next;
+ }
+ }
+ finally {
+ isFlushing = false;
}
}
--- a/jdk/src/share/classes/sun/font/SunLayoutEngine.java Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/share/classes/sun/font/SunLayoutEngine.java Fri Jul 27 22:26:19 2012 -0700
@@ -137,8 +137,9 @@
LayoutEngine e = (LayoutEngine)cache.get(key);
if (e == null) {
- e = new SunLayoutEngine(key.copy());
- cache.put(key, e);
+ LayoutEngineKey copy = key.copy();
+ e = new SunLayoutEngine(copy);
+ cache.put(copy, e);
}
return e;
}
--- a/jdk/src/share/native/sun/java2d/opengl/OGLBlitLoops.c Fri Jul 27 16:53:15 2012 -0700
+++ b/jdk/src/share/native/sun/java2d/opengl/OGLBlitLoops.c Fri Jul 27 22:26:19 2012 -0700
@@ -393,7 +393,16 @@
OGLSDOps *dstOps,
jint dx1, jint dy1, jint dx2, jint dy2)
{
+ jboolean adjustAlpha = (pf != NULL && !pf->hasAlpha);
j2d_glBindTexture(dstOps->textureTarget, dstOps->textureID);
+
+ if (adjustAlpha) {
+ // if the source surface does not have an alpha channel,
+ // we need to ensure that the alpha values are forced to 1.0f
+ j2d_glPixelTransferf(GL_ALPHA_SCALE, 0.0f);
+ j2d_glPixelTransferf(GL_ALPHA_BIAS, 1.0f);
+ }
+
// in case pixel stride is not a multiple of scanline stride the copy
// has to be done line by line (see 6207877)
if (srcInfo->scanStride % srcInfo->pixelStride != 0) {
@@ -413,6 +422,11 @@
dx1, dy1, dx2-dx1, dy2-dy1,
pf->format, pf->type, srcInfo->rasBase);
}
+ if (adjustAlpha) {
+ // restore scale/bias to their original values
+ j2d_glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
+ j2d_glPixelTransferf(GL_ALPHA_BIAS, 0.0f);
+ }
}
/**
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/FontMetrics/StyledSpaceAdvance.java Fri Jul 27 22:26:19 2012 -0700
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * 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 7183458
+ * @summary Verify advance of space is not overly widened by bold styling.
+ * @run main StyledSpaceAdvance
+ */
+import java.awt.Font;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.Rectangle2D;
+import java.util.Locale;
+
+public class StyledSpaceAdvance {
+
+ static String name = "Gulim";
+
+ public static void main(String args[]) {
+ for (int sz=9;sz<18;sz++) {
+ test(sz);
+ }
+ }
+
+ static void test(int sz) {
+ Font reg = new Font(name, Font.PLAIN, sz);
+ Font bold = new Font(name, Font.BOLD, sz);
+ //System.out.println("reg="+reg);
+ //System.out.println("bold="+bold);
+ FontRenderContext frc = new FontRenderContext(null, false, false);
+ if (reg.getFontName(Locale.ENGLISH).equals(name) &&
+ bold.getFontName(Locale.ENGLISH).equals(name)) {
+ Rectangle2D rb = reg.getStringBounds(" ", frc);
+ Rectangle2D bb = bold.getStringBounds(" ", frc);
+ if (bb.getWidth() > rb.getWidth() + 1.01f) {
+ System.err.println("reg="+reg+" bds = " + rb);
+ System.err.println("bold="+bold+" bds = " + bb);
+ throw new RuntimeException("Advance difference too great.");
+ }
+ } else {
+ System.out.println("Skipping test because fonts aren't as expected");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/Frame/HideMaximized/HideMaximized.java Fri Jul 27 22:26:19 2012 -0700
@@ -0,0 +1,70 @@
+/*
+ * 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 7177173
+ @summary The maximized state shouldn't be reset upon hiding a frame
+ @author anthony.petrov@oracle.com: area=awt.toplevel
+ @run main HideMaximized
+*/
+
+import java.awt.*;
+
+public class HideMaximized {
+ public static void main(String[] args) {
+ if (!Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) {
+ // Nothing to test
+ return;
+ }
+
+ // First test a decorated frame
+ Frame frame = new Frame("test");
+ test(frame);
+
+ // Now test an undecorated frames
+ frame = new Frame("undecorated test");
+ frame.setUndecorated(true);
+ test(frame);
+ }
+
+ private static void test(Frame frame) {
+ frame.setExtendedState(Frame.MAXIMIZED_BOTH);
+ frame.setVisible(true);
+
+ try { Thread.sleep(1000); } catch (Exception ex) {}
+
+ if (frame.getExtendedState() != Frame.MAXIMIZED_BOTH) {
+ throw new RuntimeException("The maximized state has not been applied");
+ }
+
+ // This will hide the frame, and also clean things up for safe exiting
+ frame.dispose();
+
+ try { Thread.sleep(1000); } catch (Exception ex) {}
+
+ if (frame.getExtendedState() != Frame.MAXIMIZED_BOTH) {
+ throw new RuntimeException("The maximized state has been reset");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/SwingUtilities/7170657/bug7170657.java Fri Jul 27 22:26:19 2012 -0700
@@ -0,0 +1,78 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Frame;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseWheelEvent;
+
+import javax.swing.SwingUtilities;
+import javax.swing.event.MenuDragMouseEvent;
+
+/**
+ * @test
+ * @bug 7170657
+ * @author Sergey Bylokhov
+ */
+public final class bug7170657 {
+
+ private static boolean FAILED;
+
+ public static void main(final String[] args) {
+ final int mask = InputEvent.META_DOWN_MASK | InputEvent.CTRL_MASK;
+
+ Frame f = new Frame();
+
+ MouseEvent mwe = new MouseWheelEvent(f, 1, 1, mask, 1, 1, 1, 1, 1, true,
+ 1, 1, 1);
+ MouseEvent mdme = new MenuDragMouseEvent(f, 1, 1, mask, 1, 1, 1, 1, 1,
+ true, null, null);
+ MouseEvent me = new MouseEvent(f, 1, 1, mask, 1, 1, 1, 1, 1, true,
+ MouseEvent.NOBUTTON);
+
+ test(f, mwe);
+ test(f, mdme);
+ test(f, me);
+
+ if (FAILED) {
+ throw new RuntimeException("Wrong mouse event");
+ }
+ }
+
+
+ private static void test(final Frame frame, final MouseEvent me) {
+ MouseEvent newme = SwingUtilities.convertMouseEvent(frame, me, frame);
+ if (me.getModifiersEx() != newme.getModifiersEx()
+ || me.getModifiers() != newme.getModifiers()) {
+ fail(me, newme);
+ }
+ }
+
+ private static void fail(final MouseEvent exp, final MouseEvent act) {
+ System.err.println("Expected: " + exp);
+ System.err.println("Actual: " + act);
+ FAILED = true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/swing/border/Test7022041.java Fri Jul 27 22:26:19 2012 -0700
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2012 Red Hat, Inc. 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
+ * 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.
+ */
+
+import java.awt.Color;
+import java.awt.Font;
+
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.TitledBorder;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+/* @test
+ * @bug 7022041
+ * @summary This test check the behaviour of getTitleFont() and getTitleColor()
+ * methods of the TitledBorder class.
+ * @author Pavel Tisnovsky
+ */
+public class Test7022041 {
+
+ public static void main(String[] args) throws Exception {
+ UIManager.LookAndFeelInfo[] installedLookAndFeels = UIManager.getInstalledLookAndFeels();
+ // try to test all installed Look and Feels
+ for (UIManager.LookAndFeelInfo lookAndFeel : installedLookAndFeels) {
+ String name = lookAndFeel.getName();
+ System.out.println("Testing " + name);
+ // Some Look and Feels work only when test is run in a GUI environment
+ // (GTK+ LAF is an example)
+ try {
+ UIManager.setLookAndFeel(lookAndFeel.getClassName());
+ checkTitleColor();
+ System.out.println(" titleColor test ok");
+ checkTitleFont();
+ System.out.println(" titleFont test ok");
+ }
+ catch (UnsupportedLookAndFeelException e) {
+ System.out.println(" Note: LookAndFeel " + name
+ + " is not supported on this configuration");
+ }
+ }
+ }
+
+ /**
+ * Check behaviour of method TitledBorder.getTitleColor()
+ */
+ private static void checkTitleColor() {
+ TitledBorder titledBorder = new TitledBorder(new EmptyBorder(1, 1, 1, 1));
+ Color defaultColor = UIManager.getLookAndFeelDefaults().getColor("TitledBorder.titleColor");
+ Color titledBorderColor = titledBorder.getTitleColor();
+
+ // check default configuration
+ if (defaultColor == null) {
+ if (titledBorderColor == null) {
+ return;
+ }
+ else {
+ throw new RuntimeException("TitledBorder default color should be null");
+ }
+ }
+ if (!defaultColor.equals(titledBorderColor)) {
+ throw new RuntimeException("L&F default color " + defaultColor.toString()
+ + " differs from TitledBorder color " + titledBorderColor.toString());
+ }
+
+ // title color is explicitly specified
+ Color color = Color.green;
+ titledBorder.setTitleColor(color);
+ if (!color.equals(titledBorder.getTitleColor())) {
+ throw new RuntimeException("TitledBorder color should be " + color.toString());
+ }
+
+ // title color is unspecified
+ titledBorder.setTitleColor(null);
+ if (!defaultColor.equals(titledBorder.getTitleColor())) {
+ throw new RuntimeException("L&F default color " + defaultColor.toString()
+ + " differs from TitledBorder color " + titledBorderColor.toString());
+ }
+ }
+
+ /**
+ * Check behaviour of method TitledBorder.getTitleFont()
+ */
+ private static void checkTitleFont() {
+ TitledBorder titledBorder = new TitledBorder(new EmptyBorder(1, 1, 1, 1));
+ Font defaultFont = UIManager.getLookAndFeelDefaults().getFont("TitledBorder.font");
+ Font titledBorderFont = titledBorder.getTitleFont();
+
+ // check default configuration
+ if (defaultFont == null) {
+ if (titledBorderFont == null) {
+ return;
+ }
+ else {
+ throw new RuntimeException("TitledBorder default font should be null");
+ }
+ }
+ if (!defaultFont.equals(titledBorderFont)) {
+ throw new RuntimeException("L&F default font " + defaultFont.toString()
+ + " differs from TitledBorder font " + titledBorderFont.toString());
+ }
+
+ // title font is explicitly specified
+ Font font = new Font("Dialog", Font.PLAIN, 10);
+ titledBorder.setTitleFont(font);
+ if (!font.equals(titledBorder.getTitleFont())) {
+ throw new RuntimeException("TitledBorder font should be " + font.toString());
+ }
+
+ // title Font is unspecified
+ titledBorder.setTitleFont(null);
+ if (!defaultFont.equals(titledBorder.getTitleFont())) {
+ throw new RuntimeException("L&F default font " + defaultFont.toString()
+ + " differs from TitledBorder font " + titledBorderFont.toString());
+ }
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/java2d/OpenGL/bug7181438.java Fri Jul 27 22:26:19 2012 -0700
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Transparency;
+import java.awt.image.BufferedImage;
+import java.awt.image.VolatileImage;
+
+/**
+ * @test
+ * @bug 7181438
+ * @summary Verifies that we get correct alpha, when we draw opaque
+ * BufferedImage to non opaque VolatileImage via intermediate opaque texture.
+ * @author Sergey Bylokhov
+ * @run main/othervm -Dsun.java2d.accthreshold=0 bug7181438
+ */
+public final class bug7181438 {
+
+ private static final int SIZE = 500;
+
+ public static void main(final String[] args) {
+
+ final BufferedImage bi = createBufferedImage();
+ final VolatileImage vi = createVolatileImage();
+ final Graphics s2dVi = vi.getGraphics();
+
+ //sw->texture->surface blit
+ s2dVi.drawImage(bi, 0, 0, null);
+
+ final BufferedImage results = vi.getSnapshot();
+ for (int i = 0; i < SIZE; ++i) {
+ for (int j = 0; j < SIZE; ++j) {
+ //Image should be opaque: (black color and alpha = 255)
+ if (results.getRGB(i, j) != 0xFF000000) {
+ throw new RuntimeException("Failed: Wrong alpha");
+ }
+ }
+ }
+ System.out.println("Passed");
+ }
+
+
+ private static VolatileImage createVolatileImage() {
+ final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+ final GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
+ return gc.createCompatibleVolatileImage(SIZE, SIZE,
+ Transparency.TRANSLUCENT);
+ }
+
+ private static BufferedImage createBufferedImage() {
+ final BufferedImage bi = new BufferedImage(SIZE, SIZE,
+ BufferedImage.TYPE_INT_RGB);
+ final Graphics bg = bi.getGraphics();
+ //Black color and alpha = 0
+ bg.setColor(new Color(0, 0, 0, 0));
+ bg.fillRect(0, 0, SIZE, SIZE);
+ bg.dispose();
+ return bi;
+ }
+}
--- a/langtools/.hgtags Fri Jul 27 16:53:15 2012 -0700
+++ b/langtools/.hgtags Fri Jul 27 22:26:19 2012 -0700
@@ -169,3 +169,5 @@
e111e4587ccada8eb93f72e834e378c76256f4b7 jdk8-b45
4ca5994971724731233735f055f33d4936fd11d3 jdk8-b46
7e6be2f239c9a4ac6dec280bd18ec296dd78e464 jdk8-b47
+afb0a523155727d42b1c773f783ff3a7cfab8e86 jdk8-b48
+c72c164ced676d3c360d99b1c52cc80940fc3122 jdk8-b49
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Jul 27 16:53:15 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Fri Jul 27 22:26:19 2012 -0700
@@ -746,6 +746,7 @@
pendingExits = prevPendingExits;
alive = true;
scanStat(tree.finalizer);
+ tree.finallyCanCompleteNormally = alive;
if (!alive) {
// discard exits and exceptions from try and finally
thrown = chk.union(thrown, thrownPrev);
@@ -764,7 +765,6 @@
}
alive = aliveEnd;
}
- tree.finallyCanCompleteNormally = alive;
} else {
thrown = chk.union(thrown, chk.diff(thrownInTry, caughtInTry));
alive = aliveEnd;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/DefiniteAssignment/T7181578.java Fri Jul 27 22:26:19 2012 -0700
@@ -0,0 +1,46 @@
+/*
+ * 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 7181578
+ * @summary javac reports uninitialized variable with nested try...finally blocks
+ *
+ * @compile T7181578.java
+ */
+class T7181578 {
+ String test(boolean cond) {
+ final String s;
+ try {
+ if (cond) {
+ try {
+ s = "";
+ return s;
+ } finally { }
+ } else {
+ s = "";
+ }
+ return s; // bug occurs here: mapping is always initialized
+ } finally { }
+ }
+}