This commit is contained in:
J. Duke 2017-07-05 16:37:49 +02:00
commit 14b567cf35
159 changed files with 3541 additions and 1334 deletions

View File

@ -2,3 +2,4 @@ cfeea66a3fa8ca3686a7cfa2d0ce8ab0169f168d jdk7-b24
cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25 cbc8ad9dd0e085a607427ea35411990982f19a36 jdk7-b25
9410f77cc30c604d1caf7c9fe3a57fa19e1acbe8 jdk7-b26 9410f77cc30c604d1caf7c9fe3a57fa19e1acbe8 jdk7-b26
11b4dc9f2be3523ef989a0db8459eb56b3045c3a jdk7-b27 11b4dc9f2be3523ef989a0db8459eb56b3045c3a jdk7-b27
56652b46f328937f6b9b5130f1e4cd80f48868ef jdk7-b28

View File

@ -2,3 +2,4 @@
5e61d5df62586474414d1058e9186441aa908f51 jdk7-b25 5e61d5df62586474414d1058e9186441aa908f51 jdk7-b25
0043eb3d4e628f049ff80a8c223b5657136085e7 jdk7-b26 0043eb3d4e628f049ff80a8c223b5657136085e7 jdk7-b26
e84e9018bebbf3e5bafc5706e7882a15cb1c7d99 jdk7-b27 e84e9018bebbf3e5bafc5706e7882a15cb1c7d99 jdk7-b27
27509b7d21ed783b3f6eb7b7612781c675a30c2f jdk7-b28

View File

@ -31,6 +31,9 @@ COMPILER_NAME=Sun Studio
# Sun Studio Compiler settings specific to Solaris # Sun Studio Compiler settings specific to Solaris
ifeq ($(PLATFORM), solaris) ifeq ($(PLATFORM), solaris)
# FIXUP: Change to SS12 when validated
#COMPILER_VERSION=SS12
#REQUIRED_CC_VER=5.9
COMPILER_VERSION=SS11 COMPILER_VERSION=SS11
REQUIRED_CC_VER=5.8 REQUIRED_CC_VER=5.8
CC = $(COMPILER_PATH)cc CC = $(COMPILER_PATH)cc
@ -51,8 +54,8 @@ endif
# Sun Studio Compiler settings specific to Linux # Sun Studio Compiler settings specific to Linux
ifeq ($(PLATFORM), linux) ifeq ($(PLATFORM), linux)
# This has not been tested # This has not been tested
COMPILER_VERSION=SS11 COMPILER_VERSION=SS12
REQUIRED_CC_VER=5.8 REQUIRED_CC_VER=5.9
CC = $(COMPILER_PATH)cc CC = $(COMPILER_PATH)cc
CPP = $(COMPILER_PATH)cc -E CPP = $(COMPILER_PATH)cc -E
CXX = $(COMPILER_PATH)CC CXX = $(COMPILER_PATH)CC

View File

@ -123,9 +123,15 @@ if [ "${osname}" = SunOS ] ; then
solaris_arch=i386 solaris_arch=i386
fi fi
# Get the SS11 compilers into path (make sure it matches ALT setting) # Get the compilers into path (make sure it matches ALT setting)
compiler_path=${jdk_devtools}/${solaris_arch}/SUNWspro/SS11/bin if [ "${JPRT_SOLARIS_COMPILER_NAME}" != "" ] ; then
compiler_name=SS11 compiler_name=${JPRT_SOLARIS_COMPILER_NAME}
else
# FIXUP: Change to SS12 when validated
#compiler_name=SS12
compiler_name=SS11
fi
compiler_path=${jdk_devtools}/${solaris_arch}/SUNWspro/${compiler_name}/bin
ALT_COMPILER_PATH="${compiler_path}" ALT_COMPILER_PATH="${compiler_path}"
export ALT_COMPILER_PATH export ALT_COMPILER_PATH
dirMustExist "${compiler_path}" ALT_COMPILER_PATH dirMustExist "${compiler_path}" ALT_COMPILER_PATH

View File

@ -2,3 +2,4 @@ a61af66fc99eb5ec9d50c05b0c599757b1289ceb jdk7-b24
7836be3e92d0a4f9ee7566f602c91f5609534e66 jdk7-b25 7836be3e92d0a4f9ee7566f602c91f5609534e66 jdk7-b25
ad0b851458ff9d1d490ed2d79bb84f75a9fdb753 jdk7-b26 ad0b851458ff9d1d490ed2d79bb84f75a9fdb753 jdk7-b26
e3d2692f8442e2d951166dc9bd9a330684754438 jdk7-b27 e3d2692f8442e2d951166dc9bd9a330684754438 jdk7-b27
c14dab40ed9bf45ad21150bd70c9c80cdf655415 jdk7-b28

View File

@ -246,16 +246,16 @@ SA_PROPERTIES = $(OUTPUT_DIR)/sa.properties
all: filelist all: filelist
@mkdir -p $(OUTPUT_DIR) @mkdir -p $(OUTPUT_DIR)
@echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES) @echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
@javac -source 1.4 -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist @${JDK_HOME}/bin/javac -source 1.4 -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
@rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer @${JDK_HOME}/bin/rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js
cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql
allprof: filelist allprof: filelist
@mkdir -p $(OUTPUT_DIR) @mkdir -p $(OUTPUT_DIR)
@echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES) @echo "$(SA_BUILD_VERSION_PROP)" > $(SA_PROPERTIES)
@javac -source 1.4 -J-Xprof -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist @${JDK_HOME}/bin/javac -source 1.4 -J-Xprof -classpath $(CLASSPATH) -deprecation -sourcepath $(SRC_DIR) -g -d $(OUTPUT_DIR) @filelist
@rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer @${JDK_HOME}/bin/rmic -classpath $(OUTPUT_DIR) -d $(OUTPUT_DIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js rm -f $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql/sa.js
cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql cp $(SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(OUTPUT_DIR)/sun/jvm/hotspot/utilities/soql

View File

@ -398,7 +398,7 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener {
frame.getContentPane().add(desktop); frame.getContentPane().add(desktop);
GraphicsUtilities.reshapeToAspectRatio(frame, 4.0f/3.0f, 0.75f, Toolkit.getDefaultToolkit().getScreenSize()); GraphicsUtilities.reshapeToAspectRatio(frame, 4.0f/3.0f, 0.75f, Toolkit.getDefaultToolkit().getScreenSize());
GraphicsUtilities.centerInContainer(frame, Toolkit.getDefaultToolkit().getScreenSize()); GraphicsUtilities.centerInContainer(frame, Toolkit.getDefaultToolkit().getScreenSize());
frame.show(); frame.setVisible(true);
Runtime.getRuntime().addShutdownHook(new java.lang.Thread() { Runtime.getRuntime().addShutdownHook(new java.lang.Thread() {
public void run() { public void run() {

View File

@ -148,7 +148,7 @@ public class SALauncherLoader extends URLClassLoader {
} }
try { try {
return file.toURL(); return file.toURI().toURL();
} catch (MalformedURLException mue) { } catch (MalformedURLException mue) {
throw new InternalError(mue.getMessage()); throw new InternalError(mue.getMessage());
} }

View File

@ -47,6 +47,6 @@ public class Main {
4.0f/3.0f, 0.85f, Toolkit.getDefaultToolkit().getScreenSize()); 4.0f/3.0f, 0.85f, Toolkit.getDefaultToolkit().getScreenSize());
GraphicsUtilities.centerInContainer(frame, GraphicsUtilities.centerInContainer(frame,
Toolkit.getDefaultToolkit().getScreenSize()); Toolkit.getDefaultToolkit().getScreenSize());
frame.show(); frame.setVisible(true);
} }
} }

View File

@ -78,7 +78,7 @@ class SAJDIClassLoader extends URLClassLoader {
this(parent); this(parent);
this.classPathSet = true; this.classPathSet = true;
try { try {
addURL(new File(classPath).toURL()); addURL(new File(classPath).toURI().toURL());
} catch(MalformedURLException mue) { } catch(MalformedURLException mue) {
throw new RuntimeException(mue); throw new RuntimeException(mue);
} }

View File

@ -0,0 +1,59 @@
/*
* @(#)BinaryTreeDictionary.java
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
package sun.jvm.hotspot.memory;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.runtime.*;
public class BinaryTreeDictionary extends VMObject {
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("BinaryTreeDictionary");
totalSizeField = type.getCIntegerField("_totalSize");
}
// Fields
private static CIntegerField totalSizeField;
// Accessors
public long size() {
return totalSizeField.getValue(addr);
}
// Constructor
public BinaryTreeDictionary(Address addr) {
super(addr);
}
}

View File

@ -35,6 +35,20 @@ import sun.jvm.hotspot.utilities.*;
public class CompactibleFreeListSpace extends CompactibleSpace { public class CompactibleFreeListSpace extends CompactibleSpace {
private static AddressField collectorField; private static AddressField collectorField;
// for free size, three fields
// FreeBlockDictionary* _dictionary; // ptr to dictionary for large size blocks
// FreeList _indexedFreeList[IndexSetSize]; // indexed array for small size blocks
// LinearAllocBlock _smallLinearAllocBlock; // small linear alloc in TLAB
private static AddressField indexedFreeListField;
private static AddressField dictionaryField;
private static long smallLinearAllocBlockFieldOffset;
private static long indexedFreeListSizeOf;
private int heapWordSize; // 4 for 32bit, 8 for 64 bits
private int IndexSetStart; // for small indexed list
private int IndexSetSize;
private int IndexSetStride;
static { static {
VM.registerVMInitializedObserver(new Observer() { VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) { public void update(Observable o, Object data) {
@ -51,10 +65,26 @@ public class CompactibleFreeListSpace extends CompactibleSpace {
Type type = db.lookupType("CompactibleFreeListSpace"); Type type = db.lookupType("CompactibleFreeListSpace");
collectorField = type.getAddressField("_collector"); collectorField = type.getAddressField("_collector");
collectorField = type.getAddressField("_collector");
dictionaryField = type.getAddressField("_dictionary");
indexedFreeListField = type.getAddressField("_indexedFreeList[0]");
smallLinearAllocBlockFieldOffset = type.getField("_smallLinearAllocBlock").getOffset();
} }
public CompactibleFreeListSpace(Address addr) { public CompactibleFreeListSpace(Address addr) {
super(addr); super(addr);
if ( VM.getVM().isLP64() ) {
heapWordSize = 8;
IndexSetStart = 1;
IndexSetStride = 1;
}
else {
heapWordSize = 4;
IndexSetStart = 2;
IndexSetStride = 2;
}
IndexSetSize = 257;
} }
// Accessing block offset table // Accessing block offset table
@ -62,9 +92,17 @@ public class CompactibleFreeListSpace extends CompactibleSpace {
return (CMSCollector) VMObjectFactory.newObject( return (CMSCollector) VMObjectFactory.newObject(
CMSCollector.class, CMSCollector.class,
collectorField.getValue(addr)); collectorField.getValue(addr));
} }
public long free0() {
return capacity() - used0();
}
public long used() { public long used() {
return capacity() - free();
}
public long used0() {
List regions = getLiveRegions(); List regions = getLiveRegions();
long usedSize = 0L; long usedSize = 0L;
for (Iterator itr = regions.iterator(); itr.hasNext();) { for (Iterator itr = regions.iterator(); itr.hasNext();) {
@ -75,11 +113,41 @@ public class CompactibleFreeListSpace extends CompactibleSpace {
} }
public long free() { public long free() {
return capacity() - used(); // small chunks
} long size = 0;
Address cur = addr.addOffsetTo( indexedFreeListField.getOffset() );
cur = cur.addOffsetTo(IndexSetStart*FreeList.sizeOf());
for (int i=IndexSetStart; i<IndexSetSize; i += IndexSetStride) {
FreeList freeList = (FreeList) VMObjectFactory.newObject(FreeList.class, cur);
size += i*freeList.count();
cur= cur.addOffsetTo(IndexSetStride*FreeList.sizeOf());
}
// large block
BinaryTreeDictionary bfbd = (BinaryTreeDictionary) VMObjectFactory.newObject(BinaryTreeDictionary.class,
dictionaryField.getValue(addr));
size += bfbd.size();
// linear block in TLAB
LinearAllocBlock lab = (LinearAllocBlock) VMObjectFactory.newObject(LinearAllocBlock.class,
addr.addOffsetTo(smallLinearAllocBlockFieldOffset));
size += lab.word_size();
return size*heapWordSize;
}
public void printOn(PrintStream tty) { public void printOn(PrintStream tty) {
tty.print("free-list-space"); tty.print("free-list-space");
tty.print("[ " + bottom() + " , " + end() + " ) ");
long cap = capacity();
long used_size = used();
long free_size = free();
int used_perc = (int)((double)used_size/cap*100);
tty.print("space capacity = " + cap + " used(" + used_perc + "%)= " + used_size + " ");
tty.print("free= " + free_size );
tty.print("\n");
} }
public Address skipBlockSizeUsingPrintezisBits(Address pos) { public Address skipBlockSizeUsingPrintezisBits(Address pos) {
@ -121,7 +189,7 @@ public class CompactibleFreeListSpace extends CompactibleSpace {
cur = cur.addOffsetTo(adjustObjectSizeInBytes(size)); cur = cur.addOffsetTo(adjustObjectSizeInBytes(size));
} }
if (FreeChunk.secondWordIndicatesFreeChunk(dbg.getAddressValue(klassOop))) { if (FreeChunk.indicatesFreeChunk(cur)) {
if (! cur.equals(regionStart)) { if (! cur.equals(regionStart)) {
res.add(new MemRegion(regionStart, cur)); res.add(new MemRegion(regionStart, cur));
} }

View File

@ -96,9 +96,9 @@ public class DefNewGeneration extends Generation {
public void printOn(PrintStream tty) { public void printOn(PrintStream tty) {
tty.print(" eden"); tty.print(" eden");
eden().printOn(tty); eden().printOn(tty);
tty.print(" from"); tty.print("\n from");
from().printOn(tty); from().printOn(tty);
tty.print(" to "); tty.print("\n to ");
to().printOn(tty); to().printOn(tty);
} }
} }

View File

@ -28,6 +28,7 @@ import java.util.*;
import sun.jvm.hotspot.debugger.*; import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*; import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.runtime.*;
import sun.jvm.hotspot.oops.*;
public class FreeChunk extends VMObject { public class FreeChunk extends VMObject {
static { static {
@ -42,13 +43,13 @@ public class FreeChunk extends VMObject {
Type type = db.lookupType("FreeChunk"); Type type = db.lookupType("FreeChunk");
nextField = type.getAddressField("_next"); nextField = type.getAddressField("_next");
prevField = type.getAddressField("_prev"); prevField = type.getAddressField("_prev");
sizeField = type.getCIntegerField("_size"); sizeField = type.getAddressField("_size");
} }
// Fields // Fields
private static AddressField nextField; private static AddressField nextField;
private static AddressField prevField; private static AddressField prevField;
private static CIntegerField sizeField; private static AddressField sizeField;
// Accessors // Accessors
public FreeChunk next() { public FreeChunk next() {
@ -61,20 +62,34 @@ public class FreeChunk extends VMObject {
} }
public long size() { public long size() {
return sizeField.getValue(addr); if (VM.getVM().isCompressedOopsEnabled()) {
Mark mark = new Mark(sizeField.getValue(addr));
return mark.getSize();
} else {
Address size = sizeField.getValue(addr);
Debugger dbg = VM.getVM().getDebugger();
return dbg.getAddressValue(size);
}
} }
public FreeChunk(Address addr) { public FreeChunk(Address addr) {
super(addr); super(addr);
} }
public static boolean secondWordIndicatesFreeChunk(long word) { public static boolean indicatesFreeChunk(Address cur) {
return (word & 0x1L) == 0x1L; FreeChunk f = new FreeChunk(cur);
return f.isFree();
} }
public boolean isFree() { public boolean isFree() {
Debugger dbg = VM.getVM().getDebugger(); if (VM.getVM().isCompressedOopsEnabled()) {
Address prev = prevField.getValue(addr); Mark mark = new Mark(sizeField.getValue(addr));
return secondWordIndicatesFreeChunk(dbg.getAddressValue(prev)); return mark.isCmsFreeChunk();
} else {
Address prev = prevField.getValue(addr);
Debugger dbg = VM.getVM().getDebugger();
long word = dbg.getAddressValue(prev);
return (word & 0x1L) == 0x1L;
}
} }
} }

View File

@ -0,0 +1,72 @@
/*
* @(#)FreeList.java
*
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
package sun.jvm.hotspot.memory;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.runtime.*;
public class FreeList extends VMObject {
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("FreeList");
sizeField = type.getCIntegerField("_size");
countField = type.getCIntegerField("_count");
headerSize = type.getSize();
}
// Fields
private static CIntegerField sizeField;
private static CIntegerField countField;
private static long headerSize;
//Constructor
public FreeList(Address address) {
super(address);
}
// Accessors
public long size() {
return sizeField.getValue(addr);
}
public long count() {
return countField.getValue(addr);
}
public static long sizeOf() {
return headerSize;
}
}

View File

@ -0,0 +1,59 @@
/*
* @(#)BinaryTreeDictionary.java
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
package sun.jvm.hotspot.memory;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.runtime.*;
public class LinearAllocBlock extends VMObject {
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
initialize(VM.getVM().getTypeDataBase());
}
});
}
private static synchronized void initialize(TypeDataBase db) {
Type type = db.lookupType("LinearAllocBlock");
word_sizeField= type.getCIntegerField("_word_size");
}
// Fields
private static CIntegerField word_sizeField;
// Accessors
public long word_size() {
return word_sizeField.getValue(addr);
}
// Constructor
public LinearAllocBlock(Address addr) {
super(addr);
}
}

View File

@ -79,6 +79,11 @@ public class Mark extends VMObject {
noHashInPlace = db.lookupLongConstant("markOopDesc::no_hash_in_place").longValue(); noHashInPlace = db.lookupLongConstant("markOopDesc::no_hash_in_place").longValue();
noLockInPlace = db.lookupLongConstant("markOopDesc::no_lock_in_place").longValue(); noLockInPlace = db.lookupLongConstant("markOopDesc::no_lock_in_place").longValue();
maxAge = db.lookupLongConstant("markOopDesc::max_age").longValue(); maxAge = db.lookupLongConstant("markOopDesc::max_age").longValue();
/* Constants in markOop used by CMS. */
cmsShift = db.lookupLongConstant("markOopDesc::cms_shift").longValue();
cmsMask = db.lookupLongConstant("markOopDesc::cms_mask").longValue();
sizeShift = db.lookupLongConstant("markOopDesc::size_shift").longValue();
} }
// Field accessors // Field accessors
@ -120,6 +125,11 @@ public class Mark extends VMObject {
private static long maxAge; private static long maxAge;
/* Constants in markOop used by CMS. */
private static long cmsShift;
private static long cmsMask;
private static long sizeShift;
public Mark(Address addr) { public Mark(Address addr) {
super(addr); super(addr);
} }
@ -290,4 +300,11 @@ public class Mark extends VMObject {
// //
// // Recover address of oop from encoded form used in mark // // Recover address of oop from encoded form used in mark
// inline void* decode_pointer() { return clear_lock_bits(); } // inline void* decode_pointer() { return clear_lock_bits(); }
// Copy markOop methods for CMS here.
public boolean isCmsFreeChunk() {
return isUnlocked() &&
(Bits.maskBitsLong(value() >> cmsShift, cmsMask) & 0x1L) == 0x1L;
}
public long getSize() { return (long)(value() >> sizeShift); }
} }

View File

@ -274,10 +274,10 @@ public class OopUtilities implements /* imports */ JVMTIThreadState {
// hc_klass is a HotSpot magic field and hence we can't // hc_klass is a HotSpot magic field and hence we can't
// find it from InstanceKlass for java.lang.Class. // find it from InstanceKlass for java.lang.Class.
TypeDataBase db = VM.getVM().getTypeDataBase(); TypeDataBase db = VM.getVM().getTypeDataBase();
int hcKlassOffset = (int) Oop.getHeaderSize(); int hcKlassOffset = (int) Instance.getHeaderSize();
try { try {
hcKlassOffset += (db.lookupIntConstant("java_lang_Class::hc_klass_offset").intValue() * hcKlassOffset += (db.lookupIntConstant("java_lang_Class::hc_klass_offset").intValue() *
db.getAddressSize()); VM.getVM().getHeapOopSize());
} catch (RuntimeException re) { } catch (RuntimeException re) {
// ignore, currently java_lang_Class::hc_klass_offset is zero // ignore, currently java_lang_Class::hc_klass_offset is zero
} }

View File

@ -648,6 +648,6 @@ public class AnnotatedMemoryPanel extends JPanel {
System.exit(0); System.exit(0);
} }
}); });
frame.show(); frame.setVisible(true);
} }
} }

View File

@ -220,7 +220,7 @@ public class CommandProcessorPanel extends JPanel {
} }
}); });
frame.setSize(500, 500); frame.setSize(500, 500);
frame.show(); frame.setVisible(true);
panel.requestFocus(); panel.requestFocus();
} }
} }

View File

@ -226,7 +226,7 @@ public class DebuggerConsolePanel extends JPanel {
} }
}); });
frame.setSize(500, 500); frame.setSize(500, 500);
frame.show(); frame.setVisible(true);
panel.requestFocus(); panel.requestFocus();
} }
} }

View File

@ -424,7 +424,7 @@ public class HighPrecisionJScrollBar extends JScrollBar {
} }
}); });
frame.getContentPane().add(hpsb); frame.getContentPane().add(hpsb);
frame.show(); frame.setVisible(true);
} }
} }

View File

