Merge
This commit is contained in:
commit
70c24bcc29
@ -307,3 +307,4 @@ ea38728b4f4bdd8fd0d7a89b18069f521cf05013 jdk9-b61
|
||||
105d045a69174d870b69bfe471b3f2d05a9f8ecc jdk9-b62
|
||||
0b32ed628fa60e4ab99fb0b5866d648e16231f17 jdk9-b63
|
||||
82cf9aab9a83e41c8194ba01af9666afdb856cbe jdk9-b64
|
||||
7c31f9d7b932f7924f1258d52885b1c7c3e078c2 jdk9-b65
|
||||
|
@ -83,7 +83,6 @@ ACCEPTED_BIN_DIFF="
|
||||
./bin/jcmd
|
||||
./bin/jconsole
|
||||
./bin/jdb
|
||||
./bin/jhat
|
||||
./bin/jimage
|
||||
./bin/jinfo
|
||||
./bin/jjs
|
||||
@ -163,7 +162,6 @@ ACCEPTED_BIN_DIFF="
|
||||
./bin/jcmd
|
||||
./bin/jconsole
|
||||
./bin/jdb
|
||||
./bin/jhat
|
||||
./bin/jimage
|
||||
./bin/jinfo
|
||||
./bin/jjs
|
||||
@ -284,7 +282,6 @@ ACCEPTED_SMALL_SIZE_DIFF="
|
||||
./bin/jcmd
|
||||
./bin/jconsole
|
||||
./bin/jdb
|
||||
./bin/jhat
|
||||
./bin/jimage
|
||||
./bin/jinfo
|
||||
./bin/jjs
|
||||
@ -420,7 +417,6 @@ ACCEPTED_SMALL_SIZE_DIFF="
|
||||
./bin/jcmd
|
||||
./bin/jconsole
|
||||
./bin/jdb
|
||||
./bin/jhat
|
||||
./bin/jimage
|
||||
./bin/jinfo
|
||||
./bin/jjs
|
||||
@ -499,7 +495,6 @@ ACCEPTED_SMALL_SIZE_DIFF="
|
||||
./bin/jcmd.exe
|
||||
./bin/jconsole.exe
|
||||
./bin/jdb.exe
|
||||
./bin/jhat.exe
|
||||
./bin/jimage.exe
|
||||
./bin/jinfo.exe
|
||||
./bin/jjs.exe
|
||||
@ -579,7 +574,6 @@ ACCEPTED_BIN_DIFF="
|
||||
./bin/jcmd
|
||||
./bin/jconsole
|
||||
./bin/jdb
|
||||
./bin/jhat
|
||||
./bin/jimage
|
||||
./bin/jinfo
|
||||
./bin/jjs
|
||||
|
@ -307,3 +307,4 @@ d690f489ca0bb95a6157d996da2fa72bcbcf02ea jdk9-b61
|
||||
d27f7e0a7aca129969de23e9934408a31b4abf4c jdk9-b62
|
||||
0acac6937de7a0868f8c6f88b7d036d780abeee6 jdk9-b63
|
||||
0a5e5a7c3539e8bde73d9fe55750e49a49cb8dac jdk9-b64
|
||||
afc1e295c4bf83f9a5dd539c29914edd4a754a3f jdk9-b65
|
||||
|
@ -6,5 +6,7 @@
|
||||
^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/
|
||||
^src/share/tools/IdealGraphVisualizer/build/
|
||||
^src/share/tools/IdealGraphVisualizer/dist/
|
||||
^src/share/tools/IdealGraphVisualizer/nbplatform/
|
||||
.igv.log
|
||||
^.hgtip
|
||||
.DS_Store
|
||||
|
@ -467,3 +467,4 @@ ee878f3d6732856f7725c590312bfbe2ffa52cc7 jdk9-b58
|
||||
1eab877142cce6ca06e556e2ad0af688f993f00b jdk9-b62
|
||||
2ac9b6b36689b50d1562627067c92d51781b5684 jdk9-b63
|
||||
bf92b8db249cdfa5651ef954b6c0743a7e0ea4cd jdk9-b64
|
||||
e7ae94c4f35e940ea423fc1dd260435df34a77c0 jdk9-b65
|
||||
|
@ -27,9 +27,7 @@ package sun.jvm.hotspot;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.math.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.*;
|
||||
import java.util.*;
|
||||
|
||||
import sun.jvm.hotspot.code.*;
|
||||
@ -928,7 +926,7 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
|
||||
boolean shouldSkipOopMaps = false;
|
||||
if (curVFrame.isCompiledFrame()) {
|
||||
CodeBlob cb = VM.getVM().getCodeCache().findBlob(curFrame.getPC());
|
||||
OopMapSet maps = cb.getOopMaps();
|
||||
ImmutableOopMapSet maps = cb.getOopMaps();
|
||||
if ((maps == null) || (maps.getSize() == 0)) {
|
||||
shouldSkipOopMaps = true;
|
||||
}
|
||||
@ -977,7 +975,7 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
|
||||
} while (nextVFrame != null && nextFrame.equals(curFrame));
|
||||
|
||||
if (shouldSkipOopMaps) {
|
||||
anno = anno + "\nNOTE: null or empty OopMapSet found for this CodeBlob";
|
||||
anno = anno + "\nNOTE: null or empty ImmutableOopMapSet found for this CodeBlob";
|
||||
}
|
||||
|
||||
if (curFrame.getFP() != null) {
|
||||
|
@ -171,17 +171,17 @@ public class CodeBlob extends VMObject {
|
||||
public boolean isLockedByVM() { return false; }
|
||||
|
||||
/** OopMap for frame; can return null if none available */
|
||||
public OopMapSet getOopMaps() {
|
||||
public ImmutableOopMapSet getOopMaps() {
|
||||
Address oopMapsAddr = oopMapsField.getValue(addr);
|
||||
if (oopMapsAddr == null) {
|
||||
return null;
|
||||
}
|
||||
return new OopMapSet(oopMapsAddr);
|
||||
return new ImmutableOopMapSet(oopMapsAddr);
|
||||
}
|
||||
// FIXME: not yet implementable
|
||||
// void set_oop_maps(OopMapSet* p);
|
||||
// void set_oop_maps(ImmutableOopMapSet* p);
|
||||
|
||||
public OopMap getOopMapForReturnAddress(Address returnAddress, boolean debugging) {
|
||||
public ImmutableOopMap getOopMapForReturnAddress(Address returnAddress, boolean debugging) {
|
||||
Address pc = returnAddress;
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(getOopMaps() != null, "nope");
|
||||
|
@ -31,15 +31,9 @@ import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
|
||||
public class OopMap extends VMObject {
|
||||
private static CIntegerField pcOffsetField;
|
||||
private static CIntegerField omvCountField;
|
||||
private static CIntegerField omvDataSizeField;
|
||||
private static AddressField omvDataField;
|
||||
private static AddressField compressedWriteStreamField;
|
||||
|
||||
// This is actually a field inside class CompressedStream
|
||||
private static AddressField compressedStreamBufferField;
|
||||
public class ImmutableOopMap extends VMObject {
|
||||
private static CIntegerField countField;
|
||||
private static long classSize;
|
||||
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
@ -50,52 +44,24 @@ public class OopMap extends VMObject {
|
||||
}
|
||||
|
||||
private static void initialize(TypeDataBase db) {
|
||||
Type type = db.lookupType("OopMap");
|
||||
|
||||
pcOffsetField = type.getCIntegerField("_pc_offset");
|
||||
omvCountField = type.getCIntegerField("_omv_count");
|
||||
omvDataSizeField = type.getCIntegerField("_omv_data_size");
|
||||
omvDataField = type.getAddressField("_omv_data");
|
||||
compressedWriteStreamField = type.getAddressField("_write_stream");
|
||||
|
||||
type = db.lookupType("CompressedStream");
|
||||
compressedStreamBufferField = type.getAddressField("_buffer");
|
||||
Type type = db.lookupType("ImmutableOopMap");
|
||||
countField = type.getCIntegerField("_count");
|
||||
classSize = type.getSize();
|
||||
}
|
||||
|
||||
public OopMap(Address addr) {
|
||||
public ImmutableOopMap(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
public long getOffset() {
|
||||
return pcOffsetField.getValue(addr);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// Internals only below this point
|
||||
//
|
||||
|
||||
// Accessors -- package private for now
|
||||
Address getOMVData() {
|
||||
return omvDataField.getValue(addr);
|
||||
long getCount() {
|
||||
return countField.getValue(addr);
|
||||
}
|
||||
|
||||
long getOMVDataSize() {
|
||||
return omvDataSizeField.getValue(addr);
|
||||
}
|
||||
|
||||
long getOMVCount() {
|
||||
return omvCountField.getValue(addr);
|
||||
}
|
||||
|
||||
CompressedWriteStream getWriteStream() {
|
||||
Address wsAddr = compressedWriteStreamField.getValue(addr);
|
||||
if (wsAddr == null) {
|
||||
return null;
|
||||
}
|
||||
Address bufferAddr = compressedStreamBufferField.getValue(wsAddr);
|
||||
if (bufferAddr == null) {
|
||||
return null;
|
||||
}
|
||||
return new CompressedWriteStream(bufferAddr);
|
||||
public Address getData() {
|
||||
return addr.addOffsetTo(classSize);
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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.compiler;
|
||||
|
||||
import sun.jvm.hotspot.debugger.Address;
|
||||
import sun.jvm.hotspot.runtime.VM;
|
||||
import sun.jvm.hotspot.types.CIntegerField;
|
||||
import sun.jvm.hotspot.types.Type;
|
||||
import sun.jvm.hotspot.types.TypeDataBase;
|
||||
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
||||
public class ImmutableOopMapPair {
|
||||
private static CIntegerField pcField;
|
||||
private static CIntegerField offsetField;
|
||||
private static long classSize;
|
||||
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private final Address address;
|
||||
|
||||
public ImmutableOopMapPair(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public static long classSize() {
|
||||
return classSize;
|
||||
}
|
||||
|
||||
public int getPC() {
|
||||
return (int) pcField.getValue(address);
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return (int) offsetField.getValue(address);
|
||||
}
|
||||
|
||||
private static void initialize(TypeDataBase db) {
|
||||
Type type = db.lookupType("ImmutableOopMapPair");
|
||||
|
||||
pcField = type.getCIntegerField("_pc_offset");
|
||||
offsetField = type.getCIntegerField("_oopmap_offset");
|
||||
classSize = type.getSize();
|
||||
}
|
||||
}
|
@ -32,15 +32,17 @@ import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.utilities.*;
|
||||
|
||||
public class OopMapSet extends VMObject {
|
||||
private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.compiler.OopMapSet.DEBUG") != null;
|
||||
public class ImmutableOopMapSet extends VMObject {
|
||||
private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.compiler.ImmutableOopMapSet.DEBUG") != null;
|
||||
|
||||
private static CIntegerField omCountField;
|
||||
private static CIntegerField omSizeField;
|
||||
private static AddressField omDataField;
|
||||
private static CIntegerField countField;
|
||||
private static CIntegerField sizeField;
|
||||
private static AddressField omDataField;
|
||||
private static int REG_COUNT;
|
||||
private static int SAVED_ON_ENTRY_REG_COUNT;
|
||||
private static int C_SAVED_ON_ENTRY_REG_COUNT;
|
||||
private static long classSize;
|
||||
|
||||
private static class MyVisitor implements OopMapVisitor {
|
||||
private AddressVisitor addressVisitor;
|
||||
|
||||
@ -60,7 +62,7 @@ public class OopMapSet extends VMObject {
|
||||
if (VM.getVM().isClientCompiler()) {
|
||||
Assert.that(false, "should not reach here");
|
||||
} else if (VM.getVM().isServerCompiler() &&
|
||||
VM.getVM().useDerivedPointerTable()) {
|
||||
VM.getVM().useDerivedPointerTable()) {
|
||||
Assert.that(false, "FIXME: add derived pointer table");
|
||||
}
|
||||
}
|
||||
@ -75,18 +77,18 @@ public class OopMapSet extends VMObject {
|
||||
|
||||
static {
|
||||
VM.registerVMInitializedObserver(new Observer() {
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
public void update(Observable o, Object data) {
|
||||
initialize(VM.getVM().getTypeDataBase());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void initialize(TypeDataBase db) {
|
||||
Type type = db.lookupType("OopMapSet");
|
||||
Type type = db.lookupType("ImmutableOopMapSet");
|
||||
|
||||
omCountField = type.getCIntegerField("_om_count");
|
||||
omSizeField = type.getCIntegerField("_om_size");
|
||||
omDataField = type.getAddressField("_om_data");
|
||||
countField = type.getCIntegerField("_count");
|
||||
sizeField = type.getCIntegerField("_size");
|
||||
classSize = type.getSize();
|
||||
|
||||
if (!VM.getVM().isCore()) {
|
||||
REG_COUNT = db.lookupIntConstant("REG_COUNT").intValue();
|
||||
@ -97,29 +99,41 @@ public class OopMapSet extends VMObject {
|
||||
}
|
||||
}
|
||||
|
||||
public OopMapSet(Address addr) {
|
||||
public ImmutableOopMapSet(Address addr) {
|
||||
super(addr);
|
||||
}
|
||||
|
||||
/** Returns the number of OopMaps in this OopMapSet */
|
||||
/**
|
||||
* Returns the number of OopMaps in this ImmutableOopMapSet
|
||||
*/
|
||||
public long getSize() {
|
||||
return omCountField.getValue(addr);
|
||||
return countField.getValue(addr);
|
||||
}
|
||||
|
||||
/** returns the OopMap at a given index */
|
||||
public OopMap getMapAt(int index) {
|
||||
public int getCount() { return (int) countField.getValue(addr); }
|
||||
|
||||
private Address dataStart() {
|
||||
return (addr.addOffsetTo(ImmutableOopMapSet.classSize * getCount()));
|
||||
}
|
||||
|
||||
public ImmutableOopMapPair pairAt(int index) {
|
||||
Assert.that((index >= 0) && (index < getCount()), "bad index");
|
||||
return new ImmutableOopMapPair(addr.addOffsetTo(index * ImmutableOopMapPair.classSize()));
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the OopMap at a given index
|
||||
*/
|
||||
public ImmutableOopMap getMapAt(int index) {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that((index >= 0) && (index <= getSize()),"bad index");
|
||||
Assert.that((index >= 0) && (index <= getSize()), "bad index");
|
||||
}
|
||||
Address omDataAddr = omDataField.getValue(addr);
|
||||
Address oopMapAddr = omDataAddr.getAddressAt(index * VM.getVM().getAddressSize());
|
||||
if (oopMapAddr == null) {
|
||||
return null;
|
||||
}
|
||||
return new OopMap(oopMapAddr);
|
||||
|
||||
ImmutableOopMapPair immutableOopMapPair = pairAt(index);
|
||||
return getMap(immutableOopMapPair);
|
||||
}
|
||||
|
||||
public OopMap findMapAtOffset(long pcOffset, boolean debugging) {
|
||||
public ImmutableOopMap findMapAtOffset(long pcOffset, boolean debugging) {
|
||||
int i;
|
||||
int len = (int) getSize();
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
@ -129,7 +143,7 @@ public class OopMapSet extends VMObject {
|
||||
// Scan through oopmaps. Stop when current offset is either equal or greater
|
||||
// than the one we are looking for.
|
||||
for (i = 0; i < len; i++) {
|
||||
if (getMapAt(i).getOffset() >= pcOffset) {
|
||||
if (pairAt(i).getPC() >= pcOffset) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -137,7 +151,7 @@ public class OopMapSet extends VMObject {
|
||||
if (!debugging) {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(i < len, "oopmap not found for pcOffset = " + pcOffset + "; len = " + len);
|
||||
Assert.that(getMapAt(i).getOffset() == pcOffset, "oopmap not found");
|
||||
Assert.that(pairAt(i).getPC() == pcOffset, "oopmap not found");
|
||||
}
|
||||
} else {
|
||||
if (i == len) {
|
||||
@ -145,7 +159,7 @@ public class OopMapSet extends VMObject {
|
||||
System.out.println("can't find oopmap at " + pcOffset);
|
||||
System.out.print("Oopmap offsets are [ ");
|
||||
for (i = 0; i < len; i++) {
|
||||
System.out.print(getMapAt(i).getOffset());
|
||||
System.out.print(pairAt(i).getPC());
|
||||
}
|
||||
System.out.println("]");
|
||||
}
|
||||
@ -154,28 +168,32 @@ public class OopMapSet extends VMObject {
|
||||
}
|
||||
}
|
||||
|
||||
OopMap m = getMapAt(i);
|
||||
ImmutableOopMap m = getMapAt(i);
|
||||
return m;
|
||||
}
|
||||
|
||||
/** Visitation -- iterates through the frame for a compiled method.
|
||||
This is a very generic mechanism that requires the Address to be
|
||||
dereferenced by the callee. Other, more specialized, visitation
|
||||
mechanisms are given below. */
|
||||
/**
|
||||
* Visitation -- iterates through the frame for a compiled method.
|
||||
* This is a very generic mechanism that requires the Address to be
|
||||
* dereferenced by the callee. Other, more specialized, visitation
|
||||
* mechanisms are given below.
|
||||
*/
|
||||
public static void oopsDo(Frame fr, CodeBlob cb, RegisterMap regMap, AddressVisitor oopVisitor, boolean debugging) {
|
||||
allDo(fr, cb, regMap, new MyVisitor(oopVisitor), debugging);
|
||||
}
|
||||
|
||||
/** Note that there are 4 required AddressVisitors: one for oops,
|
||||
one for derived oops, one for values, and one for dead values */
|
||||
/**
|
||||
* Note that there are 4 required AddressVisitors: one for oops,
|
||||
* one for derived oops, one for values, and one for dead values
|
||||
*/
|
||||
public static void allDo(Frame fr, CodeBlob cb, RegisterMap regMap, OopMapVisitor visitor, boolean debugging) {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
CodeBlob tmpCB = VM.getVM().getCodeCache().findBlob(fr.getPC());
|
||||
Assert.that(tmpCB != null && cb.equals(tmpCB), "wrong codeblob passed in");
|
||||
}
|
||||
|
||||
OopMapSet maps = cb.getOopMaps();
|
||||
OopMap map = cb.getOopMapForReturnAddress(fr.getPC(), debugging);
|
||||
ImmutableOopMapSet maps = cb.getOopMaps();
|
||||
ImmutableOopMap map = cb.getOopMapForReturnAddress(fr.getPC(), debugging);
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(map != null, "no ptr map found");
|
||||
}
|
||||
@ -191,7 +209,7 @@ public class OopMapSet extends VMObject {
|
||||
omv = oms.getCurrent();
|
||||
Address loc = fr.oopMapRegToLocation(omv.getReg(), regMap);
|
||||
if (loc != null) {
|
||||
Address baseLoc = fr.oopMapRegToLocation(omv.getContentReg(), regMap);
|
||||
Address baseLoc = fr.oopMapRegToLocation(omv.getContentReg(), regMap);
|
||||
Address derivedLoc = loc;
|
||||
visitor.visitDerivedOopLocation(baseLoc, derivedLoc);
|
||||
}
|
||||
@ -199,8 +217,8 @@ public class OopMapSet extends VMObject {
|
||||
}
|
||||
|
||||
// We want narow oop, value and oop oop_types
|
||||
OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[] {
|
||||
OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.VALUE_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
|
||||
OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[]{
|
||||
OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.VALUE_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
|
||||
};
|
||||
|
||||
{
|
||||
@ -223,8 +241,10 @@ public class OopMapSet extends VMObject {
|
||||
}
|
||||
}
|
||||
|
||||
/** Update callee-saved register info for the following frame.
|
||||
Should only be called in non-core builds. */
|
||||
/**
|
||||
* Update callee-saved register info for the following frame.
|
||||
* Should only be called in non-core builds.
|
||||
*/
|
||||
public static void updateRegisterMap(Frame fr, CodeBlob cb, RegisterMap regMap, boolean debugging) {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(!VM.getVM().isCore(), "non-core builds only");
|
||||
@ -232,14 +252,14 @@ public class OopMapSet extends VMObject {
|
||||
|
||||
if (!VM.getVM().isDebugging()) {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
OopMapSet maps = cb.getOopMaps();
|
||||
Assert.that((maps != null) && (maps.getSize() > 0), "found null or empty OopMapSet for CodeBlob");
|
||||
ImmutableOopMapSet maps = cb.getOopMaps();
|
||||
Assert.that((maps != null) && (maps.getSize() > 0), "found null or empty ImmutableOopMapSet for CodeBlob");
|
||||
}
|
||||
} else {
|
||||
// Hack for some topmost frames that have been found with empty
|
||||
// OopMapSets. (Actually have not seen the null case, but don't
|
||||
// want to take any chances.) See HSDB.showThreadStackMemory().
|
||||
OopMapSet maps = cb.getOopMaps();
|
||||
ImmutableOopMapSet maps = cb.getOopMaps();
|
||||
if ((maps == null) || (maps.getSize() == 0)) {
|
||||
return;
|
||||
}
|
||||
@ -250,18 +270,18 @@ public class OopMapSet extends VMObject {
|
||||
|
||||
int nofCallee = 0;
|
||||
Address[] locs = new Address[2 * REG_COUNT + 1];
|
||||
VMReg [] regs = new VMReg [2 * REG_COUNT + 1];
|
||||
VMReg[] regs = new VMReg[2 * REG_COUNT + 1];
|
||||
// ("+1" because REG_COUNT might be zero)
|
||||
|
||||
// Scan through oopmap and find location of all callee-saved registers
|
||||
// (we do not do update in place, since info could be overwritten)
|
||||
OopMap map = cb.getOopMapForReturnAddress(fr.getPC(), debugging);
|
||||
ImmutableOopMap map = cb.getOopMapForReturnAddress(fr.getPC(), debugging);
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(map != null, "no ptr map found");
|
||||
}
|
||||
|
||||
OopMapValue omv = null;
|
||||
for(OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE); !oms.isDone(); oms.next()) {
|
||||
for (OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE); !oms.isDone(); oms.next()) {
|
||||
omv = oms.getCurrent();
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
Assert.that(nofCallee < 2 * REG_COUNT, "overflow");
|
||||
@ -276,8 +296,8 @@ public class OopMapSet extends VMObject {
|
||||
if (Assert.ASSERTS_ENABLED) {
|
||||
if (VM.getVM().isServerCompiler()) {
|
||||
Assert.that(!cb.isRuntimeStub() ||
|
||||
(nofCallee >= SAVED_ON_ENTRY_REG_COUNT || nofCallee >= C_SAVED_ON_ENTRY_REG_COUNT),
|
||||
"must save all");
|
||||
(nofCallee >= SAVED_ON_ENTRY_REG_COUNT || nofCallee >= C_SAVED_ON_ENTRY_REG_COUNT),
|
||||
"must save all");
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,4 +306,13 @@ public class OopMapSet extends VMObject {
|
||||
regMap.setLocation(regs[i], locs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public ImmutableOopMapPair getPairAt(int index) {
|
||||
return pairAt(index);
|
||||
}
|
||||
|
||||
public ImmutableOopMap getMap(ImmutableOopMapPair pair) {
|
||||
Assert.that(pair.getOffset() < (int) sizeField.getValue(), "boundary check");
|
||||
return new ImmutableOopMap(dataStart().addOffsetTo(pair.getOffset()));
|
||||
}
|
||||
}
|
@ -28,30 +28,26 @@ import sun.jvm.hotspot.code.*;
|
||||
|
||||
public class OopMapStream {
|
||||
private CompressedReadStream stream;
|
||||
private OopMap oopMap;
|
||||
private ImmutableOopMap oopMap;
|
||||
private int mask;
|
||||
private int size;
|
||||
private int position;
|
||||
private OopMapValue omv;
|
||||
private boolean omvValid;
|
||||
|
||||
public OopMapStream(OopMap oopMap) {
|
||||
public OopMapStream(ImmutableOopMap oopMap) {
|
||||
this(oopMap, (OopMapValue.OopTypes[]) null);
|
||||
}
|
||||
|
||||
public OopMapStream(OopMap oopMap, OopMapValue.OopTypes type) {
|
||||
public OopMapStream(ImmutableOopMap oopMap, OopMapValue.OopTypes type) {
|
||||
this(oopMap, (OopMapValue.OopTypes[]) null);
|
||||
mask = type.getValue();
|
||||
}
|
||||
|
||||
public OopMapStream(OopMap oopMap, OopMapValue.OopTypes[] types) {
|
||||
if (oopMap.getOMVData() == null) {
|
||||
stream = new CompressedReadStream(oopMap.getWriteStream().getBuffer());
|
||||
} else {
|
||||
stream = new CompressedReadStream(oopMap.getOMVData());
|
||||
}
|
||||
public OopMapStream(ImmutableOopMap oopMap, OopMapValue.OopTypes[] types) {
|
||||
stream = new CompressedReadStream(oopMap.getData());
|
||||
mask = computeMask(types);
|
||||
size = (int) oopMap.getOMVCount();
|
||||
size = (int) oopMap.getCount();
|
||||
position = 0;
|
||||
omv = new OopMapValue();
|
||||
omvValid = false;
|
||||
|
@ -26,14 +26,12 @@ package sun.jvm.hotspot.runtime;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import sun.jvm.hotspot.*;
|
||||
|
||||
import sun.jvm.hotspot.code.*;
|
||||
import sun.jvm.hotspot.compiler.*;
|
||||
import sun.jvm.hotspot.c1.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.interpreter.*;
|
||||
import sun.jvm.hotspot.oops.*;
|
||||
import sun.jvm.hotspot.runtime.sparc.SPARCFrame;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.utilities.*;
|
||||
|
||||
@ -626,7 +624,7 @@ public abstract class Frame implements Cloneable {
|
||||
Assert.that(cb != null, "sanity check");
|
||||
}
|
||||
if (cb.getOopMaps() != null) {
|
||||
OopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging());
|
||||
ImmutableOopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging());
|
||||
|
||||
// FIXME: add in traversal of argument oops (skipping this for
|
||||
// now until we have the other stuff tested)
|
||||
|
@ -358,7 +358,7 @@ public class PPC64Frame extends Frame {
|
||||
map.setIncludeArgumentOops(cb.callerMustGCArguments());
|
||||
|
||||
if (cb.getOopMaps() != null) {
|
||||
OopMapSet.updateRegisterMap(this, cb, map, true);
|
||||
ImmutableOopMapSet.updateRegisterMap(this, cb, map, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,6 @@
|
||||
|
||||
package sun.jvm.hotspot.runtime.sparc;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import sun.jvm.hotspot.asm.sparc.*;
|
||||
import sun.jvm.hotspot.code.*;
|
||||
import sun.jvm.hotspot.compiler.*;
|
||||
@ -34,7 +32,6 @@ import sun.jvm.hotspot.debugger.cdbg.*;
|
||||
import sun.jvm.hotspot.oops.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.runtime.posix.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.utilities.*;
|
||||
|
||||
/** Specialization of and implementation of abstract methods of the
|
||||
@ -592,7 +589,7 @@ public class SPARCFrame extends Frame {
|
||||
map.setIncludeArgumentOops(true);
|
||||
}
|
||||
if (cb.getOopMaps() != null) {
|
||||
OopMapSet.updateRegisterMap(this, cb, map, VM.getVM().isDebugging());
|
||||
ImmutableOopMapSet.updateRegisterMap(this, cb, map, VM.getVM().isDebugging());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ public class X86Frame extends Frame {
|
||||
map.setIncludeArgumentOops(cb.callerMustGCArguments());
|
||||
|
||||
if (cb.getOopMaps() != null) {
|
||||
OopMapSet.updateRegisterMap(this, cb, map, true);
|
||||
ImmutableOopMapSet.updateRegisterMap(this, cb, map, true);
|
||||
}
|
||||
|
||||
// Since the prolog does the save and restore of EBP there is no oopmap
|
||||
|
@ -31,11 +31,9 @@ import sun.jvm.hotspot.code.*;
|
||||
import sun.jvm.hotspot.compiler.*;
|
||||
import sun.jvm.hotspot.debugger.*;
|
||||
import sun.jvm.hotspot.interpreter.*;
|
||||
import sun.jvm.hotspot.memory.*;
|
||||
import sun.jvm.hotspot.oops.*;
|
||||
import sun.jvm.hotspot.runtime.*;
|
||||
import sun.jvm.hotspot.tools.jcore.*;
|
||||
import sun.jvm.hotspot.types.*;
|
||||
import sun.jvm.hotspot.utilities.*;
|
||||
|
||||
public class HTMLGenerator implements /* imports */ ClassConstants {
|
||||
@ -887,7 +885,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
|
||||
private Formatter buf;
|
||||
private SymbolFinder symFinder = createSymbolFinder();
|
||||
private long pc;
|
||||
private OopMapSet oms;
|
||||
private ImmutableOopMapSet oms;
|
||||
private CodeBlob blob;
|
||||
private NMethod nmethod;
|
||||
|
||||
@ -954,13 +952,13 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
|
||||
|
||||
if (oms != null) {
|
||||
long base = addressToLong(blob.codeBegin());
|
||||
for (int i = 0, imax = (int)oms.getSize(); i < imax; i++) {
|
||||
OopMap om = oms.getMapAt(i);
|
||||
long omspc = base + om.getOffset();
|
||||
for (int i = 0, imax = oms.getCount(); i < imax; i++) {
|
||||
ImmutableOopMapPair pair = oms.getPairAt(i);
|
||||
long omspc = base + pair.getPC();
|
||||
if (omspc > pc) {
|
||||
if (omspc <= endPc) {
|
||||
buf.br();
|
||||
buf.append(genOopMapInfo(om));
|
||||
buf.append(genOopMapInfo(oms.getMap(pair)));
|
||||
// st.move_to(column);
|
||||
// visitor.print("; ");
|
||||
// om.print_on(st);
|
||||
@ -1167,7 +1165,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
|
||||
}
|
||||
}
|
||||
|
||||
protected String genHTMLForOopMap(OopMap map) {
|
||||
protected String genHTMLForOopMap(ImmutableOopMap map) {
|
||||
final int stack0 = VMRegImpl.getStack0().getValue();
|
||||
Formatter buf = new Formatter(genHTML);
|
||||
|
||||
@ -1237,11 +1235,11 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
|
||||
|
||||
|
||||
protected String genOopMapInfo(NMethod nmethod, PCDesc pcDesc) {
|
||||
OopMapSet mapSet = nmethod.getOopMaps();
|
||||
ImmutableOopMapSet mapSet = nmethod.getOopMaps();
|
||||
if (mapSet == null || (mapSet.getSize() <= 0))
|
||||
return "";
|
||||
int pcOffset = pcDesc.getPCOffset();
|
||||
OopMap map = mapSet.findMapAtOffset(pcOffset, VM.getVM().isDebugging());
|
||||
ImmutableOopMap map = mapSet.findMapAtOffset(pcOffset, VM.getVM().isDebugging());
|
||||
if (map == null) {
|
||||
throw new IllegalArgumentException("no oopmap at safepoint!");
|
||||
}
|
||||
@ -1249,7 +1247,7 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
|
||||
return genOopMapInfo(map);
|
||||
}
|
||||
|
||||
protected String genOopMapInfo(OopMap map) {
|
||||
protected String genOopMapInfo(ImmutableOopMap map) {
|
||||
Formatter buf = new Formatter(genHTML);
|
||||
buf.beginTag("pre");
|
||||
buf.append("OopMap: ");
|
||||
|
@ -421,7 +421,40 @@ reg_class any_reg(
|
||||
);
|
||||
|
||||
// Class for all non-special integer registers
|
||||
reg_class no_special_reg32(
|
||||
reg_class no_special_reg32_no_fp(
|
||||
R0,
|
||||
R1,
|
||||
R2,
|
||||
R3,
|
||||
R4,
|
||||
R5,
|
||||
R6,
|
||||
R7,
|
||||
R10,
|
||||
R11,
|
||||
R12, // rmethod
|
||||
R13,
|
||||
R14,
|
||||
R15,
|
||||
R16,
|
||||
R17,
|
||||
R18,
|
||||
R19,
|
||||
R20,
|
||||
R21,
|
||||
R22,
|
||||
R23,
|
||||
R24,
|
||||
R25,
|
||||
R26
|
||||
/* R27, */ // heapbase
|
||||
/* R28, */ // thread
|
||||
/* R29, */ // fp
|
||||
/* R30, */ // lr
|
||||
/* R31 */ // sp
|
||||
);
|
||||
|
||||
reg_class no_special_reg32_with_fp(
|
||||
R0,
|
||||
R1,
|
||||
R2,
|
||||
@ -454,8 +487,43 @@ reg_class no_special_reg32(
|
||||
/* R31 */ // sp
|
||||
);
|
||||
|
||||
reg_class_dynamic no_special_reg32(no_special_reg32_no_fp, no_special_reg32_with_fp, %{ PreserveFramePointer %});
|
||||
|
||||
// Class for all non-special long integer registers
|
||||
reg_class no_special_reg(
|
||||
reg_class no_special_reg_no_fp(
|
||||
R0, R0_H,
|
||||
R1, R1_H,
|
||||
R2, R2_H,
|
||||
R3, R3_H,
|
||||
R4, R4_H,
|
||||
R5, R5_H,
|
||||
R6, R6_H,
|
||||
R7, R7_H,
|
||||
R10, R10_H,
|
||||
R11, R11_H,
|
||||
R12, R12_H, // rmethod
|
||||
R13, R13_H,
|
||||
R14, R14_H,
|
||||
R15, R15_H,
|
||||
R16, R16_H,
|
||||
R17, R17_H,
|
||||
R18, R18_H,
|
||||
R19, R19_H,
|
||||
R20, R20_H,
|
||||
R21, R21_H,
|
||||
R22, R22_H,
|
||||
R23, R23_H,
|
||||
R24, R24_H,
|
||||
R25, R25_H,
|
||||
R26, R26_H,
|
||||
/* R27, R27_H, */ // heapbase
|
||||
/* R28, R28_H, */ // thread
|
||||
/* R29, R29_H, */ // fp
|
||||
/* R30, R30_H, */ // lr
|
||||
/* R31, R31_H */ // sp
|
||||
);
|
||||
|
||||
reg_class no_special_reg_with_fp(
|
||||
R0, R0_H,
|
||||
R1, R1_H,
|
||||
R2, R2_H,
|
||||
@ -488,6 +556,8 @@ reg_class no_special_reg(
|
||||
/* R31, R31_H */ // sp
|
||||
);
|
||||
|
||||
reg_class_dynamic no_special_reg(no_special_reg_no_fp, no_special_reg_with_fp, %{ PreserveFramePointer %});
|
||||
|
||||
// Class for 64 bit register r0
|
||||
reg_class r0_reg(
|
||||
R0, R0_H
|
||||
@ -1637,12 +1707,7 @@ bool needs_releasing_store(const Node *n)
|
||||
int MachCallStaticJavaNode::ret_addr_offset()
|
||||
{
|
||||
// call should be a simple bl
|
||||
// unless this is a method handle invoke in which case it is
|
||||
// mov(rfp, sp), bl, mov(sp, rfp)
|
||||
int off = 4;
|
||||
if (_method_handle_invoke) {
|
||||
off += 4;
|
||||
}
|
||||
return off;
|
||||
}
|
||||
|
||||
@ -1753,14 +1818,13 @@ void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
|
||||
if (C->need_stack_bang(framesize))
|
||||
st->print("# stack bang size=%d\n\t", framesize);
|
||||
|
||||
if (framesize == 0) {
|
||||
// Is this even possible?
|
||||
st->print("stp lr, rfp, [sp, #%d]!", -(2 * wordSize));
|
||||
} else if (framesize < ((1 << 9) + 2 * wordSize)) {
|
||||
if (framesize < ((1 << 9) + 2 * wordSize)) {
|
||||
st->print("sub sp, sp, #%d\n\t", framesize);
|
||||
st->print("stp rfp, lr, [sp, #%d]", framesize - 2 * wordSize);
|
||||
if (PreserveFramePointer) st->print("\n\tadd rfp, sp, #%d", framesize - 2 * wordSize);
|
||||
} else {
|
||||
st->print("stp lr, rfp, [sp, #%d]!\n\t", -(2 * wordSize));
|
||||
if (PreserveFramePointer) st->print("mov rfp, sp\n\t");
|
||||
st->print("mov rscratch1, #%d\n\t", framesize - 2 * wordSize);
|
||||
st->print("sub sp, sp, rscratch1");
|
||||
}
|
||||
@ -3517,34 +3581,6 @@ encode %{
|
||||
}
|
||||
%}
|
||||
|
||||
enc_class aarch64_enc_java_handle_call(method meth) %{
|
||||
MacroAssembler _masm(&cbuf);
|
||||
relocInfo::relocType reloc;
|
||||
|
||||
// RFP is preserved across all calls, even compiled calls.
|
||||
// Use it to preserve SP.
|
||||
__ mov(rfp, sp);
|
||||
|
||||
const int start_offset = __ offset();
|
||||
address addr = (address)$meth$$method;
|
||||
if (!_method) {
|
||||
// A call to a runtime wrapper, e.g. new, new_typeArray_Java, uncommon_trap.
|
||||
__ trampoline_call(Address(addr, relocInfo::runtime_call_type), &cbuf);
|
||||
} else if (_optimized_virtual) {
|
||||
__ trampoline_call(Address(addr, relocInfo::opt_virtual_call_type), &cbuf);
|
||||
} else {
|
||||
__ trampoline_call(Address(addr, relocInfo::static_call_type), &cbuf);
|
||||
}
|
||||
|
||||
if (_method) {
|
||||
// Emit stub for static call
|
||||
CompiledStaticCall::emit_to_interp_stub(cbuf);
|
||||
}
|
||||
|
||||
// now restore sp
|
||||
__ mov(sp, rfp);
|
||||
%}
|
||||
|
||||
enc_class aarch64_enc_java_dynamic_call(method meth) %{
|
||||
MacroAssembler _masm(&cbuf);
|
||||
__ ic_call((address)$meth$$method);
|
||||
@ -12561,8 +12597,6 @@ instruct CallStaticJavaDirect(method meth)
|
||||
|
||||
effect(USE meth);
|
||||
|
||||
predicate(!((CallStaticJavaNode*)n)->is_method_handle_invoke());
|
||||
|
||||
ins_cost(CALL_COST);
|
||||
|
||||
format %{ "call,static $meth \t// ==> " %}
|
||||
@ -12575,26 +12609,6 @@ instruct CallStaticJavaDirect(method meth)
|
||||
|
||||
// TO HERE
|
||||
|
||||
// Call Java Static Instruction (method handle version)
|
||||
|
||||
instruct CallStaticJavaDirectHandle(method meth, iRegP_FP reg_mh_save)
|
||||
%{
|
||||
match(CallStaticJava);
|
||||
|
||||
effect(USE meth);
|
||||
|
||||
predicate(((CallStaticJavaNode*)n)->is_method_handle_invoke());
|
||||
|
||||
ins_cost(CALL_COST);
|
||||
|
||||
format %{ "call,static $meth \t// (methodhandle) ==> " %}
|
||||
|
||||
ins_encode( aarch64_enc_java_handle_call(meth),
|
||||
aarch64_enc_call_epilog );
|
||||
|
||||
ins_pipe(pipe_class_call);
|
||||
%}
|
||||
|
||||
// Call Java Dynamic Instruction
|
||||
instruct CallDynamicJavaDirect(method meth)
|
||||
%{
|
||||
|
@ -346,8 +346,7 @@ LIR_Opr FrameMap::stack_pointer() {
|
||||
|
||||
// JSR 292
|
||||
LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() {
|
||||
// assert(rfp == rbp_mh_SP_save, "must be same register");
|
||||
return rfp_opr;
|
||||
return LIR_OprFact::illegalOpr; // Not needed on aarch64
|
||||
}
|
||||
|
||||
|
||||
|
@ -443,18 +443,8 @@ OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) {
|
||||
restore_live_registers(sasm, id != handle_exception_nofpu_id);
|
||||
break;
|
||||
case handle_exception_from_callee_id:
|
||||
// Pop the return address since we are possibly changing SP (restoring from BP).
|
||||
// Pop the return address.
|
||||
__ leave();
|
||||
|
||||
// Restore SP from FP if the exception PC is a method handle call site.
|
||||
{
|
||||
Label nope;
|
||||
__ ldrw(rscratch1, Address(rthread, JavaThread::is_method_handle_return_offset()));
|
||||
__ cbzw(rscratch1, nope);
|
||||
__ mov(sp, rfp);
|
||||
__ bind(nope);
|
||||
}
|
||||
|
||||
__ ret(lr); // jump to exception handler
|
||||
break;
|
||||
default: ShouldNotReachHere();
|
||||
@ -514,14 +504,6 @@ void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
|
||||
|
||||
__ verify_not_null_oop(exception_oop);
|
||||
|
||||
{
|
||||
Label foo;
|
||||
__ ldrw(rscratch1, Address(rthread, JavaThread::is_method_handle_return_offset()));
|
||||
__ cbzw(rscratch1, foo);
|
||||
__ mov(sp, rfp);
|
||||
__ bind(foo);
|
||||
}
|
||||
|
||||
// continue at exception handler (return address removed)
|
||||
// note: do *not* remove arguments when unwinding the
|
||||
// activation since the caller assumes having
|
||||
|
@ -223,7 +223,8 @@ bool frame::safe_for_sender(JavaThread *thread) {
|
||||
if (sender_blob->is_nmethod()) {
|
||||
nmethod* nm = sender_blob->as_nmethod_or_null();
|
||||
if (nm != NULL) {
|
||||
if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc)) {
|
||||
if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc) ||
|
||||
nm->method()->is_method_handle_intrinsic()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -389,10 +390,9 @@ frame frame::sender_for_entry_frame(RegisterMap* map) const {
|
||||
// frame::verify_deopt_original_pc
|
||||
//
|
||||
// Verifies the calculated original PC of a deoptimization PC for the
|
||||
// given unextended SP. The unextended SP might also be the saved SP
|
||||
// for MethodHandle call sites.
|
||||
// given unextended SP.
|
||||
#ifdef ASSERT
|
||||
void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return) {
|
||||
void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp) {
|
||||
frame fr;
|
||||
|
||||
// This is ugly but it's better than to change {get,set}_original_pc
|
||||
@ -402,33 +402,23 @@ void frame::verify_deopt_original_pc(nmethod* nm, intptr_t* unextended_sp, bool
|
||||
|
||||
address original_pc = nm->get_original_pc(&fr);
|
||||
assert(nm->insts_contains(original_pc), "original PC must be in nmethod");
|
||||
assert(nm->is_method_handle_return(original_pc) == is_method_handle_return, "must be");
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// frame::adjust_unextended_sp
|
||||
void frame::adjust_unextended_sp() {
|
||||
// If we are returning to a compiled MethodHandle call site, the
|
||||
// saved_fp will in fact be a saved value of the unextended SP. The
|
||||
// simplest way to tell whether we are returning to such a call site
|
||||
// is as follows:
|
||||
// On aarch64, sites calling method handle intrinsics and lambda forms are treated
|
||||
// as any other call site. Therefore, no special action is needed when we are
|
||||
// returning to any of these call sites.
|
||||
|
||||
nmethod* sender_nm = (_cb == NULL) ? NULL : _cb->as_nmethod_or_null();
|
||||
if (sender_nm != NULL) {
|
||||
// If the sender PC is a deoptimization point, get the original
|
||||
// PC. For MethodHandle call site the unextended_sp is stored in
|
||||
// saved_fp.
|
||||
if (sender_nm->is_deopt_mh_entry(_pc)) {
|
||||
DEBUG_ONLY(verify_deopt_mh_original_pc(sender_nm, _fp));
|
||||
_unextended_sp = _fp;
|
||||
}
|
||||
else if (sender_nm->is_deopt_entry(_pc)) {
|
||||
// If the sender PC is a deoptimization point, get the original PC.
|
||||
if (sender_nm->is_deopt_entry(_pc) ||
|
||||
sender_nm->is_deopt_mh_entry(_pc)) {
|
||||
DEBUG_ONLY(verify_deopt_original_pc(sender_nm, _unextended_sp));
|
||||
}
|
||||
else if (sender_nm->is_method_handle_return(_pc)) {
|
||||
_unextended_sp = _fp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,10 +167,7 @@
|
||||
|
||||
#ifdef ASSERT
|
||||
// Used in frame::sender_for_{interpreter,compiled}_frame
|
||||
static void verify_deopt_original_pc( nmethod* nm, intptr_t* unextended_sp, bool is_method_handle_return = false);
|
||||
static void verify_deopt_mh_original_pc(nmethod* nm, intptr_t* unextended_sp) {
|
||||
verify_deopt_original_pc(nm, unextended_sp, true);
|
||||
}
|
||||
static void verify_deopt_original_pc( nmethod* nm, intptr_t* unextended_sp);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
@ -47,12 +47,6 @@ static int spin;
|
||||
inline void frame::init(intptr_t* sp, intptr_t* fp, address pc) {
|
||||
intptr_t a = intptr_t(sp);
|
||||
intptr_t b = intptr_t(fp);
|
||||
#ifndef PRODUCT
|
||||
if (fp)
|
||||
if (sp > fp || (fp - sp > 0x100000))
|
||||
for(;;)
|
||||
asm("nop");
|
||||
#endif
|
||||
_sp = sp;
|
||||
_unextended_sp = sp;
|
||||
_fp = fp;
|
||||
|
@ -3788,14 +3788,14 @@ void MacroAssembler::adrp(Register reg1, const Address &dest, unsigned long &byt
|
||||
}
|
||||
|
||||
void MacroAssembler::build_frame(int framesize) {
|
||||
if (framesize == 0) {
|
||||
// Is this even possible?
|
||||
stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
|
||||
} else if (framesize < ((1 << 9) + 2 * wordSize)) {
|
||||
assert(framesize > 0, "framesize must be > 0");
|
||||
if (framesize < ((1 << 9) + 2 * wordSize)) {
|
||||
sub(sp, sp, framesize);
|
||||
stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
|
||||
if (PreserveFramePointer) add(rfp, sp, framesize - 2 * wordSize);
|
||||
} else {
|
||||
stp(rfp, lr, Address(pre(sp, -2 * wordSize)));
|
||||
if (PreserveFramePointer) mov(rfp, sp);
|
||||
if (framesize < ((1 << 12) + 2 * wordSize))
|
||||
sub(sp, sp, framesize - 2 * wordSize);
|
||||
else {
|
||||
@ -3806,9 +3806,8 @@ void MacroAssembler::build_frame(int framesize) {
|
||||
}
|
||||
|
||||
void MacroAssembler::remove_frame(int framesize) {
|
||||
if (framesize == 0) {
|
||||
ldp(rfp, lr, Address(post(sp, 2 * wordSize)));
|
||||
} else if (framesize < ((1 << 9) + 2 * wordSize)) {
|
||||
assert(framesize > 0, "framesize must be > 0");
|
||||
if (framesize < ((1 << 9) + 2 * wordSize)) {
|
||||
ldp(rfp, lr, Address(sp, framesize - 2 * wordSize));
|
||||
add(sp, sp, framesize);
|
||||
} else {
|
||||
|
@ -149,7 +149,3 @@ REGISTER_DEFINITION(Register, rthread);
|
||||
REGISTER_DEFINITION(Register, rheapbase);
|
||||
|
||||
REGISTER_DEFINITION(Register, r31_sp);
|
||||
|
||||
// TODO : x86 uses rbp to save SP in method handle code
|
||||
// we may need to do the same with fp
|
||||
// REGISTER_DEFINITION(Register, rbp_mh_SP_save)
|
||||
|
@ -2995,21 +2995,6 @@ void OptoRuntime::generate_exception_blob() {
|
||||
|
||||
// r0: exception handler
|
||||
|
||||
// Restore SP from BP if the exception PC is a MethodHandle call site.
|
||||
__ ldrw(rscratch1, Address(rthread, JavaThread::is_method_handle_return_offset()));
|
||||
// n.b. Intel uses special register rbp_mh_SP_save here but we will
|
||||
// just hard wire rfp
|
||||
__ cmpw(rscratch1, zr);
|
||||
// the obvious way to conditionally copy rfp to sp if NE
|
||||
// Label skip;
|
||||
// __ br(Assembler::EQ, skip);
|
||||
// __ mov(sp, rfp);
|
||||
// __ bind(skip);
|
||||
// same but branchless
|
||||
__ mov(rscratch1, sp);
|
||||
__ csel(rscratch1, rfp, rscratch1, Assembler::NE);
|
||||
__ mov(sp, rscratch1);
|
||||
|
||||
// We have a handler in r0 (could be deopt blob).
|
||||
__ mov(r8, r0);
|
||||
|
||||
|
@ -1891,7 +1891,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
address start = __ pc();
|
||||
__ enter();
|
||||
|
||||
__ mov(rscratch1, len_reg);
|
||||
__ mov(rscratch2, len_reg);
|
||||
__ ldrw(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
|
||||
|
||||
__ ld1(v0, __ T16B, rvec);
|
||||
|
@ -629,7 +629,7 @@ void VM_Version::config_dscr() {
|
||||
// Print the detection code.
|
||||
if (PrintAssembly) {
|
||||
ttyLocker ttyl;
|
||||
tty->print_cr("Decoding dscr configuration stub at " INTPTR_FORMAT " before execution:", code);
|
||||
tty->print_cr("Decoding dscr configuration stub at " INTPTR_FORMAT " before execution:", p2i(code));
|
||||
Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -438,7 +438,7 @@ class ArrayAddress VALUE_OBJ_CLASS_SPEC {
|
||||
|
||||
};
|
||||
|
||||
const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY( 512 / wordSize);
|
||||
const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY( 512*2 / wordSize);
|
||||
|
||||
// The Intel x86/Amd64 Assembler: Pure assembler doing NO optimizations on the instruction
|
||||
// level (e.g. mov rax, 0 is not translated into xor rax, rax!); i.e., what you write
|
||||
@ -503,7 +503,8 @@ class Assembler : public AbstractAssembler {
|
||||
REX_WRXB = 0x4F,
|
||||
|
||||
VEX_3bytes = 0xC4,
|
||||
VEX_2bytes = 0xC5
|
||||
VEX_2bytes = 0xC5,
|
||||
EVEX_4bytes = 0x62
|
||||
};
|
||||
|
||||
enum VexPrefix {
|
||||
@ -513,6 +514,14 @@ class Assembler : public AbstractAssembler {
|
||||
VEX_W = 0x80
|
||||
};
|
||||
|
||||
enum ExexPrefix {
|
||||
EVEX_F = 0x04,
|
||||
EVEX_V = 0x08,
|
||||
EVEX_Rb = 0x10,
|
||||
EVEX_X = 0x40,
|
||||
EVEX_Z = 0x80
|
||||
};
|
||||
|
||||
enum VexSimdPrefix {
|
||||
VEX_SIMD_NONE = 0x0,
|
||||
VEX_SIMD_66 = 0x1,
|
||||
@ -527,6 +536,37 @@ class Assembler : public AbstractAssembler {
|
||||
VEX_OPCODE_0F_3A = 0x3
|
||||
};
|
||||
|
||||
enum AvxVectorLen {
|
||||
AVX_128bit = 0x0,
|
||||
AVX_256bit = 0x1,
|
||||
AVX_512bit = 0x2,
|
||||
AVX_NoVec = 0x4
|
||||
};
|
||||
|
||||
enum EvexTupleType {
|
||||
EVEX_FV = 0,
|
||||
EVEX_HV = 4,
|
||||
EVEX_FVM = 6,
|
||||
EVEX_T1S = 7,
|
||||
EVEX_T1F = 11,
|
||||
EVEX_T2 = 13,
|
||||
EVEX_T4 = 15,
|
||||
EVEX_T8 = 17,
|
||||
EVEX_HVM = 18,
|
||||
EVEX_QVM = 19,
|
||||
EVEX_OVM = 20,
|
||||
EVEX_M128 = 21,
|
||||
EVEX_DUP = 22,
|
||||
EVEX_ETUP = 23
|
||||
};
|
||||
|
||||
enum EvexInputSizeInBits {
|
||||
EVEX_8bit = 0,
|
||||
EVEX_16bit = 1,
|
||||
EVEX_32bit = 2,
|
||||
EVEX_64bit = 3
|
||||
};
|
||||
|
||||
enum WhichOperand {
|
||||
// input to locate_operand, and format code for relocations
|
||||
imm_operand = 0, // embedded 32-bit|64-bit immediate operand
|
||||
@ -554,6 +594,11 @@ class Assembler : public AbstractAssembler {
|
||||
|
||||
private:
|
||||
|
||||
int evex_encoding;
|
||||
int input_size_in_bits;
|
||||
int avx_vector_len;
|
||||
int tuple_type;
|
||||
bool is_evex_instruction;
|
||||
|
||||
// 64bit prefixes
|
||||
int prefix_and_encode(int reg_enc, bool byteinst = false);
|
||||
@ -580,108 +625,143 @@ private:
|
||||
|
||||
void vex_prefix(bool vex_r, bool vex_b, bool vex_x, bool vex_w,
|
||||
int nds_enc, VexSimdPrefix pre, VexOpcode opc,
|
||||
bool vector256);
|
||||
int vector_len);
|
||||
|
||||
void evex_prefix(bool vex_r, bool vex_b, bool vex_x, bool vex_w, bool evex_r, bool evex_v,
|
||||
int nds_enc, VexSimdPrefix pre, VexOpcode opc,
|
||||
bool is_extended_context, bool is_merge_context,
|
||||
int vector_len, bool no_mask_reg );
|
||||
|
||||
void vex_prefix(Address adr, int nds_enc, int xreg_enc,
|
||||
VexSimdPrefix pre, VexOpcode opc,
|
||||
bool vex_w, bool vector256);
|
||||
bool vex_w, int vector_len,
|
||||
bool legacy_mode = false, bool no_mask_reg = false);
|
||||
|
||||
void vex_prefix(XMMRegister dst, XMMRegister nds, Address src,
|
||||
VexSimdPrefix pre, bool vector256 = false) {
|
||||
VexSimdPrefix pre, int vector_len = AVX_128bit,
|
||||
bool no_mask_reg = false, bool legacy_mode = false) {
|
||||
int dst_enc = dst->encoding();
|
||||
int nds_enc = nds->is_valid() ? nds->encoding() : 0;
|
||||
vex_prefix(src, nds_enc, dst_enc, pre, VEX_OPCODE_0F, false, vector256);
|
||||
vex_prefix(src, nds_enc, dst_enc, pre, VEX_OPCODE_0F, false, vector_len, legacy_mode, no_mask_reg);
|
||||
}
|
||||
|
||||
void vex_prefix_0F38(Register dst, Register nds, Address src) {
|
||||
void vex_prefix_q(XMMRegister dst, XMMRegister nds, Address src,
|
||||
VexSimdPrefix pre, int vector_len = AVX_128bit,
|
||||
bool no_mask_reg = false) {
|
||||
int dst_enc = dst->encoding();
|
||||
int nds_enc = nds->is_valid() ? nds->encoding() : 0;
|
||||
vex_prefix(src, nds_enc, dst_enc, pre, VEX_OPCODE_0F, true, vector_len, false, no_mask_reg);
|
||||
}
|
||||
|
||||
void vex_prefix_0F38(Register dst, Register nds, Address src, bool no_mask_reg = false) {
|
||||
bool vex_w = false;
|
||||
bool vector256 = false;
|
||||
int vector_len = AVX_128bit;
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(),
|
||||
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector256);
|
||||
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w,
|
||||
vector_len, no_mask_reg);
|
||||
}
|
||||
|
||||
void vex_prefix_0F38_q(Register dst, Register nds, Address src) {
|
||||
void vex_prefix_0F38_q(Register dst, Register nds, Address src, bool no_mask_reg = false) {
|
||||
bool vex_w = true;
|
||||
bool vector256 = false;
|
||||
int vector_len = AVX_128bit;
|
||||
vex_prefix(src, nds->encoding(), dst->encoding(),
|
||||
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector256);
|
||||
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w,
|
||||
vector_len, no_mask_reg);
|
||||
}
|
||||
int vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc,
|
||||
VexSimdPrefix pre, VexOpcode opc,
|
||||
bool vex_w, bool vector256);
|
||||
bool vex_w, int vector_len,
|
||||
bool legacy_mode, bool no_mask_reg);
|
||||
|
||||
int vex_prefix_0F38_and_encode(Register dst, Register nds, Register src) {
|
||||
int vex_prefix_0F38_and_encode(Register dst, Register nds, Register src, bool no_mask_reg = false) {
|
||||
bool vex_w = false;
|
||||
bool vector256 = false;
|
||||
int vector_len = AVX_128bit;
|
||||
return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
|
||||
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector256);
|
||||
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector_len,
|
||||
false, no_mask_reg);
|
||||
}
|
||||
int vex_prefix_0F38_and_encode_q(Register dst, Register nds, Register src) {
|
||||
int vex_prefix_0F38_and_encode_q(Register dst, Register nds, Register src, bool no_mask_reg = false) {
|
||||
bool vex_w = true;
|
||||
bool vector256 = false;
|
||||
int vector_len = AVX_128bit;
|
||||
return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
|
||||
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector256);
|
||||
VEX_SIMD_NONE, VEX_OPCODE_0F_38, vex_w, vector_len,
|
||||
false, no_mask_reg);
|
||||
}
|
||||
int vex_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src,
|
||||
VexSimdPrefix pre, bool vector256 = false,
|
||||
VexOpcode opc = VEX_OPCODE_0F) {
|
||||
VexSimdPrefix pre, int vector_len = AVX_128bit,
|
||||
VexOpcode opc = VEX_OPCODE_0F, bool legacy_mode = false,
|
||||
bool no_mask_reg = false) {
|
||||
int src_enc = src->encoding();
|
||||
int dst_enc = dst->encoding();
|
||||
int nds_enc = nds->is_valid() ? nds->encoding() : 0;
|
||||
return vex_prefix_and_encode(dst_enc, nds_enc, src_enc, pre, opc, false, vector256);
|
||||
return vex_prefix_and_encode(dst_enc, nds_enc, src_enc, pre, opc, false, vector_len, legacy_mode, no_mask_reg);
|
||||
}
|
||||
|
||||
void simd_prefix(XMMRegister xreg, XMMRegister nds, Address adr,
|
||||
VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F,
|
||||
bool rex_w = false, bool vector256 = false);
|
||||
VexSimdPrefix pre, bool no_mask_reg, VexOpcode opc = VEX_OPCODE_0F,
|
||||
bool rex_w = false, int vector_len = AVX_128bit, bool legacy_mode = false);
|
||||
|
||||
void simd_prefix(XMMRegister dst, Address src,
|
||||
VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F) {
|
||||
simd_prefix(dst, xnoreg, src, pre, opc);
|
||||
void simd_prefix(XMMRegister dst, Address src, VexSimdPrefix pre,
|
||||
bool no_mask_reg, VexOpcode opc = VEX_OPCODE_0F) {
|
||||
simd_prefix(dst, xnoreg, src, pre, no_mask_reg, opc);
|
||||
}
|
||||
|
||||
void simd_prefix(Address dst, XMMRegister src, VexSimdPrefix pre) {
|
||||
simd_prefix(src, dst, pre);
|
||||
void simd_prefix(Address dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg) {
|
||||
simd_prefix(src, dst, pre, no_mask_reg);
|
||||
}
|
||||
void simd_prefix_q(XMMRegister dst, XMMRegister nds, Address src,
|
||||
VexSimdPrefix pre) {
|
||||
VexSimdPrefix pre, bool no_mask_reg = false) {
|
||||
bool rex_w = true;
|
||||
simd_prefix(dst, nds, src, pre, VEX_OPCODE_0F, rex_w);
|
||||
simd_prefix(dst, nds, src, pre, no_mask_reg, VEX_OPCODE_0F, rex_w);
|
||||
}
|
||||
|
||||
int simd_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src,
|
||||
VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F,
|
||||
bool rex_w = false, bool vector256 = false);
|
||||
VexSimdPrefix pre, bool no_mask_reg,
|
||||
VexOpcode opc = VEX_OPCODE_0F,
|
||||
bool rex_w = false, int vector_len = AVX_128bit,
|
||||
bool legacy_mode = false);
|
||||
|
||||
int kreg_prefix_and_encode(KRegister dst, KRegister nds, KRegister src,
|
||||
VexSimdPrefix pre, bool no_mask_reg,
|
||||
VexOpcode opc = VEX_OPCODE_0F,
|
||||
bool rex_w = false, int vector_len = AVX_128bit);
|
||||
|
||||
int kreg_prefix_and_encode(KRegister dst, KRegister nds, Register src,
|
||||
VexSimdPrefix pre, bool no_mask_reg,
|
||||
VexOpcode opc = VEX_OPCODE_0F,
|
||||
bool rex_w = false, int vector_len = AVX_128bit);
|
||||
|
||||
// Move/convert 32-bit integer value.
|
||||
int simd_prefix_and_encode(XMMRegister dst, XMMRegister nds, Register src,
|
||||
VexSimdPrefix pre) {
|
||||
VexSimdPrefix pre, bool no_mask_reg) {
|
||||
// It is OK to cast from Register to XMMRegister to pass argument here
|
||||
// since only encoding is used in simd_prefix_and_encode() and number of
|
||||
// Gen and Xmm registers are the same.
|
||||
return simd_prefix_and_encode(dst, nds, as_XMMRegister(src->encoding()), pre);
|
||||
return simd_prefix_and_encode(dst, nds, as_XMMRegister(src->encoding()), pre, no_mask_reg, VEX_OPCODE_0F);
|
||||
}
|
||||
int simd_prefix_and_encode(XMMRegister dst, Register src, VexSimdPrefix pre) {
|
||||
return simd_prefix_and_encode(dst, xnoreg, src, pre);
|
||||
int simd_prefix_and_encode(XMMRegister dst, Register src, VexSimdPrefix pre, bool no_mask_reg) {
|
||||
return simd_prefix_and_encode(dst, xnoreg, src, pre, no_mask_reg);
|
||||
}
|
||||
int simd_prefix_and_encode(Register dst, XMMRegister src,
|
||||
VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F) {
|
||||
return simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, pre, opc);
|
||||
VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F,
|
||||
bool no_mask_reg = false) {
|
||||
return simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, pre, no_mask_reg, opc);
|
||||
}
|
||||
|
||||
// Move/convert 64-bit integer value.
|
||||
int simd_prefix_and_encode_q(XMMRegister dst, XMMRegister nds, Register src,
|
||||
VexSimdPrefix pre) {
|
||||
VexSimdPrefix pre, bool no_mask_reg = false) {
|
||||
bool rex_w = true;
|
||||
return simd_prefix_and_encode(dst, nds, as_XMMRegister(src->encoding()), pre, VEX_OPCODE_0F, rex_w);
|
||||
return simd_prefix_and_encode(dst, nds, as_XMMRegister(src->encoding()), pre, no_mask_reg, VEX_OPCODE_0F, rex_w);
|
||||
}
|
||||
int simd_prefix_and_encode_q(XMMRegister dst, Register src, VexSimdPrefix pre) {
|
||||
return simd_prefix_and_encode_q(dst, xnoreg, src, pre);
|
||||
int simd_prefix_and_encode_q(XMMRegister dst, Register src, VexSimdPrefix pre, bool no_mask_reg) {
|
||||
return simd_prefix_and_encode_q(dst, xnoreg, src, pre, no_mask_reg);
|
||||
}
|
||||
int simd_prefix_and_encode_q(Register dst, XMMRegister src,
|
||||
VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F) {
|
||||
VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F,
|
||||
bool no_mask_reg = false) {
|
||||
bool rex_w = true;
|
||||
return simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, pre, opc, rex_w);
|
||||
return simd_prefix_and_encode(as_XMMRegister(dst->encoding()), xnoreg, src, pre, no_mask_reg, opc, rex_w);
|
||||
}
|
||||
|
||||
// Helper functions for groups of instructions
|
||||
@ -692,14 +772,28 @@ private:
|
||||
void emit_arith_imm32(int op1, int op2, Register dst, int32_t imm32);
|
||||
void emit_arith(int op1, int op2, Register dst, Register src);
|
||||
|
||||
void emit_simd_arith(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre);
|
||||
void emit_simd_arith(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre);
|
||||
void emit_simd_arith_nonds(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre);
|
||||
void emit_simd_arith_nonds(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre);
|
||||
void emit_simd_arith(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre, bool no_mask_reg = false, bool legacy_mode = false);
|
||||
void emit_simd_arith_q(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre, bool no_mask_reg = false);
|
||||
void emit_simd_arith(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg = false, bool legacy_mode = false);
|
||||
void emit_simd_arith_q(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg = false);
|
||||
void emit_simd_arith_nonds(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre, bool no_mask_reg = false);
|
||||
void emit_simd_arith_nonds_q(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre, bool no_mask_reg = false);
|
||||
void emit_simd_arith_nonds(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg = false, bool legacy_mode = false);
|
||||
void emit_simd_arith_nonds_q(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre, bool no_mask_reg = false);
|
||||
void emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
|
||||
Address src, VexSimdPrefix pre, bool vector256);
|
||||
Address src, VexSimdPrefix pre, int vector_len,
|
||||
bool no_mask_reg = false, bool legacy_mode = false);
|
||||
void emit_vex_arith_q(int opcode, XMMRegister dst, XMMRegister nds,
|
||||
Address src, VexSimdPrefix pre, int vector_len,
|
||||
bool no_mask_reg = false);
|
||||
void emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
|
||||
XMMRegister src, VexSimdPrefix pre, bool vector256);
|
||||
XMMRegister src, VexSimdPrefix pre, int vector_len,
|
||||
bool no_mask_reg = false, bool legacy_mode = false);
|
||||
void emit_vex_arith_q(int opcode, XMMRegister dst, XMMRegister nds,
|
||||
XMMRegister src, VexSimdPrefix pre, int vector_len,
|
||||
bool no_mask_reg = false);
|
||||
|
||||
bool emit_compressed_disp_byte(int &disp);
|
||||
|
||||
void emit_operand(Register reg,
|
||||
Register base, Register index, Address::ScaleFactor scale,
|
||||
@ -825,7 +919,9 @@ private:
|
||||
public:
|
||||
|
||||
// Creation
|
||||
Assembler(CodeBuffer* code) : AbstractAssembler(code) {}
|
||||
Assembler(CodeBuffer* code) : AbstractAssembler(code) {
|
||||
init_attributes();
|
||||
}
|
||||
|
||||
// Decoding
|
||||
static address locate_operand(address inst, WhichOperand which);
|
||||
@ -833,11 +929,21 @@ private:
|
||||
|
||||
// Utilities
|
||||
static bool is_polling_page_far() NOT_LP64({ return false;});
|
||||
static bool query_compressed_disp_byte(int disp, bool is_evex_inst, int vector_len,
|
||||
int cur_tuple_type, int in_size_in_bits, int cur_encoding);
|
||||
|
||||
// Generic instructions
|
||||
// Does 32bit or 64bit as needed for the platform. In some sense these
|
||||
// belong in macro assembler but there is no need for both varieties to exist
|
||||
|
||||
void init_attributes(void) {
|
||||
evex_encoding = 0;
|
||||
input_size_in_bits = 0;
|
||||
avx_vector_len = AVX_NoVec;
|
||||
tuple_type = EVEX_ETUP;
|
||||
is_evex_instruction = false;
|
||||
}
|
||||
|
||||
void lea(Register dst, Address src);
|
||||
|
||||
void mov(Register dst, Register src);
|
||||
@ -1338,6 +1444,12 @@ private:
|
||||
void movb(Address dst, int imm8);
|
||||
void movb(Register dst, Address src);
|
||||
|
||||
void kmovq(KRegister dst, KRegister src);
|
||||
void kmovql(KRegister dst, Register src);
|
||||
void kmovdl(KRegister dst, Register src);
|
||||
void kmovq(Address dst, KRegister src);
|
||||
void kmovq(KRegister dst, Address src);
|
||||
|
||||
void movdl(XMMRegister dst, Register src);
|
||||
void movdl(Register dst, XMMRegister src);
|
||||
void movdl(XMMRegister dst, Address src);
|
||||
@ -1361,6 +1473,11 @@ private:
|
||||
void vmovdqu(XMMRegister dst, Address src);
|
||||
void vmovdqu(XMMRegister dst, XMMRegister src);
|
||||
|
||||
// Move Unaligned 512bit Vector
|
||||
void evmovdqu(Address dst, XMMRegister src, int vector_len);
|
||||
void evmovdqu(XMMRegister dst, Address src, int vector_len);
|
||||
void evmovdqu(XMMRegister dst, XMMRegister src, int vector_len);
|
||||
|
||||
// Move lower 64bit to high 64bit in 128bit register
|
||||
void movlhps(XMMRegister dst, XMMRegister src);
|
||||
|
||||
@ -1486,10 +1603,10 @@ private:
|
||||
// Pack with unsigned saturation
|
||||
void packuswb(XMMRegister dst, XMMRegister src);
|
||||
void packuswb(XMMRegister dst, Address src);
|
||||
void vpackuswb(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpackuswb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
|
||||
// Pemutation of 64bit words
|
||||
void vpermq(XMMRegister dst, XMMRegister src, int imm8, bool vector256);
|
||||
void vpermq(XMMRegister dst, XMMRegister src, int imm8, int vector_len);
|
||||
|
||||
void pause();
|
||||
|
||||
@ -1734,54 +1851,54 @@ private:
|
||||
// Add Packed Floating-Point Values
|
||||
void addpd(XMMRegister dst, XMMRegister src);
|
||||
void addps(XMMRegister dst, XMMRegister src);
|
||||
void vaddpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vaddps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vaddpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vaddps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vaddpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vaddps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vaddpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vaddps(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Subtract Packed Floating-Point Values
|
||||
void subpd(XMMRegister dst, XMMRegister src);
|
||||
void subps(XMMRegister dst, XMMRegister src);
|
||||
void vsubpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vsubps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vsubpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vsubps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vsubpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vsubps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vsubpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vsubps(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Multiply Packed Floating-Point Values
|
||||
void mulpd(XMMRegister dst, XMMRegister src);
|
||||
void mulps(XMMRegister dst, XMMRegister src);
|
||||
void vmulpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vmulps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vmulpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vmulps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vmulpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vmulps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vmulpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vmulps(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Divide Packed Floating-Point Values
|
||||
void divpd(XMMRegister dst, XMMRegister src);
|
||||
void divps(XMMRegister dst, XMMRegister src);
|
||||
void vdivpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vdivps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vdivpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vdivps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vdivpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vdivps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vdivpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vdivps(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Bitwise Logical AND of Packed Floating-Point Values
|
||||
void andpd(XMMRegister dst, XMMRegister src);
|
||||
void andps(XMMRegister dst, XMMRegister src);
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vandps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vandps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vandps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vandps(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Bitwise Logical XOR of Packed Floating-Point Values
|
||||
void xorpd(XMMRegister dst, XMMRegister src);
|
||||
void xorps(XMMRegister dst, XMMRegister src);
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Add horizontal packed integers
|
||||
void vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vphaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vphaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vphaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void phaddw(XMMRegister dst, XMMRegister src);
|
||||
void phaddd(XMMRegister dst, XMMRegister src);
|
||||
|
||||
@ -1790,36 +1907,38 @@ private:
|
||||
void paddw(XMMRegister dst, XMMRegister src);
|
||||
void paddd(XMMRegister dst, XMMRegister src);
|
||||
void paddq(XMMRegister dst, XMMRegister src);
|
||||
void vpaddb(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpaddq(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpaddb(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpaddw(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpaddd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpaddq(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpaddb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpaddq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpaddb(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpaddw(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpaddd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpaddq(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Sub packed integers
|
||||
void psubb(XMMRegister dst, XMMRegister src);
|
||||
void psubw(XMMRegister dst, XMMRegister src);
|
||||
void psubd(XMMRegister dst, XMMRegister src);
|
||||
void psubq(XMMRegister dst, XMMRegister src);
|
||||
void vpsubb(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpsubw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpsubd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpsubq(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpsubb(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpsubw(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpsubd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpsubq(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpsubb(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpsubw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpsubd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpsubq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpsubb(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpsubw(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpsubd(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpsubq(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Multiply packed integers (only shorts and ints)
|
||||
void pmullw(XMMRegister dst, XMMRegister src);
|
||||
void pmulld(XMMRegister dst, XMMRegister src);
|
||||
void vpmullw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpmulld(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpmullw(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpmulld(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpmullw(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpmulld(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpmullq(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpmullw(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpmulld(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
void vpmullq(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Shift left packed integers
|
||||
void psllw(XMMRegister dst, int shift);
|
||||
@ -1828,12 +1947,12 @@ private:
|
||||
void psllw(XMMRegister dst, XMMRegister shift);
|
||||
void pslld(XMMRegister dst, XMMRegister shift);
|
||||
void psllq(XMMRegister dst, XMMRegister shift);
|
||||
void vpsllw(XMMRegister dst, XMMRegister src, int shift, bool vector256);
|
||||
void vpslld(XMMRegister dst, XMMRegister src, int shift, bool vector256);
|
||||
void vpsllq(XMMRegister dst, XMMRegister src, int shift, bool vector256);
|
||||
void vpsllw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
|
||||
void vpslld(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
|
||||
void vpsllq(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
|
||||
void vpsllw(XMMRegister dst, XMMRegister src, int shift, int vector_len);
|
||||
void vpslld(XMMRegister dst, XMMRegister src, int shift, int vector_len);
|
||||
void vpsllq(XMMRegister dst, XMMRegister src, int shift, int vector_len);
|
||||
void vpsllw(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len);
|
||||
void vpslld(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len);
|
||||
void vpsllq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len);
|
||||
|
||||
// Logical shift right packed integers
|
||||
void psrlw(XMMRegister dst, int shift);
|
||||
@ -1842,42 +1961,43 @@ private:
|
||||
void psrlw(XMMRegister dst, XMMRegister shift);
|
||||
void psrld(XMMRegister dst, XMMRegister shift);
|
||||
void psrlq(XMMRegister dst, XMMRegister shift);
|
||||
void vpsrlw(XMMRegister dst, XMMRegister src, int shift, bool vector256);
|
||||
void vpsrld(XMMRegister dst, XMMRegister src, int shift, bool vector256);
|
||||
void vpsrlq(XMMRegister dst, XMMRegister src, int shift, bool vector256);
|
||||
void vpsrlw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
|
||||
void vpsrld(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
|
||||
void vpsrlq(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
|
||||
void vpsrlw(XMMRegister dst, XMMRegister src, int shift, int vector_len);
|
||||
void vpsrld(XMMRegister dst, XMMRegister src, int shift, int vector_len);
|
||||
void vpsrlq(XMMRegister dst, XMMRegister src, int shift, int vector_len);
|
||||
void vpsrlw(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len);
|
||||
void vpsrld(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len);
|
||||
void vpsrlq(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len);
|
||||
|
||||
// Arithmetic shift right packed integers (only shorts and ints, no instructions for longs)
|
||||
void psraw(XMMRegister dst, int shift);
|
||||
void psrad(XMMRegister dst, int shift);
|
||||
void psraw(XMMRegister dst, XMMRegister shift);
|
||||
void psrad(XMMRegister dst, XMMRegister shift);
|
||||
void vpsraw(XMMRegister dst, XMMRegister src, int shift, bool vector256);
|
||||
void vpsrad(XMMRegister dst, XMMRegister src, int shift, bool vector256);
|
||||
void vpsraw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
|
||||
void vpsrad(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
|
||||
void vpsraw(XMMRegister dst, XMMRegister src, int shift, int vector_len);
|
||||
void vpsrad(XMMRegister dst, XMMRegister src, int shift, int vector_len);
|
||||
void vpsraw(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len);
|
||||
void vpsrad(XMMRegister dst, XMMRegister src, XMMRegister shift, int vector_len);
|
||||
|
||||
// And packed integers
|
||||
void pand(XMMRegister dst, XMMRegister src);
|
||||
void vpand(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpand(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpand(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpand(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Or packed integers
|
||||
void por(XMMRegister dst, XMMRegister src);
|
||||
void vpor(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpor(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpor(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpor(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Xor packed integers
|
||||
void pxor(XMMRegister dst, XMMRegister src);
|
||||
void vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
|
||||
void vpxor(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
|
||||
void vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len);
|
||||
void vpxor(XMMRegister dst, XMMRegister nds, Address src, int vector_len);
|
||||
|
||||
// Copy low 128bit into high 128bit of YMM registers.
|
||||
void vinsertf128h(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vextractf128h(XMMRegister dst, XMMRegister src);
|
||||
void vextracti128h(XMMRegister dst, XMMRegister src);
|
||||
|
||||
// Load/store high 128bit of YMM registers which does not destroy other half.
|
||||
void vinsertf128h(XMMRegister dst, Address src);
|
||||
@ -1885,9 +2005,25 @@ private:
|
||||
void vextractf128h(Address dst, XMMRegister src);
|
||||
void vextracti128h(Address dst, XMMRegister src);
|
||||
|
||||
// Copy low 256bit into high 256bit of ZMM registers.
|
||||
void vinserti64x4h(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vinsertf64x4h(XMMRegister dst, XMMRegister nds, XMMRegister src);
|
||||
void vextracti64x4h(XMMRegister dst, XMMRegister src);
|
||||
void vextractf64x4h(XMMRegister dst, XMMRegister src);
|
||||
void vextractf64x4h(Address dst, XMMRegister src);
|
||||
void vinsertf64x4h(XMMRegister dst, Address src);
|
||||
|
||||
// Copy targeted 128bit segments of the ZMM registers
|
||||
void vextracti64x2h(XMMRegister dst, XMMRegister src, int value);
|
||||
void vextractf64x2h(XMMRegister dst, XMMRegister src, int value);
|
||||
void vextractf32x4h(XMMRegister dst, XMMRegister src, int value);
|
||||
|
||||
// duplicate 4-bytes integer data from src into 8 locations in dest
|
||||
void vpbroadcastd(XMMRegister dst, XMMRegister src);
|
||||
|
||||
// duplicate 4-bytes integer data from src into vector_len locations in dest
|
||||
void evpbroadcastd(XMMRegister dst, XMMRegister src, int vector_len);
|
||||
|
||||
// Carry-Less Multiplication Quadword
|
||||
void pclmulqdq(XMMRegister dst, XMMRegister src, int mask);
|
||||
void vpclmulqdq(XMMRegister dst, XMMRegister nds, XMMRegister src, int mask);
|
||||
|
@ -233,13 +233,30 @@ void FrameMap::initialize() {
|
||||
_xmm_regs[13] = xmm13;
|
||||
_xmm_regs[14] = xmm14;
|
||||
_xmm_regs[15] = xmm15;
|
||||
_xmm_regs[16] = xmm16;
|
||||
_xmm_regs[17] = xmm17;
|
||||
_xmm_regs[18] = xmm18;
|
||||
_xmm_regs[19] = xmm19;
|
||||
_xmm_regs[20] = xmm20;
|
||||
_xmm_regs[21] = xmm21;
|
||||
_xmm_regs[22] = xmm22;
|
||||
_xmm_regs[23] = xmm23;
|
||||
_xmm_regs[24] = xmm24;
|
||||
_xmm_regs[25] = xmm25;
|
||||
_xmm_regs[26] = xmm26;
|
||||
_xmm_regs[27] = xmm27;
|
||||
_xmm_regs[28] = xmm28;
|
||||
_xmm_regs[29] = xmm29;
|
||||
_xmm_regs[30] = xmm30;
|
||||
_xmm_regs[31] = xmm31;
|
||||
#endif // _LP64
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
_caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < nof_caller_save_xmm_regs ; i++) {
|
||||
int num_caller_save_xmm_regs = get_num_caller_save_xmms();
|
||||
for (int i = 0; i < num_caller_save_xmm_regs; i++) {
|
||||
_caller_save_xmm_regs[i] = LIR_OprFact::single_xmm(i);
|
||||
}
|
||||
|
||||
|
@ -152,6 +152,16 @@
|
||||
return range;
|
||||
}
|
||||
|
||||
static int get_num_caller_save_xmms(void) {
|
||||
int num_caller_save_xmm_regs = nof_caller_save_xmm_regs;
|
||||
#ifdef _LP64
|
||||
if (UseAVX < 3) {
|
||||
num_caller_save_xmm_regs = num_caller_save_xmm_regs / 2;
|
||||
}
|
||||
#endif
|
||||
return num_caller_save_xmm_regs;
|
||||
}
|
||||
|
||||
static int nof_caller_save_cpu_regs() { return adjust_reg_range(pd_nof_caller_save_cpu_regs_frame_map); }
|
||||
static int last_cpu_reg() { return adjust_reg_range(pd_last_cpu_reg); }
|
||||
static int last_byte_reg() { return adjust_reg_range(pd_last_byte_reg); }
|
||||
|
@ -85,8 +85,9 @@ inline void LinearScan::pd_add_temps(LIR_Op* op) {
|
||||
tty->print_cr("killing XMMs for trig");
|
||||
}
|
||||
#endif
|
||||
int num_caller_save_xmm_regs = FrameMap::get_num_caller_save_xmms();
|
||||
int op_id = op->id();
|
||||
for (int xmm = 0; xmm < FrameMap::nof_caller_save_xmm_regs; xmm++) {
|
||||
for (int xmm = 0; xmm < num_caller_save_xmm_regs; xmm++) {
|
||||
LIR_Opr opr = FrameMap::caller_save_xmm_reg_at(xmm);
|
||||
add_temp(reg_num(opr), op_id, noUse, T_ILLEGAL);
|
||||
}
|
||||
@ -100,6 +101,10 @@ inline void LinearScan::pd_add_temps(LIR_Op* op) {
|
||||
// Implementation of LinearScanWalker
|
||||
|
||||
inline bool LinearScanWalker::pd_init_regs_for_alloc(Interval* cur) {
|
||||
int last_xmm_reg = pd_last_xmm_reg;
|
||||
if (UseAVX < 3) {
|
||||
last_xmm_reg = pd_first_xmm_reg + (pd_nof_xmm_regs_frame_map / 2) - 1;
|
||||
}
|
||||
if (allocator()->gen()->is_vreg_flag_set(cur->reg_num(), LIRGenerator::byte_reg)) {
|
||||
assert(cur->type() != T_FLOAT && cur->type() != T_DOUBLE, "cpu regs only");
|
||||
_first_reg = pd_first_byte_reg;
|
||||
@ -107,7 +112,7 @@ inline bool LinearScanWalker::pd_init_regs_for_alloc(Interval* cur) {
|
||||
return true;
|
||||
} else if ((UseSSE >= 1 && cur->type() == T_FLOAT) || (UseSSE >= 2 && cur->type() == T_DOUBLE)) {
|
||||
_first_reg = pd_first_xmm_reg;
|
||||
_last_reg = pd_last_xmm_reg;
|
||||
_last_reg = last_xmm_reg;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -323,7 +323,7 @@ static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args,
|
||||
LP64_ONLY(num_rt_args = 0);
|
||||
LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");)
|
||||
int frame_size_in_slots = reg_save_frame_size + num_rt_args; // args + thread
|
||||
sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word );
|
||||
sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word);
|
||||
|
||||
// record saved value locations in an OopMap
|
||||
// locations are offsets from sp after runtime call; num_rt_args is number of arguments in call, including thread
|
||||
@ -362,6 +362,13 @@ static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args,
|
||||
map->set_callee_saved(VMRegImpl::stack2reg(r15H_off + num_rt_args), r15->as_VMReg()->next());
|
||||
#endif // _LP64
|
||||
|
||||
int xmm_bypass_limit = FrameMap::nof_xmm_regs;
|
||||
#ifdef _LP64
|
||||
if (UseAVX < 3) {
|
||||
xmm_bypass_limit = xmm_bypass_limit / 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (save_fpu_registers) {
|
||||
if (UseSSE < 2) {
|
||||
int fpu_off = float_regs_as_doubles_off;
|
||||
@ -380,11 +387,13 @@ static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args,
|
||||
if (UseSSE >= 2) {
|
||||
int xmm_off = xmm_regs_as_doubles_off;
|
||||
for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
|
||||
VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
|
||||
map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
|
||||
// %%% This is really a waste but we'll keep things as they were for now
|
||||
if (true) {
|
||||
map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + 1 + num_rt_args), xmm_name_0->next());
|
||||
if (n < xmm_bypass_limit) {
|
||||
VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
|
||||
map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
|
||||
// %%% This is really a waste but we'll keep things as they were for now
|
||||
if (true) {
|
||||
map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + 1 + num_rt_args), xmm_name_0->next());
|
||||
}
|
||||
}
|
||||
xmm_off += 2;
|
||||
}
|
||||
@ -393,8 +402,10 @@ static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args,
|
||||
} else if (UseSSE == 1) {
|
||||
int xmm_off = xmm_regs_as_doubles_off;
|
||||
for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
|
||||
VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
|
||||
map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
|
||||
if (n < xmm_bypass_limit) {
|
||||
VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
|
||||
map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
|
||||
}
|
||||
xmm_off += 2;
|
||||
}
|
||||
assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
|
||||
@ -474,6 +485,24 @@ static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 104), xmm13);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 112), xmm14);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 120), xmm15);
|
||||
if (UseAVX > 2) {
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 128), xmm16);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 136), xmm17);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 144), xmm18);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 152), xmm19);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 160), xmm20);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 168), xmm21);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 176), xmm22);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 184), xmm23);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 192), xmm24);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 200), xmm25);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 208), xmm26);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 216), xmm27);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 224), xmm28);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 232), xmm29);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 240), xmm30);
|
||||
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 248), xmm31);
|
||||
}
|
||||
#endif // _LP64
|
||||
} else if (UseSSE == 1) {
|
||||
// save XMM registers as float because double not supported without SSE2
|
||||
@ -516,6 +545,24 @@ static void restore_fpu(StubAssembler* sasm, bool restore_fpu_registers = true)
|
||||
__ movdbl(xmm13, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 104));
|
||||
__ movdbl(xmm14, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 112));
|
||||
__ movdbl(xmm15, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 120));
|
||||
if (UseAVX > 2) {
|
||||
__ movdbl(xmm16, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 128));
|
||||
__ movdbl(xmm17, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 136));
|
||||
__ movdbl(xmm18, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 144));
|
||||
__ movdbl(xmm19, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 152));
|
||||
__ movdbl(xmm20, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 160));
|
||||
__ movdbl(xmm21, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 168));
|
||||
__ movdbl(xmm22, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 176));
|
||||
__ movdbl(xmm23, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 184));
|
||||
__ movdbl(xmm24, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 192));
|
||||
__ movdbl(xmm25, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 200));
|
||||
__ movdbl(xmm26, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 208));
|
||||
__ movdbl(xmm27, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 216));
|
||||
__ movdbl(xmm28, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 224));
|
||||
__ movdbl(xmm29, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 232));
|
||||
__ movdbl(xmm30, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 240));
|
||||
__ movdbl(xmm31, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 248));
|
||||
}
|
||||
#endif // _LP64
|
||||
} else if (UseSSE == 1) {
|
||||
// restore XMM registers
|
||||
@ -1631,36 +1678,22 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
|
||||
NOT_LP64(__ get_thread(thread);)
|
||||
|
||||
Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||
PtrQueue::byte_offset_of_active()));
|
||||
|
||||
Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||
PtrQueue::byte_offset_of_index()));
|
||||
Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
|
||||
PtrQueue::byte_offset_of_buf()));
|
||||
|
||||
|
||||
Label done;
|
||||
Label runtime;
|
||||
|
||||
// Can we store original value in the thread's buffer?
|
||||
|
||||
#ifdef _LP64
|
||||
__ movslq(tmp, queue_index);
|
||||
__ cmpq(tmp, 0);
|
||||
#else
|
||||
__ cmpl(queue_index, 0);
|
||||
#endif
|
||||
__ jcc(Assembler::equal, runtime);
|
||||
#ifdef _LP64
|
||||
__ subq(tmp, wordSize);
|
||||
__ movl(queue_index, tmp);
|
||||
__ addq(tmp, buffer);
|
||||
#else
|
||||
__ subl(queue_index, wordSize);
|
||||
__ movl(tmp, buffer);
|
||||
__ addl(tmp, queue_index);
|
||||
#endif
|
||||
__ movptr(tmp, queue_index);
|
||||
__ testptr(tmp, tmp);
|
||||
__ jcc(Assembler::zero, runtime);
|
||||
__ subptr(tmp, wordSize);
|
||||
__ movptr(queue_index, tmp);
|
||||
__ addptr(tmp, buffer);
|
||||
|
||||
// prev_val (rax)
|
||||
f.load_argument(0, pre_val);
|
||||
@ -1713,6 +1746,7 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
|
||||
|
||||
Label done;
|
||||
Label enqueued;
|
||||
Label runtime;
|
||||
|
||||
// At this point we know new_value is non-NULL and the new_value crosses regions.
|
||||
@ -1752,28 +1786,19 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
|
||||
__ movb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
|
||||
|
||||
__ cmpl(queue_index, 0);
|
||||
__ jcc(Assembler::equal, runtime);
|
||||
__ subl(queue_index, wordSize);
|
||||
const Register tmp = rdx;
|
||||
__ push(rdx);
|
||||
|
||||
const Register buffer_addr = rbx;
|
||||
__ push(rbx);
|
||||
|
||||
__ movptr(buffer_addr, buffer);
|
||||
|
||||
#ifdef _LP64
|
||||
__ movslq(rscratch1, queue_index);
|
||||
__ addptr(buffer_addr, rscratch1);
|
||||
#else
|
||||
__ addptr(buffer_addr, queue_index);
|
||||
#endif
|
||||
__ movptr(Address(buffer_addr, 0), card_addr);
|
||||
|
||||
__ pop(rbx);
|
||||
__ jmp(done);
|
||||
__ movptr(tmp, queue_index);
|
||||
__ testptr(tmp, tmp);
|
||||
__ jcc(Assembler::zero, runtime);
|
||||
__ subptr(tmp, wordSize);
|
||||
__ movptr(queue_index, tmp);
|
||||
__ addptr(tmp, buffer);
|
||||
__ movptr(Address(tmp, 0), card_addr);
|
||||
__ jmp(enqueued);
|
||||
|
||||
__ bind(runtime);
|
||||
__ push(rdx);
|
||||
#ifdef _LP64
|
||||
__ push(r8);
|
||||
__ push(r9);
|
||||
@ -1795,12 +1820,12 @@ OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
|
||||
__ pop(r9);
|
||||
__ pop(r8);
|
||||
#endif
|
||||
__ bind(enqueued);
|
||||
__ pop(rdx);
|
||||
__ bind(done);
|
||||
|
||||
__ bind(done);
|
||||
__ pop(rcx);
|
||||
__ pop(rax);
|
||||
|
||||
}
|
||||
break;
|
||||
#endif // INCLUDE_ALL_GCS
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "opto/compile.hpp"
|
||||
#include "opto/node.hpp"
|
||||
#include "opto/optoreg.hpp"
|
||||
|
||||
// processor dependent initialization for i486
|
||||
|
||||
@ -37,4 +38,24 @@ void Compile::pd_compiler2_init() {
|
||||
ConditionalMoveLimit = 0;
|
||||
}
|
||||
#endif // AMD64
|
||||
|
||||
if (UseAVX < 3) {
|
||||
int delta = XMMRegisterImpl::max_slots_per_register * XMMRegisterImpl::number_of_registers;
|
||||
int bottom = ConcreteRegisterImpl::max_fpr;
|
||||
int top = bottom + delta;
|
||||
int middle = bottom + (delta / 2);
|
||||
int xmm_slots = XMMRegisterImpl::max_slots_per_register;
|
||||
int lower = xmm_slots / 2;
|
||||
// mark bad every register that we cannot get to if AVX less than 3, we have all slots in the array
|
||||
// Note: vm2opto is allocated to ConcreteRegisterImpl::number_of_registers
|
||||
for (int i = bottom; i < middle; i += xmm_slots) {
|
||||
for (OptoReg::Name j = OptoReg::Name(i + lower); j<OptoReg::Name(i + xmm_slots); j = OptoReg::add(j, 1)) {
|
||||
OptoReg::invalidate(j);
|
||||
}
|
||||
}
|
||||
// mark the upper zmm bank bad and all the mask registers bad in this case
|
||||
for (OptoReg::Name i = OptoReg::Name(middle); i<OptoReg::Name(_last_Mach_Reg - 1); i = OptoReg::add(i, 1)) {
|
||||
OptoReg::invalidate(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +125,7 @@
|
||||
// Entry frames
|
||||
#ifdef AMD64
|
||||
#ifdef _WIN64
|
||||
entry_frame_after_call_words = 28,
|
||||
entry_frame_after_call_words = 60,
|
||||
entry_frame_call_wrapper_offset = 2,
|
||||
|
||||
arg_reg_save_area_bytes = 32 // Register argument save area
|
||||
|
@ -3996,21 +3996,21 @@ void MacroAssembler::vaddss(XMMRegister dst, XMMRegister nds, AddressLiteral src
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256) {
|
||||
void MacroAssembler::vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len) {
|
||||
if (reachable(src)) {
|
||||
vandpd(dst, nds, as_Address(src), vector256);
|
||||
vandpd(dst, nds, as_Address(src), vector_len);
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vandpd(dst, nds, Address(rscratch1, 0), vector256);
|
||||
vandpd(dst, nds, Address(rscratch1, 0), vector_len);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256) {
|
||||
void MacroAssembler::vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len) {
|
||||
if (reachable(src)) {
|
||||
vandps(dst, nds, as_Address(src), vector256);
|
||||
vandps(dst, nds, as_Address(src), vector_len);
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vandps(dst, nds, Address(rscratch1, 0), vector256);
|
||||
vandps(dst, nds, Address(rscratch1, 0), vector_len);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4068,21 +4068,21 @@ void MacroAssembler::vsubss(XMMRegister dst, XMMRegister nds, AddressLiteral src
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256) {
|
||||
void MacroAssembler::vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len) {
|
||||
if (reachable(src)) {
|
||||
vxorpd(dst, nds, as_Address(src), vector256);
|
||||
vxorpd(dst, nds, as_Address(src), vector_len);
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vxorpd(dst, nds, Address(rscratch1, 0), vector256);
|
||||
vxorpd(dst, nds, Address(rscratch1, 0), vector_len);
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256) {
|
||||
void MacroAssembler::vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len) {
|
||||
if (reachable(src)) {
|
||||
vxorps(dst, nds, as_Address(src), vector256);
|
||||
vxorps(dst, nds, as_Address(src), vector_len);
|
||||
} else {
|
||||
lea(rscratch1, src);
|
||||
vxorps(dst, nds, Address(rscratch1, 0), vector256);
|
||||
vxorps(dst, nds, Address(rscratch1, 0), vector_len);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4561,6 +4561,14 @@ void MacroAssembler::fp_runtime_fallback(address runtime_entry, int nb_args, int
|
||||
movflt(Address(rsp,off++*sizeof(jdouble)),xmm6);
|
||||
movflt(Address(rsp,off++*sizeof(jdouble)),xmm7);
|
||||
} else if (UseSSE >= 2) {
|
||||
if (UseAVX > 2) {
|
||||
movl(rbx, 0xffff);
|
||||
#ifdef _LP64
|
||||
kmovql(k1, rbx);
|
||||
#else
|
||||
kmovdl(k1, rbx);
|
||||
#endif
|
||||
}
|
||||
#ifdef COMPILER2
|
||||
if (MaxVectorSize > 16) {
|
||||
assert(UseAVX > 0, "256bit vectors are supported only with AVX");
|
||||
@ -7063,8 +7071,39 @@ void MacroAssembler::generate_fill(BasicType t, bool aligned,
|
||||
{
|
||||
assert( UseSSE >= 2, "supported cpu only" );
|
||||
Label L_fill_32_bytes_loop, L_check_fill_8_bytes, L_fill_8_bytes_loop, L_fill_8_bytes;
|
||||
if (UseAVX > 2) {
|
||||
movl(rtmp, 0xffff);
|
||||
#ifdef _LP64
|
||||
kmovql(k1, rtmp);
|
||||
#else
|
||||
kmovdl(k1, rtmp);
|
||||
#endif
|
||||
}
|
||||
movdl(xtmp, value);
|
||||
if (UseAVX >= 2 && UseUnalignedLoadStores) {
|
||||
if (UseAVX > 2 && UseUnalignedLoadStores) {
|
||||
// Fill 64-byte chunks
|
||||
Label L_fill_64_bytes_loop, L_check_fill_32_bytes;
|
||||
evpbroadcastd(xtmp, xtmp, Assembler::AVX_512bit);
|
||||
|
||||
subl(count, 16 << shift);
|
||||
jcc(Assembler::less, L_check_fill_32_bytes);
|
||||
align(16);
|
||||
|
||||
BIND(L_fill_64_bytes_loop);
|
||||
evmovdqu(Address(to, 0), xtmp, Assembler::AVX_512bit);
|
||||
addptr(to, 64);
|
||||
subl(count, 16 << shift);
|
||||
jcc(Assembler::greaterEqual, L_fill_64_bytes_loop);
|
||||
|
||||
BIND(L_check_fill_32_bytes);
|
||||
addl(count, 8 << shift);
|
||||
jccb(Assembler::less, L_check_fill_8_bytes);
|
||||
evmovdqu(Address(to, 0), xtmp, Assembler::AVX_256bit);
|
||||
addptr(to, 32);
|
||||
subl(count, 8 << shift);
|
||||
|
||||
BIND(L_check_fill_8_bytes);
|
||||
} else if (UseAVX == 2 && UseUnalignedLoadStores) {
|
||||
// Fill 64-byte chunks
|
||||
Label L_fill_64_bytes_loop, L_check_fill_32_bytes;
|
||||
vpbroadcastd(xtmp, xtmp);
|
||||
@ -7200,11 +7239,11 @@ void MacroAssembler::encode_iso_array(Register src, Register dst, Register len,
|
||||
bind(L_copy_32_chars);
|
||||
vmovdqu(tmp3Reg, Address(src, len, Address::times_2, -64));
|
||||
vmovdqu(tmp4Reg, Address(src, len, Address::times_2, -32));
|
||||
vpor(tmp2Reg, tmp3Reg, tmp4Reg, /* vector256 */ true);
|
||||
vpor(tmp2Reg, tmp3Reg, tmp4Reg, /* vector_len */ 1);
|
||||
vptest(tmp2Reg, tmp1Reg); // check for Unicode chars in vector
|
||||
jccb(Assembler::notZero, L_copy_32_chars_exit);
|
||||
vpackuswb(tmp3Reg, tmp3Reg, tmp4Reg, /* vector256 */ true);
|
||||
vpermq(tmp4Reg, tmp3Reg, 0xD8, /* vector256 */ true);
|
||||
vpackuswb(tmp3Reg, tmp3Reg, tmp4Reg, /* vector_len */ 1);
|
||||
vpermq(tmp4Reg, tmp3Reg, 0xD8, /* vector_len */ 1);
|
||||
vmovdqu(Address(dst, len, Address::times_1, -32), tmp4Reg);
|
||||
|
||||
bind(L_chars_32_check);
|
||||
@ -7227,13 +7266,13 @@ void MacroAssembler::encode_iso_array(Register src, Register dst, Register len,
|
||||
vmovdqu(tmp2Reg, Address(src, len, Address::times_2, -32));
|
||||
vptest(tmp2Reg, tmp1Reg);
|
||||
jccb(Assembler::notZero, L_copy_16_chars_exit);
|
||||
vpackuswb(tmp2Reg, tmp2Reg, tmp1Reg, /* vector256 */ true);
|
||||
vpermq(tmp3Reg, tmp2Reg, 0xD8, /* vector256 */ true);
|
||||
vpackuswb(tmp2Reg, tmp2Reg, tmp1Reg, /* vector_len */ 1);
|
||||
vpermq(tmp3Reg, tmp2Reg, 0xD8, /* vector_len */ 1);
|
||||
} else {
|
||||
if (UseAVX > 0) {
|
||||
movdqu(tmp3Reg, Address(src, len, Address::times_2, -32));
|
||||
movdqu(tmp4Reg, Address(src, len, Address::times_2, -16));
|
||||
vpor(tmp2Reg, tmp3Reg, tmp4Reg, /* vector256 */ false);
|
||||
vpor(tmp2Reg, tmp3Reg, tmp4Reg, /* vector_len */ 0);
|
||||
} else {
|
||||
movdqu(tmp3Reg, Address(src, len, Address::times_2, -32));
|
||||
por(tmp2Reg, tmp3Reg);
|
||||
@ -7776,7 +7815,7 @@ void MacroAssembler::fold_128bit_crc32(XMMRegister xcrc, XMMRegister xK, XMMRegi
|
||||
if (UseAVX > 0) {
|
||||
vpclmulhdq(xtmp, xK, xcrc); // [123:64]
|
||||
vpclmulldq(xcrc, xK, xcrc); // [63:0]
|
||||
vpxor(xcrc, xcrc, Address(buf, offset), false /* vector256 */);
|
||||
vpxor(xcrc, xcrc, Address(buf, offset), 0 /* vector_len */);
|
||||
pxor(xcrc, xtmp);
|
||||
} else {
|
||||
movdqa(xtmp, xcrc);
|
||||
@ -7920,7 +7959,7 @@ void MacroAssembler::kernel_crc32(Register crc, Register buf, Register len, Regi
|
||||
movdqu(xmm0, ExternalAddress(StubRoutines::x86::crc_by128_masks_addr()));
|
||||
if (UseAVX > 0) {
|
||||
vpclmulqdq(xmm2, xmm0, xmm1, 0x1);
|
||||
vpand(xmm3, xmm0, xmm2, false /* vector256 */);
|
||||
vpand(xmm3, xmm0, xmm2, 0 /* vector_len */);
|
||||
vpclmulqdq(xmm0, xmm0, xmm3, 0x1);
|
||||
} else {
|
||||
movdqa(xmm2, xmm0);
|
||||
|
@ -1024,13 +1024,13 @@ public:
|
||||
void vaddss(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vaddss(dst, nds, src); }
|
||||
void vaddss(XMMRegister dst, XMMRegister nds, AddressLiteral src);
|
||||
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) { Assembler::vandpd(dst, nds, src, vector256); }
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256) { Assembler::vandpd(dst, nds, src, vector256); }
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256);
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vandpd(dst, nds, src, vector_len); }
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { Assembler::vandpd(dst, nds, src, vector_len); }
|
||||
void vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len);
|
||||
|
||||
void vandps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) { Assembler::vandps(dst, nds, src, vector256); }
|
||||
void vandps(XMMRegister dst, XMMRegister nds, Address src, bool vector256) { Assembler::vandps(dst, nds, src, vector256); }
|
||||
void vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256);
|
||||
void vandps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vandps(dst, nds, src, vector_len); }
|
||||
void vandps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { Assembler::vandps(dst, nds, src, vector_len); }
|
||||
void vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len);
|
||||
|
||||
void vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vdivsd(dst, nds, src); }
|
||||
void vdivsd(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vdivsd(dst, nds, src); }
|
||||
@ -1058,25 +1058,25 @@ public:
|
||||
|
||||
// AVX Vector instructions
|
||||
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) { Assembler::vxorpd(dst, nds, src, vector256); }
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256) { Assembler::vxorpd(dst, nds, src, vector256); }
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256);
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vxorpd(dst, nds, src, vector_len); }
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { Assembler::vxorpd(dst, nds, src, vector_len); }
|
||||
void vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len);
|
||||
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) { Assembler::vxorps(dst, nds, src, vector256); }
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, Address src, bool vector256) { Assembler::vxorps(dst, nds, src, vector256); }
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256);
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) { Assembler::vxorps(dst, nds, src, vector_len); }
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, Address src, int vector_len) { Assembler::vxorps(dst, nds, src, vector_len); }
|
||||
void vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src, int vector_len);
|
||||
|
||||
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);
|
||||
void vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, int vector_len) {
|
||||
if (UseAVX > 1 || (vector_len < 1)) // vpxor 256 bit is available only in AVX2
|
||||
Assembler::vpxor(dst, nds, src, vector_len);
|
||||
else
|
||||
Assembler::vxorpd(dst, nds, src, vector256);
|
||||
Assembler::vxorpd(dst, nds, src, vector_len);
|
||||
}
|
||||
void vpxor(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
|
||||
if (UseAVX > 1 || !vector256) // vpxor 256 bit is available only in AVX2
|
||||
Assembler::vpxor(dst, nds, src, vector256);
|
||||
void vpxor(XMMRegister dst, XMMRegister nds, Address src, int vector_len) {
|
||||
if (UseAVX > 1 || (vector_len < 1)) // vpxor 256 bit is available only in AVX2
|
||||
Assembler::vpxor(dst, nds, src, vector_len);
|
||||
else
|
||||
Assembler::vxorpd(dst, nds, src, vector256);
|
||||
Assembler::vxorpd(dst, nds, src, vector_len);
|
||||
}
|
||||
|
||||
// Simple version for AVX2 256bit vectors
|
||||
|
@ -68,6 +68,22 @@ REGISTER_DEFINITION(XMMRegister, xmm12);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm13);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm14);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm15);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm16);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm17);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm18);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm19);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm20);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm21);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm22);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm23);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm24);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm25);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm26);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm27);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm28);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm29);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm30);
|
||||
REGISTER_DEFINITION(XMMRegister, xmm31);
|
||||
|
||||
REGISTER_DEFINITION(Register, c_rarg0);
|
||||
REGISTER_DEFINITION(Register, c_rarg1);
|
||||
@ -123,5 +139,15 @@ REGISTER_DEFINITION(MMXRegister, mmx5 );
|
||||
REGISTER_DEFINITION(MMXRegister, mmx6 );
|
||||
REGISTER_DEFINITION(MMXRegister, mmx7 );
|
||||
|
||||
REGISTER_DEFINITION(KRegister, knoreg);
|
||||
REGISTER_DEFINITION(KRegister, k0);
|
||||
REGISTER_DEFINITION(KRegister, k1);
|
||||
REGISTER_DEFINITION(KRegister, k2);
|
||||
REGISTER_DEFINITION(KRegister, k3);
|
||||
REGISTER_DEFINITION(KRegister, k4);
|
||||
REGISTER_DEFINITION(KRegister, k5);
|
||||
REGISTER_DEFINITION(KRegister, k6);
|
||||
REGISTER_DEFINITION(KRegister, k7);
|
||||
|
||||
// JSR 292
|
||||
REGISTER_DEFINITION(Register, rbp_mh_SP_save);
|
||||
|
@ -31,11 +31,13 @@ const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers;
|
||||
const int ConcreteRegisterImpl::max_gpr = RegisterImpl::number_of_registers << 1;
|
||||
#endif // AMD64
|
||||
|
||||
|
||||
const int ConcreteRegisterImpl::max_fpr = ConcreteRegisterImpl::max_gpr +
|
||||
2 * FloatRegisterImpl::number_of_registers;
|
||||
2 * FloatRegisterImpl::number_of_registers;
|
||||
const int ConcreteRegisterImpl::max_xmm = ConcreteRegisterImpl::max_fpr +
|
||||
8 * XMMRegisterImpl::number_of_registers;
|
||||
XMMRegisterImpl::max_slots_per_register * XMMRegisterImpl::number_of_registers;
|
||||
const int ConcreteRegisterImpl::max_kpr = ConcreteRegisterImpl::max_xmm +
|
||||
KRegisterImpl::max_slots_per_register * KRegisterImpl::number_of_registers;
|
||||
|
||||
const char* RegisterImpl::name() const {
|
||||
const char* names[number_of_registers] = {
|
||||
#ifndef AMD64
|
||||
@ -59,8 +61,17 @@ const char* XMMRegisterImpl::name() const {
|
||||
const char* names[number_of_registers] = {
|
||||
"xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7"
|
||||
#ifdef AMD64
|
||||
,"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
|
||||
,"xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"
|
||||
,"xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", "xmm22", "xmm23"
|
||||
,"xmm24", "xmm25", "xmm26", "xmm27", "xmm28", "xmm29", "xmm30", "xmm31"
|
||||
#endif // AMD64
|
||||
};
|
||||
return is_valid() ? names[encoding()] : "xnoreg";
|
||||
}
|
||||
|
||||
const char* KRegisterImpl::name() const {
|
||||
const char* names[number_of_registers] = {
|
||||
"k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7"
|
||||
};
|
||||
return is_valid() ? names[encoding()] : "knoreg";
|
||||
}
|
||||
|
@ -45,10 +45,12 @@ class RegisterImpl: public AbstractRegisterImpl {
|
||||
enum {
|
||||
#ifndef AMD64
|
||||
number_of_registers = 8,
|
||||
number_of_byte_registers = 4
|
||||
number_of_byte_registers = 4,
|
||||
max_slots_per_register = 1
|
||||
#else
|
||||
number_of_registers = 16,
|
||||
number_of_byte_registers = 16
|
||||
number_of_byte_registers = 16,
|
||||
max_slots_per_register = 1
|
||||
#endif // AMD64
|
||||
};
|
||||
|
||||
@ -143,9 +145,11 @@ class XMMRegisterImpl: public AbstractRegisterImpl {
|
||||
public:
|
||||
enum {
|
||||
#ifndef AMD64
|
||||
number_of_registers = 8
|
||||
number_of_registers = 8,
|
||||
max_slots_per_register = 16 // 512-bit
|
||||
#else
|
||||
number_of_registers = 16
|
||||
number_of_registers = 32,
|
||||
max_slots_per_register = 16 // 512-bit
|
||||
#endif // AMD64
|
||||
};
|
||||
|
||||
@ -183,6 +187,22 @@ CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm12, (12));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm13, (13));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm14, (14));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm15, (15));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm16, (16));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm17, (17));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm18, (18));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm19, (19));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm20, (20));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm21, (21));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm22, (22));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm23, (23));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm24, (24));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm25, (25));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm26, (26));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm27, (27));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm28, (28));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm29, (29));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm30, (30));
|
||||
CONSTANT_REGISTER_DECLARATION(XMMRegister, xmm31, (31));
|
||||
#endif // AMD64
|
||||
|
||||
// Only used by the 32bit stubGenerator. These can't be described by vmreg and hence
|
||||
@ -200,6 +220,46 @@ CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx5 , ( 5));
|
||||
CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx6 , ( 6));
|
||||
CONSTANT_REGISTER_DECLARATION(MMXRegister, mmx7 , ( 7));
|
||||
|
||||
// Use XMMRegister as shortcut
|
||||
class KRegisterImpl;
|
||||
typedef KRegisterImpl* KRegister;
|
||||
|
||||
inline KRegister as_KRegister(int encoding) {
|
||||
return (KRegister)(intptr_t)encoding;
|
||||
}
|
||||
|
||||
// The implementation of XMM registers for the IA32 architecture
|
||||
class KRegisterImpl : public AbstractRegisterImpl {
|
||||
public:
|
||||
enum {
|
||||
number_of_registers = 8,
|
||||
max_slots_per_register = 1
|
||||
};
|
||||
|
||||
// construction
|
||||
friend KRegister as_KRegister(int encoding);
|
||||
|
||||
inline VMReg as_VMReg();
|
||||
|
||||
// derived registers, offsets, and addresses
|
||||
KRegister successor() const { return as_KRegister(encoding() + 1); }
|
||||
|
||||
// accessors
|
||||
int encoding() const { assert(is_valid(), err_msg("invalid register (%d)", (int)(intptr_t)this)); return (intptr_t)this; }
|
||||
bool is_valid() const { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
|
||||
const char* name() const;
|
||||
};
|
||||
|
||||
// The Mask registers, for AVX3 enabled and up chips
|
||||
CONSTANT_REGISTER_DECLARATION(KRegister, knoreg, (-1));
|
||||
CONSTANT_REGISTER_DECLARATION(KRegister, k0, (0));
|
||||
CONSTANT_REGISTER_DECLARATION(KRegister, k1, (1));
|
||||
CONSTANT_REGISTER_DECLARATION(KRegister, k2, (2));
|
||||
CONSTANT_REGISTER_DECLARATION(KRegister, k3, (3));
|
||||
CONSTANT_REGISTER_DECLARATION(KRegister, k4, (4));
|
||||
CONSTANT_REGISTER_DECLARATION(KRegister, k5, (5));
|
||||
CONSTANT_REGISTER_DECLARATION(KRegister, k6, (6));
|
||||
CONSTANT_REGISTER_DECLARATION(KRegister, k7, (7));
|
||||
|
||||
// Need to know the total number of registers of all sorts for SharedInfo.
|
||||
// Define a class that exports it.
|
||||
@ -211,18 +271,20 @@ class ConcreteRegisterImpl : public AbstractRegisterImpl {
|
||||
// There is no requirement that any ordering here matches any ordering c2 gives
|
||||
// it's optoregs.
|
||||
|
||||
number_of_registers = RegisterImpl::number_of_registers +
|
||||
number_of_registers = RegisterImpl::number_of_registers +
|
||||
#ifdef AMD64
|
||||
RegisterImpl::number_of_registers + // "H" half of a 64bit register
|
||||
RegisterImpl::number_of_registers + // "H" half of a 64bit register
|
||||
#endif // AMD64
|
||||
2 * FloatRegisterImpl::number_of_registers +
|
||||
8 * XMMRegisterImpl::number_of_registers +
|
||||
1 // eflags
|
||||
2 * FloatRegisterImpl::number_of_registers +
|
||||
XMMRegisterImpl::max_slots_per_register * XMMRegisterImpl::number_of_registers +
|
||||
KRegisterImpl::number_of_registers + // mask registers
|
||||
1 // eflags
|
||||
};
|
||||
|
||||
static const int max_gpr;
|
||||
static const int max_fpr;
|
||||
static const int max_xmm;
|
||||
static const int max_kpr;
|
||||
|
||||
};
|
||||
|
||||
|
@ -117,9 +117,9 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
|
||||
int vect_words = 0;
|
||||
#ifdef COMPILER2
|
||||
if (save_vectors) {
|
||||
assert(UseAVX > 0, "256bit vectors are supported only with AVX");
|
||||
assert(MaxVectorSize == 32, "only 256bit vectors are supported now");
|
||||
// Save upper half of YMM registes
|
||||
assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
|
||||
assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
|
||||
// Save upper half of ZMM/YMM registers :
|
||||
vect_words = 8 * 16 / wordSize;
|
||||
additional_frame_words += vect_words;
|
||||
}
|
||||
@ -216,6 +216,17 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
|
||||
__ vextractf128h(Address(rsp, 80),xmm5);
|
||||
__ vextractf128h(Address(rsp, 96),xmm6);
|
||||
__ vextractf128h(Address(rsp,112),xmm7);
|
||||
if (UseAVX > 2) {
|
||||
__ subptr(rsp, 256); // Save upper half of ZMM registes
|
||||
__ vextractf64x4h(Address(rsp, 0), xmm0);
|
||||
__ vextractf64x4h(Address(rsp, 32), xmm1);
|
||||
__ vextractf64x4h(Address(rsp, 64), xmm2);
|
||||
__ vextractf64x4h(Address(rsp, 96), xmm3);
|
||||
__ vextractf64x4h(Address(rsp, 128), xmm4);
|
||||
__ vextractf64x4h(Address(rsp, 160), xmm5);
|
||||
__ vextractf64x4h(Address(rsp, 192), xmm6);
|
||||
__ vextractf64x4h(Address(rsp, 224), xmm7);
|
||||
}
|
||||
}
|
||||
|
||||
// Set an oopmap for the call site. This oopmap will map all
|
||||
@ -283,8 +294,8 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_ve
|
||||
int additional_frame_bytes = 0;
|
||||
#ifdef COMPILER2
|
||||
if (restore_vectors) {
|
||||
assert(UseAVX > 0, "256bit vectors are supported only with AVX");
|
||||
assert(MaxVectorSize == 32, "only 256bit vectors are supported now");
|
||||
assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
|
||||
assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
|
||||
additional_frame_bytes = 128;
|
||||
}
|
||||
#else
|
||||
@ -324,6 +335,18 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_ve
|
||||
__ vinsertf128h(xmm6, Address(rsp, 96));
|
||||
__ vinsertf128h(xmm7, Address(rsp,112));
|
||||
__ addptr(rsp, additional_frame_bytes);
|
||||
if (UseAVX > 2) {
|
||||
additional_frame_bytes = 256;
|
||||
__ vinsertf64x4h(xmm0, Address(rsp, 0));
|
||||
__ vinsertf64x4h(xmm1, Address(rsp, 32));
|
||||
__ vinsertf64x4h(xmm2, Address(rsp, 64));
|
||||
__ vinsertf64x4h(xmm3, Address(rsp, 96));
|
||||
__ vinsertf64x4h(xmm4, Address(rsp, 128));
|
||||
__ vinsertf64x4h(xmm5, Address(rsp, 160));
|
||||
__ vinsertf64x4h(xmm6, Address(rsp, 192));
|
||||
__ vinsertf64x4h(xmm7, Address(rsp, 224));
|
||||
__ addptr(rsp, additional_frame_bytes);
|
||||
}
|
||||
}
|
||||
__ pop_FPU_state();
|
||||
__ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers
|
||||
|
@ -86,7 +86,23 @@ class RegisterSaver {
|
||||
DEF_XMM_OFFS(13),
|
||||
DEF_XMM_OFFS(14),
|
||||
DEF_XMM_OFFS(15),
|
||||
fpu_state_end = fpu_state_off + ((FPUStateSizeInWords-1)*wordSize / BytesPerInt),
|
||||
DEF_XMM_OFFS(16),
|
||||
DEF_XMM_OFFS(17),
|
||||
DEF_XMM_OFFS(18),
|
||||
DEF_XMM_OFFS(19),
|
||||
DEF_XMM_OFFS(20),
|
||||
DEF_XMM_OFFS(21),
|
||||
DEF_XMM_OFFS(22),
|
||||
DEF_XMM_OFFS(23),
|
||||
DEF_XMM_OFFS(24),
|
||||
DEF_XMM_OFFS(25),
|
||||
DEF_XMM_OFFS(26),
|
||||
DEF_XMM_OFFS(27),
|
||||
DEF_XMM_OFFS(28),
|
||||
DEF_XMM_OFFS(29),
|
||||
DEF_XMM_OFFS(30),
|
||||
DEF_XMM_OFFS(31),
|
||||
fpu_state_end = fpu_state_off + ((FPUStateSizeInWords - 1)*wordSize / BytesPerInt),
|
||||
fpu_stateH_end,
|
||||
r15_off, r15H_off,
|
||||
r14_off, r14H_off,
|
||||
@ -136,13 +152,21 @@ class RegisterSaver {
|
||||
|
||||
OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
|
||||
int vect_words = 0;
|
||||
int num_xmm_regs = 16;
|
||||
if (UseAVX > 2) {
|
||||
num_xmm_regs = 32;
|
||||
}
|
||||
#ifdef COMPILER2
|
||||
if (save_vectors) {
|
||||
assert(UseAVX > 0, "256bit vectors are supported only with AVX");
|
||||
assert(MaxVectorSize == 32, "only 256bit vectors are supported now");
|
||||
// Save upper half of YMM registes
|
||||
vect_words = 16 * 16 / wordSize;
|
||||
assert(UseAVX > 0, "512bit vectors are supported only with EVEX");
|
||||
assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
|
||||
// Save upper half of YMM registers
|
||||
vect_words = 16 * num_xmm_regs / wordSize;
|
||||
additional_frame_words += vect_words;
|
||||
if (UseAVX > 2) {
|
||||
// Save upper half of ZMM registers as well
|
||||
additional_frame_words += vect_words;
|
||||
}
|
||||
}
|
||||
#else
|
||||
assert(!save_vectors, "vectors are generated only by C2");
|
||||
@ -150,7 +174,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
|
||||
|
||||
// Always make the frame size 16-byte aligned
|
||||
int frame_size_in_bytes = round_to(additional_frame_words*wordSize +
|
||||
reg_save_size*BytesPerInt, 16);
|
||||
reg_save_size*BytesPerInt, num_xmm_regs);
|
||||
// OopMap frame size is in compiler stack slots (jint's) not bytes or words
|
||||
int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
|
||||
// The caller will allocate additional_frame_words
|
||||
@ -169,24 +193,77 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
|
||||
__ push_CPU_state(); // Push a multiple of 16 bytes
|
||||
|
||||
if (vect_words > 0) {
|
||||
assert(vect_words*wordSize == 256, "");
|
||||
__ subptr(rsp, 256); // Save upper half of YMM registes
|
||||
__ vextractf128h(Address(rsp, 0),xmm0);
|
||||
__ vextractf128h(Address(rsp, 16),xmm1);
|
||||
__ vextractf128h(Address(rsp, 32),xmm2);
|
||||
__ vextractf128h(Address(rsp, 48),xmm3);
|
||||
__ vextractf128h(Address(rsp, 64),xmm4);
|
||||
__ vextractf128h(Address(rsp, 80),xmm5);
|
||||
__ vextractf128h(Address(rsp, 96),xmm6);
|
||||
__ vextractf128h(Address(rsp,112),xmm7);
|
||||
__ vextractf128h(Address(rsp,128),xmm8);
|
||||
__ vextractf128h(Address(rsp,144),xmm9);
|
||||
__ vextractf128h(Address(rsp,160),xmm10);
|
||||
__ vextractf128h(Address(rsp,176),xmm11);
|
||||
__ vextractf128h(Address(rsp,192),xmm12);
|
||||
__ vextractf128h(Address(rsp,208),xmm13);
|
||||
__ vextractf128h(Address(rsp,224),xmm14);
|
||||
__ vextractf128h(Address(rsp,240),xmm15);
|
||||
assert(vect_words*wordSize >= 256, "");
|
||||
__ subptr(rsp, 256); // Save upper half of YMM registes(0..15)
|
||||
__ vextractf128h(Address(rsp, 0), xmm0);
|
||||
__ vextractf128h(Address(rsp, 16), xmm1);
|
||||
__ vextractf128h(Address(rsp, 32), xmm2);
|
||||
__ vextractf128h(Address(rsp, 48), xmm3);
|
||||
__ vextractf128h(Address(rsp, 64), xmm4);
|
||||
__ vextractf128h(Address(rsp, 80), xmm5);
|
||||
__ vextractf128h(Address(rsp, 96), xmm6);
|
||||
__ vextractf128h(Address(rsp, 112), xmm7);
|
||||
__ vextractf128h(Address(rsp, 128), xmm8);
|
||||
__ vextractf128h(Address(rsp, 144), xmm9);
|
||||
__ vextractf128h(Address(rsp, 160), xmm10);
|
||||
__ vextractf128h(Address(rsp, 176), xmm11);
|
||||
__ vextractf128h(Address(rsp, 192), xmm12);
|
||||
__ vextractf128h(Address(rsp, 208), xmm13);
|
||||
__ vextractf128h(Address(rsp, 224), xmm14);
|
||||
__ vextractf128h(Address(rsp, 240), xmm15);
|
||||
if (UseAVX > 2) {
|
||||
__ subptr(rsp, 256); // Save upper half of YMM registes(16..31)
|
||||
__ vextractf128h(Address(rsp, 0), xmm16);
|
||||
__ vextractf128h(Address(rsp, 16), xmm17);
|
||||
__ vextractf128h(Address(rsp, 32), xmm18);
|
||||
__ vextractf128h(Address(rsp, 48), xmm19);
|
||||
__ vextractf128h(Address(rsp, 64), xmm20);
|
||||
__ vextractf128h(Address(rsp, 80), xmm21);
|
||||
__ vextractf128h(Address(rsp, 96), xmm22);
|
||||
__ vextractf128h(Address(rsp, 112), xmm23);
|
||||
__ vextractf128h(Address(rsp, 128), xmm24);
|
||||
__ vextractf128h(Address(rsp, 144), xmm25);
|
||||
__ vextractf128h(Address(rsp, 160), xmm26);
|
||||
__ vextractf128h(Address(rsp, 176), xmm27);
|
||||
__ vextractf128h(Address(rsp, 192), xmm28);
|
||||
__ vextractf128h(Address(rsp, 208), xmm29);
|
||||
__ vextractf128h(Address(rsp, 224), xmm30);
|
||||
__ vextractf128h(Address(rsp, 240), xmm31);
|
||||
// Now handle the ZMM registers (0..31)
|
||||
__ subptr(rsp, 1024); // Save upper half of ZMM registes
|
||||
__ vextractf64x4h(Address(rsp, 0), xmm0);
|
||||
__ vextractf64x4h(Address(rsp, 32), xmm1);
|
||||
__ vextractf64x4h(Address(rsp, 64), xmm2);
|
||||
__ vextractf64x4h(Address(rsp, 96), xmm3);
|
||||
__ vextractf64x4h(Address(rsp, 128), xmm4);
|
||||
__ vextractf64x4h(Address(rsp, 160), xmm5);
|
||||
__ vextractf64x4h(Address(rsp, 192), xmm6);
|
||||
__ vextractf64x4h(Address(rsp, 224), xmm7);
|
||||
__ vextractf64x4h(Address(rsp, 256), xmm8);
|
||||
__ vextractf64x4h(Address(rsp, 288), xmm9);
|
||||
__ vextractf64x4h(Address(rsp, 320), xmm10);
|
||||
__ vextractf64x4h(Address(rsp, 352), xmm11);
|
||||
__ vextractf64x4h(Address(rsp, 384), xmm12);
|
||||
__ vextractf64x4h(Address(rsp, 416), xmm13);
|
||||
__ vextractf64x4h(Address(rsp, 448), xmm14);
|
||||
__ vextractf64x4h(Address(rsp, 480), xmm15);
|
||||
__ vextractf64x4h(Address(rsp, 512), xmm16);
|
||||
__ vextractf64x4h(Address(rsp, 544), xmm17);
|
||||
__ vextractf64x4h(Address(rsp, 576), xmm18);
|
||||
__ vextractf64x4h(Address(rsp, 608), xmm19);
|
||||
__ vextractf64x4h(Address(rsp, 640), xmm20);
|
||||
__ vextractf64x4h(Address(rsp, 672), xmm21);
|
||||
__ vextractf64x4h(Address(rsp, 704), xmm22);
|
||||
__ vextractf64x4h(Address(rsp, 736), xmm23);
|
||||
__ vextractf64x4h(Address(rsp, 768), xmm24);
|
||||
__ vextractf64x4h(Address(rsp, 800), xmm25);
|
||||
__ vextractf64x4h(Address(rsp, 832), xmm26);
|
||||
__ vextractf64x4h(Address(rsp, 864), xmm27);
|
||||
__ vextractf64x4h(Address(rsp, 896), xmm28);
|
||||
__ vextractf64x4h(Address(rsp, 928), xmm29);
|
||||
__ vextractf64x4h(Address(rsp, 960), xmm30);
|
||||
__ vextractf64x4h(Address(rsp, 992), xmm31);
|
||||
}
|
||||
}
|
||||
if (frame::arg_reg_save_area_bytes != 0) {
|
||||
// Allocate argument register save area
|
||||
@ -235,6 +312,24 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
|
||||
map->set_callee_saved(STACK_OFFSET(xmm13_off), xmm13->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm14_off), xmm14->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm15_off), xmm15->as_VMReg());
|
||||
if (UseAVX > 2) {
|
||||
map->set_callee_saved(STACK_OFFSET(xmm16_off), xmm16->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm17_off), xmm17->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm18_off), xmm18->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm19_off), xmm19->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm20_off), xmm20->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm21_off), xmm21->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm22_off), xmm22->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm23_off), xmm23->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm24_off), xmm24->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm25_off), xmm25->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm26_off), xmm26->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm27_off), xmm27->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm28_off), xmm28->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm29_off), xmm29->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm30_off), xmm30->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm31_off), xmm31->as_VMReg());
|
||||
}
|
||||
|
||||
// %%% These should all be a waste but we'll keep things as they were for now
|
||||
if (true) {
|
||||
@ -269,6 +364,24 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
|
||||
map->set_callee_saved(STACK_OFFSET(xmm13H_off), xmm13->as_VMReg()->next());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm14H_off), xmm14->as_VMReg()->next());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm15H_off), xmm15->as_VMReg()->next());
|
||||
if (UseAVX > 2) {
|
||||
map->set_callee_saved(STACK_OFFSET(xmm16H_off), xmm16->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm17H_off), xmm17->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm18H_off), xmm18->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm19H_off), xmm19->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm20H_off), xmm20->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm21H_off), xmm21->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm22H_off), xmm22->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm23H_off), xmm23->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm24H_off), xmm24->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm25H_off), xmm25->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm26H_off), xmm26->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm27H_off), xmm27->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm28H_off), xmm28->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm29H_off), xmm29->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm30H_off), xmm30->as_VMReg());
|
||||
map->set_callee_saved(STACK_OFFSET(xmm31H_off), xmm31->as_VMReg());
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
@ -281,9 +394,9 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_ve
|
||||
}
|
||||
#ifdef COMPILER2
|
||||
if (restore_vectors) {
|
||||
// Restore upper half of YMM registes.
|
||||
assert(UseAVX > 0, "256bit vectors are supported only with AVX");
|
||||
assert(MaxVectorSize == 32, "only 256bit vectors are supported now");
|
||||
// Restore upper half of YMM registes (0..15)
|
||||
assert(UseAVX > 0, "512bit vectors are supported only with AVX");
|
||||
assert(MaxVectorSize == 64, "only 512bit vectors are supported now");
|
||||
__ vinsertf128h(xmm0, Address(rsp, 0));
|
||||
__ vinsertf128h(xmm1, Address(rsp, 16));
|
||||
__ vinsertf128h(xmm2, Address(rsp, 32));
|
||||
@ -301,6 +414,60 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_ve
|
||||
__ vinsertf128h(xmm14, Address(rsp,224));
|
||||
__ vinsertf128h(xmm15, Address(rsp,240));
|
||||
__ addptr(rsp, 256);
|
||||
if (UseAVX > 2) {
|
||||
// Restore upper half of YMM registes (16..31)
|
||||
__ vinsertf128h(xmm16, Address(rsp, 0));
|
||||
__ vinsertf128h(xmm17, Address(rsp, 16));
|
||||
__ vinsertf128h(xmm18, Address(rsp, 32));
|
||||
__ vinsertf128h(xmm19, Address(rsp, 48));
|
||||
__ vinsertf128h(xmm20, Address(rsp, 64));
|
||||
__ vinsertf128h(xmm21, Address(rsp, 80));
|
||||
__ vinsertf128h(xmm22, Address(rsp, 96));
|
||||
__ vinsertf128h(xmm23, Address(rsp,112));
|
||||
__ vinsertf128h(xmm24, Address(rsp,128));
|
||||
__ vinsertf128h(xmm25, Address(rsp,144));
|
||||
__ vinsertf128h(xmm26, Address(rsp,160));
|
||||
__ vinsertf128h(xmm27, Address(rsp,176));
|
||||
__ vinsertf128h(xmm28, Address(rsp,192));
|
||||
__ vinsertf128h(xmm29, Address(rsp,208));
|
||||
__ vinsertf128h(xmm30, Address(rsp,224));
|
||||
__ vinsertf128h(xmm31, Address(rsp,240));
|
||||
__ addptr(rsp, 256);
|
||||
// Restore upper half of ZMM registes.
|
||||
__ vinsertf64x4h(xmm0, Address(rsp, 0));
|
||||
__ vinsertf64x4h(xmm1, Address(rsp, 32));
|
||||
__ vinsertf64x4h(xmm2, Address(rsp, 64));
|
||||
__ vinsertf64x4h(xmm3, Address(rsp, 96));
|
||||
__ vinsertf64x4h(xmm4, Address(rsp, 128));
|
||||
__ vinsertf64x4h(xmm5, Address(rsp, 160));
|
||||
__ vinsertf64x4h(xmm6, Address(rsp, 192));
|
||||
__ vinsertf64x4h(xmm7, Address(rsp, 224));
|
||||
__ vinsertf64x4h(xmm8, Address(rsp, 256));
|
||||
__ vinsertf64x4h(xmm9, Address(rsp, 288));
|
||||
__ vinsertf64x4h(xmm10, Address(rsp, 320));
|
||||
__ vinsertf64x4h(xmm11, Address(rsp, 352));
|
||||
__ vinsertf64x4h(xmm12, Address(rsp, 384));
|
||||
__ vinsertf64x4h(xmm13, Address(rsp, 416));
|
||||
__ vinsertf64x4h(xmm14, Address(rsp, 448));
|
||||
__ vinsertf64x4h(xmm15, Address(rsp, 480));
|
||||
__ vinsertf64x4h(xmm16, Address(rsp, 512));
|
||||
__ vinsertf64x4h(xmm17, Address(rsp, 544));
|
||||
__ vinsertf64x4h(xmm18, Address(rsp, 576));
|
||||
__ vinsertf64x4h(xmm19, Address(rsp, 608));
|
||||
__ vinsertf64x4h(xmm20, Address(rsp, 640));
|
||||
__ vinsertf64x4h(xmm21, Address(rsp, 672));
|
||||
__ vinsertf64x4h(xmm22, Address(rsp, 704));
|
||||
__ vinsertf64x4h(xmm23, Address(rsp, 736));
|
||||
__ vinsertf64x4h(xmm24, Address(rsp, 768));
|
||||
__ vinsertf64x4h(xmm25, Address(rsp, 800));
|
||||
__ vinsertf64x4h(xmm26, Address(rsp, 832));
|
||||
__ vinsertf64x4h(xmm27, Address(rsp, 864));
|
||||
__ vinsertf64x4h(xmm28, Address(rsp, 896));
|
||||
__ vinsertf64x4h(xmm29, Address(rsp, 928));
|
||||
__ vinsertf64x4h(xmm30, Address(rsp, 960));
|
||||
__ vinsertf64x4h(xmm31, Address(rsp, 992));
|
||||
__ subptr(rsp, 1024);
|
||||
}
|
||||
}
|
||||
#else
|
||||
assert(!restore_vectors, "vectors are generated only by C2");
|
||||
|
@ -166,6 +166,13 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ movptr(saved_rdi, rdi);
|
||||
__ movptr(saved_rsi, rsi);
|
||||
__ movptr(saved_rbx, rbx);
|
||||
|
||||
// provide initial value for required masks
|
||||
if (UseAVX > 2) {
|
||||
__ movl(rbx, 0xffff);
|
||||
__ kmovdl(k1, rbx);
|
||||
}
|
||||
|
||||
// save and initialize %mxcsr
|
||||
if (sse_save) {
|
||||
Label skip_ldmx;
|
||||
@ -794,7 +801,10 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ BIND(L_copy_64_bytes_loop);
|
||||
|
||||
if (UseUnalignedLoadStores) {
|
||||
if (UseAVX >= 2) {
|
||||
if (UseAVX > 2) {
|
||||
__ evmovdqu(xmm0, Address(from, 0), Assembler::AVX_512bit);
|
||||
__ evmovdqu(Address(from, to_from, Address::times_1, 0), xmm0, Assembler::AVX_512bit);
|
||||
} else if (UseAVX == 2) {
|
||||
__ vmovdqu(xmm0, Address(from, 0));
|
||||
__ vmovdqu(Address(from, to_from, Address::times_1, 0), xmm0);
|
||||
__ vmovdqu(xmm1, Address(from, 32));
|
||||
@ -833,7 +843,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ subl(qword_count, 8);
|
||||
__ jcc(Assembler::greaterEqual, L_copy_64_bytes_loop);
|
||||
|
||||
if (UseUnalignedLoadStores && (UseAVX >= 2)) {
|
||||
if (UseUnalignedLoadStores && (UseAVX == 2)) {
|
||||
// clean upper bits of YMM registers
|
||||
__ vpxor(xmm0, xmm0);
|
||||
__ vpxor(xmm1, xmm1);
|
||||
|
@ -137,8 +137,10 @@ class StubGenerator: public StubCodeGenerator {
|
||||
// [ return_from_Java ] <--- rsp
|
||||
// [ argument word n ]
|
||||
// ...
|
||||
// -28 [ argument word 1 ]
|
||||
// -27 [ saved xmm15 ] <--- rsp_after_call
|
||||
// -60 [ argument word 1 ]
|
||||
// -59 [ saved xmm31 ] <--- rsp after_call
|
||||
// [ saved xmm16-xmm30 ] (EVEX enabled, else the space is blank)
|
||||
// -27 [ saved xmm15 ]
|
||||
// [ saved xmm7-xmm14 ]
|
||||
// -9 [ saved xmm6 ] (each xmm register takes 2 slots)
|
||||
// -7 [ saved r15 ]
|
||||
@ -166,7 +168,7 @@ class StubGenerator: public StubCodeGenerator {
|
||||
enum call_stub_layout {
|
||||
#ifdef _WIN64
|
||||
xmm_save_first = 6, // save from xmm6
|
||||
xmm_save_last = 15, // to xmm15
|
||||
xmm_save_last = 31, // to xmm31
|
||||
xmm_save_base = -9,
|
||||
rsp_after_call_off = xmm_save_base - 2 * (xmm_save_last - xmm_save_first), // -27
|
||||
r15_off = -7,
|
||||
@ -262,9 +264,19 @@ class StubGenerator: public StubCodeGenerator {
|
||||
__ movptr(r13_save, r13);
|
||||
__ movptr(r14_save, r14);
|
||||
__ movptr(r15_save, r15);
|
||||
if (UseAVX > 2) {
|
||||
__ movl(rbx, 0xffff);
|
||||
__ kmovql(k1, rbx);
|
||||
}
|
||||
#ifdef _WIN64
|
||||
for (int i = 6; i <= 15; i++) {
|
||||
__ movdqu(xmm_save(i), as_XMMRegister(i));
|
||||
if (UseAVX > 2) {
|
||||
for (int i = 6; i <= 31; i++) {
|
||||
__ movdqu(xmm_save(i), as_XMMRegister(i));
|
||||
}
|
||||
} else {
|
||||
for (int i = 6; i <= 15; i++) {
|
||||
__ movdqu(xmm_save(i), as_XMMRegister(i));
|
||||
}
|
||||
}
|
||||
|
||||
const Address rdi_save(rbp, rdi_off * wordSize);
|
||||
@ -1318,7 +1330,10 @@ class StubGenerator: public StubCodeGenerator {
|
||||
Label L_end;
|
||||
// Copy 64-bytes per iteration
|
||||
__ BIND(L_loop);
|
||||
if (UseAVX >= 2) {
|
||||
if (UseAVX > 2) {
|
||||
__ evmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56), Assembler::AVX_512bit);
|
||||
__ evmovdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0, Assembler::AVX_512bit);
|
||||
} else if (UseAVX == 2) {
|
||||
__ vmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56));
|
||||
__ vmovdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0);
|
||||
__ vmovdqu(xmm1, Address(end_from, qword_count, Address::times_8, -24));
|
||||
@ -1395,7 +1410,10 @@ class StubGenerator: public StubCodeGenerator {
|
||||
Label L_end;
|
||||
// Copy 64-bytes per iteration
|
||||
__ BIND(L_loop);
|
||||
if (UseAVX >= 2) {
|
||||
if (UseAVX > 2) {
|
||||
__ evmovdqu(xmm0, Address(from, qword_count, Address::times_8, 32), Assembler::AVX_512bit);
|
||||
__ evmovdqu(Address(dest, qword_count, Address::times_8, 32), xmm0, Assembler::AVX_512bit);
|
||||
} else if (UseAVX == 2) {
|
||||
__ vmovdqu(xmm0, Address(from, qword_count, Address::times_8, 32));
|
||||
__ vmovdqu(Address(dest, qword_count, Address::times_8, 32), xmm0);
|
||||
__ vmovdqu(xmm1, Address(from, qword_count, Address::times_8, 0));
|
||||
|
@ -35,7 +35,7 @@
|
||||
int VM_Version::_cpu;
|
||||
int VM_Version::_model;
|
||||
int VM_Version::_stepping;
|
||||
int VM_Version::_cpuFeatures;
|
||||
uint64_t VM_Version::_cpuFeatures;
|
||||
const char* VM_Version::_features_str = "";
|
||||
VM_Version::CpuidInfo VM_Version::_cpuid_info = { 0, };
|
||||
|
||||
@ -45,7 +45,7 @@ address VM_Version::_cpuinfo_segv_addr = 0;
|
||||
address VM_Version::_cpuinfo_cont_addr = 0;
|
||||
|
||||
static BufferBlob* stub_blob;
|
||||
static const int stub_size = 600;
|
||||
static const int stub_size = 1000;
|
||||
|
||||
extern "C" {
|
||||
typedef void (*get_cpu_info_stub_t)(void*);
|
||||
@ -60,15 +60,16 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
|
||||
|
||||
address generate_get_cpu_info() {
|
||||
// Flags to test CPU type.
|
||||
const uint32_t HS_EFL_AC = 0x40000;
|
||||
const uint32_t HS_EFL_ID = 0x200000;
|
||||
const uint32_t HS_EFL_AC = 0x40000;
|
||||
const uint32_t HS_EFL_ID = 0x200000;
|
||||
// Values for when we don't have a CPUID instruction.
|
||||
const int CPU_FAMILY_SHIFT = 8;
|
||||
const uint32_t CPU_FAMILY_386 = (3 << CPU_FAMILY_SHIFT);
|
||||
const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT);
|
||||
const uint32_t CPU_FAMILY_386 = (3 << CPU_FAMILY_SHIFT);
|
||||
const uint32_t CPU_FAMILY_486 = (4 << CPU_FAMILY_SHIFT);
|
||||
|
||||
Label detect_486, cpu486, detect_586, std_cpuid1, std_cpuid4;
|
||||
Label sef_cpuid, ext_cpuid, ext_cpuid1, ext_cpuid5, ext_cpuid7, done;
|
||||
Label sef_cpuid, ext_cpuid, ext_cpuid1, ext_cpuid5, ext_cpuid7, done, wrapup;
|
||||
Label legacy_setup, save_restore_except, legacy_save_restore, start_simd_check;
|
||||
|
||||
StubCodeMark mark(this, "VM_Version", "get_cpu_info_stub");
|
||||
# define __ _masm->
|
||||
@ -241,53 +242,6 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
|
||||
__ movl(Address(rsi, 0), rax);
|
||||
__ movl(Address(rsi, 4), rdx);
|
||||
|
||||
__ andl(rax, 0x6); // xcr0 bits sse | ymm
|
||||
__ cmpl(rax, 0x6);
|
||||
__ jccb(Assembler::notEqual, sef_cpuid); // jump if AVX is not supported
|
||||
|
||||
//
|
||||
// Some OSs have a bug when upper 128bits of YMM
|
||||
// registers are not restored after a signal processing.
|
||||
// Generate SEGV here (reference through NULL)
|
||||
// and check upper YMM bits after it.
|
||||
//
|
||||
VM_Version::set_avx_cpuFeatures(); // Enable temporary to pass asserts
|
||||
intx saved_useavx = UseAVX;
|
||||
intx saved_usesse = UseSSE;
|
||||
UseAVX = 1;
|
||||
UseSSE = 2;
|
||||
|
||||
// load value into all 32 bytes of ymm7 register
|
||||
__ movl(rcx, VM_Version::ymm_test_value());
|
||||
|
||||
__ movdl(xmm0, rcx);
|
||||
__ pshufd(xmm0, xmm0, 0x00);
|
||||
__ vinsertf128h(xmm0, xmm0, xmm0);
|
||||
__ vmovdqu(xmm7, xmm0);
|
||||
#ifdef _LP64
|
||||
__ vmovdqu(xmm8, xmm0);
|
||||
__ vmovdqu(xmm15, xmm0);
|
||||
#endif
|
||||
|
||||
__ xorl(rsi, rsi);
|
||||
VM_Version::set_cpuinfo_segv_addr( __ pc() );
|
||||
// Generate SEGV
|
||||
__ movl(rax, Address(rsi, 0));
|
||||
|
||||
VM_Version::set_cpuinfo_cont_addr( __ pc() );
|
||||
// Returns here after signal. Save xmm0 to check it later.
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::ymm_save_offset())));
|
||||
__ vmovdqu(Address(rsi, 0), xmm0);
|
||||
__ vmovdqu(Address(rsi, 32), xmm7);
|
||||
#ifdef _LP64
|
||||
__ vmovdqu(Address(rsi, 64), xmm8);
|
||||
__ vmovdqu(Address(rsi, 96), xmm15);
|
||||
#endif
|
||||
|
||||
VM_Version::clean_cpuFeatures();
|
||||
UseAVX = saved_useavx;
|
||||
UseSSE = saved_usesse;
|
||||
|
||||
//
|
||||
// cpuid(0x7) Structured Extended Features
|
||||
//
|
||||
@ -364,9 +318,143 @@ class VM_Version_StubGenerator: public StubCodeGenerator {
|
||||
__ movl(Address(rsi,12), rdx);
|
||||
|
||||
//
|
||||
// return
|
||||
// Check if OS has enabled XGETBV instruction to access XCR0
|
||||
// (OSXSAVE feature flag) and CPU supports AVX
|
||||
//
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset())));
|
||||
__ movl(rcx, 0x18000000); // cpuid1 bits osxsave | avx
|
||||
__ andl(rcx, Address(rsi, 8)); // cpuid1 bits osxsave | avx
|
||||
__ cmpl(rcx, 0x18000000);
|
||||
__ jccb(Assembler::notEqual, done); // jump if AVX is not supported
|
||||
|
||||
__ movl(rax, 0x6);
|
||||
__ andl(rax, Address(rbp, in_bytes(VM_Version::xem_xcr0_offset()))); // xcr0 bits sse | ymm
|
||||
__ cmpl(rax, 0x6);
|
||||
__ jccb(Assembler::equal, start_simd_check); // return if AVX is not supported
|
||||
|
||||
// we need to bridge farther than imm8, so we use this island as a thunk
|
||||
__ bind(done);
|
||||
__ jmp(wrapup);
|
||||
|
||||
__ bind(start_simd_check);
|
||||
//
|
||||
// Some OSs have a bug when upper 128/256bits of YMM/ZMM
|
||||
// registers are not restored after a signal processing.
|
||||
// Generate SEGV here (reference through NULL)
|
||||
// and check upper YMM/ZMM bits after it.
|
||||
//
|
||||
intx saved_useavx = UseAVX;
|
||||
intx saved_usesse = UseSSE;
|
||||
// check _cpuid_info.sef_cpuid7_ebx.bits.avx512f
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::sef_cpuid7_offset())));
|
||||
__ movl(rax, 0x10000);
|
||||
__ andl(rax, Address(rsi, 4)); // xcr0 bits sse | ymm
|
||||
__ cmpl(rax, 0x10000);
|
||||
__ jccb(Assembler::notEqual, legacy_setup); // jump if EVEX is not supported
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.opmask
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.zmm512
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.zmm32
|
||||
__ movl(rax, 0xE0);
|
||||
__ andl(rax, Address(rbp, in_bytes(VM_Version::xem_xcr0_offset()))); // xcr0 bits sse | ymm
|
||||
__ cmpl(rax, 0xE0);
|
||||
__ jccb(Assembler::notEqual, legacy_setup); // jump if EVEX is not supported
|
||||
|
||||
// EVEX setup: run in lowest evex mode
|
||||
VM_Version::set_evex_cpuFeatures(); // Enable temporary to pass asserts
|
||||
UseAVX = 3;
|
||||
UseSSE = 2;
|
||||
// load value into all 64 bytes of zmm7 register
|
||||
__ movl(rcx, VM_Version::ymm_test_value());
|
||||
__ movdl(xmm0, rcx);
|
||||
__ movl(rcx, 0xffff);
|
||||
#ifdef _LP64
|
||||
__ kmovql(k1, rcx);
|
||||
#else
|
||||
__ kmovdl(k1, rcx);
|
||||
#endif
|
||||
__ evpbroadcastd(xmm0, xmm0, Assembler::AVX_512bit);
|
||||
__ evmovdqu(xmm7, xmm0, Assembler::AVX_512bit);
|
||||
#ifdef _LP64
|
||||
__ evmovdqu(xmm8, xmm0, Assembler::AVX_512bit);
|
||||
__ evmovdqu(xmm31, xmm0, Assembler::AVX_512bit);
|
||||
#endif
|
||||
VM_Version::clean_cpuFeatures();
|
||||
__ jmp(save_restore_except);
|
||||
|
||||
__ bind(legacy_setup);
|
||||
// AVX setup
|
||||
VM_Version::set_avx_cpuFeatures(); // Enable temporary to pass asserts
|
||||
UseAVX = 1;
|
||||
UseSSE = 2;
|
||||
// load value into all 32 bytes of ymm7 register
|
||||
__ movl(rcx, VM_Version::ymm_test_value());
|
||||
|
||||
__ movdl(xmm0, rcx);
|
||||
__ pshufd(xmm0, xmm0, 0x00);
|
||||
__ vinsertf128h(xmm0, xmm0, xmm0);
|
||||
__ vmovdqu(xmm7, xmm0);
|
||||
#ifdef _LP64
|
||||
__ vmovdqu(xmm8, xmm0);
|
||||
__ vmovdqu(xmm15, xmm0);
|
||||
#endif
|
||||
VM_Version::clean_cpuFeatures();
|
||||
|
||||
__ bind(save_restore_except);
|
||||
__ xorl(rsi, rsi);
|
||||
VM_Version::set_cpuinfo_segv_addr(__ pc());
|
||||
// Generate SEGV
|
||||
__ movl(rax, Address(rsi, 0));
|
||||
|
||||
VM_Version::set_cpuinfo_cont_addr(__ pc());
|
||||
// Returns here after signal. Save xmm0 to check it later.
|
||||
|
||||
// check _cpuid_info.sef_cpuid7_ebx.bits.avx512f
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::sef_cpuid7_offset())));
|
||||
__ movl(rax, 0x10000);
|
||||
__ andl(rax, Address(rsi, 4));
|
||||
__ cmpl(rax, 0x10000);
|
||||
__ jccb(Assembler::notEqual, legacy_save_restore);
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.opmask
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.zmm512
|
||||
// check _cpuid_info.xem_xcr0_eax.bits.zmm32
|
||||
__ movl(rax, 0xE0);
|
||||
__ andl(rax, Address(rbp, in_bytes(VM_Version::xem_xcr0_offset()))); // xcr0 bits sse | ymm
|
||||
__ cmpl(rax, 0xE0);
|
||||
__ jccb(Assembler::notEqual, legacy_save_restore);
|
||||
|
||||
// EVEX check: run in lowest evex mode
|
||||
VM_Version::set_evex_cpuFeatures(); // Enable temporary to pass asserts
|
||||
UseAVX = 3;
|
||||
UseSSE = 2;
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::zmm_save_offset())));
|
||||
__ evmovdqu(Address(rsi, 0), xmm0, Assembler::AVX_512bit);
|
||||
__ evmovdqu(Address(rsi, 64), xmm7, Assembler::AVX_512bit);
|
||||
#ifdef _LP64
|
||||
__ evmovdqu(Address(rsi, 128), xmm8, Assembler::AVX_512bit);
|
||||
__ evmovdqu(Address(rsi, 192), xmm31, Assembler::AVX_512bit);
|
||||
#endif
|
||||
VM_Version::clean_cpuFeatures();
|
||||
UseAVX = saved_useavx;
|
||||
UseSSE = saved_usesse;
|
||||
__ jmp(wrapup);
|
||||
|
||||
__ bind(legacy_save_restore);
|
||||
// AVX check
|
||||
VM_Version::set_avx_cpuFeatures(); // Enable temporary to pass asserts
|
||||
UseAVX = 1;
|
||||
UseSSE = 2;
|
||||
__ lea(rsi, Address(rbp, in_bytes(VM_Version::ymm_save_offset())));
|
||||
__ vmovdqu(Address(rsi, 0), xmm0);
|
||||
__ vmovdqu(Address(rsi, 32), xmm7);
|
||||
#ifdef _LP64
|
||||
__ vmovdqu(Address(rsi, 64), xmm8);
|
||||
__ vmovdqu(Address(rsi, 96), xmm15);
|
||||
#endif
|
||||
VM_Version::clean_cpuFeatures();
|
||||
UseAVX = saved_useavx;
|
||||
UseSSE = saved_usesse;
|
||||
|
||||
__ bind(wrapup);
|
||||
__ popf();
|
||||
__ pop(rsi);
|
||||
__ pop(rbx);
|
||||
@ -459,6 +547,29 @@ void VM_Version::get_processor_features() {
|
||||
if (UseSSE < 1)
|
||||
_cpuFeatures &= ~CPU_SSE;
|
||||
|
||||
// first try initial setting and detect what we can support
|
||||
if (UseAVX > 0) {
|
||||
if (UseAVX > 2 && supports_evex()) {
|
||||
UseAVX = 3;
|
||||
} else if (UseAVX > 1 && supports_avx2()) {
|
||||
UseAVX = 2;
|
||||
} else if (UseAVX > 0 && supports_avx()) {
|
||||
UseAVX = 1;
|
||||
} else {
|
||||
UseAVX = 0;
|
||||
}
|
||||
} else if (UseAVX < 0) {
|
||||
UseAVX = 0;
|
||||
}
|
||||
|
||||
if (UseAVX < 3) {
|
||||
_cpuFeatures &= ~CPU_AVX512F;
|
||||
_cpuFeatures &= ~CPU_AVX512DQ;
|
||||
_cpuFeatures &= ~CPU_AVX512CD;
|
||||
_cpuFeatures &= ~CPU_AVX512BW;
|
||||
_cpuFeatures &= ~CPU_AVX512VL;
|
||||
}
|
||||
|
||||
if (UseAVX < 2)
|
||||
_cpuFeatures &= ~CPU_AVX2;
|
||||
|
||||
@ -474,7 +585,7 @@ void VM_Version::get_processor_features() {
|
||||
}
|
||||
|
||||
char buf[256];
|
||||
jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
|
||||
cores_per_cpu(), threads_per_core(),
|
||||
cpu_family(), _model, _stepping,
|
||||
(supports_cmov() ? ", cmov" : ""),
|
||||
@ -504,7 +615,8 @@ void VM_Version::get_processor_features() {
|
||||
(supports_tscinv() ? ", tscinv": ""),
|
||||
(supports_bmi1() ? ", bmi1" : ""),
|
||||
(supports_bmi2() ? ", bmi2" : ""),
|
||||
(supports_adx() ? ", adx" : ""));
|
||||
(supports_adx() ? ", adx" : ""),
|
||||
(supports_evex() ? ", evex" : ""));
|
||||
_features_str = os::strdup(buf);
|
||||
|
||||
// UseSSE is set to the smaller of what hardware supports and what
|
||||
@ -521,13 +633,6 @@ void VM_Version::get_processor_features() {
|
||||
if (!supports_sse ()) // Drop to 0 if no SSE support
|
||||
UseSSE = 0;
|
||||
|
||||
if (UseAVX > 2) UseAVX=2;
|
||||
if (UseAVX < 0) UseAVX=0;
|
||||
if (!supports_avx2()) // Drop to 1 if no AVX2 support
|
||||
UseAVX = MIN2((intx)1,UseAVX);
|
||||
if (!supports_avx ()) // Drop to 0 if no AVX support
|
||||
UseAVX = 0;
|
||||
|
||||
// Use AES instructions if available.
|
||||
if (supports_aes()) {
|
||||
if (FLAG_IS_DEFAULT(UseAES)) {
|
||||
@ -598,7 +703,8 @@ void VM_Version::get_processor_features() {
|
||||
if ((_model == CPU_MODEL_HASWELL_E3) ||
|
||||
(_model == CPU_MODEL_HASWELL_E7 && _stepping < 3) ||
|
||||
(_model == CPU_MODEL_BROADWELL && _stepping < 4)) {
|
||||
if (!UnlockExperimentalVMOptions) {
|
||||
// currently a collision between SKL and HSW_E3
|
||||
if (!UnlockExperimentalVMOptions && UseAVX < 3) {
|
||||
vm_exit_during_initialization("UseRTMLocking is only available as experimental option on this platform. It must be enabled via -XX:+UnlockExperimentalVMOptions flag.");
|
||||
} else {
|
||||
warning("UseRTMLocking is only available as experimental option on this platform.");
|
||||
@ -651,10 +757,10 @@ void VM_Version::get_processor_features() {
|
||||
if (MaxVectorSize > 0) {
|
||||
if (!is_power_of_2(MaxVectorSize)) {
|
||||
warning("MaxVectorSize must be a power of 2");
|
||||
FLAG_SET_DEFAULT(MaxVectorSize, 32);
|
||||
FLAG_SET_DEFAULT(MaxVectorSize, 64);
|
||||
}
|
||||
if (MaxVectorSize > 32) {
|
||||
FLAG_SET_DEFAULT(MaxVectorSize, 32);
|
||||
if (MaxVectorSize > 64) {
|
||||
FLAG_SET_DEFAULT(MaxVectorSize, 64);
|
||||
}
|
||||
if (MaxVectorSize > 16 && (UseAVX == 0 || !os_supports_avx_vectors())) {
|
||||
// 32 bytes vectors (in YMM) are only supported with AVX+
|
||||
|
@ -208,20 +208,33 @@ public:
|
||||
bmi2 : 1,
|
||||
erms : 1,
|
||||
: 1,
|
||||
rtm : 1,
|
||||
: 7,
|
||||
adx : 1,
|
||||
: 12;
|
||||
rtm : 1,
|
||||
: 4,
|
||||
avx512f : 1,
|
||||
avx512dq : 1,
|
||||
: 1,
|
||||
adx : 1,
|
||||
: 6,
|
||||
avx512pf : 1,
|
||||
avx512er : 1,
|
||||
avx512cd : 1,
|
||||
: 1,
|
||||
avx512bw : 1,
|
||||
avx512vl : 1;
|
||||
} bits;
|
||||
};
|
||||
|
||||
union XemXcr0Eax {
|
||||
uint32_t value;
|
||||
struct {
|
||||
uint32_t x87 : 1,
|
||||
sse : 1,
|
||||
ymm : 1,
|
||||
: 29;
|
||||
uint32_t x87 : 1,
|
||||
sse : 1,
|
||||
ymm : 1,
|
||||
: 2,
|
||||
opmask : 1,
|
||||
zmm512 : 1,
|
||||
zmm32 : 1,
|
||||
: 24;
|
||||
} bits;
|
||||
};
|
||||
|
||||
@ -229,43 +242,51 @@ protected:
|
||||
static int _cpu;
|
||||
static int _model;
|
||||
static int _stepping;
|
||||
static int _cpuFeatures; // features returned by the "cpuid" instruction
|
||||
// 0 if this instruction is not available
|
||||
static uint64_t _cpuFeatures; // features returned by the "cpuid" instruction
|
||||
// 0 if this instruction is not available
|
||||
static const char* _features_str;
|
||||
|
||||
static address _cpuinfo_segv_addr; // address of instruction which causes SEGV
|
||||
static address _cpuinfo_cont_addr; // address of instruction after the one which causes SEGV
|
||||
|
||||
enum {
|
||||
CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX)
|
||||
CPU_CMOV = (1 << 1),
|
||||
CPU_FXSR = (1 << 2),
|
||||
CPU_HT = (1 << 3),
|
||||
CPU_MMX = (1 << 4),
|
||||
CPU_3DNOW_PREFETCH = (1 << 5), // Processor supports 3dnow prefetch and prefetchw instructions
|
||||
// may not necessarily support other 3dnow instructions
|
||||
CPU_SSE = (1 << 6),
|
||||
CPU_SSE2 = (1 << 7),
|
||||
CPU_SSE3 = (1 << 8), // SSE3 comes from cpuid 1 (ECX)
|
||||
CPU_SSSE3 = (1 << 9),
|
||||
CPU_SSE4A = (1 << 10),
|
||||
CPU_SSE4_1 = (1 << 11),
|
||||
CPU_SSE4_2 = (1 << 12),
|
||||
CPU_POPCNT = (1 << 13),
|
||||
CPU_LZCNT = (1 << 14),
|
||||
CPU_TSC = (1 << 15),
|
||||
CPU_TSCINV = (1 << 16),
|
||||
CPU_AVX = (1 << 17),
|
||||
CPU_AVX2 = (1 << 18),
|
||||
CPU_AES = (1 << 19),
|
||||
CPU_ERMS = (1 << 20), // enhanced 'rep movsb/stosb' instructions
|
||||
CPU_CLMUL = (1 << 21), // carryless multiply for CRC
|
||||
CPU_BMI1 = (1 << 22),
|
||||
CPU_BMI2 = (1 << 23),
|
||||
CPU_RTM = (1 << 24), // Restricted Transactional Memory instructions
|
||||
CPU_ADX = (1 << 25)
|
||||
CPU_CX8 = (1 << 0), // next bits are from cpuid 1 (EDX)
|
||||
CPU_CMOV = (1 << 1),
|
||||
CPU_FXSR = (1 << 2),
|
||||
CPU_HT = (1 << 3),
|
||||
CPU_MMX = (1 << 4),
|
||||
CPU_3DNOW_PREFETCH = (1 << 5), // Processor supports 3dnow prefetch and prefetchw instructions
|
||||
// may not necessarily support other 3dnow instructions
|
||||
CPU_SSE = (1 << 6),
|
||||
CPU_SSE2 = (1 << 7),
|
||||
CPU_SSE3 = (1 << 8), // SSE3 comes from cpuid 1 (ECX)
|
||||
CPU_SSSE3 = (1 << 9),
|
||||
CPU_SSE4A = (1 << 10),
|
||||
CPU_SSE4_1 = (1 << 11),
|
||||
CPU_SSE4_2 = (1 << 12),
|
||||
CPU_POPCNT = (1 << 13),
|
||||
CPU_LZCNT = (1 << 14),
|
||||
CPU_TSC = (1 << 15),
|
||||
CPU_TSCINV = (1 << 16),
|
||||
CPU_AVX = (1 << 17),
|
||||
CPU_AVX2 = (1 << 18),
|
||||
CPU_AES = (1 << 19),
|
||||
CPU_ERMS = (1 << 20), // enhanced 'rep movsb/stosb' instructions
|
||||
CPU_CLMUL = (1 << 21), // carryless multiply for CRC
|
||||
CPU_BMI1 = (1 << 22),
|
||||
CPU_BMI2 = (1 << 23),
|
||||
CPU_RTM = (1 << 24), // Restricted Transactional Memory instructions
|
||||
CPU_ADX = (1 << 25),
|
||||
CPU_AVX512F = (1 << 26), // AVX 512bit foundation instructions
|
||||
CPU_AVX512DQ = (1 << 27),
|
||||
CPU_AVX512PF = (1 << 28),
|
||||
CPU_AVX512ER = (1 << 29),
|
||||
CPU_AVX512CD = (1 << 30),
|
||||
CPU_AVX512BW = (1 << 31)
|
||||
} cpuFeatureFlags;
|
||||
|
||||
#define CPU_AVX512VL 0x100000000 // EVEX instructions with smaller vector length : enums are limited to 32bit
|
||||
|
||||
enum {
|
||||
// AMD
|
||||
CPU_FAMILY_AMD_11H = 0x11,
|
||||
@ -282,7 +303,8 @@ protected:
|
||||
CPU_MODEL_IVYBRIDGE_EP = 0x3a,
|
||||
CPU_MODEL_HASWELL_E3 = 0x3c,
|
||||
CPU_MODEL_HASWELL_E7 = 0x3f,
|
||||
CPU_MODEL_BROADWELL = 0x3d
|
||||
CPU_MODEL_BROADWELL = 0x3d,
|
||||
CPU_MODEL_SKYLAKE = CPU_MODEL_HASWELL_E3
|
||||
} cpuExtendedFamily;
|
||||
|
||||
// cpuid information block. All info derived from executing cpuid with
|
||||
@ -376,6 +398,9 @@ protected:
|
||||
|
||||
// Space to save ymm registers after signal handle
|
||||
int ymm_save[8*4]; // Save ymm0, ymm7, ymm8, ymm15
|
||||
|
||||
// Space to save zmm registers after signal handle
|
||||
int zmm_save[16*4]; // Save zmm0, zmm7, zmm8, zmm31
|
||||
};
|
||||
|
||||
// The actual cpuid info block
|
||||
@ -404,8 +429,8 @@ protected:
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t feature_flags() {
|
||||
uint32_t result = 0;
|
||||
static uint64_t feature_flags() {
|
||||
uint64_t result = 0;
|
||||
if (_cpuid_info.std_cpuid1_edx.bits.cmpxchg8 != 0)
|
||||
result |= CPU_CX8;
|
||||
if (_cpuid_info.std_cpuid1_edx.bits.cmov != 0)
|
||||
@ -440,6 +465,24 @@ protected:
|
||||
result |= CPU_AVX;
|
||||
if (_cpuid_info.sef_cpuid7_ebx.bits.avx2 != 0)
|
||||
result |= CPU_AVX2;
|
||||
if (_cpuid_info.sef_cpuid7_ebx.bits.avx512f != 0 &&
|
||||
_cpuid_info.xem_xcr0_eax.bits.opmask != 0 &&
|
||||
_cpuid_info.xem_xcr0_eax.bits.zmm512 != 0 &&
|
||||
_cpuid_info.xem_xcr0_eax.bits.zmm32 != 0) {
|
||||
result |= CPU_AVX512F;
|
||||
if (_cpuid_info.sef_cpuid7_ebx.bits.avx512cd != 0)
|
||||
result |= CPU_AVX512CD;
|
||||
if (_cpuid_info.sef_cpuid7_ebx.bits.avx512dq != 0)
|
||||
result |= CPU_AVX512DQ;
|
||||
if (_cpuid_info.sef_cpuid7_ebx.bits.avx512pf != 0)
|
||||
result |= CPU_AVX512PF;
|
||||
if (_cpuid_info.sef_cpuid7_ebx.bits.avx512er != 0)
|
||||
result |= CPU_AVX512ER;
|
||||
if (_cpuid_info.sef_cpuid7_ebx.bits.avx512bw != 0)
|
||||
result |= CPU_AVX512BW;
|
||||
if (_cpuid_info.sef_cpuid7_ebx.bits.avx512vl != 0)
|
||||
result |= CPU_AVX512VL;
|
||||
}
|
||||
}
|
||||
if(_cpuid_info.sef_cpuid7_ebx.bits.bmi1 != 0)
|
||||
result |= CPU_BMI1;
|
||||
@ -484,18 +527,31 @@ protected:
|
||||
}
|
||||
|
||||
static bool os_supports_avx_vectors() {
|
||||
if (!supports_avx()) {
|
||||
return false;
|
||||
}
|
||||
// Verify that OS save/restore all bits of AVX registers
|
||||
// during signal processing.
|
||||
int nreg = 2 LP64_ONLY(+2);
|
||||
for (int i = 0; i < 8 * nreg; i++) { // 32 bytes per ymm register
|
||||
if (_cpuid_info.ymm_save[i] != ymm_test_value()) {
|
||||
return false;
|
||||
bool retVal = false;
|
||||
if (supports_evex()) {
|
||||
// Verify that OS save/restore all bits of EVEX registers
|
||||
// during signal processing.
|
||||
int nreg = 2 LP64_ONLY(+2);
|
||||
retVal = true;
|
||||
for (int i = 0; i < 16 * nreg; i++) { // 64 bytes per zmm register
|
||||
if (_cpuid_info.zmm_save[i] != ymm_test_value()) {
|
||||
retVal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (supports_avx()) {
|
||||
// Verify that OS save/restore all bits of AVX registers
|
||||
// during signal processing.
|
||||
int nreg = 2 LP64_ONLY(+2);
|
||||
retVal = true;
|
||||
for (int i = 0; i < 8 * nreg; i++) { // 32 bytes per ymm register
|
||||
if (_cpuid_info.ymm_save[i] != ymm_test_value()) {
|
||||
retVal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
static void get_processor_features();
|
||||
@ -515,6 +571,7 @@ public:
|
||||
static ByteSize tpl_cpuidB2_offset() { return byte_offset_of(CpuidInfo, tpl_cpuidB2_eax); }
|
||||
static ByteSize xem_xcr0_offset() { return byte_offset_of(CpuidInfo, xem_xcr0_eax); }
|
||||
static ByteSize ymm_save_offset() { return byte_offset_of(CpuidInfo, ymm_save); }
|
||||
static ByteSize zmm_save_offset() { return byte_offset_of(CpuidInfo, zmm_save); }
|
||||
|
||||
// The value used to check ymm register after signal handle
|
||||
static int ymm_test_value() { return 0xCAFEBABE; }
|
||||
@ -527,6 +584,7 @@ public:
|
||||
|
||||
static void clean_cpuFeatures() { _cpuFeatures = 0; }
|
||||
static void set_avx_cpuFeatures() { _cpuFeatures = (CPU_SSE | CPU_SSE2 | CPU_AVX); }
|
||||
static void set_evex_cpuFeatures() { _cpuFeatures = (CPU_AVX512F | CPU_SSE | CPU_SSE2 ); }
|
||||
|
||||
|
||||
// Initialization
|
||||
@ -636,7 +694,14 @@ public:
|
||||
static bool supports_rtm() { return (_cpuFeatures & CPU_RTM) != 0; }
|
||||
static bool supports_bmi1() { return (_cpuFeatures & CPU_BMI1) != 0; }
|
||||
static bool supports_bmi2() { return (_cpuFeatures & CPU_BMI2) != 0; }
|
||||
static bool supports_adx() { return (_cpuFeatures & CPU_ADX) != 0; }
|
||||
static bool supports_adx() { return (_cpuFeatures & CPU_ADX) != 0; }
|
||||
static bool supports_evex() { return (_cpuFeatures & CPU_AVX512F) != 0; }
|
||||
static bool supports_avx512dq() { return (_cpuFeatures & CPU_AVX512DQ) != 0; }
|
||||
static bool supports_avx512pf() { return (_cpuFeatures & CPU_AVX512PF) != 0; }
|
||||
static bool supports_avx512er() { return (_cpuFeatures & CPU_AVX512ER) != 0; }
|
||||
static bool supports_avx512cd() { return (_cpuFeatures & CPU_AVX512CD) != 0; }
|
||||
static bool supports_avx512bw() { return (_cpuFeatures & CPU_AVX512BW) != 0; }
|
||||
static bool supports_avx512vl() { return (_cpuFeatures & CPU_AVX512VL) != 0; }
|
||||
// Intel features
|
||||
static bool is_intel_family_core() { return is_intel() &&
|
||||
extended_cpu_family() == CPU_FAMILY_INTEL_CORE; }
|
||||
|
@ -47,13 +47,22 @@ void VMRegImpl::set_regName() {
|
||||
}
|
||||
|
||||
XMMRegister xreg = ::as_XMMRegister(0);
|
||||
for ( ; i < ConcreteRegisterImpl::max_xmm ; ) {
|
||||
for (int j = 0 ; j < 8 ; j++) {
|
||||
for (; i < ConcreteRegisterImpl::max_xmm;) {
|
||||
for (int j = 0 ; j < XMMRegisterImpl::max_slots_per_register ; j++) {
|
||||
regName[i++] = xreg->name();
|
||||
}
|
||||
xreg = xreg->successor();
|
||||
}
|
||||
|
||||
KRegister kreg = ::as_KRegister(0);
|
||||
for (; i < ConcreteRegisterImpl::max_kpr;) {
|
||||
for (int j = 0; j < KRegisterImpl::max_slots_per_register; j++) {
|
||||
regName[i++] = kreg->name();
|
||||
}
|
||||
kreg = kreg->successor();
|
||||
}
|
||||
|
||||
for ( ; i < ConcreteRegisterImpl::number_of_registers ; i ++ ) {
|
||||
regName[i] = "NON-GPR-FPR-XMM";
|
||||
regName[i] = "NON-GPR-FPR-XMM-KREG";
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,24 @@ inline bool is_FloatRegister() {
|
||||
}
|
||||
|
||||
inline bool is_XMMRegister() {
|
||||
return value() >= ConcreteRegisterImpl::max_fpr && value() < ConcreteRegisterImpl::max_xmm;
|
||||
int uarch_max_xmm = ConcreteRegisterImpl::max_xmm;
|
||||
|
||||
#ifdef _LP64
|
||||
if (UseAVX < 3) {
|
||||
int half_xmm = (XMMRegisterImpl::max_slots_per_register * XMMRegisterImpl::number_of_registers) / 2;
|
||||
uarch_max_xmm -= half_xmm;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (value() >= ConcreteRegisterImpl::max_fpr && value() < uarch_max_xmm);
|
||||
}
|
||||
|
||||
inline bool is_KRegister() {
|
||||
if (UseAVX > 2) {
|
||||
return value() >= ConcreteRegisterImpl::max_xmm && value() < ConcreteRegisterImpl::max_kpr;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline Register as_Register() {
|
||||
@ -59,7 +76,13 @@ inline FloatRegister as_FloatRegister() {
|
||||
inline XMMRegister as_XMMRegister() {
|
||||
assert( is_XMMRegister() && is_even(value()), "must be" );
|
||||
// Yuk
|
||||
return ::as_XMMRegister((value() - ConcreteRegisterImpl::max_fpr) >> 3);
|
||||
return ::as_XMMRegister((value() - ConcreteRegisterImpl::max_fpr) >> 4);
|
||||
}
|
||||
|
||||
inline KRegister as_KRegister() {
|
||||
assert(is_KRegister(), "must be");
|
||||
// Yuk
|
||||
return ::as_KRegister((value() - ConcreteRegisterImpl::max_xmm));
|
||||
}
|
||||
|
||||
inline bool is_concrete() {
|
||||
|
@ -39,7 +39,11 @@ inline VMReg FloatRegisterImpl::as_VMReg() {
|
||||
}
|
||||
|
||||
inline VMReg XMMRegisterImpl::as_VMReg() {
|
||||
return VMRegImpl::as_VMReg((encoding() << 3) + ConcreteRegisterImpl::max_fpr);
|
||||
return VMRegImpl::as_VMReg((encoding() << 4) + ConcreteRegisterImpl::max_fpr);
|
||||
}
|
||||
|
||||
inline VMReg KRegisterImpl::as_VMReg() {
|
||||
return VMRegImpl::as_VMReg(encoding() + ConcreteRegisterImpl::max_xmm);
|
||||
}
|
||||
|
||||
#endif // CPU_X86_VM_VMREG_X86_INLINE_HPP
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -101,6 +101,17 @@ reg_def FPR6L( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg());
|
||||
reg_def FPR6H( SOC, SOC, Op_RegF, 6, as_FloatRegister(5)->as_VMReg()->next());
|
||||
reg_def FPR7L( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg());
|
||||
reg_def FPR7H( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next());
|
||||
//
|
||||
// Empty fill registers, which are never used, but supply alignment to xmm regs
|
||||
//
|
||||
reg_def FILL0( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(2));
|
||||
reg_def FILL1( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(3));
|
||||
reg_def FILL2( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(4));
|
||||
reg_def FILL3( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(5));
|
||||
reg_def FILL4( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(6));
|
||||
reg_def FILL5( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(7));
|
||||
reg_def FILL6( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(8));
|
||||
reg_def FILL7( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next(9));
|
||||
|
||||
// Specify priority of register selection within phases of register
|
||||
// allocation. Highest priority is first. A useful heuristic is to
|
||||
@ -112,7 +123,8 @@ reg_def FPR7H( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next());
|
||||
alloc_class chunk0( ECX, EBX, EBP, EDI, EAX, EDX, ESI, ESP,
|
||||
FPR0L, FPR0H, FPR1L, FPR1H, FPR2L, FPR2H,
|
||||
FPR3L, FPR3H, FPR4L, FPR4H, FPR5L, FPR5H,
|
||||
FPR6L, FPR6H, FPR7L, FPR7H );
|
||||
FPR6L, FPR6H, FPR7L, FPR7H,
|
||||
FILL0, FILL1, FILL2, FILL3, FILL4, FILL5, FILL6, FILL7);
|
||||
|
||||
|
||||
//----------Architecture Description Register Classes--------------------------
|
||||
@ -131,7 +143,7 @@ reg_class any_reg_with_ebp(EAX, EDX, EBP, EDI, ESI, ECX, EBX, ESP);
|
||||
// Class for all registers (excluding EBP)
|
||||
reg_class any_reg_no_ebp(EAX, EDX, EDI, ESI, ECX, EBX, ESP);
|
||||
// Dynamic register class that selects at runtime between register classes
|
||||
// any_reg and any_no_ebp_reg (depending on the value of the flag PreserveFramePointer).
|
||||
// any_reg and any_no_ebp_reg (depending on the value of the flag PreserveFramePointer).
|
||||
// Equivalent to: return PreserveFramePointer ? any_no_ebp_reg : any_reg;
|
||||
reg_class_dynamic any_reg(any_reg_no_ebp, any_reg_with_ebp, %{ PreserveFramePointer %});
|
||||
|
||||
@ -279,7 +291,9 @@ static int pre_call_resets_size() {
|
||||
size += 6; // fldcw
|
||||
}
|
||||
if (C->max_vector_size() > 16) {
|
||||
size += 3; // vzeroupper
|
||||
if(UseAVX <= 2) {
|
||||
size += 3; // vzeroupper
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
@ -288,7 +302,7 @@ static int pre_call_resets_size() {
|
||||
// from the start of the call to the point where the return address
|
||||
// will point.
|
||||
int MachCallStaticJavaNode::ret_addr_offset() {
|
||||
return 5 + pre_call_resets_size(); // 5 bytes from start of call to where return address points
|
||||
return 5 + pre_call_resets_size(); // 5 bytes from start of call to where return address points
|
||||
}
|
||||
|
||||
int MachCallDynamicJavaNode::ret_addr_offset() {
|
||||
@ -767,6 +781,12 @@ static int impl_helper( CodeBuffer *cbuf, bool do_size, bool is_load, int offset
|
||||
// Helper for XMM registers. Extra opcode bits, limited syntax.
|
||||
static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
|
||||
int offset, int reg_lo, int reg_hi, int size, outputStream* st ) {
|
||||
int in_size_in_bits = Assembler::EVEX_32bit;
|
||||
int evex_encoding = 0;
|
||||
if (reg_lo+1 == reg_hi) {
|
||||
in_size_in_bits = Assembler::EVEX_64bit;
|
||||
evex_encoding = Assembler::VEX_W;
|
||||
}
|
||||
if (cbuf) {
|
||||
MacroAssembler _masm(cbuf);
|
||||
if (reg_lo+1 == reg_hi) { // double move?
|
||||
@ -799,7 +819,17 @@ static int impl_x_helper( CodeBuffer *cbuf, bool do_size, bool is_load,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
|
||||
bool is_single_byte = false;
|
||||
if ((UseAVX > 2) && (offset != 0)) {
|
||||
is_single_byte = Assembler::query_compressed_disp_byte(offset, true, 0, Assembler::EVEX_T1S, in_size_in_bits, evex_encoding);
|
||||
}
|
||||
int offset_size = 0;
|
||||
if (UseAVX > 2 ) {
|
||||
offset_size = (offset == 0) ? 0 : ((is_single_byte) ? 1 : 4);
|
||||
} else {
|
||||
offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
|
||||
}
|
||||
size += (UseAVX > 2) ? 2 : 0; // Need an additional two bytes for EVEX
|
||||
// VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes as SIMD prefix.
|
||||
return size+5+offset_size;
|
||||
}
|
||||
@ -835,8 +865,8 @@ static int impl_movx_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int dst
|
||||
#endif
|
||||
}
|
||||
// VEX_2bytes prefix is used if UseAVX > 0, and it takes the same 2 bytes as SIMD prefix.
|
||||
// Only MOVAPS SSE prefix uses 1 byte.
|
||||
int sz = 4;
|
||||
// Only MOVAPS SSE prefix uses 1 byte. EVEX uses an additional 2 bytes.
|
||||
int sz = (UseAVX > 2) ? 6 : 4;
|
||||
if (!(src_lo+1 == src_hi && dst_lo+1 == dst_hi) &&
|
||||
UseXmmRegToRegMoveAll && (UseAVX == 0)) sz = 3;
|
||||
return size + sz;
|
||||
@ -854,7 +884,7 @@ static int impl_movgpr2x_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int
|
||||
st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
|
||||
#endif
|
||||
}
|
||||
return 4;
|
||||
return (UseAVX> 2) ? 6 : 4;
|
||||
}
|
||||
|
||||
|
||||
@ -870,7 +900,7 @@ static int impl_movx2gpr_helper( CodeBuffer *cbuf, bool do_size, int src_lo, int
|
||||
st->print("movdl %s, %s\t# spill", Matcher::regName[dst_lo], Matcher::regName[src_lo]);
|
||||
#endif
|
||||
}
|
||||
return 4;
|
||||
return (UseAVX> 2) ? 6 : 4;
|
||||
}
|
||||
|
||||
static int impl_mov_helper( CodeBuffer *cbuf, bool do_size, int src, int dst, int size, outputStream* st ) {
|
||||
@ -941,9 +971,8 @@ static int vec_stack_to_stack_helper(CodeBuffer *cbuf, bool do_size, int src_off
|
||||
calc_size += 3+src_offset_size + 3+dst_offset_size;
|
||||
break;
|
||||
case Op_VecX:
|
||||
calc_size = 6 + 6 + 5+src_offset_size + 5+dst_offset_size;
|
||||
break;
|
||||
case Op_VecY:
|
||||
case Op_VecZ:
|
||||
calc_size = 6 + 6 + 5+src_offset_size + 5+dst_offset_size;
|
||||
break;
|
||||
default:
|
||||
@ -974,6 +1003,11 @@ static int vec_stack_to_stack_helper(CodeBuffer *cbuf, bool do_size, int src_off
|
||||
__ vmovdqu(xmm0, Address(rsp, src_offset));
|
||||
__ vmovdqu(Address(rsp, dst_offset), xmm0);
|
||||
__ vmovdqu(xmm0, Address(rsp, -32));
|
||||
case Op_VecZ:
|
||||
__ evmovdqu(Address(rsp, -64), xmm0, 2);
|
||||
__ evmovdqu(xmm0, Address(rsp, src_offset), 2);
|
||||
__ evmovdqu(Address(rsp, dst_offset), xmm0, 2);
|
||||
__ evmovdqu(xmm0, Address(rsp, -64), 2);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@ -1009,6 +1043,12 @@ static int vec_stack_to_stack_helper(CodeBuffer *cbuf, bool do_size, int src_off
|
||||
"vmovdqu [rsp + #%d], xmm0\n\t"
|
||||
"vmovdqu xmm0, [rsp - #32]",
|
||||
src_offset, dst_offset);
|
||||
case Op_VecZ:
|
||||
st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t"
|
||||
"vmovdqu xmm0, [rsp + #%d]\n\t"
|
||||
"vmovdqu [rsp + #%d], xmm0\n\t"
|
||||
"vmovdqu xmm0, [rsp - #64]",
|
||||
src_offset, dst_offset);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@ -1042,7 +1082,7 @@ uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bo
|
||||
uint ireg = ideal_reg();
|
||||
assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
|
||||
assert((src_first_rc != rc_float && dst_first_rc != rc_float), "sanity");
|
||||
assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity");
|
||||
assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity");
|
||||
if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
|
||||
// mem -> mem
|
||||
int src_offset = ra_->reg2offset(src_first);
|
||||
@ -3998,7 +4038,7 @@ operand regFPR1(regFPR reg) %{
|
||||
// XMM Float register operands
|
||||
operand regF() %{
|
||||
predicate( UseSSE>=1 );
|
||||
constraint(ALLOC_IN_RC(float_reg));
|
||||
constraint(ALLOC_IN_RC(float_reg_legacy));
|
||||
match(RegF);
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
@ -4007,12 +4047,45 @@ operand regF() %{
|
||||
// XMM Double register operands
|
||||
operand regD() %{
|
||||
predicate( UseSSE>=2 );
|
||||
constraint(ALLOC_IN_RC(double_reg));
|
||||
constraint(ALLOC_IN_RC(double_reg_legacy));
|
||||
match(RegD);
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
// Vectors : note, we use legacy registers to avoid extra (unneeded in 32-bit VM)
|
||||
// runtime code generation via reg_class_dynamic.
|
||||
operand vecS() %{
|
||||
constraint(ALLOC_IN_RC(vectors_reg_legacy));
|
||||
match(VecS);
|
||||
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
operand vecD() %{
|
||||
constraint(ALLOC_IN_RC(vectord_reg_legacy));
|
||||
match(VecD);
|
||||
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
operand vecX() %{
|
||||
constraint(ALLOC_IN_RC(vectorx_reg_legacy));
|
||||
match(VecX);
|
||||
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
operand vecY() %{
|
||||
constraint(ALLOC_IN_RC(vectory_reg_legacy));
|
||||
match(VecY);
|
||||
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
//----------Memory Operands----------------------------------------------------
|
||||
// Direct Memory Operand
|
||||
@ -5020,11 +5093,11 @@ instruct bytes_reverse_unsigned_short(rRegI dst, eFlagsReg cr) %{
|
||||
match(Set dst (ReverseBytesUS dst));
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "BSWAP $dst\n\t"
|
||||
format %{ "BSWAP $dst\n\t"
|
||||
"SHR $dst,16\n\t" %}
|
||||
ins_encode %{
|
||||
__ bswapl($dst$$Register);
|
||||
__ shrl($dst$$Register, 16);
|
||||
__ shrl($dst$$Register, 16);
|
||||
%}
|
||||
ins_pipe( ialu_reg );
|
||||
%}
|
||||
@ -5033,11 +5106,11 @@ instruct bytes_reverse_short(rRegI dst, eFlagsReg cr) %{
|
||||
match(Set dst (ReverseBytesS dst));
|
||||
effect(KILL cr);
|
||||
|
||||
format %{ "BSWAP $dst\n\t"
|
||||
format %{ "BSWAP $dst\n\t"
|
||||
"SAR $dst,16\n\t" %}
|
||||
ins_encode %{
|
||||
__ bswapl($dst$$Register);
|
||||
__ sarl($dst$$Register, 16);
|
||||
__ sarl($dst$$Register, 16);
|
||||
%}
|
||||
ins_pipe( ialu_reg );
|
||||
%}
|
||||
@ -6525,7 +6598,7 @@ instruct membar_volatile(eFlagsReg cr) %{
|
||||
effect(KILL cr);
|
||||
ins_cost(400);
|
||||
|
||||
format %{
|
||||
format %{
|
||||
$$template
|
||||
if (os::is_MP()) {
|
||||
$$emit$$"LOCK ADDL [ESP + #0], 0\t! membar_volatile"
|
||||
@ -8288,10 +8361,10 @@ instruct xorI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
|
||||
|
||||
// Xor Register with Immediate -1
|
||||
instruct xorI_eReg_im1(rRegI dst, immI_M1 imm) %{
|
||||
match(Set dst (XorI dst imm));
|
||||
match(Set dst (XorI dst imm));
|
||||
|
||||
size(2);
|
||||
format %{ "NOT $dst" %}
|
||||
format %{ "NOT $dst" %}
|
||||
ins_encode %{
|
||||
__ notl($dst$$Register);
|
||||
%}
|
||||
@ -8939,7 +9012,7 @@ instruct xorl_eReg(eRegL dst, eRegL src, eFlagsReg cr) %{
|
||||
|
||||
// Xor Long Register with Immediate -1
|
||||
instruct xorl_eReg_im1(eRegL dst, immL_M1 imm) %{
|
||||
match(Set dst (XorL dst imm));
|
||||
match(Set dst (XorL dst imm));
|
||||
format %{ "NOT $dst.lo\n\t"
|
||||
"NOT $dst.hi" %}
|
||||
ins_encode %{
|
||||
@ -8994,7 +9067,7 @@ instruct shlL_eReg_2(eRegL dst, immI_2 cnt, eFlagsReg cr) %{
|
||||
effect(KILL cr);
|
||||
ins_cost(100);
|
||||
format %{ "ADD $dst.lo,$dst.lo\n\t"
|
||||
"ADC $dst.hi,$dst.hi\n\t"
|
||||
"ADC $dst.hi,$dst.hi\n\t"
|
||||
"ADD $dst.lo,$dst.lo\n\t"
|
||||
"ADC $dst.hi,$dst.hi" %}
|
||||
ins_encode %{
|
||||
@ -9013,9 +9086,9 @@ instruct shlL_eReg_3(eRegL dst, immI_3 cnt, eFlagsReg cr) %{
|
||||
effect(KILL cr);
|
||||
ins_cost(100);
|
||||
format %{ "ADD $dst.lo,$dst.lo\n\t"
|
||||
"ADC $dst.hi,$dst.hi\n\t"
|
||||
"ADC $dst.hi,$dst.hi\n\t"
|
||||
"ADD $dst.lo,$dst.lo\n\t"
|
||||
"ADC $dst.hi,$dst.hi\n\t"
|
||||
"ADC $dst.hi,$dst.hi\n\t"
|
||||
"ADD $dst.lo,$dst.lo\n\t"
|
||||
"ADC $dst.hi,$dst.hi" %}
|
||||
ins_encode %{
|
||||
@ -11168,7 +11241,6 @@ instruct convL2I_reg( rRegI dst, eRegL src ) %{
|
||||
ins_pipe( ialu_reg_reg );
|
||||
%}
|
||||
|
||||
|
||||
instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
|
||||
match(Set dst (MoveF2I src));
|
||||
effect( DEF dst, USE src );
|
||||
@ -11400,7 +11472,7 @@ instruct rep_stos(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy, eFlag
|
||||
format %{ "XOR EAX,EAX\t# ClearArray:\n\t"
|
||||
"SHL ECX,1\t# Convert doublewords to words\n\t"
|
||||
"REP STOS\t# store EAX into [EDI++] while ECX--" %}
|
||||
ins_encode %{
|
||||
ins_encode %{
|
||||
__ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
@ -11413,7 +11485,7 @@ instruct rep_fast_stosb(eCXRegI cnt, eDIRegP base, eAXRegI zero, Universe dummy,
|
||||
format %{ "XOR EAX,EAX\t# ClearArray:\n\t"
|
||||
"SHL ECX,3\t# Convert doublewords to bytes\n\t"
|
||||
"REP STOSB\t# store EAX into [EDI++] while ECX--" %}
|
||||
ins_encode %{
|
||||
ins_encode %{
|
||||
__ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
|
@ -172,7 +172,7 @@ reg_class no_reg();
|
||||
// Class for all pointer registers (including RSP and RBP)
|
||||
reg_class any_reg_with_rbp(RAX, RAX_H,
|
||||
RDX, RDX_H,
|
||||
RBP, RBP_H,
|
||||
RBP, RBP_H,
|
||||
RDI, RDI_H,
|
||||
RSI, RSI_H,
|
||||
RCX, RCX_H,
|
||||
@ -189,7 +189,7 @@ reg_class any_reg_with_rbp(RAX, RAX_H,
|
||||
|
||||
// Class for all pointer registers (including RSP, but excluding RBP)
|
||||
reg_class any_reg_no_rbp(RAX, RAX_H,
|
||||
RDX, RDX_H,
|
||||
RDX, RDX_H,
|
||||
RDI, RDI_H,
|
||||
RSI, RSI_H,
|
||||
RCX, RCX_H,
|
||||
@ -205,10 +205,10 @@ reg_class any_reg_no_rbp(RAX, RAX_H,
|
||||
R15, R15_H);
|
||||
|
||||
// Dynamic register class that selects at runtime between register classes
|
||||
// any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer).
|
||||
// any_reg_no_rbp and any_reg_with_rbp (depending on the value of the flag PreserveFramePointer).
|
||||
// Equivalent to: return PreserveFramePointer ? any_reg_no_rbp : any_reg_with_rbp;
|
||||
reg_class_dynamic any_reg(any_reg_no_rbp, any_reg_with_rbp, %{ PreserveFramePointer %});
|
||||
|
||||
|
||||
// Class for all pointer registers (excluding RSP)
|
||||
reg_class ptr_reg_with_rbp(RAX, RAX_H,
|
||||
RDX, RDX_H,
|
||||
@ -226,7 +226,7 @@ reg_class ptr_reg_with_rbp(RAX, RAX_H,
|
||||
|
||||
// Class for all pointer registers (excluding RSP and RBP)
|
||||
reg_class ptr_reg_no_rbp(RAX, RAX_H,
|
||||
RDX, RDX_H,
|
||||
RDX, RDX_H,
|
||||
RDI, RDI_H,
|
||||
RSI, RSI_H,
|
||||
RCX, RCX_H,
|
||||
@ -536,7 +536,11 @@ source %{
|
||||
#define __ _masm.
|
||||
|
||||
static int clear_avx_size() {
|
||||
return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper
|
||||
if(UseAVX > 2) {
|
||||
return 0; // vzeroupper is ignored
|
||||
} else {
|
||||
return (Compile::current()->max_vector_size() > 16) ? 3 : 0; // vzeroupper
|
||||
}
|
||||
}
|
||||
|
||||
// !!!!! Special hack to get all types of calls to specify the byte offset
|
||||
@ -545,7 +549,7 @@ static int clear_avx_size() {
|
||||
int MachCallStaticJavaNode::ret_addr_offset()
|
||||
{
|
||||
int offset = 5; // 5 bytes from start of call to where return address points
|
||||
offset += clear_avx_size();
|
||||
offset += clear_avx_size();
|
||||
return offset;
|
||||
}
|
||||
|
||||
@ -860,7 +864,7 @@ void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
|
||||
st->print("subq rsp, #%d\t# Create frame",framesize);
|
||||
st->print("\n\t");
|
||||
framesize -= wordSize;
|
||||
st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize);
|
||||
st->print("movq [rsp + #%d], rbp\t# Save rbp",framesize);
|
||||
if (PreserveFramePointer) {
|
||||
st->print("\n\t");
|
||||
st->print("movq rbp, [rsp + #%d]\t# Save the caller's SP into rbp", (framesize + wordSize));
|
||||
@ -1070,6 +1074,11 @@ static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset,
|
||||
__ vmovdqu(xmm0, Address(rsp, src_offset));
|
||||
__ vmovdqu(Address(rsp, dst_offset), xmm0);
|
||||
__ vmovdqu(xmm0, Address(rsp, -32));
|
||||
case Op_VecZ:
|
||||
__ evmovdqu(Address(rsp, -64), xmm0, 2);
|
||||
__ evmovdqu(xmm0, Address(rsp, src_offset), 2);
|
||||
__ evmovdqu(Address(rsp, dst_offset), xmm0, 2);
|
||||
__ evmovdqu(xmm0, Address(rsp, -64), 2);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@ -1103,6 +1112,13 @@ static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset,
|
||||
"vmovdqu xmm0, [rsp - #32]",
|
||||
src_offset, dst_offset);
|
||||
break;
|
||||
case Op_VecZ:
|
||||
st->print("vmovdqu [rsp - #64], xmm0\t# 512-bit mem-mem spill\n\t"
|
||||
"vmovdqu xmm0, [rsp + #%d]\n\t"
|
||||
"vmovdqu [rsp + #%d], xmm0\n\t"
|
||||
"vmovdqu xmm0, [rsp - #64]",
|
||||
src_offset, dst_offset);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
}
|
||||
@ -1136,7 +1152,7 @@ uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
|
||||
if (bottom_type()->isa_vect() != NULL) {
|
||||
uint ireg = ideal_reg();
|
||||
assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
|
||||
assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity");
|
||||
assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY || ireg == Op_VecZ ), "sanity");
|
||||
if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
|
||||
// mem -> mem
|
||||
int src_offset = ra_->reg2offset(src_first);
|
||||
@ -1573,7 +1589,7 @@ uint MachUEPNode::size(PhaseRegAlloc* ra_) const
|
||||
return MachNode::size(ra_); // too many variables; just compute it
|
||||
// the hard way
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@ -2832,7 +2848,7 @@ frame
|
||||
RAX_H_num // Op_RegL
|
||||
};
|
||||
// Excluded flags and vector registers.
|
||||
assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type");
|
||||
assert(ARRAY_SIZE(hi) == _last_machine_leaf - 6, "missing type");
|
||||
return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
|
||||
%}
|
||||
%}
|
||||
@ -3335,7 +3351,7 @@ operand no_rax_rdx_RegI()
|
||||
// Pointer Register
|
||||
operand any_RegP()
|
||||
%{
|
||||
constraint(ALLOC_IN_RC(any_reg));
|
||||
constraint(ALLOC_IN_RC(any_reg));
|
||||
match(RegP);
|
||||
match(rax_RegP);
|
||||
match(rbx_RegP);
|
||||
@ -3589,20 +3605,51 @@ operand rFlagsRegUCF() %{
|
||||
%}
|
||||
|
||||
// Float register operands
|
||||
operand regF()
|
||||
%{
|
||||
constraint(ALLOC_IN_RC(float_reg));
|
||||
match(RegF);
|
||||
operand regF() %{
|
||||
constraint(ALLOC_IN_RC(float_reg));
|
||||
match(RegF);
|
||||
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
// Double register operands
|
||||
operand regD() %{
|
||||
constraint(ALLOC_IN_RC(double_reg));
|
||||
match(RegD);
|
||||
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
// Vectors
|
||||
operand vecS() %{
|
||||
constraint(ALLOC_IN_RC(vectors_reg));
|
||||
match(VecS);
|
||||
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
// Double register operands
|
||||
operand regD()
|
||||
%{
|
||||
constraint(ALLOC_IN_RC(double_reg));
|
||||
match(RegD);
|
||||
operand vecD() %{
|
||||
constraint(ALLOC_IN_RC(vectord_reg));
|
||||
match(VecD);
|
||||
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
operand vecX() %{
|
||||
constraint(ALLOC_IN_RC(vectorx_reg));
|
||||
match(VecX);
|
||||
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
%}
|
||||
|
||||
operand vecY() %{
|
||||
constraint(ALLOC_IN_RC(vectory_reg));
|
||||
match(VecY);
|
||||
|
||||
format %{ %}
|
||||
interface(REG_INTER);
|
||||
@ -4947,7 +4994,7 @@ instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{
|
||||
%}
|
||||
|
||||
// Load Unsigned Integer into Long Register
|
||||
instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask)
|
||||
instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask)
|
||||
%{
|
||||
match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
|
||||
|
||||
@ -10374,7 +10421,7 @@ instruct rep_stos(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dummy,
|
||||
|
||||
format %{ "xorq rax, rax\t# ClearArray:\n\t"
|
||||
"rep stosq\t# Store rax to *rdi++ while rcx--" %}
|
||||
ins_encode %{
|
||||
ins_encode %{
|
||||
__ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
|
||||
%}
|
||||
ins_pipe(pipe_slow);
|
||||
@ -10389,7 +10436,7 @@ instruct rep_fast_stosb(rcx_RegL cnt, rdi_RegP base, rax_RegI zero, Universe dum
|
||||
format %{ "xorq rax, rax\t# ClearArray:\n\t"
|
||||
"shlq rcx,3\t# Convert doublewords to bytes\n\t"
|
||||
"rep stosb\t# Store rax to *rdi++ while rcx--" %}
|
||||
ins_encode %{
|
||||
ins_encode %{
|
||||
__ clear_mem($base$$Register, $cnt$$Register, $zero$$Register);
|
||||
%}
|
||||
ins_pipe( pipe_slow );
|
||||
|
@ -26,6 +26,8 @@
|
||||
#ifndef CPU_ZERO_VM_ENTRY_ZERO_HPP
|
||||
#define CPU_ZERO_VM_ENTRY_ZERO_HPP
|
||||
|
||||
#include "interpreter/cppInterpreter.hpp"
|
||||
|
||||
class ZeroEntry {
|
||||
public:
|
||||
ZeroEntry() {
|
||||
|
@ -25,6 +25,8 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "assembler_zero.inline.hpp"
|
||||
#include "entry_zero.hpp"
|
||||
#include "interpreter/cppInterpreter.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "nativeInst_zero.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
|
@ -3474,25 +3474,69 @@ char* os::Linux::reserve_memory_special_huge_tlbfs_only(size_t bytes,
|
||||
return addr;
|
||||
}
|
||||
|
||||
// Helper for os::Linux::reserve_memory_special_huge_tlbfs_mixed().
|
||||
// Allocate (using mmap, NO_RESERVE, with small pages) at either a given request address
|
||||
// (req_addr != NULL) or with a given alignment.
|
||||
// - bytes shall be a multiple of alignment.
|
||||
// - req_addr can be NULL. If not NULL, it must be a multiple of alignment.
|
||||
// - alignment sets the alignment at which memory shall be allocated.
|
||||
// It must be a multiple of allocation granularity.
|
||||
// Returns address of memory or NULL. If req_addr was not NULL, will only return
|
||||
// req_addr or NULL.
|
||||
static char* anon_mmap_aligned(size_t bytes, size_t alignment, char* req_addr) {
|
||||
|
||||
size_t extra_size = bytes;
|
||||
if (req_addr == NULL && alignment > 0) {
|
||||
extra_size += alignment;
|
||||
}
|
||||
|
||||
char* start = (char*) ::mmap(req_addr, extra_size, PROT_NONE,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE,
|
||||
-1, 0);
|
||||
if (start == MAP_FAILED) {
|
||||
start = NULL;
|
||||
} else {
|
||||
if (req_addr != NULL) {
|
||||
if (start != req_addr) {
|
||||
::munmap(start, extra_size);
|
||||
start = NULL;
|
||||
}
|
||||
} else {
|
||||
char* const start_aligned = (char*) align_ptr_up(start, alignment);
|
||||
char* const end_aligned = start_aligned + bytes;
|
||||
char* const end = start + extra_size;
|
||||
if (start_aligned > start) {
|
||||
::munmap(start, start_aligned - start);
|
||||
}
|
||||
if (end_aligned < end) {
|
||||
::munmap(end_aligned, end - end_aligned);
|
||||
}
|
||||
start = start_aligned;
|
||||
}
|
||||
}
|
||||
return start;
|
||||
|
||||
}
|
||||
|
||||
// Reserve memory using mmap(MAP_HUGETLB).
|
||||
// - bytes shall be a multiple of alignment.
|
||||
// - req_addr can be NULL. If not NULL, it must be a multiple of alignment.
|
||||
// - alignment sets the alignment at which memory shall be allocated.
|
||||
// It must be a multiple of allocation granularity.
|
||||
// Returns address of memory or NULL. If req_addr was not NULL, will only return
|
||||
// req_addr or NULL.
|
||||
char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes,
|
||||
size_t alignment,
|
||||
char* req_addr,
|
||||
bool exec) {
|
||||
size_t large_page_size = os::large_page_size();
|
||||
|
||||
assert(bytes >= large_page_size, "Shouldn't allocate large pages for small sizes");
|
||||
|
||||
// Allocate small pages.
|
||||
assert(is_ptr_aligned(req_addr, alignment), "Must be");
|
||||
assert(is_size_aligned(bytes, alignment), "Must be");
|
||||
|
||||
char* start;
|
||||
if (req_addr != NULL) {
|
||||
assert(is_ptr_aligned(req_addr, alignment), "Must be");
|
||||
assert(is_size_aligned(bytes, alignment), "Must be");
|
||||
start = os::reserve_memory(bytes, req_addr);
|
||||
assert(start == NULL || start == req_addr, "Must be");
|
||||
} else {
|
||||
start = os::reserve_memory_aligned(bytes, alignment);
|
||||
}
|
||||
// First reserve - but not commit - the address range in small pages.
|
||||
char* const start = anon_mmap_aligned(bytes, alignment, req_addr);
|
||||
|
||||
if (start == NULL) {
|
||||
return NULL;
|
||||
@ -3500,13 +3544,6 @@ char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes,
|
||||
|
||||
assert(is_ptr_aligned(start, alignment), "Must be");
|
||||
|
||||
if (MemTracker::tracking_level() > NMT_minimal) {
|
||||
// os::reserve_memory_special will record this memory area.
|
||||
// Need to release it here to prevent overlapping reservations.
|
||||
Tracker tkr = MemTracker::get_virtual_memory_release_tracker();
|
||||
tkr.record((address)start, bytes);
|
||||
}
|
||||
|
||||
char* end = start + bytes;
|
||||
|
||||
// Find the regions of the allocated chunk that can be promoted to large pages.
|
||||
@ -3526,9 +3563,9 @@ char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes,
|
||||
|
||||
int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
|
||||
|
||||
|
||||
void* result;
|
||||
|
||||
// Commit small-paged leading area.
|
||||
if (start != lp_start) {
|
||||
result = ::mmap(start, lp_start - start, prot,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
|
||||
@ -3539,11 +3576,12 @@ char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes,
|
||||
}
|
||||
}
|
||||
|
||||
// Commit large-paged area.
|
||||
result = ::mmap(lp_start, lp_bytes, prot,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED|MAP_HUGETLB,
|
||||
-1, 0);
|
||||
if (result == MAP_FAILED) {
|
||||
warn_on_large_pages_failure(req_addr, bytes, errno);
|
||||
warn_on_large_pages_failure(lp_start, lp_bytes, errno);
|
||||
// If the mmap above fails, the large pages region will be unmapped and we
|
||||
// have regions before and after with small pages. Release these regions.
|
||||
//
|
||||
@ -3556,6 +3594,7 @@ char* os::Linux::reserve_memory_special_huge_tlbfs_mixed(size_t bytes,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Commit small-paged trailing area.
|
||||
if (lp_end != end) {
|
||||
result = ::mmap(lp_end, end - lp_end, prot,
|
||||
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED,
|
||||
@ -3575,7 +3614,7 @@ char* os::Linux::reserve_memory_special_huge_tlbfs(size_t bytes,
|
||||
bool exec) {
|
||||
assert(UseLargePages && UseHugeTLBFS, "only for Huge TLBFS large pages");
|
||||
assert(is_ptr_aligned(req_addr, alignment), "Must be");
|
||||
assert(is_power_of_2(alignment), "Must be");
|
||||
assert(is_size_aligned(alignment, os::vm_allocation_granularity()), "Must be");
|
||||
assert(is_power_of_2(os::large_page_size()), "Must be");
|
||||
assert(bytes >= os::large_page_size(), "Shouldn't allocate large pages for small sizes");
|
||||
|
||||
@ -4760,8 +4799,8 @@ jint os::init_2(void) {
|
||||
FLAG_IS_DEFAULT(UseSHM) &&
|
||||
FLAG_IS_DEFAULT(UseHugeTLBFS)) {
|
||||
UseLargePages = false;
|
||||
} else {
|
||||
warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing");
|
||||
} else if (UseAdaptiveSizePolicy || UseAdaptiveNUMAChunkSizing) {
|
||||
warning("UseNUMA is not fully compatible with SHM/HugeTLBFS large pages, disabling adaptive resizing (-XX:-UseAdaptiveSizePolicy -XX:-UseAdaptiveNUMAChunkSizing)");
|
||||
UseAdaptiveSizePolicy = false;
|
||||
UseAdaptiveNUMAChunkSizing = false;
|
||||
}
|
||||
@ -6086,47 +6125,100 @@ class TestReserveMemorySpecial : AllStatic {
|
||||
}
|
||||
}
|
||||
|
||||
static void test_reserve_memory_special_huge_tlbfs_mixed(size_t size, size_t alignment) {
|
||||
if (!UseHugeTLBFS) {
|
||||
return;
|
||||
}
|
||||
|
||||
test_log("test_reserve_memory_special_huge_tlbfs_mixed(" SIZE_FORMAT ", " SIZE_FORMAT ")",
|
||||
size, alignment);
|
||||
|
||||
assert(size >= os::large_page_size(), "Incorrect input to test");
|
||||
|
||||
char* addr = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, NULL, false);
|
||||
|
||||
if (addr != NULL) {
|
||||
small_page_write(addr, size);
|
||||
|
||||
os::Linux::release_memory_special_huge_tlbfs(addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(size_t size) {
|
||||
size_t lp = os::large_page_size();
|
||||
size_t ag = os::vm_allocation_granularity();
|
||||
|
||||
for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
|
||||
test_reserve_memory_special_huge_tlbfs_mixed(size, alignment);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_reserve_memory_special_huge_tlbfs_mixed() {
|
||||
size_t lp = os::large_page_size();
|
||||
size_t ag = os::vm_allocation_granularity();
|
||||
|
||||
test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp);
|
||||
test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + ag);
|
||||
test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp + lp / 2);
|
||||
test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2);
|
||||
test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + ag);
|
||||
test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 - ag);
|
||||
test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 2 + lp / 2);
|
||||
test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10);
|
||||
test_reserve_memory_special_huge_tlbfs_mixed_all_alignments(lp * 10 + lp / 2);
|
||||
// sizes to test
|
||||
const size_t sizes[] = {
|
||||
lp, lp + ag, lp + lp / 2, lp * 2,
|
||||
lp * 2 + ag, lp * 2 - ag, lp * 2 + lp / 2,
|
||||
lp * 10, lp * 10 + lp / 2
|
||||
};
|
||||
const int num_sizes = sizeof(sizes) / sizeof(size_t);
|
||||
|
||||
// For each size/alignment combination, we test three scenarios:
|
||||
// 1) with req_addr == NULL
|
||||
// 2) with a non-null req_addr at which we expect to successfully allocate
|
||||
// 3) with a non-null req_addr which contains a pre-existing mapping, at which we
|
||||
// expect the allocation to either fail or to ignore req_addr
|
||||
|
||||
// Pre-allocate two areas; they shall be as large as the largest allocation
|
||||
// and aligned to the largest alignment we will be testing.
|
||||
const size_t mapping_size = sizes[num_sizes - 1] * 2;
|
||||
char* const mapping1 = (char*) ::mmap(NULL, mapping_size,
|
||||
PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE,
|
||||
-1, 0);
|
||||
assert(mapping1 != MAP_FAILED, "should work");
|
||||
|
||||
char* const mapping2 = (char*) ::mmap(NULL, mapping_size,
|
||||
PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE,
|
||||
-1, 0);
|
||||
assert(mapping2 != MAP_FAILED, "should work");
|
||||
|
||||
// Unmap the first mapping, but leave the second mapping intact: the first
|
||||
// mapping will serve as a value for a "good" req_addr (case 2). The second
|
||||
// mapping, still intact, as "bad" req_addr (case 3).
|
||||
::munmap(mapping1, mapping_size);
|
||||
|
||||
// Case 1
|
||||
test_log("%s, req_addr NULL:", __FUNCTION__);
|
||||
test_log("size align result");
|
||||
|
||||
for (int i = 0; i < num_sizes; i++) {
|
||||
const size_t size = sizes[i];
|
||||
for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
|
||||
char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, NULL, false);
|
||||
test_log(SIZE_FORMAT_HEX " " SIZE_FORMAT_HEX " -> " PTR_FORMAT " %s",
|
||||
size, alignment, p, (p != NULL ? "" : "(failed)"));
|
||||
if (p != NULL) {
|
||||
assert(is_ptr_aligned(p, alignment), "must be");
|
||||
small_page_write(p, size);
|
||||
os::Linux::release_memory_special_huge_tlbfs(p, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Case 2
|
||||
test_log("%s, req_addr non-NULL:", __FUNCTION__);
|
||||
test_log("size align req_addr result");
|
||||
|
||||
for (int i = 0; i < num_sizes; i++) {
|
||||
const size_t size = sizes[i];
|
||||
for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
|
||||
char* const req_addr = (char*) align_ptr_up(mapping1, alignment);
|
||||
char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, req_addr, false);
|
||||
test_log(SIZE_FORMAT_HEX " " SIZE_FORMAT_HEX " " PTR_FORMAT " -> " PTR_FORMAT " %s",
|
||||
size, alignment, req_addr, p,
|
||||
((p != NULL ? (p == req_addr ? "(exact match)" : "") : "(failed)")));
|
||||
if (p != NULL) {
|
||||
assert(p == req_addr, "must be");
|
||||
small_page_write(p, size);
|
||||
os::Linux::release_memory_special_huge_tlbfs(p, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Case 3
|
||||
test_log("%s, req_addr non-NULL with preexisting mapping:", __FUNCTION__);
|
||||
test_log("size align req_addr result");
|
||||
|
||||
for (int i = 0; i < num_sizes; i++) {
|
||||
const size_t size = sizes[i];
|
||||
for (size_t alignment = ag; is_size_aligned(size, alignment); alignment *= 2) {
|
||||
char* const req_addr = (char*) align_ptr_up(mapping2, alignment);
|
||||
char* p = os::Linux::reserve_memory_special_huge_tlbfs_mixed(size, alignment, req_addr, false);
|
||||
test_log(SIZE_FORMAT_HEX " " SIZE_FORMAT_HEX " " PTR_FORMAT " -> " PTR_FORMAT " %s",
|
||||
size, alignment, req_addr, p,
|
||||
((p != NULL ? "" : "(failed)")));
|
||||
// as the area around req_addr contains already existing mappings, the API should always
|
||||
// return NULL (as per contract, it cannot return another address)
|
||||
assert(p == NULL, "must be");
|
||||
}
|
||||
}
|
||||
|
||||
::munmap(mapping2, mapping_size);
|
||||
|
||||
}
|
||||
|
||||
static void test_reserve_memory_special_huge_tlbfs() {
|
||||
|
@ -4,6 +4,13 @@
|
||||
*** EDIT ../build.xml INSTEAD ***
|
||||
-->
|
||||
<project name="com.sun.hotspot.igv.svg-impl" basedir="..">
|
||||
<fail message="Please build using Ant 1.7.1 or higher.">
|
||||
<condition>
|
||||
<not>
|
||||
<antversion atleast="1.7.1"/>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
<property file="nbproject/private/suite-private.properties"/>
|
||||
<property file="nbproject/suite.properties"/>
|
||||
<fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
|
||||
@ -16,13 +23,21 @@
|
||||
<property name="@{name}" value="${@{value}}"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
<macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
|
||||
<attribute name="property"/>
|
||||
<attribute name="value"/>
|
||||
<sequential>
|
||||
<property name="@{property}" value="@{value}"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
<property file="${user.properties.file}"/>
|
||||
<nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
|
||||
<nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
|
||||
<fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
|
||||
<nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
|
||||
<nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
|
||||
<fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
|
||||
<condition>
|
||||
<not>
|
||||
<available file="${harness.dir}" type="dir"/>
|
||||
<contains string="${cluster.path.evaluated}" substring="platform"/>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
|
@ -1,8 +1,5 @@
|
||||
build.xml.data.CRC32=ebcf0422
|
||||
build.xml.script.CRC32=d7a2678d
|
||||
build.xml.stylesheet.CRC32=79c3b980
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=ebcf0422
|
||||
nbproject/build-impl.xml.script.CRC32=57997f94
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
|
||||
nbproject/build-impl.xml.script.CRC32=42ef3ff6
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
|
||||
|
@ -1,2 +1,2 @@
|
||||
javac.source=1.5
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
javac.source=1.7
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,40 +25,58 @@ package com.sun.hotspot.igv.svg;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.io.Writer;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import org.w3c.dom.DOMImplementation;
|
||||
|
||||
/**
|
||||
*
|
||||
* Utility class
|
||||
* @author Thomas Wuerthinger
|
||||
*/
|
||||
public class BatikSVG {
|
||||
|
||||
private static Constructor SVGGraphics2DConstructor;
|
||||
private static Method Method_stream;
|
||||
private static Method Method_createDefault;
|
||||
private static Method Method_getDOMImplementation;
|
||||
private static Method Method_setEmbeddedFontsOn;
|
||||
private BatikSVG() {
|
||||
}
|
||||
|
||||
private static Constructor SVGGraphics2DConstructor;
|
||||
private static Method streamMethod;
|
||||
private static Method createDefaultMethod;
|
||||
private static Method getDOMImplementationMethod;
|
||||
private static Method setEmbeddedFontsOnMethod;
|
||||
private static Class<?> classSVGGraphics2D;
|
||||
|
||||
/**
|
||||
* Creates a graphics object that allows to be exported to SVG data using the {@link #printToStream(Graphics2D, Writer, boolean) printToStream} method.
|
||||
* @return the newly created Graphics2D object or null if the library does not exist
|
||||
*/
|
||||
public static Graphics2D createGraphicsObject() {
|
||||
try {
|
||||
if (SVGGraphics2DConstructor == null) {
|
||||
ClassLoader cl = BatikSVG.class.getClassLoader();
|
||||
Class Class_GenericDOMImplementation = cl.loadClass("org.apache.batik.dom.GenericDOMImplementation");
|
||||
Class Class_SVGGeneratorContext = cl.loadClass("org.apache.batik.svggen.SVGGeneratorContext");
|
||||
Class Class_SVGGraphics2D = cl.loadClass("org.apache.batik.svggen.SVGGraphics2D");
|
||||
Method_getDOMImplementation = Class_GenericDOMImplementation.getDeclaredMethod("getDOMImplementation", new Class[0]);
|
||||
Method_createDefault = Class_SVGGeneratorContext.getDeclaredMethod("createDefault", new Class[]{org.w3c.dom.Document.class});
|
||||
Method_setEmbeddedFontsOn = Class_SVGGeneratorContext.getDeclaredMethod("setEmbeddedFontsOn", new Class[]{boolean.class});
|
||||
Method_stream = Class_SVGGraphics2D.getDeclaredMethod("stream", Writer.class, boolean.class);
|
||||
SVGGraphics2DConstructor = Class_SVGGraphics2D.getConstructor(Class_SVGGeneratorContext, boolean.class);
|
||||
String batikJar = System.getenv().get("IGV_BATIK_JAR");
|
||||
if (batikJar == null) {
|
||||
return null;
|
||||
}
|
||||
// Load batik in it's own class loader since some it's support jars interfere with the JDK
|
||||
URL url = new File(batikJar).toURI().toURL();
|
||||
ClassLoader cl = new URLClassLoader(new URL[] { url });
|
||||
Class<?> classGenericDOMImplementation = cl.loadClass("org.apache.batik.dom.GenericDOMImplementation");
|
||||
Class<?> classSVGGeneratorContext = cl.loadClass("org.apache.batik.svggen.SVGGeneratorContext");
|
||||
classSVGGraphics2D = cl.loadClass("org.apache.batik.svggen.SVGGraphics2D");
|
||||
getDOMImplementationMethod = classGenericDOMImplementation.getDeclaredMethod("getDOMImplementation", new Class[0]);
|
||||
createDefaultMethod = classSVGGeneratorContext.getDeclaredMethod("createDefault", new Class[]{org.w3c.dom.Document.class});
|
||||
setEmbeddedFontsOnMethod = classSVGGeneratorContext.getDeclaredMethod("setEmbeddedFontsOn", new Class[]{boolean.class});
|
||||
streamMethod = classSVGGraphics2D.getDeclaredMethod("stream", Writer.class, boolean.class);
|
||||
SVGGraphics2DConstructor = classSVGGraphics2D.getConstructor(classSVGGeneratorContext, boolean.class);
|
||||
}
|
||||
DOMImplementation dom = (DOMImplementation) Method_getDOMImplementation.invoke(null);
|
||||
DOMImplementation dom = (DOMImplementation) getDOMImplementationMethod.invoke(null);
|
||||
org.w3c.dom.Document document = dom.createDocument("http://www.w3.org/2000/svg", "svg", null);
|
||||
Object ctx = Method_createDefault.invoke(null, document);
|
||||
Method_setEmbeddedFontsOn.invoke(ctx, true);
|
||||
Object ctx = createDefaultMethod.invoke(null, document);
|
||||
setEmbeddedFontsOnMethod.invoke(ctx, true);
|
||||
Graphics2D svgGenerator = (Graphics2D) SVGGraphics2DConstructor.newInstance(ctx, true);
|
||||
return svgGenerator;
|
||||
} catch (ClassNotFoundException e) {
|
||||
@ -71,12 +89,22 @@ public class BatikSVG {
|
||||
return null;
|
||||
} catch (InstantiationException e) {
|
||||
return null;
|
||||
} catch (MalformedURLException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes a graphics object to a stream in SVG format.
|
||||
* @param svgGenerator the graphics object. Only graphics objects created by the {@link #createGraphicsObject() createGraphicsObject} method are valid.
|
||||
* @param stream the stream to which the data is written
|
||||
* @param useCSS whether to use CSS styles in the SVG output
|
||||
*/
|
||||
public static void printToStream(Graphics2D svgGenerator, Writer stream, boolean useCSS) {
|
||||
assert classSVGGraphics2D != null;
|
||||
assert classSVGGraphics2D.isInstance(svgGenerator);
|
||||
try {
|
||||
Method_stream.invoke(svgGenerator, stream, useCSS);
|
||||
streamMethod.invoke(svgGenerator, stream, useCSS);
|
||||
} catch (IllegalAccessException e) {
|
||||
assert false;
|
||||
} catch (InvocationTargetException e) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -21,14 +21,9 @@
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
package com.sun.hotspot.igv.view;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Thomas Wuerthinger
|
||||
* This package is used to proxy the SVG export functionality of the BatikSVG library. Reflection is used such that the
|
||||
* library is optional and need not be present at build time.
|
||||
*/
|
||||
public class PreferenceConstants {
|
||||
package com.sun.hotspot.igv.svg;
|
||||
|
||||
public static final String KEY_LINE_GENERATOR = "lineGenerator";
|
||||
public static final String DEFAULT_LINE_GENERATOR = "com.sun.hotspot.igv.positioning.BasicLineGenerator";
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
Manifest-Version: 1.0
|
||||
OpenIDE-Module: com.sun.hotspot.igv.bytecodes
|
||||
OpenIDE-Module-Layer: com/sun/hotspot/igv/bytecodes/layer.xml
|
||||
OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/bytecodes/Bundle.properties
|
||||
OpenIDE-Module-Specification-Version: 1.0
|
||||
|
||||
Manifest-Version: 1.0
|
||||
OpenIDE-Module: com.sun.hotspot.igv.bytecodes
|
||||
OpenIDE-Module-Layer: com/sun/hotspot/igv/bytecodes/layer.xml
|
||||
OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/bytecodes/Bundle.properties
|
||||
OpenIDE-Module-Specification-Version: 1.0
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
javac.source=1.5
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
javac.source=1.7
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
|
@ -14,13 +14,37 @@
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.graph</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.util</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.jdesktop.layout</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.4</specification-version>
|
||||
<specification-version>1.16.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.awt</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.39.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -28,7 +52,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.11</specification-version>
|
||||
<specification-version>6.34.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -36,7 +60,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.2.0.1</specification-version>
|
||||
<specification-version>7.20.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -44,7 +68,15 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.9.0.1</specification-version>
|
||||
<specification-version>8.14.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.util.lookup</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.6.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -52,7 +84,7 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.16</specification-version>
|
||||
<specification-version>6.39.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</module-dependencies>
|
||||
|
@ -1,5 +1,5 @@
|
||||
CTL_BytecodeViewAction=Open BytecodeView Window
|
||||
CTL_BytecodeViewTopComponent=BytecodeView Window
|
||||
CTL_BytecodeViewAction=Bytecode
|
||||
CTL_BytecodeViewTopComponent=Bytecode
|
||||
CTL_SelectBytecodesAction=Select nodes
|
||||
HINT_BytecodeViewTopComponent=This is a BytecodeView window
|
||||
HINT_BytecodeViewTopComponent=Shows the bytecode associated with the displayed graph.
|
||||
OpenIDE-Module-Name=Bytecodes
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,14 +29,14 @@ import com.sun.hotspot.igv.data.InputNode;
|
||||
import com.sun.hotspot.igv.data.Properties;
|
||||
import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
|
||||
import java.awt.Image;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import javax.swing.Action;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.Utilities;
|
||||
import org.openide.util.ImageUtilities;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -49,29 +49,35 @@ public class BytecodeNode extends AbstractNode {
|
||||
public BytecodeNode(InputBytecode bytecode, InputGraph graph, String bciValue) {
|
||||
|
||||
super(Children.LEAF);
|
||||
this.setDisplayName(bytecode.getBci() + " " + bytecode.getName());
|
||||
String displayName = bytecode.getBci() + " " + bytecode.getName() + " " + bytecode.getOperands();
|
||||
|
||||
bciValue = bytecode.getBci() + " " + bciValue;
|
||||
bciValue = bciValue.trim();
|
||||
|
||||
Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<InputNode>(graph.getNodes());
|
||||
Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(graph.getNodes());
|
||||
StringPropertyMatcher matcher = new StringPropertyMatcher("bci", bciValue);
|
||||
List<InputNode> nodeList = selector.selectMultiple(matcher);
|
||||
if (nodeList.size() > 0) {
|
||||
nodes = new HashSet<InputNode>();
|
||||
nodes = new LinkedHashSet<>();
|
||||
for (InputNode n : nodeList) {
|
||||
nodes.add(n);
|
||||
}
|
||||
this.setDisplayName(this.getDisplayName() + " (" + nodes.size() + " nodes)");
|
||||
displayName += " (" + nodes.size() + " nodes)";
|
||||
}
|
||||
|
||||
if (bytecode.getComment() != null) {
|
||||
displayName += " // " + bytecode.getComment();
|
||||
}
|
||||
|
||||
this.setDisplayName(displayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getIcon(int i) {
|
||||
if (nodes != null) {
|
||||
return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/link.gif");
|
||||
return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/link.png");
|
||||
} else {
|
||||
return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/bytecode.gif");
|
||||
return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/bytecode.png");
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,6 +97,7 @@ public class BytecodeNode extends AbstractNode {
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T extends Node.Cookie> T getCookie(Class<T> aClass) {
|
||||
if (aClass == SelectBytecodesCookie.class && nodes != null) {
|
||||
return (T) (new SelectBytecodesCookie(nodes));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -37,6 +37,7 @@ public class BytecodeViewAction extends AbstractAction {
|
||||
super(NbBundle.getMessage(BytecodeViewAction.class, "CTL_BytecodeViewAction"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
TopComponent win = BytecodeViewTopComponent.findInstance();
|
||||
win.open();
|
||||
|
@ -3,6 +3,8 @@
|
||||
<Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,6 +26,7 @@ package com.sun.hotspot.igv.bytecodes;
|
||||
import com.sun.hotspot.igv.data.Group;
|
||||
import com.sun.hotspot.igv.data.InputGraph;
|
||||
import com.sun.hotspot.igv.data.services.InputGraphProvider;
|
||||
import com.sun.hotspot.igv.util.LookupHistory;
|
||||
import java.awt.BorderLayout;
|
||||
import java.io.Serializable;
|
||||
import javax.swing.SwingUtilities;
|
||||
@ -33,11 +34,7 @@ import org.openide.ErrorManager;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import org.openide.explorer.ExplorerUtils;
|
||||
import org.openide.explorer.view.BeanTreeView;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.LookupEvent;
|
||||
import org.openide.util.LookupListener;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.Utilities;
|
||||
import org.openide.util.*;
|
||||
import org.openide.windows.TopComponent;
|
||||
import org.openide.windows.WindowManager;
|
||||
|
||||
@ -91,6 +88,7 @@ final class BytecodeViewTopComponent extends TopComponent implements ExplorerMan
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
* Gets default instance. Do not use directly: reserved for *.settings files only,
|
||||
* i.e. deserialization routines; otherwise you could get a non-deserialized instance.
|
||||
@ -126,7 +124,7 @@ final class BytecodeViewTopComponent extends TopComponent implements ExplorerMan
|
||||
|
||||
@Override
|
||||
public void componentOpened() {
|
||||
Lookup.Template tpl = new Lookup.Template(Object.class);
|
||||
Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<>(InputGraphProvider.class);
|
||||
result = Utilities.actionsGlobalContext().lookup(tpl);
|
||||
result.addLookupListener(this);
|
||||
}
|
||||
@ -147,23 +145,47 @@ final class BytecodeViewTopComponent extends TopComponent implements ExplorerMan
|
||||
return PREFERRED_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExplorerManager getExplorerManager() {
|
||||
return manager;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestActive() {
|
||||
super.requestActive();
|
||||
this.treeView.requestFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestFocus(boolean temporary) {
|
||||
this.treeView.requestFocus();
|
||||
return super.requestFocus(temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean requestFocusInWindow(boolean temporary) {
|
||||
this.treeView.requestFocus();
|
||||
return super.requestFocusInWindow(temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resultChanged(LookupEvent lookupEvent) {
|
||||
final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
|
||||
if (p != null) {
|
||||
final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
InputGraph graph = p.getGraph();
|
||||
if (graph != null) {
|
||||
Group g = graph.getGroup();
|
||||
rootNode.update(graph, g.getMethod());
|
||||
}
|
||||
}
|
||||
if (p != null) {
|
||||
InputGraph graph = p.getGraph();
|
||||
if (graph != null) {
|
||||
Group g = graph.getGroup();
|
||||
rootNode.update(graph, g.getMethod());
|
||||
return;
|
||||
}
|
||||
}
|
||||
rootNode.update(null, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
final static class ResolvableHelper implements Serializable {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -30,7 +30,7 @@ import java.awt.Image;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.Utilities;
|
||||
import org.openide.util.ImageUtilities;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -38,7 +38,7 @@ import org.openide.util.Utilities;
|
||||
*/
|
||||
public class MethodNode extends AbstractNode {
|
||||
|
||||
private static class MethodNodeChildren extends Children.Keys {
|
||||
private static class MethodNodeChildren extends Children.Keys<InputBytecode> {
|
||||
|
||||
private InputMethod method;
|
||||
private InputGraph graph;
|
||||
@ -50,9 +50,8 @@ public class MethodNode extends AbstractNode {
|
||||
this.graph = graph;
|
||||
}
|
||||
|
||||
protected Node[] createNodes(Object object) {
|
||||
assert object instanceof InputBytecode;
|
||||
InputBytecode bc = (InputBytecode) object;
|
||||
@Override
|
||||
protected Node[] createNodes(InputBytecode bc) {
|
||||
if (bc.getInlined() == null) {
|
||||
return new Node[]{new BytecodeNode(bc, graph, bciString)};
|
||||
} else {
|
||||
@ -84,7 +83,7 @@ public class MethodNode extends AbstractNode {
|
||||
|
||||
@Override
|
||||
public Image getIcon(int i) {
|
||||
return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/method.gif");
|
||||
return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/method.png");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,9 +24,9 @@
|
||||
package com.sun.hotspot.igv.bytecodes;
|
||||
|
||||
import com.sun.hotspot.igv.data.services.InputGraphProvider;
|
||||
import com.sun.hotspot.igv.util.LookupHistory;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.HelpCtx;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.actions.CookieAction;
|
||||
|
||||
@ -36,22 +36,26 @@ import org.openide.util.actions.CookieAction;
|
||||
*/
|
||||
public final class SelectBytecodesAction extends CookieAction {
|
||||
|
||||
@Override
|
||||
protected void performAction(Node[] activatedNodes) {
|
||||
SelectBytecodesCookie c = activatedNodes[0].getCookie(SelectBytecodesCookie.class);
|
||||
InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
|
||||
InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
|
||||
if (p != null) {
|
||||
p.setSelectedNodes(c.getNodes());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int mode() {
|
||||
return CookieAction.MODE_EXACTLY_ONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NbBundle.getMessage(SelectBytecodesAction.class, "CTL_SelectBytecodesAction");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class[] cookieClasses() {
|
||||
return new Class[]{
|
||||
SelectBytecodesCookie.class
|
||||
@ -64,6 +68,7 @@ public final class SelectBytecodesAction extends CookieAction {
|
||||
putValue("noIconInMenu", Boolean.TRUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HelpCtx getHelpCtx() {
|
||||
return HelpCtx.DEFAULT_HELP;
|
||||
}
|
||||
@ -73,3 +78,4 @@ public final class SelectBytecodesAction extends CookieAction {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 70 B |
Binary file not shown.
After Width: | Height: | Size: 323 B |
Binary file not shown.
Before Width: | Height: | Size: 898 B |
Binary file not shown.
After Width: | Height: | Size: 570 B |
Binary file not shown.
Before Width: | Height: | Size: 346 B |
Binary file not shown.
After Width: | Height: | Size: 564 B |
@ -1,6 +1,6 @@
|
||||
Manifest-Version: 1.0
|
||||
OpenIDE-Module: com.sun.hotspot.igv.controlflow
|
||||
OpenIDE-Module-Layer: com/sun/hotspot/igv/controlflow/layer.xml
|
||||
OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/controlflow/Bundle.properties
|
||||
OpenIDE-Module-Specification-Version: 1.0
|
||||
|
||||
Manifest-Version: 1.0
|
||||
OpenIDE-Module: com.sun.hotspot.igv.controlflow
|
||||
OpenIDE-Module-Layer: com/sun/hotspot/igv/controlflow/layer.xml
|
||||
OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/controlflow/Bundle.properties
|
||||
OpenIDE-Module-Specification-Version: 1.0
|
||||
|
||||
|
@ -30,13 +30,21 @@
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.util</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.jdesktop.layout</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.4</specification-version>
|
||||
<specification-version>1.16.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -52,7 +60,15 @@
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.9.0.1</specification-version>
|
||||
<specification-version>8.14.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.util.lookup</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.6.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -26,7 +26,9 @@ package com.sun.hotspot.igv.controlflow;
|
||||
import com.sun.hotspot.igv.data.InputBlockEdge;
|
||||
import com.sun.hotspot.igv.layout.Link;
|
||||
import com.sun.hotspot.igv.layout.Port;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Point;
|
||||
import java.awt.Stroke;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.netbeans.api.visual.widget.ConnectionWidget;
|
||||
@ -37,12 +39,19 @@ import org.netbeans.api.visual.widget.ConnectionWidget;
|
||||
*/
|
||||
public class BlockConnectionWidget extends ConnectionWidget implements Link {
|
||||
|
||||
private static final Stroke NORMAL_STROKE = new BasicStroke(1.0f);
|
||||
private static final Stroke BOLD_STROKE = new BasicStroke(2.5f);
|
||||
private static final Stroke DASHED_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, new float[]{5, 5}, 0);
|
||||
private static final Stroke BOLD_DASHED_STROKE = new BasicStroke(2.5f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, new float[]{5, 5}, 0);
|
||||
|
||||
private BlockWidget from;
|
||||
private BlockWidget to;
|
||||
private Port inputSlot;
|
||||
private Port outputSlot;
|
||||
private List<Point> points;
|
||||
private InputBlockEdge edge;
|
||||
private boolean isDashed = false;
|
||||
private boolean isBold = false;
|
||||
|
||||
public BlockConnectionWidget(ControlFlowScene scene, InputBlockEdge edge) {
|
||||
super(scene);
|
||||
@ -67,6 +76,30 @@ public class BlockConnectionWidget extends ConnectionWidget implements Link {
|
||||
return outputSlot;
|
||||
}
|
||||
|
||||
public void setBold(boolean bold) {
|
||||
this.isBold = bold;
|
||||
updateStroke();
|
||||
}
|
||||
|
||||
public void setDashed(boolean dashed) {
|
||||
this.isDashed = dashed;
|
||||
updateStroke();
|
||||
}
|
||||
|
||||
private void updateStroke() {
|
||||
Stroke stroke = NORMAL_STROKE;
|
||||
if (isBold) {
|
||||
if (isDashed) {
|
||||
stroke = BOLD_DASHED_STROKE;
|
||||
} else {
|
||||
stroke = BOLD_STROKE;
|
||||
}
|
||||
} else if (isDashed) {
|
||||
stroke = DASHED_STROKE;
|
||||
}
|
||||
setStroke(stroke);
|
||||
}
|
||||
|
||||
public void setControlPoints(List<Point> p) {
|
||||
this.points = p;
|
||||
}
|
||||
@ -80,4 +113,9 @@ public class BlockConnectionWidget extends ConnectionWidget implements Link {
|
||||
public String toString() {
|
||||
return "Connection[ " + from.toString() + " - " + to.toString() + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVIP() {
|
||||
return isBold;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -31,6 +31,7 @@ import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import org.netbeans.api.visual.border.BorderFactory;
|
||||
import org.netbeans.api.visual.model.ObjectState;
|
||||
import org.netbeans.api.visual.widget.LabelWidget;
|
||||
@ -41,13 +42,13 @@ import org.netbeans.api.visual.widget.LabelWidget;
|
||||
*/
|
||||
public class BlockWidget extends LabelWidget implements Vertex {
|
||||
|
||||
public static final Dimension SIZE = new Dimension(20, 20);
|
||||
public static final Dimension MIN_SIZE = new Dimension(20, 20);
|
||||
private InputBlock block;
|
||||
private Port inputSlot;
|
||||
private Port outputSlot;
|
||||
private Cluster cluster;
|
||||
private boolean root;
|
||||
private static final Font font = new Font(Font.SERIF, Font.PLAIN, 12);
|
||||
private static final Font font = new Font(Font.SANS_SERIF, Font.PLAIN, 12);
|
||||
private static final Font boldFont = font.deriveFont(Font.BOLD);
|
||||
public static final Color NORMAL_FOREGROUND_COLOR = Color.BLACK;
|
||||
public static final Color HOVER_FOREGROUND_COLOR = Color.BLUE;
|
||||
@ -59,29 +60,24 @@ public class BlockWidget extends LabelWidget implements Vertex {
|
||||
this.setLabel(block.getName());
|
||||
this.setForeground(NORMAL_FOREGROUND_COLOR);
|
||||
this.setBorder(BorderFactory.createLineBorder(1, NORMAL_FOREGROUND_COLOR));
|
||||
this.setMinimumSize(SIZE);
|
||||
this.setMaximumSize(SIZE);
|
||||
this.setMinimumSize(MIN_SIZE);
|
||||
|
||||
this.setFont(font);
|
||||
this.setAlignment(Alignment.CENTER);
|
||||
|
||||
final BlockWidget widget = this;
|
||||
inputSlot = new Port() {
|
||||
|
||||
public Point getRelativePosition() {
|
||||
return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
|
||||
return new Point((int) (getSize().getWidth() / 2), (int) (getSize().getHeight() / 2));
|
||||
}
|
||||
|
||||
public Vertex getVertex() {
|
||||
return widget;
|
||||
}
|
||||
};
|
||||
|
||||
outputSlot = new Port() {
|
||||
|
||||
public Point getRelativePosition() {
|
||||
return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
|
||||
return new Point((int) (getSize().getWidth() / 2), (int) (getSize().getHeight() / 2));
|
||||
}
|
||||
|
||||
public Vertex getVertex() {
|
||||
return widget;
|
||||
}
|
||||
@ -101,7 +97,12 @@ public class BlockWidget extends LabelWidget implements Vertex {
|
||||
}
|
||||
|
||||
public Dimension getSize() {
|
||||
return SIZE;
|
||||
Rectangle bounds = getBounds();
|
||||
if (bounds != null) {
|
||||
return bounds.getSize();
|
||||
} else {
|
||||
return MIN_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
public void setPosition(Point p) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
CTL_ControlFlowAction=Open ControlFlow Window
|
||||
CTL_ControlFlowTopComponent=ControlFlow Window
|
||||
HINT_ControlFlowTopComponent=This is a ControlFlow window
|
||||
CTL_ControlFlowAction=Control Flow
|
||||
CTL_ControlFlowTopComponent=Control Flow
|
||||
HINT_ControlFlowTopComponent=Shows the blocks of the current graph.
|
||||
OpenIDE-Module-Name=ControlFlow
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,17 +23,17 @@
|
||||
*/
|
||||
package com.sun.hotspot.igv.controlflow;
|
||||
|
||||
import com.sun.hotspot.igv.data.InputBlock;
|
||||
import com.sun.hotspot.igv.data.InputBlockEdge;
|
||||
import com.sun.hotspot.igv.data.InputBlock;
|
||||
import com.sun.hotspot.igv.data.InputGraph;
|
||||
import com.sun.hotspot.igv.data.services.InputGraphProvider;
|
||||
import com.sun.hotspot.igv.data.InputNode;
|
||||
import com.sun.hotspot.igv.util.LookupHistory;
|
||||
import java.awt.Color;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.Set;
|
||||
import javax.swing.BorderFactory;
|
||||
import org.netbeans.api.visual.action.ActionFactory;
|
||||
@ -44,15 +44,14 @@ import org.netbeans.api.visual.action.SelectProvider;
|
||||
import org.netbeans.api.visual.action.WidgetAction;
|
||||
import org.netbeans.api.visual.anchor.AnchorFactory;
|
||||
import org.netbeans.api.visual.anchor.AnchorShape;
|
||||
import org.netbeans.api.visual.layout.LayoutFactory;
|
||||
import org.netbeans.api.visual.router.RouterFactory;
|
||||
import org.netbeans.api.visual.widget.LayerWidget;
|
||||
import org.netbeans.api.visual.widget.Widget;
|
||||
import org.netbeans.api.visual.graph.GraphScene;
|
||||
import org.netbeans.api.visual.graph.layout.GraphLayout;
|
||||
import org.netbeans.api.visual.layout.LayoutFactory;
|
||||
import org.netbeans.api.visual.layout.SceneLayout;
|
||||
import org.netbeans.api.visual.widget.ConnectionWidget;
|
||||
import org.openide.util.Lookup;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -61,13 +60,12 @@ import org.openide.util.Lookup;
|
||||
public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
|
||||
|
||||
private HashSet<BlockWidget> selection;
|
||||
private HashMap<InputBlock, BlockWidget> blockMap;
|
||||
private InputGraph oldGraph;
|
||||
private LayerWidget edgeLayer;
|
||||
private LayerWidget mainLayer;
|
||||
private LayerWidget selectLayer;
|
||||
private WidgetAction hoverAction = this.createWidgetHoverAction();
|
||||
private WidgetAction selectAction = ActionFactory.createSelectAction(this);
|
||||
private WidgetAction selectAction = new DoubleClickSelectAction(this);
|
||||
private WidgetAction moveAction = ActionFactory.createMoveAction(null, this);
|
||||
|
||||
public ControlFlowScene() {
|
||||
@ -111,27 +109,21 @@ public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> imp
|
||||
addNode(b);
|
||||
}
|
||||
|
||||
for (InputBlock b : g.getBlocks()) {
|
||||
for (InputBlockEdge e : b.getOutputs()) {
|
||||
addEdge(e);
|
||||
assert g.getBlocks().contains(e.getFrom());
|
||||
assert g.getBlocks().contains(e.getTo());
|
||||
this.setEdgeSource(e, e.getFrom());
|
||||
this.setEdgeTarget(e, e.getTo());
|
||||
}
|
||||
for (InputBlockEdge e : g.getBlockEdges()) {
|
||||
addEdge(e);
|
||||
assert g.getBlocks().contains(e.getFrom());
|
||||
assert g.getBlocks().contains(e.getTo());
|
||||
this.setEdgeSource(e, e.getFrom());
|
||||
this.setEdgeTarget(e, e.getTo());
|
||||
}
|
||||
|
||||
GraphLayout layout = new HierarchicalGraphLayout();//GridGraphLayout();
|
||||
GraphLayout<InputBlock, InputBlockEdge> layout = new HierarchicalGraphLayout<InputBlock, InputBlockEdge>();//GridGraphLayout();
|
||||
SceneLayout sceneLayout = LayoutFactory.createSceneGraphLayout(this, layout);
|
||||
sceneLayout.invokeLayout();
|
||||
|
||||
this.validate();
|
||||
}
|
||||
|
||||
public BlockWidget getBlockWidget(InputBlock b) {
|
||||
return blockMap.get(b);
|
||||
}
|
||||
|
||||
public void clearSelection() {
|
||||
for (BlockWidget w : selection) {
|
||||
w.setState(w.getState().deriveSelected(false));
|
||||
@ -141,7 +133,7 @@ public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> imp
|
||||
}
|
||||
|
||||
public void selectionChanged() {
|
||||
InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
|
||||
InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
|
||||
if (p != null) {
|
||||
Set<InputNode> inputNodes = new HashSet<InputNode>();
|
||||
for (BlockWidget w : selection) {
|
||||
@ -204,15 +196,19 @@ public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> imp
|
||||
}
|
||||
|
||||
public void setNewLocation(Widget widget, Point location) {
|
||||
Point originalLocation = getOriginalLocation(widget);
|
||||
int xOffset = location.x - originalLocation.x;
|
||||
int yOffset = location.y - originalLocation.y;
|
||||
for (Widget w : this.selection) {
|
||||
Point p = new Point(w.getPreferredLocation());
|
||||
p.translate(xOffset, yOffset);
|
||||
w.setPreferredLocation(p);
|
||||
if (selection.contains(widget)) {
|
||||
// move entire selection
|
||||
Point originalLocation = getOriginalLocation(widget);
|
||||
int xOffset = location.x - originalLocation.x;
|
||||
int yOffset = location.y - originalLocation.y;
|
||||
for (Widget w : selection) {
|
||||
Point p = new Point(w.getPreferredLocation());
|
||||
p.translate(xOffset, yOffset);
|
||||
w.setPreferredLocation(p);
|
||||
}
|
||||
} else {
|
||||
widget.setPreferredLocation(location);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Widget createSelectionWidget() {
|
||||
@ -271,7 +267,15 @@ public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> imp
|
||||
}
|
||||
|
||||
protected Widget attachEdgeWidget(InputBlockEdge edge) {
|
||||
ConnectionWidget w = new BlockConnectionWidget(this, edge);
|
||||
BlockConnectionWidget w = new BlockConnectionWidget(this, edge);
|
||||
switch (edge.getState()) {
|
||||
case NEW:
|
||||
w.setBold(true);
|
||||
break;
|
||||
case DELETED:
|
||||
w.setDashed(true);
|
||||
break;
|
||||
}
|
||||
w.setRouter(RouterFactory.createDirectRouter());
|
||||
w.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
|
||||
edgeLayer.addChild(w);
|
||||
|
@ -3,6 +3,8 @@
|
||||
<Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -25,6 +25,7 @@ package com.sun.hotspot.igv.controlflow;
|
||||
|
||||
import com.sun.hotspot.igv.data.InputGraph;
|
||||
import com.sun.hotspot.igv.data.services.InputGraphProvider;
|
||||
import com.sun.hotspot.igv.util.LookupHistory;
|
||||
import java.awt.BorderLayout;
|
||||
import java.io.Serializable;
|
||||
import javax.swing.JScrollPane;
|
||||
@ -63,17 +64,7 @@ final class ControlFlowTopComponent extends TopComponent implements LookupListen
|
||||
this.add(panel, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestFocus() {
|
||||
super.requestFocus();
|
||||
scene.getView().requestFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestFocusInWindow() {
|
||||
super.requestFocusInWindow();
|
||||
return scene.getView().requestFocusInWindow();
|
||||
}
|
||||
|
||||
/** This method is called from within the constructor to
|
||||
* initialize the form.
|
||||
@ -96,6 +87,7 @@ final class ControlFlowTopComponent extends TopComponent implements LookupListen
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
// End of variables declaration//GEN-END:variables
|
||||
|
||||
/**
|
||||
* Gets default instance. Do not use directly: reserved for *.settings files only,
|
||||
* i.e. deserialization routines; otherwise you could get a non-deserialized instance.
|
||||
@ -131,7 +123,7 @@ final class ControlFlowTopComponent extends TopComponent implements LookupListen
|
||||
|
||||
@Override
|
||||
public void componentOpened() {
|
||||
Lookup.Template tpl = new Lookup.Template(Object.class);
|
||||
Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<InputGraphProvider>(InputGraphProvider.class);
|
||||
result = Utilities.actionsGlobalContext().lookup(tpl);
|
||||
result.addLookupListener(this);
|
||||
}
|
||||
@ -143,16 +135,16 @@ final class ControlFlowTopComponent extends TopComponent implements LookupListen
|
||||
}
|
||||
|
||||
public void resultChanged(LookupEvent lookupEvent) {
|
||||
|
||||
final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
|
||||
final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
|
||||
if (p != null) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
public void run() {
|
||||
InputGraph g = p.getGraph();
|
||||
if (g != null) {
|
||||
scene.setGraph(g);
|
||||
}
|
||||
}
|
||||
InputGraph g = p.getGraph();
|
||||
if (g != null) {
|
||||
scene.setGraph(g);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -169,8 +161,8 @@ final class ControlFlowTopComponent extends TopComponent implements LookupListen
|
||||
|
||||
@Override
|
||||
public void requestActive() {
|
||||
scene.getView().requestFocusInWindow();
|
||||
super.requestActive();
|
||||
scene.getView().requestFocus();
|
||||
}
|
||||
|
||||
final static class ResolvableHelper implements Serializable {
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
package com.sun.hotspot.igv.controlflow;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.event.MouseEvent;
|
||||
import org.netbeans.api.visual.action.SelectProvider;
|
||||
import org.netbeans.api.visual.action.WidgetAction;
|
||||
import org.netbeans.api.visual.widget.Widget;
|
||||
|
||||
/**
|
||||
* Selection action that acts on double-click only. Does not support aiming.
|
||||
*
|
||||
* @author Peter Hofer
|
||||
*/
|
||||
public class DoubleClickSelectAction extends WidgetAction.LockedAdapter {
|
||||
|
||||
private final SelectProvider provider;
|
||||
|
||||
public DoubleClickSelectAction(SelectProvider provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
protected boolean isLocked() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public State mousePressed(Widget widget, WidgetMouseEvent event) {
|
||||
if (event.getClickCount() >= 2 && (event.getButton() == MouseEvent.BUTTON1 || event.getButton() == MouseEvent.BUTTON2)) {
|
||||
boolean invert = (event.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0;
|
||||
Point point = event.getPoint();
|
||||
if (provider.isSelectionAllowed(widget, point, invert)) {
|
||||
provider.select(widget, point, invert);
|
||||
return State.CHAIN_ONLY;
|
||||
}
|
||||
}
|
||||
return State.REJECTED;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -34,7 +34,7 @@ import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -76,6 +76,10 @@ public class HierarchicalGraphLayout<N, E> extends GraphLayout<N, E> {
|
||||
public void setControlPoints(List<Point> list) {
|
||||
// Do nothing for now
|
||||
}
|
||||
|
||||
public boolean isVIP() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class VertexWrapper implements Vertex {
|
||||
@ -127,6 +131,7 @@ public class HierarchicalGraphLayout<N, E> extends GraphLayout<N, E> {
|
||||
}
|
||||
|
||||
public int compareTo(Vertex o) {
|
||||
@SuppressWarnings("unchecked")
|
||||
VertexWrapper vw = (VertexWrapper) o;
|
||||
return node.toString().compareTo(vw.node.toString());
|
||||
}
|
||||
@ -138,8 +143,8 @@ public class HierarchicalGraphLayout<N, E> extends GraphLayout<N, E> {
|
||||
|
||||
protected void performGraphLayout(UniversalGraph<N, E> graph) {
|
||||
|
||||
Set<LinkWrapper> links = new HashSet<LinkWrapper>();
|
||||
Set<VertexWrapper> vertices = new HashSet<VertexWrapper>();
|
||||
Set<LinkWrapper> links = new LinkedHashSet<LinkWrapper>();
|
||||
Set<VertexWrapper> vertices = new LinkedHashSet<VertexWrapper>();
|
||||
Map<N, VertexWrapper> vertexMap = new HashMap<N, VertexWrapper>();
|
||||
|
||||
for (N node : graph.getNodes()) {
|
||||
|
@ -1,2 +1,2 @@
|
||||
javac.source=1.5
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
javac.source=1.7
|
||||
javac.compilerargs=-Xlint -Xlint:-serial
|
||||
|
@ -1,126 +1,142 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.apisupport.project</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
|
||||
<code-name-base>com.sun.hotspot.igv.coordinator</code-name-base>
|
||||
<suite-component/>
|
||||
<module-dependencies>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.data</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.difference</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.settings</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.util</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.netbeans.api.progress</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.10.0.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.actions</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.6.1.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.awt</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.11.0.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.dialogs</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.5.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.explorer</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.11</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.filesystems</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.3</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.loaders</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.7</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.nodes</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.2.0.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.util</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.9.0.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.windows</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.16</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</module-dependencies>
|
||||
<public-packages/>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.apisupport.project</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
|
||||
<code-name-base>com.sun.hotspot.igv.coordinator</code-name-base>
|
||||
<suite-component/>
|
||||
<module-dependencies>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.connection</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.data</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.difference</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.settings</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>com.sun.hotspot.igv.util</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>1.0</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.netbeans.api.progress</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.23.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.actions</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.21.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.awt</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.30.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.dialogs</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.18.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.explorer</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.34.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.filesystems</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.46.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.loaders</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.20.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.nodes</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>7.20.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.util</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.14.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.util.lookup</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>8.6.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.windows</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<specification-version>6.39.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
</module-dependencies>
|
||||
<public-packages/>
|
||||
</data>
|
||||
</configuration>
|
||||
</project>
|
||||
|
@ -1,2 +0,0 @@
|
||||
com.sun.hotspot.igv.coordinator.StandardGroupOrganizer
|
||||
com.sun.hotspot.igv.coordinator.GraphCountGroupOrganizer
|
@ -1,7 +1,6 @@
|
||||
|
||||
AdvancedOption_DisplayName_Coordinator=Settings
|
||||
AdvancedOption_Tooltip_Coordinator=Visualization Tool Settings
|
||||
CTL_OutlineTopComponent=Outline Window
|
||||
CTL_SomeAction=test
|
||||
HINT_OutlineTopComponent=This is a Outline window
|
||||
OpenIDE-Module-Name=Coordinator
|
||||
AdvancedOption_DisplayName_Coordinator=Settings
|
||||
AdvancedOption_Tooltip_Coordinator=Visualization Tool Settings
|
||||
CTL_OutlineTopComponent=Outline
|
||||
CTL_SomeAction=test
|
||||
HINT_OutlineTopComponent=Displays loaded groups of graphs.
|
||||
OpenIDE-Module-Name=Coordinator
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -24,18 +24,13 @@
|
||||
package com.sun.hotspot.igv.coordinator;
|
||||
|
||||
import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
|
||||
import com.sun.hotspot.igv.data.ChangedListener;
|
||||
import com.sun.hotspot.igv.data.Group;
|
||||
import com.sun.hotspot.igv.data.services.GroupOrganizer;
|
||||
import com.sun.hotspot.igv.data.InputGraph;
|
||||
import com.sun.hotspot.igv.data.Pair;
|
||||
import com.sun.hotspot.igv.data.*;
|
||||
import java.awt.Image;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.util.Utilities;
|
||||
import org.openide.util.ImageUtilities;
|
||||
import org.openide.util.lookup.AbstractLookup;
|
||||
import org.openide.util.lookup.InstanceContent;
|
||||
|
||||
@ -45,107 +40,72 @@ import org.openide.util.lookup.InstanceContent;
|
||||
*/
|
||||
public class FolderNode extends AbstractNode {
|
||||
|
||||
private GroupOrganizer organizer;
|
||||
private InstanceContent content;
|
||||
private List<Pair<String, List<Group>>> structure;
|
||||
private List<String> subFolders;
|
||||
private FolderChildren children;
|
||||
|
||||
private static class FolderChildren extends Children.Keys implements ChangedListener<Group> {
|
||||
private static class FolderChildren extends Children.Keys<FolderElement> implements ChangedListener {
|
||||
|
||||
private FolderNode parent;
|
||||
private List<Group> registeredGroups;
|
||||
private final Folder folder;
|
||||
|
||||
public void setParent(FolderNode parent) {
|
||||
this.parent = parent;
|
||||
this.registeredGroups = new ArrayList<Group>();
|
||||
public FolderChildren(Folder folder) {
|
||||
this.folder = folder;
|
||||
folder.getChangedEvent().addListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Node[] createNodes(Object arg0) {
|
||||
|
||||
for(Group g : registeredGroups) {
|
||||
g.getChangedEvent().removeListener(this);
|
||||
}
|
||||
registeredGroups.clear();
|
||||
|
||||
Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0;
|
||||
if (p.getLeft().length() == 0) {
|
||||
|
||||
List<Node> curNodes = new ArrayList<Node>();
|
||||
for (Group g : p.getRight()) {
|
||||
for (InputGraph graph : g.getGraphs()) {
|
||||
curNodes.add(new GraphNode(graph));
|
||||
}
|
||||
g.getChangedEvent().addListener(this);
|
||||
registeredGroups.add(g);
|
||||
}
|
||||
|
||||
Node[] result = new Node[curNodes.size()];
|
||||
for (int i = 0; i < curNodes.size(); i++) {
|
||||
result[i] = curNodes.get(i);
|
||||
}
|
||||
return result;
|
||||
|
||||
} else {
|
||||
return new Node[]{new FolderNode(p.getLeft(), parent.organizer, parent.subFolders, p.getRight())};
|
||||
protected Node[] createNodes(FolderElement e) {
|
||||
if (e instanceof InputGraph) {
|
||||
return new Node[]{new GraphNode((InputGraph) e)};
|
||||
} else if (e instanceof Folder) {
|
||||
return new Node[]{new FolderNode((Folder) e)};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotify() {
|
||||
this.setKeys(parent.structure);
|
||||
this.setKeys(folder.getElements());
|
||||
}
|
||||
|
||||
public void changed(Group source) {
|
||||
List<Pair<String, List<Group>>> newStructure = new ArrayList<Pair<String, List<Group>>>();
|
||||
for(Pair<String, List<Group>> p : parent.structure) {
|
||||
refreshKey(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected InstanceContent getContent() {
|
||||
return content;
|
||||
@Override
|
||||
public void changed(Object source) {
|
||||
addNotify();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getIcon(int i) {
|
||||
return Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.gif");
|
||||
return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.png");
|
||||
}
|
||||
|
||||
protected FolderNode(String name, GroupOrganizer organizer, List<String> subFolders, List<Group> groups) {
|
||||
this(name, organizer, subFolders, groups, new FolderChildren(), new InstanceContent());
|
||||
protected FolderNode(Folder folder) {
|
||||
this(folder, new FolderChildren(folder), new InstanceContent());
|
||||
}
|
||||
|
||||
private FolderNode(String name, GroupOrganizer organizer, List<String> oldSubFolders, final List<Group> groups, FolderChildren children, InstanceContent content) {
|
||||
private FolderNode(final Folder folder, FolderChildren children, InstanceContent content) {
|
||||
super(children, new AbstractLookup(content));
|
||||
children.setParent(this);
|
||||
this.content = content;
|
||||
this.children = children;
|
||||
content.add(new RemoveCookie() {
|
||||
|
||||
public void remove() {
|
||||
for (Group g : groups) {
|
||||
if (g.getDocument() != null) {
|
||||
g.getDocument().removeGroup(g);
|
||||
}
|
||||
if (folder instanceof FolderElement) {
|
||||
final FolderElement folderElement = (FolderElement) folder;
|
||||
this.setDisplayName(folderElement.getName());
|
||||
content.add(new RemoveCookie() {
|
||||
@Override
|
||||
public void remove() {
|
||||
folderElement.getParent().removeElement(folderElement);
|
||||
}
|
||||
}
|
||||
});
|
||||
init(name, organizer, oldSubFolders, groups);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void init(String name, GroupOrganizer organizer, List<String> oldSubFolders, List<Group> groups) {
|
||||
public void init(String name, List<Group> groups) {
|
||||
this.setDisplayName(name);
|
||||
this.organizer = organizer;
|
||||
this.subFolders = new ArrayList<String>(oldSubFolders);
|
||||
if (name.length() > 0) {
|
||||
this.subFolders.add(name);
|
||||
}
|
||||
structure = organizer.organize(subFolders, groups);
|
||||
assert structure != null;
|
||||
children.addNotify();
|
||||
|
||||
for (Group g : groups) {
|
||||
content.add(g);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.hotspot.igv.coordinator;
|
||||
|
||||
import com.sun.hotspot.igv.data.Group;
|
||||
import com.sun.hotspot.igv.data.Pair;
|
||||
import com.sun.hotspot.igv.data.services.GroupOrganizer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Thomas Wuerthinger
|
||||
*/
|
||||
public class GraphCountGroupOrganizer implements GroupOrganizer {
|
||||
|
||||
public String getName() {
|
||||
return "Graph count structure";
|
||||
}
|
||||
|
||||
public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups) {
|
||||
|
||||
List<Pair<String, List<Group>>> result = new ArrayList<Pair<String, List<Group>>>();
|
||||
|
||||
if (subFolders.size() == 0) {
|
||||
Map<Integer, List<Group>> map = new HashMap<Integer, List<Group>>();
|
||||
for (Group g : groups) {
|
||||
Integer cur = g.getGraphs().size();
|
||||
if (!map.containsKey(cur)) {
|
||||
map.put(cur, new ArrayList<Group>());
|
||||
}
|
||||
map.get(cur).add(g);
|
||||
}
|
||||
|
||||
SortedSet<Integer> keys = new TreeSet<Integer>(map.keySet());
|
||||
for (Integer i : keys) {
|
||||
result.add(new Pair<String, List<Group>>("Graph count " + i, map.get(i)));
|
||||
}
|
||||
|
||||
} else if (subFolders.size() == 1) {
|
||||
for (Group g : groups) {
|
||||
List<Group> children = new ArrayList<Group>();
|
||||
children.add(g);
|
||||
Pair<String, List<Group>> p = new Pair<String, List<Group>>();
|
||||
p.setLeft(g.getName());
|
||||
p.setRight(children);
|
||||
result.add(p);
|
||||
}
|
||||
} else if (subFolders.size() == 2) {
|
||||
result.add(new Pair<String, List<Group>>("", groups));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,23 +23,27 @@
|
||||
*/
|
||||
package com.sun.hotspot.igv.coordinator;
|
||||
|
||||
import com.sun.hotspot.igv.coordinator.actions.CloneGraphAction;
|
||||
import com.sun.hotspot.igv.coordinator.actions.DiffGraphAction;
|
||||
import com.sun.hotspot.igv.coordinator.actions.DiffGraphCookie;
|
||||
import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
|
||||
import com.sun.hotspot.igv.coordinator.actions.GraphCloneCookie;
|
||||
import com.sun.hotspot.igv.coordinator.actions.GraphOpenCookie;
|
||||
import com.sun.hotspot.igv.coordinator.actions.GraphRemoveCookie;
|
||||
import com.sun.hotspot.igv.data.InputGraph;
|
||||
import com.sun.hotspot.igv.data.Properties;
|
||||
import com.sun.hotspot.igv.data.services.GraphViewer;
|
||||
import com.sun.hotspot.igv.data.services.InputGraphProvider;
|
||||
import com.sun.hotspot.igv.util.PropertiesSheet;
|
||||
import java.awt.Image;
|
||||
import javax.swing.Action;
|
||||
import org.openide.actions.OpenAction;
|
||||
import org.openide.cookies.OpenCookie;
|
||||
import org.openide.nodes.AbstractNode;
|
||||
import org.openide.nodes.Children;
|
||||
import org.openide.nodes.Node;
|
||||
import org.openide.nodes.NodeAdapter;
|
||||
import org.openide.nodes.NodeEvent;
|
||||
import org.openide.nodes.NodeMemberEvent;
|
||||
import org.openide.nodes.Sheet;
|
||||
import org.openide.util.ImageUtilities;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.Utilities;
|
||||
import org.openide.util.lookup.AbstractLookup;
|
||||
import org.openide.util.lookup.InstanceContent;
|
||||
|
||||
@ -48,7 +52,6 @@ import org.openide.util.lookup.InstanceContent;
|
||||
* @author Thomas Wuerthinger
|
||||
*/
|
||||
public class GraphNode extends AbstractNode {
|
||||
|
||||
private InputGraph graph;
|
||||
|
||||
/** Creates a new instance of GraphNode */
|
||||
@ -56,7 +59,7 @@ public class GraphNode extends AbstractNode {
|
||||
this(graph, new InstanceContent());
|
||||
}
|
||||
|
||||
private GraphNode(final InputGraph graph, InstanceContent content) {
|
||||
private GraphNode(InputGraph graph, InstanceContent content) {
|
||||
super(Children.LEAF, new AbstractLookup(content));
|
||||
this.graph = graph;
|
||||
this.setDisplayName(graph.getName());
|
||||
@ -66,19 +69,22 @@ public class GraphNode extends AbstractNode {
|
||||
|
||||
if (viewer != null) {
|
||||
// Action for opening the graph
|
||||
content.add(new OpenCookie() {
|
||||
|
||||
public void open() {
|
||||
viewer.view(graph);
|
||||
}
|
||||
});
|
||||
content.add(new GraphOpenCookie(viewer, graph));
|
||||
}
|
||||
|
||||
// Action for removing a graph
|
||||
content.add(new RemoveCookie() {
|
||||
content.add(new GraphRemoveCookie(graph));
|
||||
|
||||
public void remove() {
|
||||
graph.getGroup().removeGraph(graph);
|
||||
// Action for diffing to the current graph
|
||||
content.add(new DiffGraphCookie(graph));
|
||||
|
||||
// Action for cloning to the current graph
|
||||
content.add(new GraphCloneCookie(viewer, graph));
|
||||
|
||||
this.addNodeListener(new NodeAdapter() {
|
||||
@Override
|
||||
public void childrenRemoved(NodeMemberEvent ev) {
|
||||
GraphNode.this.graph = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -86,13 +92,17 @@ public class GraphNode extends AbstractNode {
|
||||
@Override
|
||||
protected Sheet createSheet() {
|
||||
Sheet s = super.createSheet();
|
||||
PropertiesSheet.initializeSheet(graph.getProperties(), s);
|
||||
Properties p = new Properties();
|
||||
p.add(graph.getProperties());
|
||||
p.setProperty("nodeCount", Integer.toString(graph.getNodes().size()));
|
||||
p.setProperty("edgeCount", Integer.toString(graph.getEdges().size()));
|
||||
PropertiesSheet.initializeSheet(p, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getIcon(int i) {
|
||||
return Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/graph.gif");
|
||||
return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/graph.png");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -100,31 +110,29 @@ public class GraphNode extends AbstractNode {
|
||||
return getIcon(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends Node.Cookie> T getCookie(Class<T> aClass) {
|
||||
if (aClass == DiffGraphCookie.class) {
|
||||
InputGraphProvider graphProvider = Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
|
||||
|
||||
InputGraph graphA = null;
|
||||
if (graphProvider != null) {
|
||||
graphA = graphProvider.getGraph();
|
||||
}
|
||||
|
||||
if (graphA != null && !graphA.isDifferenceGraph()) {
|
||||
return (T) new DiffGraphCookie(graphA, graph);
|
||||
}
|
||||
}
|
||||
|
||||
return super.getCookie(aClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action[] getActions(boolean b) {
|
||||
return new Action[]{(Action) DiffGraphAction.findObject(DiffGraphAction.class, true), (Action) OpenAction.findObject(OpenAction.class, true)};
|
||||
return new Action[]{(Action) DiffGraphAction.findObject(DiffGraphAction.class, true), (Action) CloneGraphAction.findObject(CloneGraphAction.class, true), (Action) OpenAction.findObject(OpenAction.class, true)};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Action getPreferredAction() {
|
||||
return (Action) OpenAction.findObject(OpenAction.class, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof GraphNode) {
|
||||
return (graph == ((GraphNode) obj).graph);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return graph.hashCode();
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
|
||||
@ -14,28 +16,17 @@
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="jPanel2">
|
||||
<Container class="javax.swing.JScrollPane" name="treeView">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BeanTreeView();"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BeanTreeView();"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
|
||||
<BorderConstraints direction="Center"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -23,37 +23,25 @@
|
||||
*/
|
||||
package com.sun.hotspot.igv.coordinator;
|
||||
|
||||
import com.sun.hotspot.igv.coordinator.actions.ImportAction;
|
||||
import com.sun.hotspot.igv.coordinator.actions.RemoveAction;
|
||||
import com.sun.hotspot.igv.coordinator.actions.RemoveAllAction;
|
||||
import com.sun.hotspot.igv.coordinator.actions.SaveAllAction;
|
||||
import com.sun.hotspot.igv.coordinator.actions.SaveAsAction;
|
||||
import com.sun.hotspot.igv.coordinator.actions.StructuredViewAction;
|
||||
import com.sun.hotspot.igv.connection.Server;
|
||||
import com.sun.hotspot.igv.coordinator.actions.*;
|
||||
import com.sun.hotspot.igv.data.GraphDocument;
|
||||
import com.sun.hotspot.igv.data.ChangedListener;
|
||||
import com.sun.hotspot.igv.data.Group;
|
||||
import com.sun.hotspot.igv.data.services.GroupCallback;
|
||||
import com.sun.hotspot.igv.data.services.GroupOrganizer;
|
||||
import com.sun.hotspot.igv.data.services.GroupReceiver;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Component;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import org.openide.ErrorManager;
|
||||
import org.openide.actions.GarbageCollectAction;
|
||||
import org.openide.awt.Toolbar;
|
||||
import org.openide.awt.ToolbarPool;
|
||||
import org.openide.explorer.ExplorerManager;
|
||||
import org.openide.explorer.ExplorerUtils;
|
||||
import org.openide.explorer.view.BeanTreeView;
|
||||
import org.openide.util.Lookup;
|
||||
import org.openide.util.LookupEvent;
|
||||
import org.openide.util.LookupListener;
|
||||
import org.openide.util.NbBundle;
|
||||
@ -72,7 +60,8 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
|
||||
private ExplorerManager manager;
|
||||
private GraphDocument document;
|
||||
private FolderNode root;
|
||||
private GroupOrganizer organizer;
|
||||
private Server server;
|
||||
private Server binaryServer;
|
||||
|
||||
private OutlineTopComponent() {
|
||||
initComponents();
|
||||
@ -88,17 +77,9 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
|
||||
|
||||
private void initListView() {
|
||||
manager = new ExplorerManager();
|
||||
organizer = new StandardGroupOrganizer();
|
||||
root = new FolderNode("", organizer, new ArrayList<String>(), document.getGroups());
|
||||
root = new FolderNode(document);
|
||||
manager.setRootContext(root);
|
||||
((BeanTreeView) this.jScrollPane1).setRootVisible(false);
|
||||
|
||||
document.getChangedEvent().addListener(new ChangedListener<GraphDocument>() {
|
||||
|
||||
public void changed(GraphDocument document) {
|
||||
updateStructure();
|
||||
}
|
||||
});
|
||||
((BeanTreeView) this.treeView).setRootVisible(false);
|
||||
|
||||
associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
|
||||
}
|
||||
@ -111,61 +92,41 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
|
||||
this.add(toolbar, BorderLayout.NORTH);
|
||||
|
||||
toolbar.add(ImportAction.get(ImportAction.class));
|
||||
toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup()));
|
||||
toolbar.add(RemoveAllAction.get(RemoveAllAction.class));
|
||||
|
||||
toolbar.add(((NodeAction) SaveAsAction.get(SaveAsAction.class)).createContextAwareInstance(this.getLookup()));
|
||||
toolbar.add(SaveAllAction.get(SaveAllAction.class));
|
||||
|
||||
toolbar.add(StructuredViewAction.get(StructuredViewAction.class).getToolbarPresenter());
|
||||
toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup()));
|
||||
toolbar.add(RemoveAllAction.get(RemoveAllAction.class));
|
||||
|
||||
toolbar.add(GarbageCollectAction.get(GarbageCollectAction.class).getToolbarPresenter());
|
||||
|
||||
for (Toolbar tb : ToolbarPool.getDefault().getToolbars()) {
|
||||
tb.setVisible(false);
|
||||
}
|
||||
|
||||
initOrganizers();
|
||||
}
|
||||
|
||||
public void setOrganizer(GroupOrganizer organizer) {
|
||||
this.organizer = organizer;
|
||||
updateStructure();
|
||||
}
|
||||
|
||||
private void initOrganizers() {
|
||||
|
||||
}
|
||||
|
||||
private void initReceivers() {
|
||||
|
||||
final GroupCallback callback = new GroupCallback() {
|
||||
|
||||
@Override
|
||||
public void started(Group g) {
|
||||
getDocument().addGroup(g);
|
||||
synchronized(OutlineTopComponent.this) {
|
||||
getDocument().addElement(g);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Collection<? extends GroupReceiver> receivers = Lookup.getDefault().lookupAll(GroupReceiver.class);
|
||||
if (receivers.size() > 0) {
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
||||
|
||||
for (GroupReceiver r : receivers) {
|
||||
Component c = r.init(callback);
|
||||
panel.add(c);
|
||||
}
|
||||
|
||||
jPanel2.add(panel, BorderLayout.PAGE_START);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateStructure() {
|
||||
root.init("", organizer, new ArrayList<String>(), document.getGroups());
|
||||
server = new Server(getDocument(), callback, false);
|
||||
binaryServer = new Server(getDocument(), callback, true);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
document.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExplorerManager getExplorerManager() {
|
||||
return manager;
|
||||
}
|
||||
@ -221,6 +182,25 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
|
||||
return PREFERRED_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestActive() {
|
||||
super.requestActive();
|
||||
treeView.requestFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requestFocus(boolean temporary) {
|
||||
treeView.requestFocus();
|
||||
return super.requestFocus(temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean requestFocusInWindow(boolean temporary) {
|
||||
treeView.requestFocus();
|
||||
return super.requestFocusInWindow(temporary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resultChanged(LookupEvent lookupEvent) {
|
||||
}
|
||||
|
||||
@ -228,7 +208,7 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
|
||||
public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException {
|
||||
// Not called when user starts application for the first time
|
||||
super.readExternal(objectInput);
|
||||
((BeanTreeView) this.jScrollPane1).setRootVisible(false);
|
||||
((BeanTreeView) this.treeView).setRootVisible(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -253,19 +233,13 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
jPanel2 = new javax.swing.JPanel();
|
||||
jScrollPane1 = new BeanTreeView();
|
||||
treeView = new BeanTreeView();
|
||||
|
||||
setLayout(new java.awt.BorderLayout());
|
||||
|
||||
jPanel2.setLayout(new java.awt.BorderLayout());
|
||||
jPanel2.add(jScrollPane1, java.awt.BorderLayout.CENTER);
|
||||
|
||||
add(jPanel2, java.awt.BorderLayout.CENTER);
|
||||
add(treeView, java.awt.BorderLayout.CENTER);
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JPanel jPanel2;
|
||||
private javax.swing.JScrollPane jScrollPane1;
|
||||
private javax.swing.JScrollPane treeView;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<Row>
|
||||
<Toolbar name="Edit" position="1" visible="false"/>
|
||||
<Toolbar name="File" position="1" visible="false" />
|
||||
<Toolbar name="Memory" position="1" visible="false" />
|
||||
<Toolbar name="Memory" position="1" visible="true" />
|
||||
</Row>
|
||||
<Row>
|
||||
<Toolbar name="WorkspaceSwitcher" />
|
||||
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package com.sun.hotspot.igv.coordinator;
|
||||
|
||||
import com.sun.hotspot.igv.data.Group;
|
||||
import com.sun.hotspot.igv.data.services.GroupOrganizer;
|
||||
import com.sun.hotspot.igv.data.Pair;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Thomas Wuerthinger
|
||||
*/
|
||||
public class StandardGroupOrganizer implements GroupOrganizer {
|
||||
|
||||
public String getName() {
|
||||
return "-- None --";
|
||||
}
|
||||
|
||||
public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups) {
|
||||
|
||||
List<Pair<String, List<Group>>> result = new ArrayList<Pair<String, List<Group>>>();
|
||||
|
||||
if (groups.size() == 1 && subFolders.size() > 0) {
|
||||
result.add(new Pair<String, List<Group>>("", groups));
|
||||
} else {
|
||||
for (Group g : groups) {
|
||||
List<Group> children = new ArrayList<Group>();
|
||||
children.add(g);
|
||||
Pair<String, List<Group>> p = new Pair<String, List<Group>>();
|
||||
p.setLeft(g.getName());
|
||||
p.setRight(children);
|
||||
result.add(p);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
@ -1,18 +1,10 @@
|
||||
CTL_EditFilterAction=Edit...
|
||||
CTL_ImportAction=Open...
|
||||
CTL_OpenGraphAction=View graph
|
||||
CTL_DiffGraphAction=Difference to current graph
|
||||
CTL_RemoveAction=Remove methods
|
||||
CTL_ApplyFilterAction=Apply
|
||||
CTL_FilterAction=Open Filter Window
|
||||
CTL_AppliedFilterAction=Open AppliedFilter Window
|
||||
CTL_OutlineAction=Open Outline Window
|
||||
CTL_MoveFilterUpAction=Move upwards
|
||||
CTL_MoveFilterDownAction=Move downwards
|
||||
CTL_RemoveFilterAction=Remove
|
||||
CTL_RemoveFilterSettingsAction=Remove filter setting
|
||||
CTL_SaveAsAction=Save selected methods...
|
||||
CTL_SaveAllAction=Save all...
|
||||
CTL_SaveFilterSettingsAction=Save filter settings...
|
||||
CTL_PropertiesAction=Open Properties Window
|
||||
CTL_RemoveAction=Remove selected graphs and groups
|
||||
CTL_RemoveAllAction=Remove all graphs and groups
|
||||
CTL_OutlineAction=Outline
|
||||
CTL_SaveAsAction=Save selected groups...
|
||||
CTL_SaveAllAction=Save all groups...
|
||||
CTL_PropertiesAction=Open Properties Window
|
||||
CTL_NewFilterAction=New filter...
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user