@ -43,7 +43,7 @@ public class JFrameWrapper implements FrameWrapper {
public void setVisible(boolean visible) { frame.setVisible(visible); } public void setVisible(boolean visible) { frame.setVisible(visible); }
public void setSize(int x, int y) { frame.setSize(x, y); } public void setSize(int x, int y) { frame.setSize(x, y); }
public void pack() { frame.pack(); } public void pack() { frame.pack(); }
public void show() { frame.show(); } public void show() { frame.setVisible(true); }
public void dispose() { frame.dispose(); } public void dispose() { frame.dispose(); }
public void setBackground(Color color) { frame.setBackground(color); } public void setBackground(Color color) { frame.setBackground(color); }
public void setResizable(boolean resizable) { frame.setResizable(resizable); } public void setResizable(boolean resizable) { frame.setResizable(resizable); }

View File

@ -477,9 +477,9 @@ public class JTreeTable extends JTable {
static class TreeTableTextField extends JTextField { static class TreeTableTextField extends JTextField {
public int offset; public int offset;
public void reshape(int x, int y, int w, int h) { public void setBounds(int x, int y, int w, int h) {
int newX = Math.max(x, offset); int newX = Math.max(x, offset);
super.reshape(newX, y, w - (newX - x), h); super.setBounds(newX, y, w - (newX - x), h);
} }
} }

View File

@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2008
HS_MAJOR_VER=13 HS_MAJOR_VER=13
HS_MINOR_VER=0 HS_MINOR_VER=0
HS_BUILD_NUMBER=01 HS_BUILD_NUMBER=02
JDK_MAJOR_VER=1 JDK_MAJOR_VER=1
JDK_MINOR_VER=7 JDK_MINOR_VER=7

View File

@ -68,8 +68,23 @@ if [ "${osname}" = SunOS ] ; then
solaris_arch=i386 solaris_arch=i386
fi fi
# Get the SS11 compilers into path (make sure it matches ALT setting) if [ "${JPRT_SOLARIS_COMPILER_NAME}" != "" ] ; then
compiler_path=${slashjava}/devtools/${solaris_arch}/SUNWspro/SS11/bin compiler_name=${JPRT_SOLARIS_COMPILER_NAME}
else
if [ "${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6" -o \
"${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6u10" -o \
"${JPRT_JOB_PRODUCT_RELEASE}" = "jdk6perf" ] ; then
# All jdk6 builds use SS11
compiler_name=SS11
else
# FIXUP: Change to SS12 once it has been validated.
#compiler_name=SS12
compiler_name=SS11
fi
fi
# Get into path (make sure it matches ALT setting)
compiler_path=${slashjava}/devtools/${solaris_arch}/SUNWspro/${compiler_name}/bin
dirMustExist "${compiler_path}" COMPILER_PATH dirMustExist "${compiler_path}" COMPILER_PATH
path4sdk=${compiler_path} path4sdk=${compiler_path}

View File

@ -24,209 +24,274 @@
# Properties for jprt # Properties for jprt
JPRT.tools.default.release=jdk1.7.0 # All build result bundles are full jdks, so the 64bit testing does not
# need the 32bit sibling bundle installed.
# Note: If the hotspot/make/Makefile changed to only bundle the 64bit files
# when bundling 64bit, and stripped out the 64bit files from any 32bit
# bundles, then this setting would be need to be "true".
# Build result bundles are not partial builds| but include everything jprt.need.sibling.build=false
JPRT.need.sibling.build=false
# Directories needed to build # At submit time, the release supplied will be in jprt.submit.release
JPRT.bundle.src.dirs=make src agent # and will be one of the official release names defined in jprt.
JPRT.bundle.exclude.src.dirs=build # jprt supports property value expansion using ${property.name} syntax.
# This tells jprt what default release we want to build
# Standard list of JPRT build targets for this workspace jprt.tools.default.release=${jprt.submit.release}
JPRT.build.targets= \
solaris_sparc_5.10-{product|fastdebug|debug}, \
solaris_sparcv9_5.10-{product|fastdebug|debug}, \
solaris_i586_5.10-{product|fastdebug|debug}, \
solaris_x64_5.10-{product|fastdebug|debug}, \
linux_i586-{product|fastdebug|debug}, \
linux_x64-{product|fastdebug}, \
windows_i586-{product|fastdebug|debug}, \
windows_x64-{product|fastdebug|debug}
# Standard list of JPRT test targets for this workspace # Define the Solaris platforms we want for the various releases
JPRT.test.targets = \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-jvm98, \ jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-scimark, \ jprt.my.solaris.sparc.jdk6=solaris_sparc_5.8
solaris_sparcv9_5.10-{product|fastdebug}-c2-jvm98, \ jprt.my.solaris.sparc.jdk6perf=solaris_sparc_5.8
solaris_sparcv9_5.10-{product|fastdebug}-c2-scimark, \ jprt.my.solaris.sparc.jdk6u10=solaris_sparc_5.8
solaris_i586_5.10-{product|fastdebug}-{c1|c2}-jvm98, \ jprt.my.solaris.sparc=${jprt.my.solaris.sparc.${jprt.tools.default.release}}
solaris_i586_5.10-{product|fastdebug}-{c1|c2}-scimark, \
solaris_x64_5.10-{product|fastdebug}-c2-jvm98, \ jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10
solaris_x64_5.10-{product|fastdebug}-c2-scimark, \ jprt.my.solaris.sparcv9.jdk6=solaris_sparcv9_5.8
linux_i586-{product|fastdebug}-{c1|c2}-jvm98, \ jprt.my.solaris.sparcv9.jdk6perf=solaris_sparcv9_5.8
linux_i586-{product|fastdebug}-{c1|c2}-scimark, \ jprt.my.solaris.sparcv9.jdk6u10=solaris_sparcv9_5.8
linux_x64-{product|fastdebug}-c2-jvm98, \ jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}}
linux_x64-{product|fastdebug}-c2-scimark, \
windows_i586-{product|fastdebug}-{c1|c2}-jvm98, \ jprt.my.solaris.i586.jdk7=solaris_i586_5.10
windows_i586-{product|fastdebug}-{c1|c2}-scimark, \ jprt.my.solaris.i586.jdk6=solaris_i586_5.8
windows_x64-{product|fastdebug}-c2-jvm98, \ jprt.my.solaris.i586.jdk6perf=solaris_i586_5.8
windows_x64-{product|fastdebug}-c2-scimark, \ jprt.my.solaris.i586.jdk6u10=solaris_i586_5.8
solaris_sparc_5.10-product-{c1|c2}-runThese, \ jprt.my.solaris.i586=${jprt.my.solaris.i586.${jprt.tools.default.release}}
solaris_sparc_5.10-product-{c1|c2}-runThese_Xcomp, \
solaris_sparc_5.10-product-{c1|c2}-runThese_Xcomp_2, \ jprt.my.solaris.x64.jdk7=solaris_x64_5.10
solaris_sparc_5.10-product-{c1|c2}-runThese_Xcomp_3, \ jprt.my.solaris.x64.jdk6=solaris_x64_5.10
solaris_sparc_5.10-fastdebug-c1-runThese_Xshare, \ jprt.my.solaris.x64.jdk6perf=solaris_x64_5.10
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_default, \ jprt.my.solaris.x64.jdk6u10=solaris_x64_5.10
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \ jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}}
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \ jprt.my.linux.i586=linux_i586
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \ jprt.my.linux.x64=linux_x64
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_default_2, \ jprt.my.windows.i586=windows_i586
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC_2, \ jprt.my.windows.x64=windows_x64
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC_2, \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC_2, \ # Standard list of jprt build targets for this source tree
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCBasher_CMS_2, \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCOld_default, \ jprt.build.targets= \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCOld_SerialGC, \ ${jprt.my.solaris.sparc}-{product|fastdebug|debug}, \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCOld_ParallelGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug|debug}, \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCOld_ParNewGC, \ ${jprt.my.solaris.i586}-{product|fastdebug|debug}, \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-GCOld_CMS, \ ${jprt.my.solaris.x64}-{product|fastdebug|debug}, \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-jbb_default, \ ${jprt.my.linux.i586}-{product|fastdebug|debug}, \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-jbb_SerialGC, \ ${jprt.my.linux.x64}-{product|fastdebug}, \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-jbb_ParallelGC, \ ${jprt.my.windows.i586}-{product|fastdebug|debug}, \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-jbb_CMS, \ ${jprt.my.windows.x64}-{product|fastdebug|debug}
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-scimark_2, \
solaris_sparc_5.10-{product|fastdebug}-{c1|c2}-scimark_3, \ # Subset lists of test targets for this source tree
solaris_sparcv9_5.10-product-c2-runThese, \
solaris_sparcv9_5.10-product-c2-runThese_Xcomp, \ jprt.my.solaris.sparc.test.targets= \
solaris_sparcv9_5.10-product-c2-runThese_Xcomp_2, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jvm98, \
solaris_sparcv9_5.10-product-c2-runThese_Xcomp_3, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_default, \ ${jprt.my.solaris.sparc}-product-{c1|c2}-runThese, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_SerialGC, \ ${jprt.my.solaris.sparc}-product-{c1|c2}-runThese_Xcomp, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_ParallelGC, \ ${jprt.my.solaris.sparc}-product-{c1|c2}-runThese_Xcomp_2, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_ParNewGC, \ ${jprt.my.solaris.sparc}-product-{c1|c2}-runThese_Xcomp_3, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_CMS, \ ${jprt.my.solaris.sparc}-fastdebug-c1-runThese_Xshare, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_default_2, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_default, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_SerialGC_2, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_ParallelGC_2, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_ParNewGC_2, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCBasher_CMS_2, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_default, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_default_2, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_SerialGC, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC_2, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_ParallelGC, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC_2, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_ParNewGC, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC_2, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-GCOld_CMS, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCBasher_CMS_2, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_default, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_default, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_SerialGC, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_SerialGC, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_ParallelGC, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParallelGC, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-jbb_CMS, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_ParNewGC, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-scimark_2, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-GCOld_CMS, \
solaris_sparcv9_5.10-{product|fastdebug}-c2-scimark_3, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_default, \
solaris_x64-product-c2-runThese, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_SerialGC, \
solaris_x64-product-c2-runThese_Xcomp, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_ParallelGC, \
solaris_x64-{product|fastdebug}-c2-GCBasher_default, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-jbb_CMS, \
solaris_x64-{product|fastdebug}-c2-GCBasher_SerialGC, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark_2, \
solaris_x64-{product|fastdebug}-c2-GCBasher_ParallelGC, \ ${jprt.my.solaris.sparc}-{product|fastdebug}-{c1|c2}-scimark_3
solaris_x64-{product|fastdebug}-c2-GCBasher_ParNewGC, \
solaris_x64-{product|fastdebug}-c2-GCBasher_CMS, \ jprt.my.solaris.sparcv9.test.targets= \
solaris_x64-{product|fastdebug}-c2-GCBasher_default_2, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jvm98, \
solaris_x64-{product|fastdebug}-c2-GCBasher_SerialGC_2, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark, \
solaris_x64-{product|fastdebug}-c2-GCBasher_ParallelGC_2, \ ${jprt.my.solaris.sparcv9}-product-c2-runThese, \
solaris_x64-{product|fastdebug}-c2-GCBasher_ParNewGC_2, \ ${jprt.my.solaris.sparcv9}-product-c2-runThese_Xcomp, \
solaris_x64-{product|fastdebug}-c2-GCBasher_CMS_2, \ ${jprt.my.solaris.sparcv9}-product-c2-runThese_Xcomp_2, \
solaris_x64-{product|fastdebug}-c2-GCOld_default, \ ${jprt.my.solaris.sparcv9}-product-c2-runThese_Xcomp_3, \
solaris_x64-{product|fastdebug}-c2-GCOld_SerialGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_default, \
solaris_x64-{product|fastdebug}-c2-GCOld_ParallelGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_SerialGC, \
solaris_x64-{product|fastdebug}-c2-GCOld_ParNewGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
solaris_x64-{product|fastdebug}-c2-GCOld_CMS, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
solaris_x64-{product|fastdebug}-c2-jbb_default, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_CMS, \
solaris_x64-{product|fastdebug}-c2-jbb_SerialGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_default_2, \
solaris_x64-{product|fastdebug}-c2-jbb_ParallelGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_SerialGC_2, \
solaris_x64-{product|fastdebug}-c2-jbb_CMS, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParallelGC_2, \
solaris_i586_5.10-product-{c1|c2}-runThese_Xcomp, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_ParNewGC_2, \
solaris_i586_5.10-product-c2-runThese_Xcomp_2, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCBasher_CMS_2, \
solaris_i586_5.10-fastdebug-c1-runThese_Xcomp_2, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_default, \
solaris_i586_5.10-fastdebug-c1-runThese_Xshare, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_SerialGC, \
solaris_i586_5.10-product-c1-GCBasher_default, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParallelGC, \
solaris_i586_5.10-product-c1-GCBasher_SerialGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_ParNewGC, \
solaris_i586_5.10-product-c1-GCBasher_ParallelGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-GCOld_CMS, \
solaris_i586_5.10-product-c1-GCBasher_ParNewGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_default, \
solaris_i586_5.10-product-c1-GCBasher_CMS, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_SerialGC, \
solaris_i586_5.10-fastdebug-c2-GCBasher_default, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_ParallelGC, \
solaris_i586_5.10-fastdebug-c2-GCBasher_SerialGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-jbb_CMS, \
solaris_i586_5.10-fastdebug-c2-GCBasher_ParallelGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark_2, \
solaris_i586_5.10-fastdebug-c2-GCBasher_ParNewGC, \ ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-scimark_3
solaris_i586_5.10-fastdebug-c2-GCBasher_CMS, \
solaris_i586_5.10-product-c1-GCOld_default, \ jprt.my.solaris.x64.test.targets= \
solaris_i586_5.10-product-c1-GCOld_SerialGC, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jvm98, \
solaris_i586_5.10-product-c1-GCOld_ParallelGC, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-scimark, \
solaris_i586_5.10-product-c1-GCOld_ParNewGC, \ ${jprt.my.solaris.x64}-product-c2-runThese, \
solaris_i586_5.10-product-c1-GCOld_CMS, \ ${jprt.my.solaris.x64}-product-c2-runThese_Xcomp, \
solaris_i586_5.10-fastdebug-c2-jbb_default, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_default, \
solaris_i586_5.10-fastdebug-c2-jbb_ParallelGC, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
solaris_i586_5.10-fastdebug-c2-jbb_CMS, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
solaris_i586_5.10-{product|fastdebug}-{c1|c2}-scimark_2, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
solaris_i586_5.10-{product|fastdebug}-{c1|c2}-scimark_3, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
linux_i586-product-c1-runThese_Xcomp, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_default_2, \
linux_i586-product-c1-runThese_Xcomp_2, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_SerialGC_2, \
linux_i586-product-c1-runThese_Xcomp_3, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC_2, \
linux_i586-fastdebug-c1-runThese_Xshare, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC_2, \
linux_i586-fastdebug-c2-runThese_Xcomp, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCBasher_CMS_2, \
linux_i586-fastdebug-c2-runThese_Xcomp_2, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_default, \
linux_i586-{product|fastdebug}-{c1|c2}-GCBasher_default, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
linux_i586-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
linux_i586-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
linux_i586-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-GCOld_CMS, \
linux_i586-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_default, \
linux_i586-product-{c1|c2}-GCOld_default, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_SerialGC, \
linux_i586-product-{c1|c2}-GCOld_SerialGC, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
linux_i586-product-{c1|c2}-GCOld_ParallelGC, \ ${jprt.my.solaris.x64}-{product|fastdebug}-c2-jbb_CMS
linux_i586-product-{c1|c2}-GCOld_ParNewGC, \
linux_i586-product-{c1|c2}-GCOld_CMS, \ jprt.my.solaris.i586.test.targets= \
linux_i586-{product|fastdebug}-c1-jbb_default, \ ${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
linux_i586-{product|fastdebug}-c1-jbb_ParallelGC, \ ${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark, \
linux_i586-{product|fastdebug}-c1-jbb_CMS, \ ${jprt.my.solaris.i586}-product-{c1|c2}-runThese_Xcomp, \
linux_i586-{product|fastdebug}-c2-scimark_2, \ ${jprt.my.solaris.i586}-product-c2-runThese_Xcomp_2, \
linux_i586-{product|fastdebug}-c2-scimark_3, \ ${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xcomp_2, \
linux_x64-{product|fastdebug}-c2-GCBasher_default, \ ${jprt.my.solaris.i586}-fastdebug-c1-runThese_Xshare, \
linux_x64-{product|fastdebug}-c2-GCBasher_SerialGC, \ ${jprt.my.solaris.i586}-product-c1-GCBasher_default, \
linux_x64-{product|fastdebug}-c2-GCBasher_ParallelGC, \ ${jprt.my.solaris.i586}-product-c1-GCBasher_SerialGC, \
linux_x64-{product|fastdebug}-c2-GCBasher_ParNewGC, \ ${jprt.my.solaris.i586}-product-c1-GCBasher_ParallelGC, \
linux_x64-{product|fastdebug}-c2-GCBasher_CMS, \ ${jprt.my.solaris.i586}-product-c1-GCBasher_ParNewGC, \
linux_x64-{product|fastdebug}-c2-GCOld_default, \ ${jprt.my.solaris.i586}-product-c1-GCBasher_CMS, \
linux_x64-{product|fastdebug}-c2-GCOld_SerialGC, \ ${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_default, \
linux_x64-{product|fastdebug}-c2-GCOld_ParallelGC, \ ${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_SerialGC, \
linux_x64-{product|fastdebug}-c2-GCOld_ParNewGC, \ ${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParallelGC, \
linux_x64-{product|fastdebug}-c2-GCOld_CMS, \ ${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_ParNewGC, \
linux_x64-{product|fastdebug}-c2-jbb_default, \ ${jprt.my.solaris.i586}-fastdebug-c2-GCBasher_CMS, \
linux_x64-{product|fastdebug}-c2-jbb_ParallelGC, \ ${jprt.my.solaris.i586}-product-c1-GCOld_default, \
linux_x64-{product|fastdebug}-c2-scimark_2, \ ${jprt.my.solaris.i586}-product-c1-GCOld_SerialGC, \
linux_x64-{product|fastdebug}-c2-scimark_3, \ ${jprt.my.solaris.i586}-product-c1-GCOld_ParallelGC, \
windows_i586-product-{c1|c2}-runThese, \ ${jprt.my.solaris.i586}-product-c1-GCOld_ParNewGC, \
windows_i586-product-{c1|c2}-runThese_Xcomp, \ ${jprt.my.solaris.i586}-product-c1-GCOld_CMS, \
windows_i586-fastdebug-c1-runThese_Xshare, \ ${jprt.my.solaris.i586}-fastdebug-c2-jbb_default, \
windows_i586-{product|fastdebug}-{c1|c2}-GCBasher_default, \ ${jprt.my.solaris.i586}-fastdebug-c2-jbb_ParallelGC, \
windows_i586-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \ ${jprt.my.solaris.i586}-fastdebug-c2-jbb_CMS, \
windows_i586-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \ ${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark_2, \
windows_i586-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \ ${jprt.my.solaris.i586}-{product|fastdebug}-{c1|c2}-scimark_3
windows_i586-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
windows_i586-product-{c1|c2}-GCOld_default, \ jprt.my.linux.i586.test.targets = \
windows_i586-product-{c1|c2}-GCOld_SerialGC, \ ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
windows_i586-product-{c1|c2}-GCOld_ParallelGC, \ ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-scimark, \
windows_i586-product-{c1|c2}-GCOld_ParNewGC, \ ${jprt.my.linux.i586}-product-c1-runThese_Xcomp, \
windows_i586-product-{c1|c2}-GCOld_CMS, \ ${jprt.my.linux.i586}-product-c1-runThese_Xcomp_2, \
windows_i586-{product|fastdebug}-{c1|c2}-jbb_default, \ ${jprt.my.linux.i586}-product-c1-runThese_Xcomp_3, \
windows_i586-product-{c1|c2}-jbb_ParallelGC, \ ${jprt.my.linux.i586}-fastdebug-c1-runThese_Xshare, \
windows_i586-product-{c1|c2}-jbb_CMS, \ ${jprt.my.linux.i586}-fastdebug-c2-runThese_Xcomp, \
windows_i586-product-{c1|c2}-scimark_2, \ ${jprt.my.linux.i586}-fastdebug-c2-runThese_Xcomp_2, \
windows_i586-product-{c1|c2}-scimark_3, \ ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_default, \
windows_x64-product-c2-runThese, \ ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
windows_x64-product-c2-runThese_Xcomp, \ ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
windows_x64-{product|fastdebug}-c2-GCBasher_default, \ ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
windows_x64-{product|fastdebug}-c2-GCBasher_SerialGC, \ ${jprt.my.linux.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
windows_x64-{product|fastdebug}-c2-GCBasher_ParallelGC, \ ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_default, \
windows_x64-{product|fastdebug}-c2-GCBasher_ParNewGC, \ ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_SerialGC, \
windows_x64-{product|fastdebug}-c2-GCBasher_CMS, \ ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParallelGC, \
windows_x64-{product|fastdebug}-c2-GCOld_default, \ ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_ParNewGC, \
windows_x64-{product|fastdebug}-c2-GCOld_SerialGC, \ ${jprt.my.linux.i586}-product-{c1|c2}-GCOld_CMS, \
windows_x64-{product|fastdebug}-c2-GCOld_ParallelGC, \ ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_default, \
windows_x64-{product|fastdebug}-c2-GCOld_ParNewGC, \ ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_ParallelGC, \
windows_x64-{product|fastdebug}-c2-GCOld_CMS, \ ${jprt.my.linux.i586}-{product|fastdebug}-c1-jbb_CMS, \
windows_x64-{product|fastdebug}-c2-jbb_default, \ ${jprt.my.linux.i586}-{product|fastdebug}-c2-scimark_2, \
windows_x64-product-c2-jbb_CMS, \ ${jprt.my.linux.i586}-{product|fastdebug}-c2-scimark_3
windows_x64-product-c2-jbb_ParallelGC, \
windows_x64-{product|fastdebug}-c2-scimark_2, \ jprt.my.linux.x64.test.targets = \
windows_x64-{product|fastdebug}-c2-scimark_3 ${jprt.my.linux.x64}-{product|fastdebug}-c2-jvm98, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_default, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_default, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-GCOld_CMS, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_default, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-jbb_ParallelGC, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark_2, \
${jprt.my.linux.x64}-{product|fastdebug}-c2-scimark_3
jprt.my.windows.i586.test.targets = \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jvm98, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-scimark, \
${jprt.my.windows.i586}-product-{c1|c2}-runThese, \
${jprt.my.windows.i586}-product-{c1|c2}-runThese_Xcomp, \
${jprt.my.windows.i586}-fastdebug-c1-runThese_Xshare, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_default, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_SerialGC, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParallelGC, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_ParNewGC, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-GCBasher_CMS, \
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_default, \
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_SerialGC, \
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParallelGC, \
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_ParNewGC, \
${jprt.my.windows.i586}-product-{c1|c2}-GCOld_CMS, \
${jprt.my.windows.i586}-{product|fastdebug}-{c1|c2}-jbb_default, \
${jprt.my.windows.i586}-product-{c1|c2}-jbb_ParallelGC, \
${jprt.my.windows.i586}-product-{c1|c2}-jbb_CMS, \
${jprt.my.windows.i586}-product-{c1|c2}-scimark_2, \
${jprt.my.windows.i586}-product-{c1|c2}-scimark_3
jprt.my.windows.x64.test.targets = \
${jprt.my.windows.x64}-{product|fastdebug}-c2-jvm98, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark, \
${jprt.my.windows.x64}-product-c2-runThese, \
${jprt.my.windows.x64}-product-c2-runThese_Xcomp, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_default, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_SerialGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParallelGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_ParNewGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCBasher_CMS, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_default, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_SerialGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParallelGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_ParNewGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-GCOld_CMS, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-jbb_default, \
${jprt.my.windows.x64}-product-c2-jbb_CMS, \
${jprt.my.windows.x64}-product-c2-jbb_ParallelGC, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark_2, \
${jprt.my.windows.x64}-{product|fastdebug}-c2-scimark_3
# The complete list of test targets for jprt
jprt.test.targets = \
${jprt.my.solaris.sparc.test.targets}, \
${jprt.my.solaris.sparcv9.test.targets}, \
${jprt.my.solaris.i586.test.targets}, \
${jprt.my.solaris.x64.test.targets}, \
${jprt.my.linux.i586.test.targets}, \
${jprt.my.linux.x64.test.targets}, \
${jprt.my.windows.i586.test.targets}, \
${jprt.my.windows.x64.test.targets}

View File

@ -45,10 +45,6 @@ OPT_CFLAGS/os_solaris_x86_64.o = -xO1
OPT_CFLAGS/generateOptoStub.o = -xO2 OPT_CFLAGS/generateOptoStub.o = -xO2
OPT_CFLAGS/thread.o = -xO2 OPT_CFLAGS/thread.o = -xO2
# Work around for 6624782
OPT_CFLAGS/instanceKlass.o = -Qoption ube -no_a2lf
OPT_CFLAGS/objArrayKlass.o = -Qoption ube -no_a2lf
else else
ifeq ("${Platform_compiler}", "gcc") ifeq ("${Platform_compiler}", "gcc")

View File

@ -29,7 +29,8 @@ DEBUG_CFLAGS/DEFAULT= $(DEBUG_CFLAGS)
DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@)) DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
ifeq ("${Platform_compiler}", "sparcWorks") ifeq ("${Platform_compiler}", "sparcWorks")
ifeq ($(shell expr $(COMPILER_REV) \>= 5.8), 1)
ifeq ($(COMPILER_REV),5.8)
# SS11 SEGV when compiling with -g and -xarch=v8, using different backend # SS11 SEGV when compiling with -g and -xarch=v8, using different backend
DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0 DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0 DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0

View File

@ -92,12 +92,12 @@ XARCH = $(subst sparcv9,v9,$(shell echo $(ISA)))
$(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE) $(XLIBJVM_DB): $(DTRACE_SRCDIR)/$(JVM_DB).c $(JVMOFFS).h $(LIBJVM_DB_MAPFILE)
@echo Making $@ @echo Making $@
$(QUIETLY) mkdir -p 64/ ; \ $(QUIETLY) mkdir -p 64/ ; \
$(CC) $(SYMFLAG) -xarch=$(XARCH) -D$(TYPE) -I. -I$(GENERATED) \ $(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. -I$(GENERATED) \
$(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc $(SHARED_FLAG) $(LFLAGS_JVM_DB) -o $@ $(DTRACE_SRCDIR)/$(JVM_DB).c -lc
$(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE) $(XLIBJVM_DTRACE): $(DTRACE_SRCDIR)/$(JVM_DTRACE).c $(DTRACE_SRCDIR)/$(JVM_DTRACE).h $(LIBJVM_DTRACE_MAPFILE)
@echo Making $@ @echo Making $@
$(QUIETLY) mkdir -p 64/ ; \ $(QUIETLY) mkdir -p 64/ ; \
$(CC) $(SYMFLAG) -xarch=$(XARCH) -D$(TYPE) -I. \ $(CC) $(SYMFLAG) $(ARCHFLAG/$(XARCH)) -D$(TYPE) -I. \
$(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor $(SHARED_FLAG) $(LFLAGS_JVM_DTRACE) -o $@ $(DTRACE_SRCDIR)/$(JVM_DTRACE).c -lc -lthread -ldoor
endif # ifneq ("${ISA}","${BUILDARCH}") endif # ifneq ("${ISA}","${BUILDARCH}")

View File

@ -25,7 +25,7 @@
# Sets make macros for making debug version of VM # Sets make macros for making debug version of VM
# Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make # Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make
# They may also specify FASTDEBUG_CFLAGS, but it defaults to DEBUG_FLAGS. # They may also specify FASTDEBUG_CFLAGS, but it defaults to DEBUG_CFLAGS.
FASTDEBUG_CFLAGS$(FASTDEBUG_CFLAGS) = $(DEBUG_CFLAGS) FASTDEBUG_CFLAGS$(FASTDEBUG_CFLAGS) = $(DEBUG_CFLAGS)
@ -35,15 +35,26 @@ OPT_CFLAGS/BYFILE = $(OPT_CFLAGS/$@)$(OPT_CFLAGS/DEFAULT$(OPT_CFLAGS/$@))
ifeq ("${Platform_compiler}", "sparcWorks") ifeq ("${Platform_compiler}", "sparcWorks")
OPT_CFLAGS/SLOWER = -xO2 OPT_CFLAGS/SLOWER = -xO2
ifeq ($(shell expr $(COMPILER_REV) \>= 5.5), 1)
# CC 5.5 has bug 4908364 with -xO4 # Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
ifeq ($(COMPILER_REV), 5.9)
# Not clear this workaround could be skipped in some cases.
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER)
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER)
OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER)
endif
ifeq ($(COMPILER_REV), 5.5)
# CC 5.5 has bug 4908364 with -xO4 (Fixed in 5.6)
OPT_CFLAGS/library_call.o = $(OPT_CFLAGS/SLOWER) OPT_CFLAGS/library_call.o = $(OPT_CFLAGS/SLOWER)
else # COMPILER_REV >= 5.5 endif # COMPILER_REV == 5.5
ifeq ($(shell expr $(COMPILER_REV) \<= 5.4), 1)
# Compilation of *_<arch>.cpp can take an hour or more at O3. Use O2 # Compilation of *_<arch>.cpp can take an hour or more at O3. Use O2
# See comments at top of sparc.make. # See comments at top of sparc.make.
OPT_CFLAGS/ad_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER) OPT_CFLAGS/ad_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
OPT_CFLAGS/dfa_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER) OPT_CFLAGS/dfa_$(Platform_arch).o = $(OPT_CFLAGS/SLOWER)
endif # COMPILER_REV >= 5.5 endif # COMPILER_REV <= 5.4
ifeq (${COMPILER_REV}, 5.0) ifeq (${COMPILER_REV}, 5.0)
# Avoid a compiler bug caused by using -xO<level> -g<level> # Avoid a compiler bug caused by using -xO<level> -g<level>

View File

@ -29,7 +29,8 @@ DEBUG_CFLAGS/DEFAULT= $(DEBUG_CFLAGS)
DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@)) DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
ifeq ("${Platform_compiler}", "sparcWorks") ifeq ("${Platform_compiler}", "sparcWorks")
ifeq ($(shell expr $(COMPILER_REV) \>= 5.8), 1)
ifeq ($(COMPILER_REV),5.8))
# SS11 SEGV when compiling with -g and -xarch=v8, using different backend # SS11 SEGV when compiling with -g and -xarch=v8, using different backend
DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0 DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0 DEBUG_CFLAGS/jvmtiTagMap.o = $(DEBUG_CFLAGS) -xO0

View File

@ -30,12 +30,21 @@ OPT_CFLAGS/DEFAULT= $(OPT_CFLAGS)
OPT_CFLAGS/BYFILE = $(OPT_CFLAGS/$@)$(OPT_CFLAGS/DEFAULT$(OPT_CFLAGS/$@)) OPT_CFLAGS/BYFILE = $(OPT_CFLAGS/$@)$(OPT_CFLAGS/DEFAULT$(OPT_CFLAGS/$@))
# (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files) # (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
# Workaround SS11 bug 6345274 (all platforms)
ifeq ("${Platform_compiler}", "sparcWorks") ifeq ("${Platform_compiler}", "sparcWorks")
ifeq ($(shell expr $(COMPILER_REV) \>= 5.8), 1)
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
ifeq ($(COMPILER_REV),5.9)
# Not clear this workaround could be skipped in some cases.
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER) -g
endif
# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
ifeq ($(COMPILER_REV),5.8))
OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2) OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
endif # COMPILER_REV >= 5.8 endif # COMPILER_REV == 5.8
endif # Platform_compiler == sparcWorks endif # Platform_compiler == sparcWorks
# If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings # If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings

View File

@ -38,12 +38,21 @@ OPT_CFLAGS/ciEnv.o = $(OPT_CFLAGS) -xinline=no%__1cFciEnvbFpost_compiled_method_
endif endif
# (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files) # (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
# Workaround SS11 bug 6345274 (all platforms)
ifeq ("${Platform_compiler}", "sparcWorks") ifeq ("${Platform_compiler}", "sparcWorks")
ifeq ($(shell expr $(COMPILER_REV) \>= 5.8), 1)
# Problem with SS12 compiler, dtrace doesn't like the .o files (bug 6693876)
ifeq ($(COMPILER_REV),5.9)
# Not clear this workaround could be skipped in some cases.
OPT_CFLAGS/vmGCOperations.o = $(OPT_CFLAGS/SLOWER) -g
OPT_CFLAGS/java.o = $(OPT_CFLAGS/SLOWER) -g
OPT_CFLAGS/jni.o = $(OPT_CFLAGS/SLOWER) -g
endif
# Workaround SS11 bug 6345274 (all platforms) (Fixed in SS11 patch and SS12)
ifeq ($(COMPILER_REV),5.8)
OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2) OPT_CFLAGS/ciTypeFlow.o = $(OPT_CFLAGS/O2)
endif # COMPILER_REV >= 5.8 endif # COMPILER_REV == 5.8
endif # Platform_compiler == sparcWorks endif # Platform_compiler == sparcWorks
# If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings # If you set HOTSPARC_GENERIC=yes, you disable all OPT_CFLAGS settings

View File

@ -23,7 +23,7 @@
# #
Obj_Files += solaris_sparc.o Obj_Files += solaris_sparc.o
ASFLAGS += $(ARCHFLAG) ASFLAGS += $(AS_ARCHFLAG)
ifeq ("${Platform_compiler}", "sparcWorks") ifeq ("${Platform_compiler}", "sparcWorks")
ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1) ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)

View File

@ -28,6 +28,8 @@
CC = cc CC = cc
CPP = CC CPP = CC
# Note that this 'as' is an older version of the Sun Studio 'fbe', and will
# use the older style options. The 'fbe' options will match 'cc' and 'CC'.
AS = /usr/ccs/bin/as AS = /usr/ccs/bin/as
NM = /usr/ccs/bin/nm NM = /usr/ccs/bin/nm
@ -43,25 +45,33 @@ $(shell $(CPP) -V 2>&1 | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/')
C_COMPILER_REV := \ C_COMPILER_REV := \
$(shell $(CC) -V 2>&1 | grep -i "cc:" | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/') $(shell $(CC) -V 2>&1 | grep -i "cc:" | sed -e 's/^.*\([1-9]\.[0-9][0-9]*\).*/\1/')
VALIDATED_COMPILER_REV := 5.8 # Pick which compiler is validated
VALIDATED_C_COMPILER_REV := 5.8 ifeq ($(JDK_MINOR_VERSION),6)
# Validated compiler for JDK6 is SS11 (5.8)
VALIDATED_COMPILER_REV := 5.8
VALIDATED_C_COMPILER_REV := 5.8
else
# FIXUP: Change to SS12 (5.9) once it has been validated.
# Validated compiler for JDK7 is SS12 (5.9)
#VALIDATED_COMPILER_REV := 5.9
#VALIDATED_C_COMPILER_REV := 5.9
VALIDATED_COMPILER_REV := 5.8
VALIDATED_C_COMPILER_REV := 5.8
endif
# Warning messages about not using the above validated version
ENFORCE_COMPILER_REV${ENFORCE_COMPILER_REV} := ${VALIDATED_COMPILER_REV} ENFORCE_COMPILER_REV${ENFORCE_COMPILER_REV} := ${VALIDATED_COMPILER_REV}
ifneq (${COMPILER_REV},${ENFORCE_COMPILER_REV}) ifneq (${COMPILER_REV},${ENFORCE_COMPILER_REV})
dummy_target_to_enforce_compiler_rev: dummy_target_to_enforce_compiler_rev:=\
@echo "Wrong ${CPP} version: ${COMPILER_REV}. " \ $(info WARNING: You are using CC version ${COMPILER_REV} \
"Use version ${ENFORCE_COMPILER_REV}, or set" \ and should be using version ${ENFORCE_COMPILER_REV})
"ENFORCE_COMPILER_REV=${COMPILER_REV}."
@exit 1
endif endif
ENFORCE_C_COMPILER_REV${ENFORCE_C_COMPILER_REV} := ${VALIDATED_C_COMPILER_REV} ENFORCE_C_COMPILER_REV${ENFORCE_C_COMPILER_REV} := ${VALIDATED_C_COMPILER_REV}
ifneq (${C_COMPILER_REV},${ENFORCE_C_COMPILER_REV}) ifneq (${C_COMPILER_REV},${ENFORCE_C_COMPILER_REV})
dummy_target_to_enforce_c_compiler_rev: dummy_target_to_enforce_c_compiler_rev:=\
@echo "Wrong ${CC} version: ${C_COMPILER_REV}. " \ $(info WARNING: You are using cc version ${C_COMPILER_REV} \
"Use version ${ENFORCE_C_COMPILER_REV}, or set" \ and should be using version ${ENFORCE_C_COMPILER_REV})
"ENFORCE_C_COMPILER_REV=${C_COMPILER_REV}."
@exit 1
endif endif
# Fail the build if __fabsf is used. __fabsf exists only in Solaris 8 2/04 # Fail the build if __fabsf is used. __fabsf exists only in Solaris 8 2/04
@ -90,20 +100,44 @@ SOLARIS_7_OR_LATER := \
$(shell uname -r | awk -F. '{ if ($$2 >= 7) print "-DSOLARIS_7_OR_LATER"; }') $(shell uname -r | awk -F. '{ if ($$2 >= 7) print "-DSOLARIS_7_OR_LATER"; }')
CFLAGS += ${SOLARIS_7_OR_LATER} CFLAGS += ${SOLARIS_7_OR_LATER}
ARCHFLAG = $(ARCHFLAG/$(BUILDARCH)) # New architecture options started in SS12 (5.9), we need both styles to build.
# set ARCHFLAG/BUILDARCH which will ultimately be ARCHFLAG # The older arch options for SS11 (5.8) or older and also for /usr/ccs/bin/as.
# Note: SS12 default for 32bit sparc is now the same as v8plus, so the
# settings below have changed all SS12 32bit sparc builds to be v8plus.
# The older SS11 (5.8) settings have remained as they always have been.
ifeq ($(TYPE),COMPILER2) ifeq ($(TYPE),COMPILER2)
ARCHFLAG/sparc = -xarch=v8plus ARCHFLAG_OLD/sparc = -xarch=v8plus
else else
ifeq ($(TYPE),TIERED) ifeq ($(TYPE),TIERED)
ARCHFLAG/sparc = -xarch=v8plus ARCHFLAG_OLD/sparc = -xarch=v8plus
else
ARCHFLAG_OLD/sparc = -xarch=v8
endif
endif
ARCHFLAG_NEW/sparc = -m32 -xarch=sparc
ARCHFLAG_OLD/sparcv9 = -xarch=v9
ARCHFLAG_NEW/sparcv9 = -m64 -xarch=sparc
ARCHFLAG_OLD/i486 =
ARCHFLAG_NEW/i486 = -m32
ARCHFLAG_OLD/amd64 = -xarch=amd64
ARCHFLAG_NEW/amd64 = -m64
# Select the ARCHFLAGs and other SS12 (5.9) options
ifeq ($(shell expr $(COMPILER_REV) \>= 5.9), 1)
ARCHFLAG/sparc = $(ARCHFLAG_NEW/sparc)
ARCHFLAG/sparcv9 = $(ARCHFLAG_NEW/sparcv9)
ARCHFLAG/i486 = $(ARCHFLAG_NEW/i486)
ARCHFLAG/amd64 = $(ARCHFLAG_NEW/amd64)
else else
ARCHFLAG/sparc = -xarch=v8 ARCHFLAG/sparc = $(ARCHFLAG_OLD/sparc)
ARCHFLAG/sparcv9 = $(ARCHFLAG_OLD/sparcv9)
ARCHFLAG/i486 = $(ARCHFLAG_OLD/i486)
ARCHFLAG/amd64 = $(ARCHFLAG_OLD/amd64)
endif endif
endif
ARCHFLAG/sparcv9 = -xarch=v9 # ARCHFLAGS for the current build arch
ARCHFLAG/i486 = ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
ARCHFLAG/amd64 = -xarch=amd64 AS_ARCHFLAG = $(ARCHFLAG_OLD/$(BUILDARCH))
# Optional sub-directory in /usr/lib where BUILDARCH libraries are kept. # Optional sub-directory in /usr/lib where BUILDARCH libraries are kept.
ISA_DIR=$(ISA_DIR/$(BUILDARCH)) ISA_DIR=$(ISA_DIR/$(BUILDARCH))
@ -166,13 +200,13 @@ endif # 32bit x86
ifeq ("${Platform_arch_model}", "x86_64") ifeq ("${Platform_arch_model}", "x86_64")
ASFLAGS += -xarch=amd64 ASFLAGS += $(AS_ARCHFLAG)
CFLAGS += -xarch=amd64 CFLAGS += $(ARCHFLAG/amd64)
# this one seemed useless # this one seemed useless
LFLAGS_VM += -xarch=amd64 LFLAGS_VM += $(ARCHFLAG/amd64)
# this one worked # this one worked
LFLAGS += -xarch=amd64 LFLAGS += $(ARCHFLAG/amd64)
AOUT_FLAGS += -xarch=amd64 AOUT_FLAGS += $(ARCHFLAG/amd64)
# -xO3 is faster than -xO4 on specjbb with SS10 compiler # -xO3 is faster than -xO4 on specjbb with SS10 compiler
OPT_CFLAGS=-xO4 $(EXTRA_OPT_CFLAGS) OPT_CFLAGS=-xO4 $(EXTRA_OPT_CFLAGS)
@ -224,7 +258,7 @@ LFLAGS += -library=%none
LFLAGS += -mt LFLAGS += -mt
endif # COMPILER_REV >= VALIDATED_COMPILER_REV endif # COMPILER_REV >= 5.5
###################################### ######################################
# End 5.5 Forte compiler options # # End 5.5 Forte compiler options #
@ -293,7 +327,7 @@ PICFLAG/BYFILE = $(PICFLAG/$@)$(PICFLAG/DEFAULT$(PICFLAG/$@))
LFLAGS += -library=Crun LFLAGS += -library=Crun
LIBS += -library=Crun -lCrun LIBS += -library=Crun -lCrun
endif # COMPILER_REV >= VALIDATED_COMPILER_REV endif # COMPILER_REV == 5.2
################################## ##################################
# End 5.2 Forte compiler options # # End 5.2 Forte compiler options #
@ -320,6 +354,7 @@ ifeq (${COMPILER_REV}, 5.0)
# Had to hoist this higher apparently because of other changes. Must # Had to hoist this higher apparently because of other changes. Must
# come before -xarch specification. # come before -xarch specification.
# NOTE: native says optimize for the machine doing the compile, bad news.
CFLAGS += -xtarget=native CFLAGS += -xtarget=native
CFLAGS += $(ARCHFLAG) CFLAGS += $(ARCHFLAG)
@ -359,7 +394,7 @@ CFLAGS += $(GAMMADIR)/src/os_cpu/solaris_x86/vm/solaris_x86_32.il
endif # 32bit x86 endif # 32bit x86
# The following options run into misaligned ldd problem (raj) # The following options run into misaligned ldd problem (raj)
#OPT_CFLAGS = -fast -O4 -xarch=v8 -xchip=ultra #OPT_CFLAGS = -fast -O4 $(ARCHFLAG/sparc) -xchip=ultra
# no more exceptions # no more exceptions
CFLAGS/NOEX=-noex CFLAGS/NOEX=-noex
@ -427,6 +462,15 @@ DEBUG_CFLAGS = -g
FASTDEBUG_CFLAGS = -g0 FASTDEBUG_CFLAGS = -g0
# The -g0 setting allows the C++ frontend to inline, which is a big win. # The -g0 setting allows the C++ frontend to inline, which is a big win.
# Special global options for SS12
ifeq ($(COMPILER_REV),5.9)
# There appears to be multiple issues with the new Dwarf2 debug format, so
# we tell the compiler to use the older 'stabs' debug format all the time.
# Note that this needs to be used in optimized compiles too to be 100%.
# This is a workaround for SS12 (5.9) bug 6694600
CFLAGS += -xdebugformat=stabs
endif
# Enable the following CFLAGS additions if you need to compare the # Enable the following CFLAGS additions if you need to compare the
# built ELF objects. # built ELF objects.
# #

View File

@ -23,7 +23,7 @@
# #
Obj_Files += solaris_sparc.o Obj_Files += solaris_sparc.o
ASFLAGS += $(ARCHFLAG) ASFLAGS += $(AS_ARCHFLAG)
ifeq ("${Platform_compiler}", "sparcWorks") ifeq ("${Platform_compiler}", "sparcWorks")
ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1) ifeq ($(shell expr $(COMPILER_REV) \< 5.5), 1)

View File

@ -1523,6 +1523,21 @@ Address MacroAssembler::constant_oop_address(jobject obj, Register d) {
return Address(d, address(obj), oop_Relocation::spec(oop_index)); return Address(d, address(obj), oop_Relocation::spec(oop_index));
} }
void MacroAssembler::set_narrow_oop(jobject obj, Register d) {
assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
int oop_index = oop_recorder()->find_index(obj);
RelocationHolder rspec = oop_Relocation::spec(oop_index);
assert_not_delayed();
// Relocation with special format (see relocInfo_sparc.hpp).
relocate(rspec, 1);
// Assembler::sethi(0x3fffff, d);
emit_long( op(branch_op) | rd(d) | op2(sethi_op2) | hi22(0x3fffff) );
// Don't add relocation for 'add'. Do patching during 'sethi' processing.
add(d, 0x3ff, d);
}
void MacroAssembler::align(int modulus) { void MacroAssembler::align(int modulus) {
while (offset() % modulus != 0) nop(); while (offset() % modulus != 0) nop();
@ -3406,13 +3421,15 @@ void MacroAssembler::tlab_refill(Label& retry, Label& try_eden, Label& slow_case
set((intptr_t)markOopDesc::prototype()->copy_set_hash(0x2), t2); set((intptr_t)markOopDesc::prototype()->copy_set_hash(0x2), t2);
st_ptr(t2, top, oopDesc::mark_offset_in_bytes()); // set up the mark word st_ptr(t2, top, oopDesc::mark_offset_in_bytes()); // set up the mark word
// set klass to intArrayKlass // set klass to intArrayKlass
set((intptr_t)Universe::intArrayKlassObj_addr(), t2);
ld_ptr(t2, 0, t2);
store_klass(t2, top);
sub(t1, typeArrayOopDesc::header_size(T_INT), t1); sub(t1, typeArrayOopDesc::header_size(T_INT), t1);
add(t1, ThreadLocalAllocBuffer::alignment_reserve(), t1); add(t1, ThreadLocalAllocBuffer::alignment_reserve(), t1);
sll_ptr(t1, log2_intptr(HeapWordSize/sizeof(jint)), t1); sll_ptr(t1, log2_intptr(HeapWordSize/sizeof(jint)), t1);
st(t1, top, arrayOopDesc::length_offset_in_bytes()); st(t1, top, arrayOopDesc::length_offset_in_bytes());
set((intptr_t)Universe::intArrayKlassObj_addr(), t2);
ld_ptr(t2, 0, t2);
// store klass last. concurrent gcs assumes klass length is valid if
// klass field is not null.
store_klass(t2, top);
verify_oop(top); verify_oop(top);
// refill the tlab with an eden allocation // refill the tlab with an eden allocation
@ -3537,28 +3554,32 @@ void MacroAssembler::bang_stack_size(Register Rsize, Register Rtsp,
} }
} }
void MacroAssembler::load_klass(Register s, Register d) { void MacroAssembler::load_klass(Register src_oop, Register klass) {
// The number of bytes in this code is used by // The number of bytes in this code is used by
// MachCallDynamicJavaNode::ret_addr_offset() // MachCallDynamicJavaNode::ret_addr_offset()
// if this changes, change that. // if this changes, change that.
if (UseCompressedOops) { if (UseCompressedOops) {
lduw(s, oopDesc::klass_offset_in_bytes(), d); lduw(src_oop, oopDesc::klass_offset_in_bytes(), klass);
decode_heap_oop_not_null(d); decode_heap_oop_not_null(klass);
} else { } else {
ld_ptr(s, oopDesc::klass_offset_in_bytes(), d); ld_ptr(src_oop, oopDesc::klass_offset_in_bytes(), klass);
} }
} }
// ??? figure out src vs. dst! void MacroAssembler::store_klass(Register klass, Register dst_oop) {
void MacroAssembler::store_klass(Register d, Register s1) {
if (UseCompressedOops) { if (UseCompressedOops) {
assert(s1 != d, "not enough registers"); assert(dst_oop != klass, "not enough registers");
encode_heap_oop_not_null(d); encode_heap_oop_not_null(klass);
// Zero out entire klass field first. st(klass, dst_oop, oopDesc::klass_offset_in_bytes());
st_ptr(G0, s1, oopDesc::klass_offset_in_bytes());
st(d, s1, oopDesc::klass_offset_in_bytes());
} else { } else {
st_ptr(d, s1, oopDesc::klass_offset_in_bytes()); st_ptr(klass, dst_oop, oopDesc::klass_offset_in_bytes());
}
}
void MacroAssembler::store_klass_gap(Register s, Register d) {
if (UseCompressedOops) {
assert(s != d, "not enough registers");
st(s, d, oopDesc::klass_gap_offset_in_bytes());
} }
} }
@ -3622,6 +3643,7 @@ void MacroAssembler::store_heap_oop(Register d, const Address& a, int offset) {
void MacroAssembler::encode_heap_oop(Register src, Register dst) { void MacroAssembler::encode_heap_oop(Register src, Register dst) {
assert (UseCompressedOops, "must be compressed"); assert (UseCompressedOops, "must be compressed");
verify_oop(src);
Label done; Label done;
if (src == dst) { if (src == dst) {
// optimize for frequent case src == dst // optimize for frequent case src == dst
@ -3643,12 +3665,14 @@ void MacroAssembler::encode_heap_oop(Register src, Register dst) {
void MacroAssembler::encode_heap_oop_not_null(Register r) { void MacroAssembler::encode_heap_oop_not_null(Register r) {
assert (UseCompressedOops, "must be compressed"); assert (UseCompressedOops, "must be compressed");
verify_oop(r);
sub(r, G6_heapbase, r); sub(r, G6_heapbase, r);
srlx(r, LogMinObjAlignmentInBytes, r); srlx(r, LogMinObjAlignmentInBytes, r);
} }
void MacroAssembler::encode_heap_oop_not_null(Register src, Register dst) { void MacroAssembler::encode_heap_oop_not_null(Register src, Register dst) {
assert (UseCompressedOops, "must be compressed"); assert (UseCompressedOops, "must be compressed");
verify_oop(src);
sub(src, G6_heapbase, dst); sub(src, G6_heapbase, dst);
srlx(dst, LogMinObjAlignmentInBytes, dst); srlx(dst, LogMinObjAlignmentInBytes, dst);
} }
@ -3661,11 +3685,13 @@ void MacroAssembler::decode_heap_oop(Register src, Register dst) {
bpr(rc_nz, true, Assembler::pt, dst, done); bpr(rc_nz, true, Assembler::pt, dst, done);
delayed() -> add(dst, G6_heapbase, dst); // annuled if not taken delayed() -> add(dst, G6_heapbase, dst); // annuled if not taken
bind(done); bind(done);
verify_oop(dst);
} }
void MacroAssembler::decode_heap_oop_not_null(Register r) { void MacroAssembler::decode_heap_oop_not_null(Register r) {
// Do not add assert code to this unless you change vtableStubs_sparc.cpp // Do not add assert code to this unless you change vtableStubs_sparc.cpp
// pd_code_size_limit. // pd_code_size_limit.
// Also do not verify_oop as this is called by verify_oop.
assert (UseCompressedOops, "must be compressed"); assert (UseCompressedOops, "must be compressed");
sllx(r, LogMinObjAlignmentInBytes, r); sllx(r, LogMinObjAlignmentInBytes, r);
add(r, G6_heapbase, r); add(r, G6_heapbase, r);
@ -3674,6 +3700,7 @@ void MacroAssembler::decode_heap_oop_not_null(Register r) {
void MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) { void MacroAssembler::decode_heap_oop_not_null(Register src, Register dst) {
// Do not add assert code to this unless you change vtableStubs_sparc.cpp // Do not add assert code to this unless you change vtableStubs_sparc.cpp
// pd_code_size_limit. // pd_code_size_limit.
// Also do not verify_oop as this is called by verify_oop.
assert (UseCompressedOops, "must be compressed"); assert (UseCompressedOops, "must be compressed");
sllx(src, LogMinObjAlignmentInBytes, dst); sllx(src, LogMinObjAlignmentInBytes, dst);
add(dst, G6_heapbase, dst); add(dst, G6_heapbase, dst);

View File

@ -1977,8 +1977,9 @@ class MacroAssembler: public Assembler {
inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); } inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); }
// klass oop manipulations if compressed // klass oop manipulations if compressed
void load_klass(Register src_oop, Register dst); void load_klass(Register src_oop, Register klass);
void store_klass(Register dst_oop, Register s1); void store_klass(Register klass, Register dst_oop);
void store_klass_gap(Register s, Register dst_oop);
// oop manipulations // oop manipulations
void load_heap_oop(const Address& s, Register d, int offset = 0); void load_heap_oop(const Address& s, Register d, int offset = 0);
@ -2103,6 +2104,8 @@ class MacroAssembler: public Assembler {
inline void set_oop_constant( jobject obj, Register d ); // uses constant_oop_address inline void set_oop_constant( jobject obj, Register d ); // uses constant_oop_address
inline void set_oop ( Address obj_addr ); // same as load_address inline void set_oop ( Address obj_addr ); // same as load_address
void set_narrow_oop( jobject obj, Register d );
// nop padding // nop padding
void align(int modulus); void align(int modulus);

View File

@ -87,6 +87,17 @@ void Relocation::pd_set_data_value(address x, intptr_t o) {
#ifdef _LP64 #ifdef _LP64
jint inst2; jint inst2;
guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi"); guarantee(Assembler::inv_op2(inst)==Assembler::sethi_op2, "must be sethi");
if (format() != 0) {
assert(type() == relocInfo::oop_type, "only narrow oops case");
jint np = oopDesc::encode_heap_oop((oop)x);
inst &= ~Assembler::hi22(-1);
inst |= Assembler::hi22((intptr_t)np);
ip->set_long_at(0, inst);
inst2 = ip->long_at( NativeInstruction::nop_instruction_size );
guarantee(Assembler::inv_op(inst2)==Assembler::arith_op, "arith op");
ip->set_long_at(NativeInstruction::nop_instruction_size, ip->set_data32_simm13( inst2, (intptr_t)np));
break;
}
ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x ); ip->set_data64_sethi( ip->addr_at(0), (intptr_t)x );
#ifdef COMPILER2 #ifdef COMPILER2
// [RGV] Someone must have missed putting in a reloc entry for the // [RGV] Someone must have missed putting in a reloc entry for the

View File

@ -31,7 +31,12 @@
// There is no need for format bits; the instructions are // There is no need for format bits; the instructions are
// sufficiently self-identifying. // sufficiently self-identifying.
#ifndef _LP64
format_width = 0 format_width = 0
#else
// Except narrow oops in 64-bits VM.
format_width = 1
#endif
}; };

View File

@ -2556,7 +2556,6 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
int total_strings = 0; int total_strings = 0;
int first_arg_to_pass = 0; int first_arg_to_pass = 0;
int total_c_args = 0; int total_c_args = 0;
int box_offset = java_lang_boxing_object::value_offset_in_bytes();
// Skip the receiver as dtrace doesn't want to see it // Skip the receiver as dtrace doesn't want to see it
if( !method->is_static() ) { if( !method->is_static() ) {
@ -2721,7 +2720,8 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
#endif /* ASSERT */ #endif /* ASSERT */
VMRegPair zero; VMRegPair zero;
zero.set2(G0->as_VMReg()); const Register g0 = G0; // without this we get a compiler warning (why??)
zero.set2(g0->as_VMReg());
int c_arg, j_arg; int c_arg, j_arg;
@ -2778,7 +2778,9 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
__ br_null(in_reg, true, Assembler::pn, skipUnbox); __ br_null(in_reg, true, Assembler::pn, skipUnbox);
__ delayed()->mov(G0, tmp); __ delayed()->mov(G0, tmp);
switch (out_sig_bt[c_arg]) { BasicType bt = out_sig_bt[c_arg];
int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
switch (bt) {
case T_BYTE: case T_BYTE:
__ ldub(in_reg, box_offset, tmp); break; __ ldub(in_reg, box_offset, tmp); break;
case T_SHORT: case T_SHORT:

View File

@ -5471,7 +5471,6 @@ instruct loadN(iRegN dst, memory mem) %{
// Load Klass Pointer // Load Klass Pointer
instruct loadKlass(iRegP dst, memory mem) %{ instruct loadKlass(iRegP dst, memory mem) %{
match(Set dst (LoadKlass mem)); match(Set dst (LoadKlass mem));
predicate(!n->in(MemNode::Address)->bottom_type()->is_narrow());
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4); size(4);
@ -5486,11 +5485,11 @@ instruct loadKlass(iRegP dst, memory mem) %{
ins_pipe(iload_mem); ins_pipe(iload_mem);
%} %}
// Load Klass Pointer // Load narrow Klass Pointer
instruct loadKlassComp(iRegP dst, memory mem) %{ instruct loadNKlass(iRegN dst, memory mem) %{
match(Set dst (LoadKlass mem)); match(Set dst (LoadNKlass mem));
predicate(n->in(MemNode::Address)->bottom_type()->is_narrow());
ins_cost(MEMORY_REF_COST); ins_cost(MEMORY_REF_COST);
size(4);
format %{ "LDUW $mem,$dst\t! compressed klass ptr" %} format %{ "LDUW $mem,$dst\t! compressed klass ptr" %}
@ -5503,9 +5502,6 @@ instruct loadKlassComp(iRegP dst, memory mem) %{
} else { } else {
__ lduw(base, $mem$$disp, dst); __ lduw(base, $mem$$disp, dst);
} }
// klass oop never null but this is generated for nonheader klass loads
// too which can be null.
__ decode_heap_oop(dst);
%} %}
ins_pipe(iload_mem); ins_pipe(iload_mem);
%} %}
@ -5609,22 +5605,24 @@ instruct loadConP_poll(iRegP dst, immP_poll src) %{
ins_pipe(loadConP_poll); ins_pipe(loadConP_poll);
%} %}
instruct loadConN0(iRegN dst, immN0 src) %{
match(Set dst src);
size(4);
format %{ "CLR $dst\t! compressed NULL ptr" %}
ins_encode( SetNull( dst ) );
ins_pipe(ialu_imm);
%}
instruct loadConN(iRegN dst, immN src) %{ instruct loadConN(iRegN dst, immN src) %{
match(Set dst src); match(Set dst src);
ins_cost(DEFAULT_COST * 2); ins_cost(DEFAULT_COST * 3/2);
format %{ "SET $src,$dst\t!ptr" %} format %{ "SET $src,$dst\t! compressed ptr" %}
ins_encode %{ ins_encode %{
address con = (address)$src$$constant;
Register dst = $dst$$Register; Register dst = $dst$$Register;
if (con == NULL) { __ set_narrow_oop((jobject)$src$$constant, dst);
__ mov(G0, dst);
} else {
__ set_oop((jobject)$src$$constant, dst);
__ encode_heap_oop(dst);
}
%} %}
ins_pipe(loadConP); ins_pipe(ialu_hi_lo_reg);
%} %}
instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{ instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{
@ -5977,7 +5975,8 @@ instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{
%} %}
instruct decodeHeapOop(iRegP dst, iRegN src) %{ instruct decodeHeapOop(iRegP dst, iRegN src) %{
predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull); predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
match(Set dst (DecodeN src)); match(Set dst (DecodeN src));
format %{ "decode_heap_oop $src, $dst" %} format %{ "decode_heap_oop $src, $dst" %}
ins_encode %{ ins_encode %{
@ -5987,7 +5986,8 @@ instruct decodeHeapOop(iRegP dst, iRegN src) %{
%} %}
instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{ instruct decodeHeapOop_not_null(iRegP dst, iRegN src) %{
predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull); predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
match(Set dst (DecodeN src)); match(Set dst (DecodeN src));
format %{ "decode_heap_oop_not_null $src, $dst" %} format %{ "decode_heap_oop_not_null $src, $dst" %}
ins_encode %{ ins_encode %{
@ -6258,6 +6258,34 @@ instruct cmovIF_imm(cmpOpF cmp, flagsRegF fcc, iRegI dst, immI11 src) %{
ins_pipe(ialu_imm); ins_pipe(ialu_imm);
%} %}
// Conditional move for RegN. Only cmov(reg,reg).
instruct cmovNP_reg(cmpOpP cmp, flagsRegP pcc, iRegN dst, iRegN src) %{
match(Set dst (CMoveN (Binary cmp pcc) (Binary dst src)));
ins_cost(150);
format %{ "MOV$cmp $pcc,$src,$dst" %}
ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::ptr_cc)) );
ins_pipe(ialu_reg);
%}
// This instruction also works with CmpN so we don't need cmovNN_reg.
instruct cmovNI_reg(cmpOp cmp, flagsReg icc, iRegN dst, iRegN src) %{
match(Set dst (CMoveN (Binary cmp icc) (Binary dst src)));
ins_cost(150);
size(4);
format %{ "MOV$cmp $icc,$src,$dst" %}
ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) );
ins_pipe(ialu_reg);
%}
instruct cmovNF_reg(cmpOpF cmp, flagsRegF fcc, iRegN dst, iRegN src) %{
match(Set dst (CMoveN (Binary cmp fcc) (Binary dst src)));
ins_cost(150);
size(4);
format %{ "MOV$cmp $fcc,$src,$dst" %}
ins_encode( enc_cmov_reg_f(cmp,dst,src, fcc) );
ins_pipe(ialu_reg);
%}
// Conditional move // Conditional move
instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{ instruct cmovPP_reg(cmpOpP cmp, flagsRegP pcc, iRegP dst, iRegP src) %{
match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src))); match(Set dst (CMoveP (Binary cmp pcc) (Binary dst src)));
@ -6275,6 +6303,7 @@ instruct cmovPP_imm(cmpOpP cmp, flagsRegP pcc, iRegP dst, immP0 src) %{
ins_pipe(ialu_imm); ins_pipe(ialu_imm);
%} %}
// This instruction also works with CmpN so we don't need cmovPN_reg.
instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{ instruct cmovPI_reg(cmpOp cmp, flagsReg icc, iRegP dst, iRegP src) %{
match(Set dst (CMoveP (Binary cmp icc) (Binary dst src))); match(Set dst (CMoveP (Binary cmp icc) (Binary dst src)));
ins_cost(150); ins_cost(150);
@ -6650,10 +6679,9 @@ instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI r
ins_pipe( long_memory_op ); ins_pipe( long_memory_op );
%} %}
instruct compareAndSwapN_bool_comp(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp, flagsReg ccr ) %{ instruct compareAndSwapN_bool(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval))); match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
effect( USE mem_ptr, KILL ccr, KILL tmp); effect( USE mem_ptr, KILL ccr, KILL tmp1);
format %{ format %{
"MOV $newval,O7\n\t" "MOV $newval,O7\n\t"
"CASA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t" "CASA [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
@ -6661,18 +6689,8 @@ instruct compareAndSwapN_bool_comp(iRegP mem_ptr, iRegN oldval, iRegN newval, iR
"MOV 1,$res\n\t" "MOV 1,$res\n\t"
"MOVne icc,R_G0,$res" "MOVne icc,R_G0,$res"
%} %}
ins_encode %{ ins_encode( enc_casi(mem_ptr, oldval, newval),
Register Rmem = reg_to_register_object($mem_ptr$$reg); enc_iflags_ne_to_boolean(res) );
Register Rold = reg_to_register_object($oldval$$reg);
Register Rnew = reg_to_register_object($newval$$reg);
Register Rres = reg_to_register_object($res$$reg);
__ cas(Rmem, Rold, Rnew);
__ cmp( Rold, Rnew );
__ mov(1, Rres);
__ movcc( Assembler::notEqual, false, Assembler::icc, G0, Rres );
%}
ins_pipe( long_memory_op ); ins_pipe( long_memory_op );
%} %}
@ -8265,6 +8283,27 @@ instruct compP_iRegP_imm13(flagsRegP pcc, iRegP op1, immP13 op2 ) %{
ins_pipe(ialu_cconly_reg_imm); ins_pipe(ialu_cconly_reg_imm);
%} %}
// Compare Narrow oops
instruct compN_iRegN(flagsReg icc, iRegN op1, iRegN op2 ) %{
match(Set icc (CmpN op1 op2));
size(4);
format %{ "CMP $op1,$op2\t! compressed ptr" %}
opcode(Assembler::subcc_op3, Assembler::arith_op);
ins_encode( form3_rs1_rs2_rd( op1, op2, R_G0 ) );
ins_pipe(ialu_cconly_reg_reg);
%}
instruct compN_iRegN_immN0(flagsReg icc, iRegN op1, immN0 op2 ) %{
match(Set icc (CmpN op1 op2));
size(4);
format %{ "CMP $op1,$op2\t! compressed ptr" %}
opcode(Assembler::subcc_op3, Assembler::arith_op);
ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) );
ins_pipe(ialu_cconly_reg_imm);
%}
//----------Max and Min-------------------------------------------------------- //----------Max and Min--------------------------------------------------------
// Min Instructions // Min Instructions
// Conditional move for min // Conditional move for min
@ -8595,6 +8634,14 @@ instruct cmovIL_imm(cmpOp cmp, flagsRegL xcc, iRegI dst, immI11 src) %{
ins_pipe(ialu_imm); ins_pipe(ialu_imm);
%} %}
instruct cmovNL_reg(cmpOp cmp, flagsRegL xcc, iRegN dst, iRegN src) %{
match(Set dst (CMoveN (Binary cmp xcc) (Binary dst src)));
ins_cost(150);
format %{ "MOV$cmp $xcc,$src,$dst" %}
ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::xcc)) );
ins_pipe(ialu_reg);
%}
instruct cmovPL_reg(cmpOp cmp, flagsRegL xcc, iRegP dst, iRegP src) %{ instruct cmovPL_reg(cmpOp cmp, flagsRegL xcc, iRegP dst, iRegP src) %{
match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src))); match(Set dst (CMoveP (Binary cmp xcc) (Binary dst src)));
ins_cost(150); ins_cost(150);
@ -8826,16 +8873,6 @@ instruct partialSubtypeCheck_vs_zero( flagsRegP pcc, o1RegP sub, o2RegP super, i
%} %}
instruct compP_iRegN_immN0(flagsRegP pcc, iRegN op1, immN0 op2 ) %{
match(Set pcc (CmpN op1 op2));
size(4);
format %{ "CMP $op1,$op2\t! ptr" %}
opcode(Assembler::subcc_op3, Assembler::arith_op);
ins_encode( form3_rs1_simm13_rd( op1, op2, R_G0 ) );
ins_pipe(ialu_cconly_reg_imm);
%}
// ============================================================================ // ============================================================================
// inlined locking and unlocking // inlined locking and unlocking

View File

@ -3222,7 +3222,8 @@ void TemplateTable::_new() {
__ set((intptr_t)markOopDesc::prototype(), G4_scratch); __ set((intptr_t)markOopDesc::prototype(), G4_scratch);
} }
__ st_ptr(G4_scratch, RallocatedObject, oopDesc::mark_offset_in_bytes()); // mark __ st_ptr(G4_scratch, RallocatedObject, oopDesc::mark_offset_in_bytes()); // mark
__ store_klass(RinstanceKlass, RallocatedObject); // klass __ store_klass_gap(G0, RallocatedObject); // klass gap if compressed
__ store_klass(RinstanceKlass, RallocatedObject); // klass (last for cms)
{ {
SkipIfEqual skip_if( SkipIfEqual skip_if(

View File

@ -1054,7 +1054,7 @@ class MacroAssembler: public Assembler {
// range (0 <= offset <= page_size). // range (0 <= offset <= page_size).
void null_check(Register reg, int offset = -1); void null_check(Register reg, int offset = -1);
static bool needs_explicit_null_check(int offset); static bool needs_explicit_null_check(intptr_t offset);
// Required platform-specific helpers for Label::patch_instructions. // Required platform-specific helpers for Label::patch_instructions.
// They _shadow_ the declarations in AbstractAssembler, which are undefined. // They _shadow_ the declarations in AbstractAssembler, which are undefined.

View File

@ -683,7 +683,8 @@ address Assembler::locate_operand(address inst, WhichOperand which) {
case REP8(0xB8): // movl/q r, #32/#64(oop?) case REP8(0xB8): // movl/q r, #32/#64(oop?)
if (which == end_pc_operand) return ip + (is_64bit ? 8 : 4); if (which == end_pc_operand) return ip + (is_64bit ? 8 : 4);
assert((which == call32_operand || which == imm64_operand) && is_64bit, ""); assert((which == call32_operand || which == imm64_operand) && is_64bit ||
which == narrow_oop_operand && !is_64bit, "");
return ip; return ip;
case 0x69: // imul r, a, #32 case 0x69: // imul r, a, #32
@ -909,7 +910,8 @@ void Assembler::check_relocation(RelocationHolder const& rspec, int format) {
} else if (r->is_call() || format == call32_operand) { } else if (r->is_call() || format == call32_operand) {
opnd = locate_operand(inst, call32_operand); opnd = locate_operand(inst, call32_operand);
} else if (r->is_data()) { } else if (r->is_data()) {
assert(format == imm64_operand || format == disp32_operand, "format ok"); assert(format == imm64_operand || format == disp32_operand ||
format == narrow_oop_operand, "format ok");
opnd = locate_operand(inst, (WhichOperand) format); opnd = locate_operand(inst, (WhichOperand) format);
} else { } else {
assert(format == 0, "cannot specify a format"); assert(format == 0, "cannot specify a format");
@ -4933,6 +4935,8 @@ void MacroAssembler::tlab_refill(Label& retry,
movq(Address(top, arrayOopDesc::length_offset_in_bytes()), t1); movq(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
// set klass to intArrayKlass // set klass to intArrayKlass
movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr())); movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr()));
// store klass last. concurrent gcs assumes klass length is valid if
// klass field is not null.
store_klass(top, t1); store_klass(top, t1);
// refill the tlab with an eden allocation // refill the tlab with an eden allocation
@ -5003,8 +5007,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Re
jcc(Assembler::notEqual, cas_label); jcc(Assembler::notEqual, cas_label);
// The bias pattern is present in the object's header. Need to check // The bias pattern is present in the object's header. Need to check
// whether the bias owner and the epoch are both still current. // whether the bias owner and the epoch are both still current.
load_klass(tmp_reg, obj_reg); load_prototype_header(tmp_reg, obj_reg);
movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
orq(tmp_reg, r15_thread); orq(tmp_reg, r15_thread);
xorq(tmp_reg, swap_reg); xorq(tmp_reg, swap_reg);
andq(tmp_reg, ~((int) markOopDesc::age_mask_in_place)); andq(tmp_reg, ~((int) markOopDesc::age_mask_in_place));
@ -5078,8 +5081,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Re
// //
// FIXME: due to a lack of registers we currently blow away the age // FIXME: due to a lack of registers we currently blow away the age
// bits in this situation. Should attempt to preserve them. // bits in this situation. Should attempt to preserve them.
load_klass(tmp_reg, obj_reg); load_prototype_header(tmp_reg, obj_reg);
movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
orq(tmp_reg, r15_thread); orq(tmp_reg, r15_thread);
if (os::is_MP()) { if (os::is_MP()) {
lock(); lock();
@ -5109,8 +5111,7 @@ int MacroAssembler::biased_locking_enter(Register lock_reg, Register obj_reg, Re
// //
// FIXME: due to a lack of registers we currently blow away the age // FIXME: due to a lack of registers we currently blow away the age
// bits in this situation. Should attempt to preserve them. // bits in this situation. Should attempt to preserve them.
load_klass(tmp_reg, obj_reg); load_prototype_header(tmp_reg, obj_reg);
movq(tmp_reg, Address(tmp_reg, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
if (os::is_MP()) { if (os::is_MP()) {
lock(); lock();
} }
@ -5154,17 +5155,32 @@ void MacroAssembler::load_klass(Register dst, Register src) {
} }
} }
void MacroAssembler::load_prototype_header(Register dst, Register src) {
if (UseCompressedOops) {
movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
movq(dst, Address(r12_heapbase, dst, Address::times_8, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
} else {
movq(dst, Address(src, oopDesc::klass_offset_in_bytes()));
movq(dst, Address(dst, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
}
}
void MacroAssembler::store_klass(Register dst, Register src) { void MacroAssembler::store_klass(Register dst, Register src) {
if (UseCompressedOops) { if (UseCompressedOops) {
encode_heap_oop_not_null(src); encode_heap_oop_not_null(src);
// zero the entire klass field first as the gap needs to be zeroed too.
movptr(Address(dst, oopDesc::klass_offset_in_bytes()), NULL_WORD);
movl(Address(dst, oopDesc::klass_offset_in_bytes()), src); movl(Address(dst, oopDesc::klass_offset_in_bytes()), src);
} else { } else {
movq(Address(dst, oopDesc::klass_offset_in_bytes()), src); movq(Address(dst, oopDesc::klass_offset_in_bytes()), src);
} }
} }
void MacroAssembler::store_klass_gap(Register dst, Register src) {
if (UseCompressedOops) {
// Store to klass gap in destination
movl(Address(dst, oopDesc::klass_gap_offset_in_bytes()), src);
}
}
void MacroAssembler::load_heap_oop(Register dst, Address src) { void MacroAssembler::load_heap_oop(Register dst, Address src) {
if (UseCompressedOops) { if (UseCompressedOops) {
movl(dst, src); movl(dst, src);
@ -5188,13 +5204,15 @@ void MacroAssembler::store_heap_oop(Address dst, Register src) {
void MacroAssembler::encode_heap_oop(Register r) { void MacroAssembler::encode_heap_oop(Register r) {
assert (UseCompressedOops, "should be compressed"); assert (UseCompressedOops, "should be compressed");
#ifdef ASSERT #ifdef ASSERT
Label ok; if (CheckCompressedOops) {
pushq(rscratch1); // cmpptr trashes rscratch1 Label ok;
cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr())); pushq(rscratch1); // cmpptr trashes rscratch1
jcc(Assembler::equal, ok); cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
stop("MacroAssembler::encode_heap_oop: heap base corrupted?"); jcc(Assembler::equal, ok);
bind(ok); stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
popq(rscratch1); bind(ok);
popq(rscratch1);
}
#endif #endif
verify_oop(r, "broken oop in encode_heap_oop"); verify_oop(r, "broken oop in encode_heap_oop");
testq(r, r); testq(r, r);
@ -5206,11 +5224,13 @@ void MacroAssembler::encode_heap_oop(Register r) {
void MacroAssembler::encode_heap_oop_not_null(Register r) { void MacroAssembler::encode_heap_oop_not_null(Register r) {
assert (UseCompressedOops, "should be compressed"); assert (UseCompressedOops, "should be compressed");
#ifdef ASSERT #ifdef ASSERT
Label ok; if (CheckCompressedOops) {
testq(r, r); Label ok;
jcc(Assembler::notEqual, ok); testq(r, r);
stop("null oop passed to encode_heap_oop_not_null"); jcc(Assembler::notEqual, ok);
bind(ok); stop("null oop passed to encode_heap_oop_not_null");
bind(ok);
}
#endif #endif
verify_oop(r, "broken oop in encode_heap_oop_not_null"); verify_oop(r, "broken oop in encode_heap_oop_not_null");
subq(r, r12_heapbase); subq(r, r12_heapbase);
@ -5220,11 +5240,13 @@ void MacroAssembler::encode_heap_oop_not_null(Register r) {
void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) { void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
assert (UseCompressedOops, "should be compressed"); assert (UseCompressedOops, "should be compressed");
#ifdef ASSERT #ifdef ASSERT
Label ok; if (CheckCompressedOops) {
testq(src, src); Label ok;
jcc(Assembler::notEqual, ok); testq(src, src);
stop("null oop passed to encode_heap_oop_not_null2"); jcc(Assembler::notEqual, ok);
bind(ok); stop("null oop passed to encode_heap_oop_not_null2");
bind(ok);
}
#endif #endif
verify_oop(src, "broken oop in encode_heap_oop_not_null2"); verify_oop(src, "broken oop in encode_heap_oop_not_null2");
if (dst != src) { if (dst != src) {
@ -5237,14 +5259,16 @@ void MacroAssembler::encode_heap_oop_not_null(Register dst, Register src) {
void MacroAssembler::decode_heap_oop(Register r) { void MacroAssembler::decode_heap_oop(Register r) {
assert (UseCompressedOops, "should be compressed"); assert (UseCompressedOops, "should be compressed");
#ifdef ASSERT #ifdef ASSERT
Label ok; if (CheckCompressedOops) {
pushq(rscratch1); Label ok;
cmpptr(r12_heapbase, pushq(rscratch1);
ExternalAddress((address)Universe::heap_base_addr())); cmpptr(r12_heapbase,
jcc(Assembler::equal, ok); ExternalAddress((address)Universe::heap_base_addr()));
stop("MacroAssembler::decode_heap_oop: heap base corrupted?"); jcc(Assembler::equal, ok);
bind(ok); stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
popq(rscratch1); bind(ok);
popq(rscratch1);
}
#endif #endif
Label done; Label done;
@ -5265,6 +5289,7 @@ void MacroAssembler::decode_heap_oop_not_null(Register r) {
assert (UseCompressedOops, "should only be used for compressed headers"); assert (UseCompressedOops, "should only be used for compressed headers");
// Cannot assert, unverified entry point counts instructions (see .ad file) // Cannot assert, unverified entry point counts instructions (see .ad file)
// vtableStubs also counts instructions in pd_code_size_limit. // vtableStubs also counts instructions in pd_code_size_limit.
// Also do not verify_oop as this is called by verify_oop.
assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
leaq(r, Address(r12_heapbase, r, Address::times_8, 0)); leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
} }
@ -5273,10 +5298,24 @@ void MacroAssembler::decode_heap_oop_not_null(Register dst, Register src) {
assert (UseCompressedOops, "should only be used for compressed headers"); assert (UseCompressedOops, "should only be used for compressed headers");
// Cannot assert, unverified entry point counts instructions (see .ad file) // Cannot assert, unverified entry point counts instructions (see .ad file)
// vtableStubs also counts instructions in pd_code_size_limit. // vtableStubs also counts instructions in pd_code_size_limit.
// Also do not verify_oop as this is called by verify_oop.
assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong"); assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
leaq(dst, Address(r12_heapbase, src, Address::times_8, 0)); leaq(dst, Address(r12_heapbase, src, Address::times_8, 0));
} }
void MacroAssembler::set_narrow_oop(Register dst, jobject obj) {
assert(oop_recorder() != NULL, "this assembler needs an OopRecorder");
int oop_index = oop_recorder()->find_index(obj);
RelocationHolder rspec = oop_Relocation::spec(oop_index);
// movl dst,obj
InstructionMark im(this);
int encode = prefix_and_encode(dst->encoding());
emit_byte(0xB8 | encode);
emit_data(oop_index, rspec, narrow_oop_operand);
}
Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) { Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
switch (cond) { switch (cond) {
// Note some conditions are synonyms for others // Note some conditions are synonyms for others

View File

@ -490,7 +490,12 @@ class Assembler : public AbstractAssembler {
imm64_operand = 0, // embedded 64-bit immediate operand imm64_operand = 0, // embedded 64-bit immediate operand
disp32_operand = 1, // embedded 32-bit displacement disp32_operand = 1, // embedded 32-bit displacement
call32_operand = 2, // embedded 32-bit self-relative displacement call32_operand = 2, // embedded 32-bit self-relative displacement
#ifndef AMD64
_WhichOperand_limit = 3 _WhichOperand_limit = 3
#else
narrow_oop_operand = 3, // embedded 32-bit immediate narrow oop
_WhichOperand_limit = 4
#endif
}; };
public: public:
@ -1023,7 +1028,7 @@ class MacroAssembler : public Assembler {
// is needed if the offset is within a certain range (0 <= offset <= // is needed if the offset is within a certain range (0 <= offset <=
// page_size). // page_size).
void null_check(Register reg, int offset = -1); void null_check(Register reg, int offset = -1);
static bool needs_explicit_null_check(int offset); static bool needs_explicit_null_check(intptr_t offset);
// Required platform-specific helpers for Label::patch_instructions. // Required platform-specific helpers for Label::patch_instructions.
// They _shadow_ the declarations in AbstractAssembler, which are undefined. // They _shadow_ the declarations in AbstractAssembler, which are undefined.
@ -1104,6 +1109,9 @@ class MacroAssembler : public Assembler {
// oop manipulations // oop manipulations
void load_klass(Register dst, Register src); void load_klass(Register dst, Register src);
void store_klass(Register dst, Register src); void store_klass(Register dst, Register src);
void store_klass_gap(Register dst, Register src);
void load_prototype_header(Register dst, Register src);
void load_heap_oop(Register dst, Address src); void load_heap_oop(Register dst, Address src);
void store_heap_oop(Address dst, Register src); void store_heap_oop(Address dst, Register src);
@ -1114,6 +1122,8 @@ class MacroAssembler : public Assembler {
void encode_heap_oop_not_null(Register dst, Register src); void encode_heap_oop_not_null(Register dst, Register src);
void decode_heap_oop_not_null(Register dst, Register src); void decode_heap_oop_not_null(Register dst, Register src);
void set_narrow_oop(Register dst, jobject obj);
// Stack frame creation/removal // Stack frame creation/removal
void enter(); void enter();
void leave(); void leave();

View File

@ -233,7 +233,7 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
assert(Rsub_klass != rcx, "rcx holds 2ndary super array length"); assert(Rsub_klass != rcx, "rcx holds 2ndary super array length");
assert(Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr"); assert(Rsub_klass != rdi, "rdi holds 2ndary super array scan ptr");
Label not_subtype, loop; Label not_subtype, not_subtype_pop, loop;
// Profile the not-null value's klass. // Profile the not-null value's klass.
profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, rdi profile_typecheck(rcx, Rsub_klass, rdi); // blows rcx, rdi
@ -272,12 +272,13 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
// and we store values in objArrays always encoded, thus we need to encode value // and we store values in objArrays always encoded, thus we need to encode value
// before repne // before repne
if (UseCompressedOops) { if (UseCompressedOops) {
pushq(rax);
encode_heap_oop(rax); encode_heap_oop(rax);
repne_scanl(); repne_scanl();
// Not equal? // Not equal?
jcc(Assembler::notEqual, not_subtype); jcc(Assembler::notEqual, not_subtype_pop);
// decode heap oop here for movq // restore heap oop here for movq
decode_heap_oop(rax); popq(rax);
} else { } else {
repne_scanq(); repne_scanq();
jcc(Assembler::notEqual, not_subtype); jcc(Assembler::notEqual, not_subtype);
@ -287,9 +288,10 @@ void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
Klass::secondary_super_cache_offset_in_bytes()), rax); Klass::secondary_super_cache_offset_in_bytes()), rax);
jmp(ok_is_subtype); jmp(ok_is_subtype);
bind(not_subtype_pop);
// restore heap oop here for miss
if (UseCompressedOops) popq(rax);
bind(not_subtype); bind(not_subtype);
// decode heap oop here for miss
if (UseCompressedOops) decode_heap_oop(rax);
profile_typecheck_failed(rcx); // blows rcx profile_typecheck_failed(rcx); // blows rcx
} }

View File

@ -30,11 +30,15 @@ void Relocation::pd_set_data_value(address x, intptr_t o) {
#ifdef AMD64 #ifdef AMD64
x += o; x += o;
typedef Assembler::WhichOperand WhichOperand; typedef Assembler::WhichOperand WhichOperand;
WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64, call32 WhichOperand which = (WhichOperand) format(); // that is, disp32 or imm64, call32, narrow oop
assert(which == Assembler::disp32_operand || assert(which == Assembler::disp32_operand ||
which == Assembler::narrow_oop_operand ||
which == Assembler::imm64_operand, "format unpacks ok"); which == Assembler::imm64_operand, "format unpacks ok");
if (which == Assembler::imm64_operand) { if (which == Assembler::imm64_operand) {
*pd_address_in_code() = x; *pd_address_in_code() = x;
} else if (which == Assembler::narrow_oop_operand) {
address disp = Assembler::locate_operand(addr(), which);
*(int32_t*) disp = oopDesc::encode_heap_oop((oop)x);
} else { } else {
// Note: Use runtime_call_type relocations for call32_operand. // Note: Use runtime_call_type relocations for call32_operand.
address ip = addr(); address ip = addr();

View File

@ -29,5 +29,10 @@
offset_unit = 1, offset_unit = 1,
// Encodes Assembler::disp32_operand vs. Assembler::imm32_operand. // Encodes Assembler::disp32_operand vs. Assembler::imm32_operand.
#ifndef AMD64
format_width = 1 format_width = 1
#else
// vs Assembler::narrow_oop_operand.
format_width = 2
#endif
}; };

View File

@ -1920,7 +1920,6 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
int total_strings = 0; int total_strings = 0;
int first_arg_to_pass = 0; int first_arg_to_pass = 0;
int total_c_args = 0; int total_c_args = 0;
int box_offset = java_lang_boxing_object::value_offset_in_bytes();
if( !method->is_static() ) { // Pass in receiver first if( !method->is_static() ) { // Pass in receiver first
in_sig_bt[i++] = T_OBJECT; in_sig_bt[i++] = T_OBJECT;
@ -2131,7 +2130,10 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(
assert(dst.first()->is_stack() && assert(dst.first()->is_stack() &&
(!dst.second()->is_valid() || dst.second()->is_stack()), (!dst.second()->is_valid() || dst.second()->is_stack()),
"value(s) must go into stack slots"); "value(s) must go into stack slots");
if ( out_sig_bt[c_arg] == T_LONG ) {
BasicType bt = out_sig_bt[c_arg];
int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
if ( bt == T_LONG ) {
__ movl(rbx, Address(in_reg, __ movl(rbx, Address(in_reg,
box_offset + VMRegImpl::stack_slot_size)); box_offset + VMRegImpl::stack_slot_size));
__ movl(Address(rsp, reg2offset_out(dst.second())), rbx); __ movl(Address(rsp, reg2offset_out(dst.second())), rbx);

View File

@ -1950,7 +1950,6 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm,
int total_strings = 0; int total_strings = 0;
int first_arg_to_pass = 0; int first_arg_to_pass = 0;
int total_c_args = 0; int total_c_args = 0;
int box_offset = java_lang_boxing_object::value_offset_in_bytes();
// Skip the receiver as dtrace doesn't want to see it // Skip the receiver as dtrace doesn't want to see it
if( !method->is_static() ) { if( !method->is_static() ) {
@ -2197,8 +2196,10 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm,
__ testq(in_reg, in_reg); __ testq(in_reg, in_reg);
__ jcc(Assembler::zero, skipUnbox); __ jcc(Assembler::zero, skipUnbox);
BasicType bt = out_sig_bt[c_arg];
int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
Address src1(in_reg, box_offset); Address src1(in_reg, box_offset);
if ( out_sig_bt[c_arg] == T_LONG ) { if ( bt == T_LONG ) {
__ movq(in_reg, src1); __ movq(in_reg, src1);
__ movq(stack_dst, in_reg); __ movq(stack_dst, in_reg);
assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); assert(out_sig_bt[c_arg+1] == T_VOID, "must be");
@ -2460,8 +2461,10 @@ nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm,
Label skip; Label skip;
__ testq(r, r); __ testq(r, r);
__ jcc(Assembler::equal, skip); __ jcc(Assembler::equal, skip);
BasicType bt = out_sig_bt[c_arg];
int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt);
Address src1(r, box_offset); Address src1(r, box_offset);
if ( out_sig_bt[c_arg] == T_LONG ) { if ( bt == T_LONG ) {
__ movq(r, src1); __ movq(r, src1);
} else { } else {
__ movl(r, src1); __ movl(r, src1);

View File

@ -3163,7 +3163,9 @@ void TemplateTable::_new() {
__ movptr(Address(rax, oopDesc::mark_offset_in_bytes()), __ movptr(Address(rax, oopDesc::mark_offset_in_bytes()),
(intptr_t) markOopDesc::prototype()); // header (address 0x1) (intptr_t) markOopDesc::prototype()); // header (address 0x1)
} }
__ store_klass(rax, rsi); // klass __ xorl(rcx, rcx); // use zero reg to clear memory (shorter code)
__ store_klass_gap(rax, rcx); // zero klass gap for compressed oops
__ store_klass(rax, rsi); // store klass last
__ jmp(done); __ jmp(done);
} }

View File

@ -3806,6 +3806,78 @@ encode %{
masm.bind(DONE_LABEL); masm.bind(DONE_LABEL);
%} %}
enc_class enc_Array_Equals(eDIRegP ary1, eSIRegP ary2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result) %{
Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP;
MacroAssembler masm(&cbuf);
Register ary1Reg = as_Register($ary1$$reg);
Register ary2Reg = as_Register($ary2$$reg);
Register tmp1Reg = as_Register($tmp1$$reg);
Register tmp2Reg = as_Register($tmp2$$reg);
Register resultReg = as_Register($result$$reg);
int length_offset = arrayOopDesc::length_offset_in_bytes();
int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
// Check the input args
masm.cmpl(ary1Reg, ary2Reg);
masm.jcc(Assembler::equal, TRUE_LABEL);
masm.testl(ary1Reg, ary1Reg);
masm.jcc(Assembler::zero, FALSE_LABEL);
masm.testl(ary2Reg, ary2Reg);
masm.jcc(Assembler::zero, FALSE_LABEL);
// Check the lengths
masm.movl(tmp2Reg, Address(ary1Reg, length_offset));
masm.movl(resultReg, Address(ary2Reg, length_offset));
masm.cmpl(tmp2Reg, resultReg);
masm.jcc(Assembler::notEqual, FALSE_LABEL);
masm.testl(resultReg, resultReg);
masm.jcc(Assembler::zero, TRUE_LABEL);
// Get the number of 4 byte vectors to compare
masm.shrl(resultReg, 1);
// Check for odd-length arrays
masm.andl(tmp2Reg, 1);
masm.testl(tmp2Reg, tmp2Reg);
masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
// Compare 2-byte "tail" at end of arrays
masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
masm.cmpl(tmp1Reg, tmp2Reg);
masm.jcc(Assembler::notEqual, FALSE_LABEL);
masm.testl(resultReg, resultReg);
masm.jcc(Assembler::zero, TRUE_LABEL);
// Setup compare loop
masm.bind(COMPARE_LOOP_HDR);
// Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays
masm.leal(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
masm.leal(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
masm.negl(resultReg);
// 4-byte-wide compare loop
masm.bind(COMPARE_LOOP);
masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0));
masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0));
masm.cmpl(ary1Reg, ary2Reg);
masm.jcc(Assembler::notEqual, FALSE_LABEL);
masm.increment(resultReg);
masm.jcc(Assembler::notZero, COMPARE_LOOP);
masm.bind(TRUE_LABEL);
masm.movl(resultReg, 1); // return true
masm.jmp(DONE_LABEL);
masm.bind(FALSE_LABEL);
masm.xorl(resultReg, resultReg); // return false
// That's it
masm.bind(DONE_LABEL);
%}
enc_class enc_pop_rdx() %{ enc_class enc_pop_rdx() %{
emit_opcode(cbuf,0x5A); emit_opcode(cbuf,0x5A);
%} %}
@ -11565,6 +11637,17 @@ instruct string_compare(eDIRegP str1, eSIRegP str2, eAXRegI tmp1, eBXRegI tmp2,
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
%} %}
// fast array equals
instruct array_equals(eDIRegP ary1, eSIRegP ary2, eAXRegI tmp1, eBXRegI tmp2, eCXRegI result, eFlagsReg cr) %{
match(Set result (AryEq ary1 ary2));
effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr);
//ins_cost(300);
format %{ "Array Equals $ary1,$ary2 -> $result // KILL EAX, EBX" %}
ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) );
ins_pipe( pipe_slow );
%}
//----------Control Flow Instructions------------------------------------------ //----------Control Flow Instructions------------------------------------------
// Signed compare Instructions // Signed compare Instructions
instruct compI_eReg(eFlagsReg cr, eRegI op1, eRegI op2) %{ instruct compI_eReg(eFlagsReg cr, eRegI op1, eRegI op2) %{

View File

@ -3808,6 +3808,78 @@ encode %{
masm.bind(DONE_LABEL); masm.bind(DONE_LABEL);
%} %}
enc_class enc_Array_Equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1, rbx_RegI tmp2, rcx_RegI result) %{
Label TRUE_LABEL, FALSE_LABEL, DONE_LABEL, COMPARE_LOOP_HDR, COMPARE_LOOP;
MacroAssembler masm(&cbuf);
Register ary1Reg = as_Register($ary1$$reg);
Register ary2Reg = as_Register($ary2$$reg);
Register tmp1Reg = as_Register($tmp1$$reg);
Register tmp2Reg = as_Register($tmp2$$reg);
Register resultReg = as_Register($result$$reg);
int length_offset = arrayOopDesc::length_offset_in_bytes();
int base_offset = arrayOopDesc::base_offset_in_bytes(T_CHAR);
// Check the input args
masm.cmpq(ary1Reg, ary2Reg);
masm.jcc(Assembler::equal, TRUE_LABEL);
masm.testq(ary1Reg, ary1Reg);
masm.jcc(Assembler::zero, FALSE_LABEL);
masm.testq(ary2Reg, ary2Reg);
masm.jcc(Assembler::zero, FALSE_LABEL);
// Check the lengths
masm.movl(tmp2Reg, Address(ary1Reg, length_offset));
masm.movl(resultReg, Address(ary2Reg, length_offset));
masm.cmpl(tmp2Reg, resultReg);
masm.jcc(Assembler::notEqual, FALSE_LABEL);
masm.testl(resultReg, resultReg);
masm.jcc(Assembler::zero, TRUE_LABEL);
// Get the number of 4 byte vectors to compare
masm.shrl(resultReg, 1);
// Check for odd-length arrays
masm.andl(tmp2Reg, 1);
masm.testl(tmp2Reg, tmp2Reg);
masm.jcc(Assembler::zero, COMPARE_LOOP_HDR);
// Compare 2-byte "tail" at end of arrays
masm.load_unsigned_word(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
masm.load_unsigned_word(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
masm.cmpl(tmp1Reg, tmp2Reg);
masm.jcc(Assembler::notEqual, FALSE_LABEL);
masm.testl(resultReg, resultReg);
masm.jcc(Assembler::zero, TRUE_LABEL);
// Setup compare loop
masm.bind(COMPARE_LOOP_HDR);
// Shift tmp1Reg and tmp2Reg to the last 4-byte boundary of the arrays
masm.leaq(tmp1Reg, Address(ary1Reg, resultReg, Address::times_4, base_offset));
masm.leaq(tmp2Reg, Address(ary2Reg, resultReg, Address::times_4, base_offset));
masm.negq(resultReg);
// 4-byte-wide compare loop
masm.bind(COMPARE_LOOP);
masm.movl(ary1Reg, Address(tmp1Reg, resultReg, Address::times_4, 0));
masm.movl(ary2Reg, Address(tmp2Reg, resultReg, Address::times_4, 0));
masm.cmpl(ary1Reg, ary2Reg);
masm.jcc(Assembler::notEqual, FALSE_LABEL);
masm.incrementq(resultReg);
masm.jcc(Assembler::notZero, COMPARE_LOOP);
masm.bind(TRUE_LABEL);
masm.movl(resultReg, 1); // return true
masm.jmp(DONE_LABEL);
masm.bind(FALSE_LABEL);
masm.xorl(resultReg, resultReg); // return false
// That's it
masm.bind(DONE_LABEL);
%}
enc_class enc_rethrow() enc_class enc_rethrow()
%{ %{
cbuf.set_inst_mark(); cbuf.set_inst_mark();
@ -5202,15 +5274,15 @@ operand indIndexScaleOffset(any_RegP reg, immL32 off, rRegL lreg, immI2 scale)
%} %}
%} %}
// Indirect Memory Times Scale Plus Index Register Plus Offset Operand // Indirect Narrow Oop Plus Offset Operand
operand indIndexScaleOffsetComp(rRegN src, immL32 off, r12RegL base) %{ operand indNarrowOopOffset(rRegN src, immL32 off) %{
constraint(ALLOC_IN_RC(ptr_reg)); constraint(ALLOC_IN_RC(ptr_reg));
match(AddP (DecodeN src base) off); match(AddP (DecodeN src) off);
op_cost(10); op_cost(10);
format %{"[$base + $src << 3 + $off] (compressed)" %} format %{"[R12 + $src << 3 + $off] (compressed oop addressing)" %}
interface(MEMORY_INTER) %{ interface(MEMORY_INTER) %{
base($base); base(0xc); // R12
index($src); index($src);
scale(0x3); scale(0x3);
disp($off); disp($off);
@ -5365,7 +5437,7 @@ operand cmpOpU()
opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex, opclass memory(indirect, indOffset8, indOffset32, indIndexOffset, indIndex,
indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset, indIndexScale, indIndexScaleOffset, indPosIndexScaleOffset,
indIndexScaleOffsetComp); indNarrowOopOffset);
//----------PIPELINE----------------------------------------------------------- //----------PIPELINE-----------------------------------------------------------
// Rules which define the behavior of the target architectures pipeline. // Rules which define the behavior of the target architectures pipeline.
@ -6044,10 +6116,9 @@ instruct loadP(rRegP dst, memory mem)
%} %}
// Load Compressed Pointer // Load Compressed Pointer
instruct loadN(rRegN dst, memory mem, rFlagsReg cr) instruct loadN(rRegN dst, memory mem)
%{ %{
match(Set dst (LoadN mem)); match(Set dst (LoadN mem));
effect(KILL cr);
ins_cost(125); // XXX ins_cost(125); // XXX
format %{ "movl $dst, $mem\t# compressed ptr" %} format %{ "movl $dst, $mem\t# compressed ptr" %}
@ -6064,7 +6135,6 @@ instruct loadN(rRegN dst, memory mem, rFlagsReg cr)
instruct loadKlass(rRegP dst, memory mem) instruct loadKlass(rRegP dst, memory mem)
%{ %{
match(Set dst (LoadKlass mem)); match(Set dst (LoadKlass mem));
predicate(!n->in(MemNode::Address)->bottom_type()->is_narrow());
ins_cost(125); // XXX ins_cost(125); // XXX
format %{ "movq $dst, $mem\t# class" %} format %{ "movq $dst, $mem\t# class" %}
@ -6073,22 +6143,17 @@ instruct loadKlass(rRegP dst, memory mem)
ins_pipe(ialu_reg_mem); // XXX ins_pipe(ialu_reg_mem); // XXX
%} %}
// Load Klass Pointer // Load narrow Klass Pointer
instruct loadKlassComp(rRegP dst, memory mem) instruct loadNKlass(rRegN dst, memory mem)
%{ %{
match(Set dst (LoadKlass mem)); match(Set dst (LoadNKlass mem));
predicate(n->in(MemNode::Address)->bottom_type()->is_narrow());
ins_cost(125); // XXX ins_cost(125); // XXX
format %{ "movl $dst, $mem\t# compressed class\n\t" format %{ "movl $dst, $mem\t# compressed klass ptr" %}
"decode_heap_oop $dst,$dst" %}
ins_encode %{ ins_encode %{
Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
Register dst = as_Register($dst$$reg); Register dst = as_Register($dst$$reg);
__ movl(dst, addr); __ movl(dst, addr);
// klass is never null in the header but this is generated for all
// klass loads not just the _klass field in the header.
__ decode_heap_oop(dst);
%} %}
ins_pipe(ialu_reg_mem); // XXX ins_pipe(ialu_reg_mem); // XXX
%} %}
@ -6362,16 +6427,14 @@ instruct loadConN(rRegN dst, immN src) %{
match(Set dst src); match(Set dst src);
ins_cost(125); ins_cost(125);
format %{ "movq $dst, $src\t# compressed ptr\n\t" format %{ "movl $dst, $src\t# compressed ptr" %}
"encode_heap_oop_not_null $dst,$dst" %}
ins_encode %{ ins_encode %{
address con = (address)$src$$constant; address con = (address)$src$$constant;
Register dst = $dst$$Register; Register dst = $dst$$Register;
if (con == NULL) { if (con == NULL) {
ShouldNotReachHere(); ShouldNotReachHere();
} else { } else {
__ movoop(dst, (jobject)$src$$constant); __ set_narrow_oop(dst, (jobject)$src$$constant);
__ encode_heap_oop_not_null(dst);
} }
%} %}
ins_pipe(ialu_reg_fat); // XXX ins_pipe(ialu_reg_fat); // XXX
@ -6633,13 +6696,12 @@ instruct storeImmP(memory mem, immP31 src)
%} %}
// Store Compressed Pointer // Store Compressed Pointer
instruct storeN(memory mem, rRegN src, rFlagsReg cr) instruct storeN(memory mem, rRegN src)
%{ %{
match(Set mem (StoreN mem src)); match(Set mem (StoreN mem src));
effect(KILL cr);
ins_cost(125); // XXX ins_cost(125); // XXX
format %{ "movl $mem, $src\t# ptr" %} format %{ "movl $mem, $src\t# compressed ptr" %}
ins_encode %{ ins_encode %{
Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp); Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
Register src = as_Register($src$$reg); Register src = as_Register($src$$reg);
@ -7027,7 +7089,8 @@ instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
%} %}
instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{ instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull); predicate(n->bottom_type()->is_oopptr()->ptr() != TypePtr::NotNull &&
n->bottom_type()->is_oopptr()->ptr() != TypePtr::Constant);
match(Set dst (DecodeN src)); match(Set dst (DecodeN src));
effect(KILL cr); effect(KILL cr);
format %{ "decode_heap_oop $dst,$src" %} format %{ "decode_heap_oop $dst,$src" %}
@ -7043,7 +7106,8 @@ instruct decodeHeapOop(rRegP dst, rRegN src, rFlagsReg cr) %{
%} %}
instruct decodeHeapOop_not_null(rRegP dst, rRegN src) %{ instruct decodeHeapOop_not_null(rRegP dst, rRegN src) %{
predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull); predicate(n->bottom_type()->is_oopptr()->ptr() == TypePtr::NotNull ||
n->bottom_type()->is_oopptr()->ptr() == TypePtr::Constant);
match(Set dst (DecodeN src)); match(Set dst (DecodeN src));
format %{ "decode_heap_oop_not_null $dst,$src" %} format %{ "decode_heap_oop_not_null $dst,$src" %}
ins_encode %{ ins_encode %{
@ -7142,6 +7206,30 @@ instruct cmovI_memU(cmpOpU cop, rFlagsRegU cr, rRegI dst, memory src)
ins_pipe(pipe_cmov_mem); ins_pipe(pipe_cmov_mem);
%} %}
// Conditional move
instruct cmovN_reg(rRegN dst, rRegN src, rFlagsReg cr, cmpOp cop)
%{
match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
ins_cost(200); // XXX
format %{ "cmovl$cop $dst, $src\t# signed, compressed ptr" %}
opcode(0x0F, 0x40);
ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
ins_pipe(pipe_cmov_reg);
%}
// Conditional move
instruct cmovN_regU(rRegN dst, rRegN src, rFlagsRegU cr, cmpOpU cop)
%{
match(Set dst (CMoveN (Binary cop cr) (Binary dst src)));
ins_cost(200); // XXX
format %{ "cmovl$cop $dst, $src\t# unsigned, compressed ptr" %}
opcode(0x0F, 0x40);
ins_encode(REX_reg_reg(dst, src), enc_cmov(cop), reg_reg(dst, src));
ins_pipe(pipe_cmov_reg);
%}
// Conditional move // Conditional move
instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop) instruct cmovP_reg(rRegP dst, rRegP src, rFlagsReg cr, cmpOp cop)
%{ %{
@ -10862,6 +10950,18 @@ instruct string_compare(rdi_RegP str1, rsi_RegP str2, rax_RegI tmp1,
ins_pipe( pipe_slow ); ins_pipe( pipe_slow );
%} %}
// fast array equals
instruct array_equals(rdi_RegP ary1, rsi_RegP ary2, rax_RegI tmp1,
rbx_RegI tmp2, rcx_RegI result, rFlagsReg cr) %{
match(Set result (AryEq ary1 ary2));
effect(USE_KILL ary1, USE_KILL ary2, KILL tmp1, KILL tmp2, KILL cr);
//ins_cost(300);
format %{ "Array Equals $ary1,$ary2 -> $result // KILL RAX, RBX" %}
ins_encode( enc_Array_Equals(ary1, ary2, tmp1, tmp2, result) );
ins_pipe( pipe_slow );
%}
//----------Control Flow Instructions------------------------------------------ //----------Control Flow Instructions------------------------------------------
// Signed compare Instructions // Signed compare Instructions
@ -11055,14 +11155,50 @@ instruct testP_reg_mem(rFlagsReg cr, memory op, immP0 zero)
ins_pipe(ialu_cr_reg_imm); ins_pipe(ialu_cr_reg_imm);
%} %}
instruct compN_rReg(rFlagsRegU cr, rRegN op1, rRegN op2)
%{
match(Set cr (CmpN op1 op2));
format %{ "cmpl $op1, $op2\t# compressed ptr" %}
ins_encode %{ __ cmpl(as_Register($op1$$reg), as_Register($op2$$reg)); %}
ins_pipe(ialu_cr_reg_reg);
%}
instruct compN_rReg_mem(rFlagsRegU cr, rRegN src, memory mem)
%{
match(Set cr (CmpN src (LoadN mem)));
ins_cost(500); // XXX
format %{ "cmpl $src, mem\t# compressed ptr" %}
ins_encode %{
Address adr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
__ cmpl(as_Register($src$$reg), adr);
%}
ins_pipe(ialu_cr_reg_mem);
%}
instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{ instruct testN_reg(rFlagsReg cr, rRegN src, immN0 zero) %{
match(Set cr (CmpN src zero)); match(Set cr (CmpN src zero));
format %{ "testl $src, $src" %} format %{ "testl $src, $src\t# compressed ptr" %}
ins_encode %{ __ testl($src$$Register, $src$$Register); %} ins_encode %{ __ testl($src$$Register, $src$$Register); %}
ins_pipe(ialu_cr_reg_imm); ins_pipe(ialu_cr_reg_imm);
%} %}
instruct testN_reg_mem(rFlagsReg cr, memory mem, immN0 zero)
%{
match(Set cr (CmpN (LoadN mem) zero));
ins_cost(500); // XXX
format %{ "testl $mem, 0xffffffff\t# compressed ptr" %}
ins_encode %{
Address addr = build_address($mem$$base, $mem$$index, $mem$$scale, $mem$$disp);
__ cmpl(addr, (int)0xFFFFFFFF);
%}
ins_pipe(ialu_cr_reg_mem);
%}
// Yanked all unsigned pointer compare operations. // Yanked all unsigned pointer compare operations.
// Pointer compares are done with CmpP which is already unsigned. // Pointer compares are done with CmpP which is already unsigned.

View File

@ -40,7 +40,7 @@ void MacroAssembler::get_thread(Register thread) {
movptr(thread, tls); movptr(thread, tls);
} }
bool MacroAssembler::needs_explicit_null_check(int offset) { bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
// Linux kernel guarantees that the first page is always unmapped. Don't // Linux kernel guarantees that the first page is always unmapped. Don't
// assume anything more than that. // assume anything more than that.
bool offset_in_first_page = 0 <= offset && offset < os::vm_page_size(); bool offset_in_first_page = 0 <= offset && offset < os::vm_page_size();

View File

@ -66,8 +66,21 @@ void MacroAssembler::get_thread(Register thread) {
} }
} }
// NOTE: since the linux kernel resides at the low end of bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
// user address space, no null pointer check is needed. // Exception handler checks the nmethod's implicit null checks table
bool MacroAssembler::needs_explicit_null_check(int offset) { // only when this method returns false.
return offset < 0 || offset >= 0x100000; if (UseCompressedOops) {
// The first page after heap_base is unmapped and
// the 'offset' is equal to [heap_base + offset] for
// narrow oop implicit null checks.
uintptr_t heap_base = (uintptr_t)Universe::heap_base();
if ((uintptr_t)offset >= heap_base) {
// Normalize offset for the next check.
offset = (intptr_t)(pointer_delta((void*)offset, (void*)heap_base, 1));
}
}
// Linux kernel guarantees that the first page is always unmapped. Don't
// assume anything more than that.
bool offset_in_first_page = 0 <= offset && offset < os::vm_page_size();
return !offset_in_first_page;
} }

View File

@ -80,7 +80,7 @@ void MacroAssembler::get_thread(Register thread) {
popl(thread); popl(thread);
} }
bool MacroAssembler::needs_explicit_null_check(int offset) { bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
// Identical to Sparc/Solaris code // Identical to Sparc/Solaris code
bool offset_in_first_page = 0 <= offset && offset < os::vm_page_size(); bool offset_in_first_page = 0 <= offset && offset < os::vm_page_size();
return !offset_in_first_page; return !offset_in_first_page;

View File

@ -86,8 +86,21 @@ void MacroAssembler::get_thread(Register thread) {
} }
} }
bool MacroAssembler::needs_explicit_null_check(int offset) { bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
// Identical to Sparc/Solaris code // Identical to Sparc/Solaris code
// Exception handler checks the nmethod's implicit null checks table
// only when this method returns false.
if (UseCompressedOops) {
// The first page after heap_base is unmapped and
// the 'offset' is equal to [heap_base + offset] for
// narrow oop implicit null checks.
uintptr_t heap_base = (uintptr_t)Universe::heap_base();
if ((uintptr_t)offset >= heap_base) {
// Normalize offset for the next check.
offset = (intptr_t)(pointer_delta((void*)offset, (void*)heap_base, 1));
}
}
bool offset_in_first_page = 0 <= offset && offset < os::vm_page_size(); bool offset_in_first_page = 0 <= offset && offset < os::vm_page_size();
return !offset_in_first_page; return !offset_in_first_page;
} }

View File

@ -59,6 +59,6 @@ void MacroAssembler::get_thread(Register thread) {
movl(thread, Address(thread, ThreadLocalStorage::get_thread_ptr_offset())); movl(thread, Address(thread, ThreadLocalStorage::get_thread_ptr_offset()));
} }
bool MacroAssembler::needs_explicit_null_check(int offset) { bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
return offset < 0 || (int)os::vm_page_size() <= offset; return offset < 0 || (int)os::vm_page_size() <= offset;
} }

View File

@ -66,6 +66,18 @@ void MacroAssembler::get_thread(Register thread) {
} }
} }
bool MacroAssembler::needs_explicit_null_check(int offset) { bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
return offset < 0 || (int)os::vm_page_size() <= offset; // Exception handler checks the nmethod's implicit null checks table
// only when this method returns false.
if (UseCompressedOops) {
// The first page after heap_base is unmapped and
// the 'offset' is equal to [heap_base + offset] for
// narrow oop implicit null checks.
uintptr_t heap_base = (uintptr_t)Universe::heap_base();
if ((uintptr_t)offset >= heap_base) {
// Normalize offset for the next check.
offset = (intptr_t)(pointer_delta((void*)offset, (void*)heap_base, 1));
}
}
return offset < 0 || os::vm_page_size() <= offset;
} }

View File

@ -252,6 +252,7 @@ Form::DataType Form::is_load_from_memory(const char *opType) const {
if( strcmp(opType,"LoadF")==0 ) return Form::idealF; if( strcmp(opType,"LoadF")==0 ) return Form::idealF;
if( strcmp(opType,"LoadI")==0 ) return Form::idealI; if( strcmp(opType,"LoadI")==0 ) return Form::idealI;
if( strcmp(opType,"LoadKlass")==0 ) return Form::idealP; if( strcmp(opType,"LoadKlass")==0 ) return Form::idealP;
if( strcmp(opType,"LoadNKlass")==0 ) return Form::idealN;
if( strcmp(opType,"LoadL")==0 ) return Form::idealL; if( strcmp(opType,"LoadL")==0 ) return Form::idealL;
if( strcmp(opType,"LoadL_unaligned")==0 ) return Form::idealL; if( strcmp(opType,"LoadL_unaligned")==0 ) return Form::idealL;
if( strcmp(opType,"LoadPLocked")==0 ) return Form::idealP; if( strcmp(opType,"LoadPLocked")==0 ) return Form::idealP;

View File

@ -3313,7 +3313,7 @@ int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
"Store8B","Store4B","Store8C","Store4C","Store2C", "Store8B","Store4B","Store8C","Store4C","Store2C",
"Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" , "Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
"Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S", "Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
"LoadRange", "LoadKlass", "LoadL_unaligned", "LoadD_unaligned", "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
"LoadPLocked", "LoadLLocked", "LoadPLocked", "LoadLLocked",
"StorePConditional", "StoreLConditional", "StorePConditional", "StoreLConditional",
"CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN", "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",

View File

@ -218,6 +218,13 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod*
ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder); ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
ciInstanceKlass* actual_recv = callee_holder; ciInstanceKlass* actual_recv = callee_holder;
// some methods are obviously bindable without any type checks so
// convert them directly to an invokespecial.
if (target->is_loaded() && !target->is_abstract() &&
target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) {
code = Bytecodes::_invokespecial;
}
// compute size of arguments // compute size of arguments
int arg_size = target->arg_size(); int arg_size = target->arg_size();
if (!target->is_loaded() && code == Bytecodes::_invokestatic) { if (!target->is_loaded() && code == Bytecodes::_invokestatic) {

View File

@ -392,12 +392,12 @@ int ciInstanceKlass::compute_nonstatic_fields() {
assert(!is_java_lang_Object(), "bootstrap OK"); assert(!is_java_lang_Object(), "bootstrap OK");
// Size in bytes of my fields, including inherited fields. // Size in bytes of my fields, including inherited fields.
int fsize = nonstatic_field_size() * wordSize; int fsize = nonstatic_field_size() * heapOopSize;
ciInstanceKlass* super = this->super(); ciInstanceKlass* super = this->super();
GrowableArray<ciField*>* super_fields = NULL; GrowableArray<ciField*>* super_fields = NULL;
if (super != NULL && super->has_nonstatic_fields()) { if (super != NULL && super->has_nonstatic_fields()) {
int super_fsize = super->nonstatic_field_size() * wordSize; int super_fsize = super->nonstatic_field_size() * heapOopSize;
int super_flen = super->nof_nonstatic_fields(); int super_flen = super->nof_nonstatic_fields();
super_fields = super->_nonstatic_fields; super_fields = super->_nonstatic_fields;
assert(super_flen == 0 || super_fields != NULL, "first get nof_fields"); assert(super_flen == 0 || super_fields != NULL, "first get nof_fields");
@ -438,7 +438,7 @@ int ciInstanceKlass::compute_nonstatic_fields() {
// This is a minor inefficiency classFileParser.cpp. // This is a minor inefficiency classFileParser.cpp.
last_offset = offset + size; last_offset = offset + size;
} }
assert(last_offset <= (int)sizeof(oopDesc) + fsize, "no overflow"); assert(last_offset <= (int)instanceOopDesc::base_offset_in_bytes() + fsize, "no overflow");
#endif #endif
_nonstatic_fields = fields; _nonstatic_fields = fields;

View File

@ -878,7 +878,7 @@ int ciMethod::instructions_size() {
(TieredCompilation && code->compiler() != NULL && code->compiler()->is_c1())) { (TieredCompilation && code->compiler() != NULL && code->compiler()->is_c1())) {
return 0; return 0;
} }
return code->code_size(); return code->code_end() - code->verified_entry_point();
) )
} }

View File

@ -44,6 +44,7 @@
// Used for backward compatibility reasons: // Used for backward compatibility reasons:
// - to check for javac bug fixes that happened after 1.5 // - to check for javac bug fixes that happened after 1.5
// - also used as the max version when running in jdk6
#define JAVA_6_VERSION 50 #define JAVA_6_VERSION 50
@ -2664,8 +2665,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
fac.static_byte_count ), wordSize ); fac.static_byte_count ), wordSize );
static_field_size = (next_static_type_offset - static_field_size = (next_static_type_offset -
next_static_oop_offset) / wordSize; next_static_oop_offset) / wordSize;
first_nonstatic_field_offset = (instanceOopDesc::header_size() + first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
nonstatic_field_size) * wordSize; nonstatic_field_size * heapOopSize;
next_nonstatic_field_offset = first_nonstatic_field_offset; next_nonstatic_field_offset = first_nonstatic_field_offset;
// Add fake fields for java.lang.Class instances (also see below) // Add fake fields for java.lang.Class instances (also see below)
@ -2734,9 +2735,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
next_nonstatic_byte_offset = next_nonstatic_short_offset + next_nonstatic_byte_offset = next_nonstatic_short_offset +
(nonstatic_short_count * BytesPerShort); (nonstatic_short_count * BytesPerShort);
next_nonstatic_type_offset = align_size_up((next_nonstatic_byte_offset + next_nonstatic_type_offset = align_size_up((next_nonstatic_byte_offset +
nonstatic_byte_count ), wordSize ); nonstatic_byte_count ), heapOopSize );
orig_nonstatic_field_size = nonstatic_field_size + orig_nonstatic_field_size = nonstatic_field_size +
((next_nonstatic_type_offset - first_nonstatic_field_offset)/wordSize); ((next_nonstatic_type_offset - first_nonstatic_field_offset)/heapOopSize);
} }
#endif #endif
bool compact_fields = CompactFields; bool compact_fields = CompactFields;
@ -2791,18 +2792,8 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
int nonstatic_short_space_offset; int nonstatic_short_space_offset;
int nonstatic_byte_space_offset; int nonstatic_byte_space_offset;
bool compact_into_header = (UseCompressedOops && if( nonstatic_double_count > 0 ) {
allocation_style == 1 && compact_fields && int offset = next_nonstatic_double_offset;
!super_has_nonstatic_fields);
if( compact_into_header || nonstatic_double_count > 0 ) {
int offset;
// Pack something in with the header if no super klass has done so.
if (compact_into_header) {
offset = oopDesc::klass_gap_offset_in_bytes();
} else {
offset = next_nonstatic_double_offset;
}
next_nonstatic_double_offset = align_size_up(offset, BytesPerLong); next_nonstatic_double_offset = align_size_up(offset, BytesPerLong);
if( compact_fields && offset != next_nonstatic_double_offset ) { if( compact_fields && offset != next_nonstatic_double_offset ) {
// Allocate available fields into the gap before double field. // Allocate available fields into the gap before double field.
@ -2830,8 +2821,7 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
} }
// Allocate oop field in the gap if there are no other fields for that. // Allocate oop field in the gap if there are no other fields for that.
nonstatic_oop_space_offset = offset; nonstatic_oop_space_offset = offset;
if(!compact_into_header && length >= heapOopSize && if( length >= heapOopSize && nonstatic_oop_count > 0 &&
nonstatic_oop_count > 0 &&
allocation_style != 0 ) { // when oop fields not first allocation_style != 0 ) { // when oop fields not first
nonstatic_oop_count -= 1; nonstatic_oop_count -= 1;
nonstatic_oop_space_count = 1; // Only one will fit nonstatic_oop_space_count = 1; // Only one will fit
@ -2854,14 +2844,13 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
} else { // allocation_style == 1 } else { // allocation_style == 1
next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count; next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
if( nonstatic_oop_count > 0 ) { if( nonstatic_oop_count > 0 ) {
notaligned_offset = next_nonstatic_oop_offset;
next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize); next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize);
} }
notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize); notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize);
} }
next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize ); next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize );
nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset
- first_nonstatic_field_offset)/wordSize); - first_nonstatic_field_offset)/heapOopSize);
// Iterate over fields again and compute correct offsets. // Iterate over fields again and compute correct offsets.
// The field allocation type was temporarily stored in the offset slot. // The field allocation type was temporarily stored in the offset slot.
@ -2962,9 +2951,10 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
// Size of instances // Size of instances
int instance_size; int instance_size;
next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize );
instance_size = align_object_size(next_nonstatic_type_offset / wordSize); instance_size = align_object_size(next_nonstatic_type_offset / wordSize);
assert(instance_size == align_object_size(instanceOopDesc::header_size() + nonstatic_field_size), "consistent layout helper value"); assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value");
// Size of non-static oop map blocks (in words) allocated at end of klass // Size of non-static oop map blocks (in words) allocated at end of klass
int nonstatic_oop_map_size = compute_oop_map_size(super_klass, nonstatic_oop_map_count, first_nonstatic_oop_offset); int nonstatic_oop_map_size = compute_oop_map_size(super_klass, nonstatic_oop_map_count, first_nonstatic_oop_offset);
@ -3122,13 +3112,15 @@ instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
#ifndef PRODUCT #ifndef PRODUCT
if( PrintCompactFieldsSavings ) { if( PrintCompactFieldsSavings ) {
if( nonstatic_field_size < orig_nonstatic_field_size ) { if( nonstatic_field_size < orig_nonstatic_field_size ) {
tty->print("[Saved %d of %3d words in %s]\n", tty->print("[Saved %d of %d bytes in %s]\n",
orig_nonstatic_field_size - nonstatic_field_size, (orig_nonstatic_field_size - nonstatic_field_size)*heapOopSize,
orig_nonstatic_field_size, this_klass->external_name()); orig_nonstatic_field_size*heapOopSize,
this_klass->external_name());
} else if( nonstatic_field_size > orig_nonstatic_field_size ) { } else if( nonstatic_field_size > orig_nonstatic_field_size ) {
tty->print("[Wasted %d over %3d words in %s]\n", tty->print("[Wasted %d over %d bytes in %s]\n",
nonstatic_field_size - orig_nonstatic_field_size, (nonstatic_field_size - orig_nonstatic_field_size)*heapOopSize,
orig_nonstatic_field_size, this_klass->external_name()); orig_nonstatic_field_size*heapOopSize,
this_klass->external_name());
} }
} }
#endif #endif
@ -3516,9 +3508,11 @@ bool ClassFileParser::has_illegal_visibility(jint flags) {
} }
bool ClassFileParser::is_supported_version(u2 major, u2 minor) { bool ClassFileParser::is_supported_version(u2 major, u2 minor) {
u2 max_version = JDK_Version::is_gte_jdk17x_version() ?
JAVA_MAX_SUPPORTED_VERSION : JAVA_6_VERSION;
return (major >= JAVA_MIN_SUPPORTED_VERSION) && return (major >= JAVA_MIN_SUPPORTED_VERSION) &&
(major <= JAVA_MAX_SUPPORTED_VERSION) && (major <= max_version) &&
((major != JAVA_MAX_SUPPORTED_VERSION) || ((major != max_version) ||
(minor <= JAVA_MAX_SUPPORTED_MINOR_VERSION)); (minor <= JAVA_MAX_SUPPORTED_MINOR_VERSION));
} }

View File

@ -1872,7 +1872,7 @@ oop java_lang_boxing_object::create(BasicType type, jvalue* value, TRAPS) {
box->float_field_put(value_offset, value->f); box->float_field_put(value_offset, value->f);
break; break;
case T_DOUBLE: case T_DOUBLE:
box->double_field_put(value_offset, value->d); box->double_field_put(long_value_offset, value->d);
break; break;
case T_BYTE: case T_BYTE:
box->byte_field_put(value_offset, value->b); box->byte_field_put(value_offset, value->b);
@ -1884,7 +1884,7 @@ oop java_lang_boxing_object::create(BasicType type, jvalue* value, TRAPS) {
box->int_field_put(value_offset, value->i); box->int_field_put(value_offset, value->i);
break; break;
case T_LONG: case T_LONG:
box->long_field_put(value_offset, value->j); box->long_field_put(long_value_offset, value->j);
break; break;
default: default:
return NULL; return NULL;
@ -1915,7 +1915,7 @@ BasicType java_lang_boxing_object::get_value(oop box, jvalue* value) {
value->f = box->float_field(value_offset); value->f = box->float_field(value_offset);
break; break;
case T_DOUBLE: case T_DOUBLE:
value->d = box->double_field(value_offset); value->d = box->double_field(long_value_offset);
break; break;
case T_BYTE: case T_BYTE:
value->b = box->byte_field(value_offset); value->b = box->byte_field(value_offset);
@ -1927,7 +1927,7 @@ BasicType java_lang_boxing_object::get_value(oop box, jvalue* value) {
value->i = box->int_field(value_offset); value->i = box->int_field(value_offset);
break; break;
case T_LONG: case T_LONG:
value->j = box->long_field(value_offset); value->j = box->long_field(long_value_offset);
break; break;
default: default:
return T_ILLEGAL; return T_ILLEGAL;
@ -1949,7 +1949,7 @@ BasicType java_lang_boxing_object::set_value(oop box, jvalue* value) {
box->float_field_put(value_offset, value->f); box->float_field_put(value_offset, value->f);
break; break;
case T_DOUBLE: case T_DOUBLE:
box->double_field_put(value_offset, value->d); box->double_field_put(long_value_offset, value->d);
break; break;
case T_BYTE: case T_BYTE:
box->byte_field_put(value_offset, value->b); box->byte_field_put(value_offset, value->b);
@ -1961,7 +1961,7 @@ BasicType java_lang_boxing_object::set_value(oop box, jvalue* value) {
box->int_field_put(value_offset, value->i); box->int_field_put(value_offset, value->i);
break; break;
case T_LONG: case T_LONG:
box->long_field_put(value_offset, value->j); box->long_field_put(long_value_offset, value->j);
break; break;
default: default:
return T_ILLEGAL; return T_ILLEGAL;
@ -2163,6 +2163,7 @@ int java_lang_reflect_Field::modifiers_offset;
int java_lang_reflect_Field::signature_offset; int java_lang_reflect_Field::signature_offset;
int java_lang_reflect_Field::annotations_offset; int java_lang_reflect_Field::annotations_offset;
int java_lang_boxing_object::value_offset; int java_lang_boxing_object::value_offset;
int java_lang_boxing_object::long_value_offset;
int java_lang_ref_Reference::referent_offset; int java_lang_ref_Reference::referent_offset;
int java_lang_ref_Reference::queue_offset; int java_lang_ref_Reference::queue_offset;
int java_lang_ref_Reference::next_offset; int java_lang_ref_Reference::next_offset;
@ -2282,10 +2283,7 @@ oop java_util_concurrent_locks_AbstractOwnableSynchronizer::get_owner_threadObj(
// are not available to determine the offset_of_static_fields. // are not available to determine the offset_of_static_fields.
void JavaClasses::compute_hard_coded_offsets() { void JavaClasses::compute_hard_coded_offsets() {
const int x = heapOopSize; const int x = heapOopSize;
// Objects don't get allocated in the gap in the header with compressed oops const int header = instanceOopDesc::base_offset_in_bytes();
// for these special classes because hard coded offsets can't be conditional
// so base_offset_in_bytes() is wrong here, allocate after the header.
const int header = sizeof(instanceOopDesc);
// Do the String Class // Do the String Class
java_lang_String::value_offset = java_lang_String::hc_value_offset * x + header; java_lang_String::value_offset = java_lang_String::hc_value_offset * x + header;
@ -2308,7 +2306,8 @@ void JavaClasses::compute_hard_coded_offsets() {
java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header; java_lang_Throwable::stackTrace_offset = java_lang_Throwable::hc_stackTrace_offset * x + header;
// java_lang_boxing_object // java_lang_boxing_object
java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset * x + header; java_lang_boxing_object::value_offset = java_lang_boxing_object::hc_value_offset + header;
java_lang_boxing_object::long_value_offset = align_size_up((java_lang_boxing_object::hc_value_offset + header), BytesPerLong);
// java_lang_ref_Reference: // java_lang_ref_Reference:
java_lang_ref_Reference::referent_offset = java_lang_ref_Reference::hc_referent_offset * x + header; java_lang_ref_Reference::referent_offset = java_lang_ref_Reference::hc_referent_offset * x + header;
@ -2322,7 +2321,7 @@ void JavaClasses::compute_hard_coded_offsets() {
java_lang_ref_Reference::number_of_fake_oop_fields = 1; java_lang_ref_Reference::number_of_fake_oop_fields = 1;
// java_lang_ref_SoftReference Class // java_lang_ref_SoftReference Class
java_lang_ref_SoftReference::timestamp_offset = java_lang_ref_SoftReference::hc_timestamp_offset * x + header; java_lang_ref_SoftReference::timestamp_offset = align_size_up((java_lang_ref_SoftReference::hc_timestamp_offset * x + header), BytesPerLong);
// Don't multiply static fields because they are always in wordSize units // Don't multiply static fields because they are always in wordSize units
java_lang_ref_SoftReference::static_clock_offset = java_lang_ref_SoftReference::hc_static_clock_offset * x; java_lang_ref_SoftReference::static_clock_offset = java_lang_ref_SoftReference::hc_static_clock_offset * x;
@ -2469,6 +2468,9 @@ void JavaClasses::check_offsets() {
#define CHECK_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \ #define CHECK_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
valid &= check_offset(klass_name, cpp_klass_name :: field_name ## _offset, #field_name, field_sig) valid &= check_offset(klass_name, cpp_klass_name :: field_name ## _offset, #field_name, field_sig)
#define CHECK_LONG_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
valid &= check_offset(klass_name, cpp_klass_name :: long_ ## field_name ## _offset, #field_name, field_sig)
#define CHECK_STATIC_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \ #define CHECK_STATIC_OFFSET(klass_name, cpp_klass_name, field_name, field_sig) \
valid &= check_static_offset(klass_name, cpp_klass_name :: static_ ## field_name ## _offset, #field_name, field_sig) valid &= check_static_offset(klass_name, cpp_klass_name :: static_ ## field_name ## _offset, #field_name, field_sig)
@ -2501,11 +2503,11 @@ void JavaClasses::check_offsets() {
CHECK_OFFSET("java/lang/Boolean", java_lang_boxing_object, value, "Z"); CHECK_OFFSET("java/lang/Boolean", java_lang_boxing_object, value, "Z");
CHECK_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C"); CHECK_OFFSET("java/lang/Character", java_lang_boxing_object, value, "C");
CHECK_OFFSET("java/lang/Float", java_lang_boxing_object, value, "F"); CHECK_OFFSET("java/lang/Float", java_lang_boxing_object, value, "F");
CHECK_OFFSET("java/lang/Double", java_lang_boxing_object, value, "D"); CHECK_LONG_OFFSET("java/lang/Double", java_lang_boxing_object, value, "D");
CHECK_OFFSET("java/lang/Byte", java_lang_boxing_object, value, "B"); CHECK_OFFSET("java/lang/Byte", java_lang_boxing_object, value, "B");
CHECK_OFFSET("java/lang/Short", java_lang_boxing_object, value, "S"); CHECK_OFFSET("java/lang/Short", java_lang_boxing_object, value, "S");
CHECK_OFFSET("java/lang/Integer", java_lang_boxing_object, value, "I"); CHECK_OFFSET("java/lang/Integer", java_lang_boxing_object, value, "I");
CHECK_OFFSET("java/lang/Long", java_lang_boxing_object, value, "J"); CHECK_LONG_OFFSET("java/lang/Long", java_lang_boxing_object, value, "J");
// java.lang.ClassLoader // java.lang.ClassLoader

View File

@ -653,6 +653,7 @@ class java_lang_boxing_object: AllStatic {
hc_value_offset = 0 hc_value_offset = 0
}; };
static int value_offset; static int value_offset;
static int long_value_offset;
static oop initialize_and_allocate(BasicType type, TRAPS); static oop initialize_and_allocate(BasicType type, TRAPS);
public: public:
@ -665,7 +666,10 @@ class java_lang_boxing_object: AllStatic {
static bool is_instance(oop box) { return basic_type(box) != T_ILLEGAL; } static bool is_instance(oop box) { return basic_type(box) != T_ILLEGAL; }
static bool is_instance(oop box, BasicType type) { return basic_type(box) == type; } static bool is_instance(oop box, BasicType type) { return basic_type(box) == type; }
static int value_offset_in_bytes() { return value_offset; } static int value_offset_in_bytes(BasicType type) {
return ( type == T_LONG || type == T_DOUBLE ) ? long_value_offset :
value_offset;
}
// Debugging // Debugging
friend class JavaClasses; friend class JavaClasses;
@ -747,7 +751,7 @@ class java_lang_ref_SoftReference: public java_lang_ref_Reference {
public: public:
enum { enum {
// The timestamp is a long field and may need to be adjusted for alignment. // The timestamp is a long field and may need to be adjusted for alignment.
hc_timestamp_offset = align_object_offset_(hc_discovered_offset + 1) hc_timestamp_offset = hc_discovered_offset + 1
}; };
enum { enum {
hc_static_clock_offset = 0 hc_static_clock_offset = 0

View File

@ -283,6 +283,7 @@
template(cache_field_name, "cache") \ template(cache_field_name, "cache") \
template(value_name, "value") \ template(value_name, "value") \
template(frontCacheEnabled_name, "frontCacheEnabled") \ template(frontCacheEnabled_name, "frontCacheEnabled") \
template(stringCacheEnabled_name, "stringCacheEnabled") \
\ \
/* non-intrinsic name/signature pairs: */ \ /* non-intrinsic name/signature pairs: */ \
template(register_method_name, "register") \ template(register_method_name, "register") \
@ -564,6 +565,10 @@
do_name( copyOfRange_name, "copyOfRange") \ do_name( copyOfRange_name, "copyOfRange") \
do_signature(copyOfRange_signature, "([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;") \ do_signature(copyOfRange_signature, "([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;") \
\ \
do_intrinsic(_equalsC, java_util_Arrays, equals_name, equalsC_signature, F_S) \
do_name( equals_name, "equals") \
do_signature(equalsC_signature, "([C[C)Z") \
\
do_intrinsic(_invoke, java_lang_reflect_Method, invoke_name, object_array_object_object_signature, F_R) \ do_intrinsic(_invoke, java_lang_reflect_Method, invoke_name, object_array_object_object_signature, F_R) \
/* (symbols invoke_name and invoke_signature defined above) */ \ /* (symbols invoke_name and invoke_signature defined above) */ \
\ \

View File

@ -130,6 +130,7 @@ class TreeChunk : public FreeChunk {
const size_t MIN_TREE_CHUNK_SIZE = sizeof(TreeChunk)/HeapWordSize; const size_t MIN_TREE_CHUNK_SIZE = sizeof(TreeChunk)/HeapWordSize;
class BinaryTreeDictionary: public FreeBlockDictionary { class BinaryTreeDictionary: public FreeBlockDictionary {
friend class VMStructs;
bool _splay; bool _splay;
size_t _totalSize; size_t _totalSize;
size_t _totalFreeBlocks; size_t _totalFreeBlocks;

View File

@ -805,28 +805,30 @@ size_t CompactibleFreeListSpace::block_size(const HeapWord* p) const {
// This must be volatile, or else there is a danger that the compiler // This must be volatile, or else there is a danger that the compiler
// will compile the code below into a sometimes-infinite loop, by keeping // will compile the code below into a sometimes-infinite loop, by keeping
// the value read the first time in a register. // the value read the first time in a register.
oop o = (oop)p;
volatile oop* second_word_addr = o->klass_addr();
while (true) { while (true) {
klassOop k = (klassOop)(*second_word_addr);
// We must do this until we get a consistent view of the object. // We must do this until we get a consistent view of the object.
if (FreeChunk::secondWordIndicatesFreeChunk((intptr_t)k)) { if (FreeChunk::indicatesFreeChunk(p)) {
FreeChunk* fc = (FreeChunk*)p; volatile FreeChunk* fc = (volatile FreeChunk*)p;
volatile size_t* sz_addr = (volatile size_t*)(fc->size_addr()); size_t res = fc->size();
size_t res = (*sz_addr); // If the object is still a free chunk, return the size, else it
klassOop k2 = (klassOop)(*second_word_addr); // Read to confirm. // has been allocated so try again.
if (k == k2) { if (FreeChunk::indicatesFreeChunk(p)) {
assert(res != 0, "Block size should not be 0");
return res;
}
} else {
// must read from what 'p' points to in each loop.
klassOop k = ((volatile oopDesc*)p)->klass_or_null();
if (k != NULL) {
assert(k->is_oop(true /* ignore mark word */), "Should really be klass oop.");
oop o = (oop)p;
assert(o->is_parsable(), "Should be parsable");
assert(o->is_oop(true /* ignore mark word */), "Should be an oop.");
size_t res = o->size_given_klass(k->klass_part());
res = adjustObjectSize(res);
assert(res != 0, "Block size should not be 0"); assert(res != 0, "Block size should not be 0");
return res; return res;
} }
} else if (k != NULL) {
assert(k->is_oop(true /* ignore mark word */), "Should really be klass oop.");
assert(o->is_parsable(), "Should be parsable");
assert(o->is_oop(true /* ignore mark word */), "Should be an oop.");
size_t res = o->size_given_klass(k->klass_part());
res = adjustObjectSize(res);
assert(res != 0, "Block size should not be 0");
return res;
} }
} }
} }
@ -845,31 +847,31 @@ const {
// This must be volatile, or else there is a danger that the compiler // This must be volatile, or else there is a danger that the compiler
// will compile the code below into a sometimes-infinite loop, by keeping // will compile the code below into a sometimes-infinite loop, by keeping
// the value read the first time in a register. // the value read the first time in a register.
oop o = (oop)p;
volatile oop* second_word_addr = o->klass_addr();
DEBUG_ONLY(uint loops = 0;) DEBUG_ONLY(uint loops = 0;)
while (true) { while (true) {
klassOop k = (klassOop)(*second_word_addr);
// We must do this until we get a consistent view of the object. // We must do this until we get a consistent view of the object.
if (FreeChunk::secondWordIndicatesFreeChunk((intptr_t)k)) { if (FreeChunk::indicatesFreeChunk(p)) {
FreeChunk* fc = (FreeChunk*)p; volatile FreeChunk* fc = (volatile FreeChunk*)p;
volatile size_t* sz_addr = (volatile size_t*)(fc->size_addr()); size_t res = fc->size();
size_t res = (*sz_addr); if (FreeChunk::indicatesFreeChunk(p)) {
klassOop k2 = (klassOop)(*second_word_addr); // Read to confirm.
if (k == k2) {
assert(res != 0, "Block size should not be 0"); assert(res != 0, "Block size should not be 0");
assert(loops == 0, "Should be 0"); assert(loops == 0, "Should be 0");
return res; return res;
} }
} else if (k != NULL && o->is_parsable()) {
assert(k->is_oop(), "Should really be klass oop.");
assert(o->is_oop(), "Should be an oop");
size_t res = o->size_given_klass(k->klass_part());
res = adjustObjectSize(res);
assert(res != 0, "Block size should not be 0");
return res;
} else { } else {
return c->block_size_if_printezis_bits(p); // must read from what 'p' points to in each loop.
klassOop k = ((volatile oopDesc*)p)->klass_or_null();
if (k != NULL && ((oopDesc*)p)->is_parsable()) {
assert(k->is_oop(), "Should really be klass oop.");
oop o = (oop)p;
assert(o->is_oop(), "Should be an oop");
size_t res = o->size_given_klass(k->klass_part());
res = adjustObjectSize(res);
assert(res != 0, "Block size should not be 0");
return res;
} else {
return c->block_size_if_printezis_bits(p);
}
} }
assert(loops == 0, "Can loop at most once"); assert(loops == 0, "Can loop at most once");
DEBUG_ONLY(loops++;) DEBUG_ONLY(loops++;)
@ -907,9 +909,8 @@ bool CompactibleFreeListSpace::block_is_obj(const HeapWord* p) const {
// and those objects (if garbage) may have been modified to hold // and those objects (if garbage) may have been modified to hold
// live range information. // live range information.
// assert(ParallelGCThreads > 0 || _bt.block_start(p) == p, "Should be a block boundary"); // assert(ParallelGCThreads > 0 || _bt.block_start(p) == p, "Should be a block boundary");
klassOop k = oop(p)->klass(); if (FreeChunk::indicatesFreeChunk(p)) return false;
intptr_t ki = (intptr_t)k; klassOop k = oop(p)->klass_or_null();
if (FreeChunk::secondWordIndicatesFreeChunk(ki)) return false;
if (k != NULL) { if (k != NULL) {
// Ignore mark word because it may have been used to // Ignore mark word because it may have been used to
// chain together promoted objects (the last one // chain together promoted objects (the last one
@ -1027,7 +1028,7 @@ HeapWord* CompactibleFreeListSpace::allocate(size_t size) {
FreeChunk* fc = (FreeChunk*)res; FreeChunk* fc = (FreeChunk*)res;
fc->markNotFree(); fc->markNotFree();
assert(!fc->isFree(), "shouldn't be marked free"); assert(!fc->isFree(), "shouldn't be marked free");
assert(oop(fc)->klass() == NULL, "should look uninitialized"); assert(oop(fc)->klass_or_null() == NULL, "should look uninitialized");
// Verify that the block offset table shows this to // Verify that the block offset table shows this to
// be a single block, but not one which is unallocated. // be a single block, but not one which is unallocated.
_bt.verify_single_block(res, size); _bt.verify_single_block(res, size);
@ -2593,7 +2594,7 @@ HeapWord* CFLS_LAB::alloc(size_t word_sz) {
} }
res->markNotFree(); res->markNotFree();
assert(!res->isFree(), "shouldn't be marked free"); assert(!res->isFree(), "shouldn't be marked free");
assert(oop(res)->klass() == NULL, "should look uninitialized"); assert(oop(res)->klass_or_null() == NULL, "should look uninitialized");
// mangle a just allocated object with a distinct pattern. // mangle a just allocated object with a distinct pattern.
debug_only(res->mangleAllocated(word_sz)); debug_only(res->mangleAllocated(word_sz));
return (HeapWord*)res; return (HeapWord*)res;

View File

@ -190,7 +190,8 @@ ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration(
// depends on this property. // depends on this property.
debug_only( debug_only(
FreeChunk* junk = NULL; FreeChunk* junk = NULL;
assert(junk->prev_addr() == (void*)(oop(junk)->klass_addr()), assert(UseCompressedOops ||
junk->prev_addr() == (void*)(oop(junk)->klass_addr()),
"Offset of FreeChunk::_prev within FreeChunk must match" "Offset of FreeChunk::_prev within FreeChunk must match"
" that of OopDesc::_klass within OopDesc"); " that of OopDesc::_klass within OopDesc");
) )
@ -1039,7 +1040,7 @@ void CMSCollector::direct_allocated(HeapWord* start, size_t size) {
// mark end of object // mark end of object
} }
// check that oop looks uninitialized // check that oop looks uninitialized
assert(oop(start)->klass() == NULL, "_klass should be NULL"); assert(oop(start)->klass_or_null() == NULL, "_klass should be NULL");
} }
void CMSCollector::promoted(bool par, HeapWord* start, void CMSCollector::promoted(bool par, HeapWord* start,
@ -1309,17 +1310,25 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num,
} }
} }
oop obj = oop(obj_ptr); oop obj = oop(obj_ptr);
assert(obj->klass() == NULL, "Object should be uninitialized here."); assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
// Otherwise, copy the object. Here we must be careful to insert the // Otherwise, copy the object. Here we must be careful to insert the
// klass pointer last, since this marks the block as an allocated object. // klass pointer last, since this marks the block as an allocated object.
// Except with compressed oops it's the mark word.
HeapWord* old_ptr = (HeapWord*)old; HeapWord* old_ptr = (HeapWord*)old;
if (word_sz > (size_t)oopDesc::header_size()) { if (word_sz > (size_t)oopDesc::header_size()) {
Copy::aligned_disjoint_words(old_ptr + oopDesc::header_size(), Copy::aligned_disjoint_words(old_ptr + oopDesc::header_size(),
obj_ptr + oopDesc::header_size(), obj_ptr + oopDesc::header_size(),
word_sz - oopDesc::header_size()); word_sz - oopDesc::header_size());
} }
if (UseCompressedOops) {
// Copy gap missed by (aligned) header size calculation above
obj->set_klass_gap(old->klass_gap());
}
// Restore the mark word copied above. // Restore the mark word copied above.
obj->set_mark(m); obj->set_mark(m);
// Now we can track the promoted object, if necessary. We take care // Now we can track the promoted object, if necessary. We take care
// To delay the transition from uninitialized to full object // To delay the transition from uninitialized to full object
// (i.e., insertion of klass pointer) until after, so that it // (i.e., insertion of klass pointer) until after, so that it
@ -1327,7 +1336,8 @@ ConcurrentMarkSweepGeneration::par_promote(int thread_num,
if (promoInfo->tracking()) { if (promoInfo->tracking()) {
promoInfo->track((PromotedObject*)obj, old->klass()); promoInfo->track((PromotedObject*)obj, old->klass());
} }
// Finally, install the klass pointer.
// Finally, install the klass pointer (this should be volatile).
obj->set_klass(old->klass()); obj->set_klass(old->klass());
assert(old->is_oop(), "Will dereference klass ptr below"); assert(old->is_oop(), "Will dereference klass ptr below");
@ -6165,7 +6175,7 @@ size_t CMSCollector::block_size_if_printezis_bits(HeapWord* addr) const {
HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const { HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
size_t sz = 0; size_t sz = 0;
oop p = (oop)addr; oop p = (oop)addr;
if (p->klass() != NULL && p->is_parsable()) { if (p->klass_or_null() != NULL && p->is_parsable()) {
sz = CompactibleFreeListSpace::adjustObjectSize(p->size()); sz = CompactibleFreeListSpace::adjustObjectSize(p->size());
} else { } else {
sz = block_size_using_printezis_bits(addr); sz = block_size_using_printezis_bits(addr);
@ -6602,7 +6612,7 @@ size_t ScanMarkedObjectsAgainCarefullyClosure::do_object_careful_m(
} }
if (_bitMap->isMarked(addr)) { if (_bitMap->isMarked(addr)) {
// it's marked; is it potentially uninitialized? // it's marked; is it potentially uninitialized?
if (p->klass() != NULL) { if (p->klass_or_null() != NULL) {
if (CMSPermGenPrecleaningEnabled && !p->is_parsable()) { if (CMSPermGenPrecleaningEnabled && !p->is_parsable()) {
// Signal precleaning to redirty the card since // Signal precleaning to redirty the card since
// the klass pointer is already installed. // the klass pointer is already installed.
@ -6615,11 +6625,8 @@ size_t ScanMarkedObjectsAgainCarefullyClosure::do_object_careful_m(
if (p->is_objArray()) { if (p->is_objArray()) {
// objArrays are precisely marked; restrict scanning // objArrays are precisely marked; restrict scanning
// to dirty cards only. // to dirty cards only.
size = p->oop_iterate(_scanningClosure, mr); size = CompactibleFreeListSpace::adjustObjectSize(
assert(size == CompactibleFreeListSpace::adjustObjectSize(size), p->oop_iterate(_scanningClosure, mr));
"adjustObjectSize should be the identity for array sizes, "
"which are necessarily larger than minimum object size of "
"two heap words");
} else { } else {
// A non-array may have been imprecisely marked; we need // A non-array may have been imprecisely marked; we need
// to scan object in its entirety. // to scan object in its entirety.
@ -6653,7 +6660,7 @@ size_t ScanMarkedObjectsAgainCarefullyClosure::do_object_careful_m(
} }
} else { } else {
// Either a not yet marked object or an uninitialized object // Either a not yet marked object or an uninitialized object
if (p->klass() == NULL || !p->is_parsable()) { if (p->klass_or_null() == NULL || !p->is_parsable()) {
// An uninitialized object, skip to the next card, since // An uninitialized object, skip to the next card, since
// we may not be able to read its P-bits yet. // we may not be able to read its P-bits yet.
assert(size == 0, "Initial value"); assert(size == 0, "Initial value");
@ -6710,7 +6717,7 @@ size_t SurvivorSpacePrecleanClosure::do_object_careful(oop p) {
HeapWord* addr = (HeapWord*)p; HeapWord* addr = (HeapWord*)p;
DEBUG_ONLY(_collector->verify_work_stacks_empty();) DEBUG_ONLY(_collector->verify_work_stacks_empty();)
assert(!_span.contains(addr), "we are scanning the survivor spaces"); assert(!_span.contains(addr), "we are scanning the survivor spaces");
assert(p->klass() != NULL, "object should be initializd"); assert(p->klass_or_null() != NULL, "object should be initializd");
assert(p->is_parsable(), "must be parsable."); assert(p->is_parsable(), "must be parsable.");
// an initialized object; ignore mark word in verification below // an initialized object; ignore mark word in verification below
// since we are running concurrent with mutators // since we are running concurrent with mutators
@ -6868,7 +6875,7 @@ void MarkFromRootsClosure::do_bit(size_t offset) {
assert(_skipBits == 0, "tautology"); assert(_skipBits == 0, "tautology");
_skipBits = 2; // skip next two marked bits ("Printezis-marks") _skipBits = 2; // skip next two marked bits ("Printezis-marks")
oop p = oop(addr); oop p = oop(addr);
if (p->klass() == NULL || !p->is_parsable()) { if (p->klass_or_null() == NULL || !p->is_parsable()) {
DEBUG_ONLY(if (!_verifying) {) DEBUG_ONLY(if (!_verifying) {)
// We re-dirty the cards on which this object lies and increase // We re-dirty the cards on which this object lies and increase
// the _threshold so that we'll come back to scan this object // the _threshold so that we'll come back to scan this object
@ -6890,7 +6897,7 @@ void MarkFromRootsClosure::do_bit(size_t offset) {
if (_threshold < end_card_addr) { if (_threshold < end_card_addr) {
_threshold = end_card_addr; _threshold = end_card_addr;
} }
if (p->klass() != NULL) { if (p->klass_or_null() != NULL) {
// Redirty the range of cards... // Redirty the range of cards...
_mut->mark_range(redirty_range); _mut->mark_range(redirty_range);
} // ...else the setting of klass will dirty the card anyway. } // ...else the setting of klass will dirty the card anyway.
@ -7048,7 +7055,7 @@ void Par_MarkFromRootsClosure::do_bit(size_t offset) {
assert(_skip_bits == 0, "tautology"); assert(_skip_bits == 0, "tautology");
_skip_bits = 2; // skip next two marked bits ("Printezis-marks") _skip_bits = 2; // skip next two marked bits ("Printezis-marks")
oop p = oop(addr); oop p = oop(addr);
if (p->klass() == NULL || !p->is_parsable()) { if (p->klass_or_null() == NULL || !p->is_parsable()) {
// in the case of Clean-on-Enter optimization, redirty card // in the case of Clean-on-Enter optimization, redirty card
// and avoid clearing card by increasing the threshold. // and avoid clearing card by increasing the threshold.
return; return;
@ -8023,7 +8030,7 @@ size_t SweepClosure::doLiveChunk(FreeChunk* fc) {
"alignment problem"); "alignment problem");
#ifdef DEBUG #ifdef DEBUG
if (oop(addr)->klass() != NULL && if (oop(addr)->klass_or_null() != NULL &&
( !_collector->should_unload_classes() ( !_collector->should_unload_classes()
|| oop(addr)->is_parsable())) { || oop(addr)->is_parsable())) {
// Ignore mark word because we are running concurrent with mutators // Ignore mark word because we are running concurrent with mutators
@ -8036,7 +8043,7 @@ size_t SweepClosure::doLiveChunk(FreeChunk* fc) {
} else { } else {
// This should be an initialized object that's alive. // This should be an initialized object that's alive.
assert(oop(addr)->klass() != NULL && assert(oop(addr)->klass_or_null() != NULL &&
(!_collector->should_unload_classes() (!_collector->should_unload_classes()
|| oop(addr)->is_parsable()), || oop(addr)->is_parsable()),
"Should be an initialized object"); "Should be an initialized object");

View File

@ -22,88 +22,6 @@
* *
*/ */
//
// Free block maintenance for Concurrent Mark Sweep Generation
//
// The main data structure for free blocks are
// . an indexed array of small free blocks, and
// . a dictionary of large free blocks
//
// No virtuals in FreeChunk (don't want any vtables).
// A FreeChunk is merely a chunk that can be in a doubly linked list
// and has a size field. NOTE: FreeChunks are distinguished from allocated
// objects in two ways (by the sweeper). The second word (prev) has the
// LSB set to indicate a free chunk; allocated objects' klass() pointers
// don't have their LSB set. The corresponding bit in the CMSBitMap is
// set when the chunk is allocated. There are also blocks that "look free"
// but are not part of the free list and should not be coalesced into larger
// free blocks. These free blocks have their two LSB's set.
class FreeChunk VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
FreeChunk* _next;
FreeChunk* _prev;
size_t _size;
public:
NOT_PRODUCT(static const size_t header_size();)
// Returns "true" if the "wrd", which is required to be the second word
// of a block, indicates that the block represents a free chunk.
static bool secondWordIndicatesFreeChunk(intptr_t wrd) {
return (wrd & 0x1) == 0x1;
}
bool isFree() const {
return secondWordIndicatesFreeChunk((intptr_t)_prev);
}
bool cantCoalesce() const { return (((intptr_t)_prev) & 0x3) == 0x3; }
FreeChunk* next() const { return _next; }
FreeChunk* prev() const { return (FreeChunk*)(((intptr_t)_prev) & ~(0x3)); }
debug_only(void* prev_addr() const { return (void*)&_prev; })
void linkAfter(FreeChunk* ptr) {
linkNext(ptr);
if (ptr != NULL) ptr->linkPrev(this);
}
void linkAfterNonNull(FreeChunk* ptr) {
assert(ptr != NULL, "precondition violation");
linkNext(ptr);
ptr->linkPrev(this);
}
void linkNext(FreeChunk* ptr) { _next = ptr; }
void linkPrev(FreeChunk* ptr) { _prev = (FreeChunk*)((intptr_t)ptr | 0x1); }
void clearPrev() { _prev = NULL; }
void clearNext() { _next = NULL; }
void dontCoalesce() {
// the block should be free
assert(isFree(), "Should look like a free block");
_prev = (FreeChunk*)(((intptr_t)_prev) | 0x2);
}
void markFree() { _prev = (FreeChunk*)((intptr_t)_prev | 0x1); }
void markNotFree() { _prev = NULL; }
size_t size() const { return _size; }
void setSize(size_t size) { _size = size; }
// For volatile reads:
size_t* size_addr() { return &_size; }
// Return the address past the end of this chunk
HeapWord* end() const { return ((HeapWord*) this) + _size; }
// debugging
void verify() const PRODUCT_RETURN;
void verifyList() const PRODUCT_RETURN;
void mangleAllocated(size_t size) PRODUCT_RETURN;
void mangleFreed(size_t size) PRODUCT_RETURN;
};
// Alignment helpers etc.
#define numQuanta(x,y) ((x+y-1)/y)
enum AlignmentConstants {
MinChunkSize = numQuanta(sizeof(FreeChunk), MinObjAlignmentInBytes) * MinObjAlignment
};
// A FreeBlockDictionary is an abstract superclass that will allow // A FreeBlockDictionary is an abstract superclass that will allow
// a number of alternative implementations in the future. // a number of alternative implementations in the future.

View File

@ -47,15 +47,15 @@ void FreeChunk::mangleAllocated(size_t size) {
Copy::fill_to_words(addr + hdr, size - hdr, baadbabeHeapWord); Copy::fill_to_words(addr + hdr, size - hdr, baadbabeHeapWord);
} }
void FreeChunk::mangleFreed(size_t size) { void FreeChunk::mangleFreed(size_t sz) {
assert(baadbabeHeapWord != deadbeefHeapWord, "Need distinct patterns"); assert(baadbabeHeapWord != deadbeefHeapWord, "Need distinct patterns");
// mangle all but the header of a just-freed block of storage // mangle all but the header of a just-freed block of storage
// just prior to passing it to the storage dictionary // just prior to passing it to the storage dictionary
assert(size >= MinChunkSize, "smallest size of object"); assert(sz >= MinChunkSize, "smallest size of object");
assert(size == _size, "just checking"); assert(sz == size(), "just checking");
HeapWord* addr = (HeapWord*)this; HeapWord* addr = (HeapWord*)this;
size_t hdr = header_size(); size_t hdr = header_size();
Copy::fill_to_words(addr + hdr, size - hdr, deadbeefHeapWord); Copy::fill_to_words(addr + hdr, sz - hdr, deadbeefHeapWord);
} }
void FreeChunk::verifyList() const { void FreeChunk::verifyList() const {

View File

@ -0,0 +1,137 @@
/*
* Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
//
// Free block maintenance for Concurrent Mark Sweep Generation
//
// The main data structure for free blocks are
// . an indexed array of small free blocks, and
// . a dictionary of large free blocks
//
// No virtuals in FreeChunk (don't want any vtables).
// A FreeChunk is merely a chunk that can be in a doubly linked list
// and has a size field. NOTE: FreeChunks are distinguished from allocated
// objects in two ways (by the sweeper), depending on whether the VM is 32 or
// 64 bits.
// In 32 bits or 64 bits without CompressedOops, the second word (prev) has the
// LSB set to indicate a free chunk; allocated objects' klass() pointers
// don't have their LSB set. The corresponding bit in the CMSBitMap is
// set when the chunk is allocated. There are also blocks that "look free"
// but are not part of the free list and should not be coalesced into larger
// free blocks. These free blocks have their two LSB's set.
class FreeChunk VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
// For 64 bit compressed oops, the markOop encodes both the size and the
// indication that this is a FreeChunk and not an object.
volatile size_t _size;
FreeChunk* _prev;
FreeChunk* _next;
markOop mark() const volatile { return (markOop)_size; }
void set_mark(markOop m) { _size = (size_t)m; }
public:
NOT_PRODUCT(static const size_t header_size();)
// Returns "true" if the address indicates that the block represents
// a free chunk.
static bool indicatesFreeChunk(const HeapWord* addr) {
// Force volatile read from addr because value might change between
// calls. We really want the read of _mark and _prev from this pointer
// to be volatile but making the fields volatile causes all sorts of
// compilation errors.
return ((volatile FreeChunk*)addr)->isFree();
}
bool isFree() const volatile {
LP64_ONLY(if (UseCompressedOops) return mark()->is_cms_free_chunk(); else)
return (((intptr_t)_prev) & 0x1) == 0x1;
}
bool cantCoalesce() const {
assert(isFree(), "can't get coalesce bit on not free");
return (((intptr_t)_prev) & 0x2) == 0x2;
}
void dontCoalesce() {
// the block should be free
assert(isFree(), "Should look like a free block");
_prev = (FreeChunk*)(((intptr_t)_prev) | 0x2);
}
FreeChunk* prev() const {
return (FreeChunk*)(((intptr_t)_prev) & ~(0x3));
}
debug_only(void* prev_addr() const { return (void*)&_prev; })
size_t size() const volatile {
LP64_ONLY(if (UseCompressedOops) return mark()->get_size(); else )
return _size;
}
void setSize(size_t sz) {
LP64_ONLY(if (UseCompressedOops) set_mark(markOopDesc::set_size_and_free(sz)); else )
_size = sz;
}
FreeChunk* next() const { return _next; }
void linkAfter(FreeChunk* ptr) {
linkNext(ptr);
if (ptr != NULL) ptr->linkPrev(this);
}
void linkAfterNonNull(FreeChunk* ptr) {
assert(ptr != NULL, "precondition violation");
linkNext(ptr);
ptr->linkPrev(this);
}
void linkNext(FreeChunk* ptr) { _next = ptr; }
void linkPrev(FreeChunk* ptr) {
LP64_ONLY(if (UseCompressedOops) _prev = ptr; else)
_prev = (FreeChunk*)((intptr_t)ptr | 0x1);
}
void clearPrev() { _prev = NULL; }
void clearNext() { _next = NULL; }
void markNotFree() {
LP64_ONLY(if (UseCompressedOops) set_mark(markOopDesc::prototype());)
// Also set _prev to null
_prev = NULL;
}
// Return the address past the end of this chunk
HeapWord* end() const { return ((HeapWord*) this) + size(); }
// debugging
void verify() const PRODUCT_RETURN;
void verifyList() const PRODUCT_RETURN;
void mangleAllocated(size_t size) PRODUCT_RETURN;
void mangleFreed(size_t size) PRODUCT_RETURN;
};
// Alignment helpers etc.
#define numQuanta(x,y) ((x+y-1)/y)
enum AlignmentConstants {
MinChunkSize = numQuanta(sizeof(FreeChunk), MinObjAlignmentInBytes) * MinObjAlignment
};

View File

@ -38,6 +38,7 @@ class Mutex;
class FreeList VALUE_OBJ_CLASS_SPEC { class FreeList VALUE_OBJ_CLASS_SPEC {
friend class CompactibleFreeListSpace; friend class CompactibleFreeListSpace;
friend class VMStructs;
friend class printTreeCensusClosure; friend class printTreeCensusClosure;
FreeChunk* _head; // List of free chunks FreeChunk* _head; // List of free chunks
FreeChunk* _tail; // Tail of list of free chunks FreeChunk* _tail; // Tail of list of free chunks

View File

@ -23,6 +23,7 @@
*/ */
#define VM_STRUCTS_CMS(nonstatic_field, \ #define VM_STRUCTS_CMS(nonstatic_field, \
volatile_nonstatic_field, \
static_field) \ static_field) \
nonstatic_field(CompactibleFreeListSpace, _collector, CMSCollector*) \ nonstatic_field(CompactibleFreeListSpace, _collector, CMSCollector*) \
nonstatic_field(CompactibleFreeListSpace, _bt, BlockOffsetArrayNonContigSpace) \ nonstatic_field(CompactibleFreeListSpace, _bt, BlockOffsetArrayNonContigSpace) \
@ -36,9 +37,17 @@
nonstatic_field(CMSCollector, _markBitMap, CMSBitMap) \ nonstatic_field(CMSCollector, _markBitMap, CMSBitMap) \
nonstatic_field(ConcurrentMarkSweepGeneration, _cmsSpace, CompactibleFreeListSpace*) \ nonstatic_field(ConcurrentMarkSweepGeneration, _cmsSpace, CompactibleFreeListSpace*) \
static_field(ConcurrentMarkSweepThread, _collector, CMSCollector*) \ static_field(ConcurrentMarkSweepThread, _collector, CMSCollector*) \
volatile_nonstatic_field(FreeChunk, _size, size_t) \
nonstatic_field(FreeChunk, _next, FreeChunk*) \ nonstatic_field(FreeChunk, _next, FreeChunk*) \
nonstatic_field(FreeChunk, _prev, FreeChunk*) \ nonstatic_field(FreeChunk, _prev, FreeChunk*) \
nonstatic_field(FreeChunk, _size, size_t) nonstatic_field(LinearAllocBlock, _word_size, size_t) \
nonstatic_field(FreeList, _size, size_t) \
nonstatic_field(FreeList, _count, ssize_t) \
nonstatic_field(BinaryTreeDictionary, _totalSize, size_t) \
nonstatic_field(CompactibleFreeListSpace, _dictionary, FreeBlockDictionary*) \
nonstatic_field(CompactibleFreeListSpace, _indexedFreeList[0], FreeList) \
nonstatic_field(CompactibleFreeListSpace, _smallLinearAllocBlock, LinearAllocBlock)
#define VM_TYPES_CMS(declare_type, \ #define VM_TYPES_CMS(declare_type, \
declare_toplevel_type) \ declare_toplevel_type) \
@ -57,7 +66,14 @@
declare_toplevel_type(SurrogateLockerThread*) \ declare_toplevel_type(SurrogateLockerThread*) \
declare_toplevel_type(CompactibleFreeListSpace*) \ declare_toplevel_type(CompactibleFreeListSpace*) \
declare_toplevel_type(CMSCollector*) \ declare_toplevel_type(CMSCollector*) \
declare_toplevel_type(FreeChunk*) declare_toplevel_type(FreeChunk*) \
declare_toplevel_type(BinaryTreeDictionary*) \
declare_toplevel_type(FreeBlockDictionary*) \
declare_toplevel_type(FreeList*) \
declare_toplevel_type(FreeList) \
declare_toplevel_type(LinearAllocBlock) \
declare_toplevel_type(FreeBlockDictionary) \
declare_type(BinaryTreeDictionary, FreeBlockDictionary)
#define VM_INT_CONSTANTS_CMS(declare_constant) \ #define VM_INT_CONSTANTS_CMS(declare_constant) \
declare_constant(Generation::ConcurrentMarkSweep) \ declare_constant(Generation::ConcurrentMarkSweep) \

View File

@ -206,6 +206,7 @@ freeBlockDictionary.cpp thread_<os_family>.inline.hpp
freeBlockDictionary.hpp allocation.hpp freeBlockDictionary.hpp allocation.hpp
freeBlockDictionary.hpp debug.hpp freeBlockDictionary.hpp debug.hpp
freeBlockDictionary.hpp freeChunk.hpp
freeBlockDictionary.hpp globalDefinitions.hpp freeBlockDictionary.hpp globalDefinitions.hpp
freeBlockDictionary.hpp memRegion.hpp freeBlockDictionary.hpp memRegion.hpp
freeBlockDictionary.hpp mutex.hpp freeBlockDictionary.hpp mutex.hpp
@ -214,6 +215,14 @@ freeBlockDictionary.hpp ostream.hpp
freeChunk.cpp copy.hpp freeChunk.cpp copy.hpp
freeChunk.cpp freeBlockDictionary.hpp freeChunk.cpp freeBlockDictionary.hpp
freeChunk.hpp allocation.hpp
freeChunk.hpp debug.hpp
freeChunk.hpp globalDefinitions.hpp
freeChunk.hpp markOop.hpp
freeChunk.hpp memRegion.hpp
freeChunk.hpp mutex.hpp
freeChunk.hpp ostream.hpp
freeList.cpp freeBlockDictionary.hpp freeList.cpp freeBlockDictionary.hpp
freeList.cpp freeList.hpp freeList.cpp freeList.hpp
freeList.cpp globals.hpp freeList.cpp globals.hpp

View File

@ -54,6 +54,7 @@ isGCActiveMark.hpp parallelScavengeHeap.hpp
markSweep.inline.hpp psParallelCompact.hpp markSweep.inline.hpp psParallelCompact.hpp
mutableNUMASpace.cpp mutableNUMASpace.hpp mutableNUMASpace.cpp mutableNUMASpace.hpp
mutableNUMASpace.cpp oop.inline.hpp
mutableNUMASpace.cpp sharedHeap.hpp mutableNUMASpace.cpp sharedHeap.hpp
mutableNUMASpace.cpp thread_<os_family>.inline.hpp mutableNUMASpace.cpp thread_<os_family>.inline.hpp

View File

@ -1169,18 +1169,18 @@ ParNewGeneration::take_from_overflow_list(ParScanThreadState* par_scan_state) {
// Trim off a prefix of at most objsFromOverflow items // Trim off a prefix of at most objsFromOverflow items
int i = 1; int i = 1;
oop cur = prefix; oop cur = prefix;
while (i < objsFromOverflow && cur->klass() != NULL) { while (i < objsFromOverflow && cur->klass_or_null() != NULL) {
i++; cur = oop(cur->klass()); i++; cur = oop(cur->klass());
} }
// Reattach remaining (suffix) to overflow list // Reattach remaining (suffix) to overflow list
if (cur->klass() != NULL) { if (cur->klass_or_null() != NULL) {
oop suffix = oop(cur->klass()); oop suffix = oop(cur->klass());
cur->set_klass_to_list_ptr(NULL); cur->set_klass_to_list_ptr(NULL);
// Find last item of suffix list // Find last item of suffix list
oop last = suffix; oop last = suffix;
while (last->klass() != NULL) { while (last->klass_or_null() != NULL) {
last = oop(last->klass()); last = oop(last->klass());
} }
// Atomically prepend suffix to current overflow list // Atomically prepend suffix to current overflow list

View File

@ -66,7 +66,7 @@ void ImmutableSpace::print() const {
#endif #endif
void ImmutableSpace::verify(bool allow_dirty) const { void ImmutableSpace::verify(bool allow_dirty) {
HeapWord* p = bottom(); HeapWord* p = bottom();
HeapWord* t = end(); HeapWord* t = end();
HeapWord* prev_p = NULL; HeapWord* prev_p = NULL;

View File

@ -59,5 +59,5 @@ class ImmutableSpace: public CHeapObj {
// Debugging // Debugging
virtual void print() const PRODUCT_RETURN; virtual void print() const PRODUCT_RETURN;
virtual void print_short() const PRODUCT_RETURN; virtual void print_short() const PRODUCT_RETURN;
virtual void verify(bool allow_dirty) const; virtual void verify(bool allow_dirty);
}; };

View File

@ -599,12 +599,28 @@ void MutableNUMASpace::initialize(MemRegion mr, bool clear_space) {
// Mark the the holes in chunks below the top() as invalid. // Mark the the holes in chunks below the top() as invalid.
void MutableNUMASpace::set_top(HeapWord* value) { void MutableNUMASpace::set_top(HeapWord* value) {
bool found_top = false; bool found_top = false;
for (int i = 0; i < lgrp_spaces()->length(); i++) { for (int i = 0; i < lgrp_spaces()->length();) {
LGRPSpace *ls = lgrp_spaces()->at(i); LGRPSpace *ls = lgrp_spaces()->at(i);
MutableSpace *s = ls->space(); MutableSpace *s = ls->space();
HeapWord *top = MAX2((HeapWord*)round_down((intptr_t)s->top(), page_size()), s->bottom()); HeapWord *top = MAX2((HeapWord*)round_down((intptr_t)s->top(), page_size()), s->bottom());
if (s->contains(value)) { if (s->contains(value)) {
// Check if setting the chunk's top to a given value would create a hole less than
// a minimal object; assuming that's not the last chunk in which case we don't care.
if (i < lgrp_spaces()->length() - 1) {
size_t remainder = pointer_delta(s->end(), value);
const size_t minimal_object_size = oopDesc::header_size();
if (remainder < minimal_object_size && remainder > 0) {
// Add a filler object of a minimal size, it will cross the chunk boundary.
SharedHeap::fill_region_with_object(MemRegion(value, minimal_object_size));
value += minimal_object_size;
assert(!s->contains(value), "Should be in the next chunk");
// Restart the loop from the same chunk, since the value has moved
// to the next one.
continue;
}
}
if (!os::numa_has_static_binding() && top < value && top < s->end()) { if (!os::numa_has_static_binding() && top < value && top < s->end()) {
ls->add_invalid_region(MemRegion(top, value)); ls->add_invalid_region(MemRegion(top, value));
} }
@ -620,6 +636,7 @@ void MutableNUMASpace::set_top(HeapWord* value) {
s->set_top(s->end()); s->set_top(s->end());
} }
} }
i++;
} }
MutableSpace::set_top(value); MutableSpace::set_top(value);
} }
@ -700,12 +717,14 @@ HeapWord* MutableNUMASpace::cas_allocate(size_t size) {
MutableSpace *s = lgrp_spaces()->at(i)->space(); MutableSpace *s = lgrp_spaces()->at(i)->space();
HeapWord *p = s->cas_allocate(size); HeapWord *p = s->cas_allocate(size);
if (p != NULL) { if (p != NULL) {
size_t remainder = pointer_delta(s->end(), p); size_t remainder = pointer_delta(s->end(), p + size);
if (remainder < (size_t)oopDesc::header_size() && remainder > 0) { if (remainder < (size_t)oopDesc::header_size() && remainder > 0) {
if (s->cas_deallocate(p, size)) { if (s->cas_deallocate(p, size)) {
// We were the last to allocate and created a fragment less than // We were the last to allocate and created a fragment less than
// a minimal object. // a minimal object.
p = NULL; p = NULL;
} else {
guarantee(false, "Deallocation should always succeed");
} }
} }
} }
@ -761,10 +780,12 @@ void MutableNUMASpace::print_on(outputStream* st) const {
} }
} }
void MutableNUMASpace::verify(bool allow_dirty) const { void MutableNUMASpace::verify(bool allow_dirty) {
for (int i = 0; i < lgrp_spaces()->length(); i++) { // This can be called after setting an arbitary value to the space's top,
lgrp_spaces()->at(i)->space()->verify(allow_dirty); // so an object can cross the chunk boundary. We ensure the parsablity
} // of the space and just walk the objects in linear fashion.
ensure_parsability();
MutableSpace::verify(allow_dirty);
} }
// Scan pages and gather stats about page placement and size. // Scan pages and gather stats about page placement and size.

View File

@ -192,7 +192,7 @@ class MutableNUMASpace : public MutableSpace {
// Debugging // Debugging
virtual void print_on(outputStream* st) const; virtual void print_on(outputStream* st) const;
virtual void print_short_on(outputStream* st) const; virtual void print_short_on(outputStream* st) const;
virtual void verify(bool allow_dirty) const; virtual void verify(bool allow_dirty);
virtual void set_top(HeapWord* value); virtual void set_top(HeapWord* value);
}; };

View File

@ -118,7 +118,7 @@ void MutableSpace::print_on(outputStream* st) const {
bottom(), top(), end()); bottom(), top(), end());
} }
void MutableSpace::verify(bool allow_dirty) const { void MutableSpace::verify(bool allow_dirty) {
HeapWord* p = bottom(); HeapWord* p = bottom();
HeapWord* t = top(); HeapWord* t = top();
HeapWord* prev_p = NULL; HeapWord* prev_p = NULL;

View File

@ -98,5 +98,5 @@ class MutableSpace: public ImmutableSpace {
virtual void print_on(outputStream* st) const; virtual void print_on(outputStream* st) const;
virtual void print_short() const; virtual void print_short() const;
virtual void print_short_on(outputStream* st) const; virtual void print_short_on(outputStream* st) const;
virtual void verify(bool allow_dirty) const; virtual void verify(bool allow_dirty);
}; };

View File

@ -90,11 +90,12 @@ void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
HeapWord* obj, HeapWord* obj,
size_t size, size_t size,
int length) { int length) {
// Set array length before setting the _klass field
// in post_allocation_setup_common() because the klass field
// indicates that the object is parsable by concurrent GC.
assert(length >= 0, "length should be non-negative"); assert(length >= 0, "length should be non-negative");
post_allocation_setup_common(klass, obj, size);
// Must set length after installing klass as set_klass zeros the length
// field in UseCompressedOops
((arrayOop)obj)->set_length(length); ((arrayOop)obj)->set_length(length);
post_allocation_setup_common(klass, obj, size);
assert(((oop)obj)->blueprint()->oop_is_array(), "must be an array"); assert(((oop)obj)->blueprint()->oop_is_array(), "must be an array");
// notify jvmti and dtrace (must be after length is set for dtrace) // notify jvmti and dtrace (must be after length is set for dtrace)
post_allocation_notify(klass, (oop)obj); post_allocation_notify(klass, (oop)obj);
@ -224,6 +225,7 @@ void CollectedHeap::init_obj(HeapWord* obj, size_t size) {
assert(obj != NULL, "cannot initialize NULL object"); assert(obj != NULL, "cannot initialize NULL object");
const size_t hs = oopDesc::header_size(); const size_t hs = oopDesc::header_size();
assert(size >= hs, "unexpected object size"); assert(size >= hs, "unexpected object size");
((oop)obj)->set_klass_gap(0);
Copy::fill_to_aligned_words(obj + hs, size - hs); Copy::fill_to_aligned_words(obj + hs, size - hs);
} }

View File

@ -3492,6 +3492,7 @@ relocInfo.hpp top.hpp
relocInfo_<arch>.cpp assembler.inline.hpp relocInfo_<arch>.cpp assembler.inline.hpp
relocInfo_<arch>.cpp assembler_<arch_model>.inline.hpp relocInfo_<arch>.cpp assembler_<arch_model>.inline.hpp
relocInfo_<arch>.cpp nativeInst_<arch>.hpp relocInfo_<arch>.cpp nativeInst_<arch>.hpp
relocInfo_<arch>.cpp oop.inline.hpp
relocInfo_<arch>.cpp relocInfo.hpp relocInfo_<arch>.cpp relocInfo.hpp
relocInfo_<arch>.cpp safepoint.hpp relocInfo_<arch>.cpp safepoint.hpp

View File

@ -1931,6 +1931,7 @@ run:
} else { } else {
result->set_mark(markOopDesc::prototype()); result->set_mark(markOopDesc::prototype());
} }
result->set_klass_gap(0);
result->set_klass(k_entry); result->set_klass(k_entry);
SET_STACK_OBJECT(result, 0); SET_STACK_OBJECT(result, 0);
UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1);

View File

@ -1,7 +1,25 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- <!--
Copyright 2006 Sun Microsystems, Inc. All rights reserved. Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
CA 95054 USA or visit www.sun.com if you need additional information or
have any questions.
--> -->
<!DOCTYPE processcode [ <!DOCTYPE processcode [
<!ELEMENT processcode ANY> <!ELEMENT processcode ANY>

View File

@ -1,10 +1,29 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<!-- <!--
Copyright 2006 Sun Microsystems, Inc. All rights reserved. Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
CA 95054 USA or visit www.sun.com if you need additional information or
have any questions.
--> -->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
<xsl:template match="processcode"> <xsl:template match="processcode">
<xsl:text> <xsl:text>
@ -15,7 +34,6 @@
</xsl:text> </xsl:text>
<xsl:output method="text" indent="no" omit-xml-declaration="yes"/>
</xsl:template> </xsl:template>
</xsl:stylesheet> </xsl:stylesheet>

View File

@ -815,6 +815,7 @@ void ContiguousSpace::allocate_temporary_filler(int factor) {
"size for smallest fake object doesn't match"); "size for smallest fake object doesn't match");
instanceOop obj = (instanceOop) allocate(size); instanceOop obj = (instanceOop) allocate(size);
obj->set_mark(markOopDesc::prototype()); obj->set_mark(markOopDesc::prototype());
obj->set_klass_gap(0);
obj->set_klass(SystemDictionary::object_klass()); obj->set_klass(SystemDictionary::object_klass());
} }
} }

View File

@ -41,11 +41,10 @@ class arrayOopDesc : public oopDesc {
// Header size computation. // Header size computation.
// The header is considered the oop part of this type plus the length. // The header is considered the oop part of this type plus the length.
// Returns the aligned header_size_in_bytes. This is not equivalent to // Returns the aligned header_size_in_bytes. This is not equivalent to
// sizeof(arrayOopDesc) which should not appear in the code, except here. // sizeof(arrayOopDesc) which should not appear in the code.
static int header_size_in_bytes() { static int header_size_in_bytes() {
size_t hs = UseCompressedOops ? size_t hs = align_size_up(length_offset_in_bytes() + sizeof(int),
sizeof(arrayOopDesc) : HeapWordSize);
align_size_up(sizeof(arrayOopDesc) + sizeof(int), HeapWordSize);
#ifdef ASSERT #ifdef ASSERT
// make sure it isn't called before UseCompressedOops is initialized. // make sure it isn't called before UseCompressedOops is initialized.
static size_t arrayoopdesc_hs = 0; static size_t arrayoopdesc_hs = 0;

View File

@ -180,9 +180,8 @@ class instanceKlass: public Klass {
// End of the oop block. // End of the oop block.
// //
// number of words used by non-static fields in this klass (including // Number of heapOopSize words used by non-static fields in this klass
// inherited fields but after header_size()). If fields are compressed into // (including inherited fields but after header_size()).
// header, this can be zero so it's not the same as number of static fields.
int _nonstatic_field_size; int _nonstatic_field_size;
int _static_field_size; // number words used by static fields (oop and non-oop) in this klass int _static_field_size; // number words used by static fields (oop and non-oop) in this klass
int _static_oop_field_size;// number of static oop fields in this klass int _static_oop_field_size;// number of static oop fields in this klass

View File

@ -581,7 +581,7 @@ void instanceKlassKlass::oop_print_on(oop obj, outputStream* st) {
OopMapBlock* map = ik->start_of_nonstatic_oop_maps(); OopMapBlock* map = ik->start_of_nonstatic_oop_maps();
OopMapBlock* end_map = map + ik->nonstatic_oop_map_size(); OopMapBlock* end_map = map + ik->nonstatic_oop_map_size();
while (map < end_map) { while (map < end_map) {
st->print("%d-%d ", map->offset(), map->offset() + oopSize*(map->length() - 1)); st->print("%d-%d ", map->offset(), map->offset() + heapOopSize*(map->length() - 1));
map++; map++;
} }
st->cr(); st->cr();

View File

@ -39,14 +39,7 @@ class instanceOopDesc : public oopDesc {
static bool contains_field_offset(int offset, int nonstatic_field_size) { static bool contains_field_offset(int offset, int nonstatic_field_size) {
int base_in_bytes = base_offset_in_bytes(); int base_in_bytes = base_offset_in_bytes();
if (UseCompressedOops) { return (offset >= base_in_bytes &&
return (offset >= base_in_bytes && (offset-base_in_bytes) < nonstatic_field_size * heapOopSize);
// field can be embedded in header, or is after header.
(offset < (int)sizeof(instanceOopDesc) ||
(offset-(int)sizeof(instanceOopDesc))/wordSize < nonstatic_field_size));
} else {
return (offset >= base_in_bytes &&
(offset-base_in_bytes)/wordSize < nonstatic_field_size);
}
} }
}; };

View File

@ -29,8 +29,10 @@
// //
// Bit-format of an object header (most significant first): // Bit-format of an object header (most significant first):
// //
// // 32 bits: unused:0 hash:25 age:4 biased_lock:1 lock:2
// unused:0/25 hash:25/31 age:4 biased_lock:1 lock:2 = 32/64 bits // 64 bits: unused:24 hash:31 cms:2 age:4 biased_lock:1 lock:2
// unused:20 size:35 cms:2 age:4 biased_lock:1 lock:2 (if cms
// free chunk)
// //
// - hash contains the identity hash value: largest value is // - hash contains the identity hash value: largest value is
// 31 bits, see os::random(). Also, 64-bit vm's require // 31 bits, see os::random(). Also, 64-bit vm's require
@ -91,6 +93,7 @@ class markOopDesc: public oopDesc {
biased_lock_bits = 1, biased_lock_bits = 1,
max_hash_bits = BitsPerWord - age_bits - lock_bits - biased_lock_bits, max_hash_bits = BitsPerWord - age_bits - lock_bits - biased_lock_bits,
hash_bits = max_hash_bits > 31 ? 31 : max_hash_bits, hash_bits = max_hash_bits > 31 ? 31 : max_hash_bits,
cms_bits = LP64_ONLY(1) NOT_LP64(0),
epoch_bits = 2 epoch_bits = 2
}; };
@ -106,7 +109,8 @@ class markOopDesc: public oopDesc {
enum { lock_shift = 0, enum { lock_shift = 0,
biased_lock_shift = lock_bits, biased_lock_shift = lock_bits,
age_shift = lock_bits + biased_lock_bits, age_shift = lock_bits + biased_lock_bits,
hash_shift = lock_bits + biased_lock_bits + age_bits, cms_shift = age_shift + age_bits,
hash_shift = cms_shift + cms_bits,
epoch_shift = hash_shift epoch_shift = hash_shift
}; };
@ -118,7 +122,9 @@ class markOopDesc: public oopDesc {
age_mask = right_n_bits(age_bits), age_mask = right_n_bits(age_bits),
age_mask_in_place = age_mask << age_shift, age_mask_in_place = age_mask << age_shift,
epoch_mask = right_n_bits(epoch_bits), epoch_mask = right_n_bits(epoch_bits),
epoch_mask_in_place = epoch_mask << epoch_shift epoch_mask_in_place = epoch_mask << epoch_shift,
cms_mask = right_n_bits(cms_bits),
cms_mask_in_place = cms_mask << cms_shift
#ifndef _WIN64 #ifndef _WIN64
,hash_mask = right_n_bits(hash_bits), ,hash_mask = right_n_bits(hash_bits),
hash_mask_in_place = (address_word)hash_mask << hash_shift hash_mask_in_place = (address_word)hash_mask << hash_shift
@ -360,4 +366,40 @@ class markOopDesc: public oopDesc {
// see the definition in markOop.cpp for the gory details // see the definition in markOop.cpp for the gory details
bool should_not_be_cached() const; bool should_not_be_cached() const;
// These markOops indicate cms free chunk blocks and not objects.
// In 64 bit, the markOop is set to distinguish them from oops.
// These are defined in 32 bit mode for vmStructs.
const static uintptr_t cms_free_chunk_pattern = 0x1;
// Constants for the size field.
enum { size_shift = cms_shift + cms_bits,
size_bits = 35 // need for compressed oops 32G
};
// These values are too big for Win64
const static uintptr_t size_mask = LP64_ONLY(right_n_bits(size_bits))
NOT_LP64(0);
const static uintptr_t size_mask_in_place =
(address_word)size_mask << size_shift;
#ifdef _LP64
static markOop cms_free_prototype() {
return markOop(((intptr_t)prototype() & ~cms_mask_in_place) |
((cms_free_chunk_pattern & cms_mask) << cms_shift));
}
uintptr_t cms_encoding() const {
return mask_bits(value() >> cms_shift, cms_mask);
}
bool is_cms_free_chunk() const {
return is_neutral() &&
(cms_encoding() & cms_free_chunk_pattern) == cms_free_chunk_pattern;
}
size_t get_size() const { return (size_t)(value() >> size_shift); }
static markOop set_size_and_free(size_t size) {
assert((size & ~size_mask) == 0, "shouldn't overflow size field");
return markOop(((intptr_t)cms_free_prototype() & ~size_mask_in_place) |
(((intptr_t)size & size_mask) << size_shift));
}
#endif // _LP64
}; };

View File

@ -158,7 +158,6 @@ public:
assert(ProfileTraps, "used only under +ProfileTraps"); assert(ProfileTraps, "used only under +ProfileTraps");
uint old_flags = (_header._struct._flags & flag_mask); uint old_flags = (_header._struct._flags & flag_mask);
_header._struct._flags = (new_state << trap_shift) | old_flags; _header._struct._flags = (new_state << trap_shift) | old_flags;
assert(trap_state() == new_state, "sanity");
} }
u1 flags() { u1 flags() {

View File

@ -77,10 +77,15 @@ class oopDesc {
void init_mark(); void init_mark();
klassOop klass() const; klassOop klass() const;
klassOop klass_or_null() const volatile;
oop* klass_addr(); oop* klass_addr();
narrowOop* compressed_klass_addr(); narrowOop* compressed_klass_addr();
void set_klass(klassOop k); void set_klass(klassOop k);
// For klass field compression
int klass_gap() const;
void set_klass_gap(int z);
// For when the klass pointer is being used as a linked list "next" field. // For when the klass pointer is being used as a linked list "next" field.
void set_klass_to_list_ptr(oop k); void set_klass_to_list_ptr(oop k);

Some files were not shown because too many files have changed in this diff Show More