6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
authorcoleenp
Sun Apr 13 17:43:42 2008 -0400 (2 years ago)
changeset 113ba764ed4b6f2
parent 110a49a647afe9a
child 11434935c25a52d
child 115e7a91a357527
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv
Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java
agent/src/share/classes/sun/jvm/hotspot/HSDB.java
agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java
agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java
agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java
agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java
agent/src/share/classes/sun/jvm/hotspot/debugger/Address.java
agent/src/share/classes/sun/jvm/hotspot/debugger/Debugger.java
agent/src/share/classes/sun/jvm/hotspot/debugger/DebuggerBase.java
agent/src/share/classes/sun/jvm/hotspot/debugger/JVMDebugger.java
agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescription.java
agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionAMD64.java
agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionIA64.java
agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionIntelX86.java
agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionSPARC32Bit.java
agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionSPARC64Bit.java
agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxAddress.java
agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxDebugger.java
agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxDebuggerLocal.java
agent/src/share/classes/sun/jvm/hotspot/debugger/dummy/DummyAddress.java
agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java
agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebugger.java
agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java
agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcAddress.java
agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebugger.java
agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java
agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteAddress.java
agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebugger.java
agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java
agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerServer.java
agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Address.java
agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Debugger.java
agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32DebuggerLocal.java
agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgAddress.java
agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebugger.java
agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java
agent/src/share/classes/sun/jvm/hotspot/memory/Universe.java
agent/src/share/classes/sun/jvm/hotspot/oops/Array.java
agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java
agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCacheKlass.java
agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolKlass.java
agent/src/share/classes/sun/jvm/hotspot/oops/DefaultOopVisitor.java
agent/src/share/classes/sun/jvm/hotspot/oops/Instance.java
agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java
agent/src/share/classes/sun/jvm/hotspot/oops/NarrowOopField.java
agent/src/share/classes/sun/jvm/hotspot/oops/ObjArray.java
agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java
agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHistogram.java
agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHistogramElement.java
agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java
agent/src/share/classes/sun/jvm/hotspot/oops/OopPrinter.java
agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java
agent/src/share/classes/sun/jvm/hotspot/oops/OopVisitor.java
agent/src/share/classes/sun/jvm/hotspot/runtime/AddressVisitor.java
agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java
agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
agent/src/share/classes/sun/jvm/hotspot/types/Field.java
agent/src/share/classes/sun/jvm/hotspot/types/NarrowOopField.java
agent/src/share/classes/sun/jvm/hotspot/types/Type.java
agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicField.java
agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicFieldWrapper.java
agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicNarrowOopField.java
agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicOopField.java
agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicType.java
agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java
agent/src/share/classes/sun/jvm/hotspot/ui/FindInHeapPanel.java
agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
agent/src/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java
agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
agent/src/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java
agent/src/share/classes/sun/jvm/hotspot/utilities/RobustOopDeterminator.java
make/Makefile
make/solaris/makefiles/sparcWorks.make
src/cpu/sparc/vm/assembler_sparc.cpp
src/cpu/sparc/vm/assembler_sparc.hpp
src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp
src/cpu/sparc/vm/copy_sparc.hpp
src/cpu/sparc/vm/interp_masm_sparc.cpp
src/cpu/sparc/vm/register_definitions_sparc.cpp
src/cpu/sparc/vm/sharedRuntime_sparc.cpp
src/cpu/sparc/vm/sparc.ad
src/cpu/sparc/vm/stubGenerator_sparc.cpp
src/cpu/sparc/vm/templateInterpreter_sparc.cpp
src/cpu/sparc/vm/templateTable_sparc.cpp
src/cpu/sparc/vm/vm_version_sparc.cpp
src/cpu/sparc/vm/vtableStubs_sparc.cpp
src/cpu/x86/vm/assembler_x86_64.cpp
src/cpu/x86/vm/assembler_x86_64.hpp
src/cpu/x86/vm/c1_MacroAssembler_x86.cpp
src/cpu/x86/vm/interp_masm_x86_64.cpp
src/cpu/x86/vm/interpreter_x86_64.cpp
src/cpu/x86/vm/register_definitions_x86.cpp
src/cpu/x86/vm/sharedRuntime_x86_64.cpp
src/cpu/x86/vm/stubGenerator_x86_64.cpp
src/cpu/x86/vm/templateInterpreter_x86_64.cpp
src/cpu/x86/vm/templateTable_x86_64.cpp
src/cpu/x86/vm/vtableStubs_x86_64.cpp
src/cpu/x86/vm/x86_32.ad
src/cpu/x86/vm/x86_64.ad
src/os/solaris/dtrace/generateJvmOffsets.cpp
src/os/solaris/dtrace/jhelper.d
src/os/solaris/dtrace/libjvm_db.c
src/os/windows/vm/os_windows.cpp
src/os_cpu/solaris_sparc/vm/solaris_sparc.s
src/share/vm/adlc/archDesc.cpp
src/share/vm/adlc/forms.cpp
src/share/vm/adlc/forms.hpp
src/share/vm/adlc/formssel.cpp
src/share/vm/adlc/output_c.cpp
src/share/vm/adlc/output_h.cpp
src/share/vm/asm/codeBuffer.cpp
src/share/vm/c1/c1_Runtime1.cpp
src/share/vm/ci/ciInstanceKlass.cpp
src/share/vm/ci/ciInstanceKlass.hpp
src/share/vm/ci/ciObjectFactory.cpp
src/share/vm/classfile/classFileParser.cpp
src/share/vm/classfile/javaClasses.cpp
src/share/vm/classfile/javaClasses.hpp
src/share/vm/compiler/oopMap.cpp
src/share/vm/compiler/oopMap.hpp
src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp
src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
src/share/vm/gc_implementation/includeDB_gc_parNew
src/share/vm/gc_implementation/includeDB_gc_parallelScavenge
src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp
src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp
src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
src/share/vm/gc_implementation/parNew/parOopClosures.hpp
src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp
src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp
src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp
src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
src/share/vm/gc_implementation/parallelScavenge/prefetchQueue.hpp
src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp
src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp
src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp
src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp
src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp
src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp
src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
src/share/vm/gc_implementation/shared/markSweep.cpp
src/share/vm/gc_implementation/shared/markSweep.hpp
src/share/vm/gc_implementation/shared/markSweep.inline.hpp
src/share/vm/gc_interface/collectedHeap.cpp
src/share/vm/gc_interface/collectedHeap.hpp
src/share/vm/gc_interface/collectedHeap.inline.hpp
src/share/vm/includeDB_core
src/share/vm/interpreter/interpreterRuntime.hpp
src/share/vm/memory/barrierSet.hpp
src/share/vm/memory/barrierSet.inline.hpp
src/share/vm/memory/cardTableModRefBS.cpp
src/share/vm/memory/cardTableModRefBS.hpp
src/share/vm/memory/cardTableRS.cpp
src/share/vm/memory/cardTableRS.hpp
src/share/vm/memory/compactingPermGenGen.cpp
src/share/vm/memory/defNewGeneration.cpp
src/share/vm/memory/defNewGeneration.hpp
src/share/vm/memory/defNewGeneration.inline.hpp
src/share/vm/memory/dump.cpp
src/share/vm/memory/genCollectedHeap.cpp
src/share/vm/memory/genCollectedHeap.hpp
src/share/vm/memory/genMarkSweep.cpp
src/share/vm/memory/genOopClosures.hpp
src/share/vm/memory/genOopClosures.inline.hpp
src/share/vm/memory/genRemSet.hpp
src/share/vm/memory/genRemSet.inline.hpp
src/share/vm/memory/generation.cpp
src/share/vm/memory/generation.hpp
src/share/vm/memory/iterator.hpp
src/share/vm/memory/modRefBarrierSet.hpp
src/share/vm/memory/referenceProcessor.cpp
src/share/vm/memory/referenceProcessor.hpp
src/share/vm/memory/restore.cpp
src/share/vm/memory/serialize.cpp
src/share/vm/memory/sharedHeap.cpp
src/share/vm/memory/space.cpp
src/share/vm/memory/space.hpp
src/share/vm/memory/universe.cpp
src/share/vm/memory/universe.hpp
src/share/vm/oops/arrayOop.hpp
src/share/vm/oops/constantPoolKlass.cpp
src/share/vm/oops/constantPoolKlass.hpp
src/share/vm/oops/constantPoolOop.hpp
src/share/vm/oops/cpCacheKlass.cpp
src/share/vm/oops/cpCacheKlass.hpp
src/share/vm/oops/cpCacheOop.cpp
src/share/vm/oops/cpCacheOop.hpp
src/share/vm/oops/instanceKlass.cpp
src/share/vm/oops/instanceKlass.hpp
src/share/vm/oops/instanceKlassKlass.cpp
src/share/vm/oops/instanceOop.hpp
src/share/vm/oops/instanceRefKlass.cpp
src/share/vm/oops/klass.cpp
src/share/vm/oops/klass.hpp
src/share/vm/oops/klassVtable.cpp
src/share/vm/oops/markOop.hpp
src/share/vm/oops/methodDataKlass.cpp
src/share/vm/oops/methodOop.cpp
src/share/vm/oops/objArrayKlass.cpp
src/share/vm/oops/objArrayKlass.hpp
src/share/vm/oops/objArrayOop.cpp
src/share/vm/oops/objArrayOop.hpp
src/share/vm/oops/oop.cpp
src/share/vm/oops/oop.hpp
src/share/vm/oops/oop.inline.hpp
src/share/vm/oops/oop.pcgc.inline.hpp
src/share/vm/oops/oopsHierarchy.hpp
src/share/vm/opto/buildOopMap.cpp
src/share/vm/opto/callnode.hpp
src/share/vm/opto/cfgnode.cpp
src/share/vm/opto/chaitin.cpp
src/share/vm/opto/classes.hpp
src/share/vm/opto/compile.cpp
src/share/vm/opto/connode.cpp
src/share/vm/opto/connode.hpp
src/share/vm/opto/escape.cpp
src/share/vm/opto/graphKit.cpp
src/share/vm/opto/idealKit.cpp
src/share/vm/opto/lcm.cpp
src/share/vm/opto/library_call.cpp
src/share/vm/opto/loopTransform.cpp
src/share/vm/opto/machnode.cpp
src/share/vm/opto/macro.cpp
src/share/vm/opto/macro.hpp
src/share/vm/opto/matcher.cpp
src/share/vm/opto/memnode.cpp
src/share/vm/opto/memnode.hpp
src/share/vm/opto/node.cpp
src/share/vm/opto/node.hpp
src/share/vm/opto/opcodes.cpp
src/share/vm/opto/opcodes.hpp
src/share/vm/opto/parse2.cpp
src/share/vm/opto/parse3.cpp
src/share/vm/opto/phaseX.cpp
src/share/vm/opto/phaseX.hpp
src/share/vm/opto/subnode.cpp
src/share/vm/opto/subnode.hpp
src/share/vm/opto/superword.cpp
src/share/vm/opto/type.cpp
src/share/vm/opto/type.hpp
src/share/vm/prims/jni.cpp
src/share/vm/prims/jvmtiTagMap.cpp
src/share/vm/prims/unsafe.cpp
src/share/vm/runtime/arguments.cpp
src/share/vm/runtime/atomic.cpp
src/share/vm/runtime/atomic.hpp
src/share/vm/runtime/frame.cpp
src/share/vm/runtime/frame.hpp
src/share/vm/runtime/globals.cpp
src/share/vm/runtime/globals.hpp
src/share/vm/runtime/globals_extension.hpp
src/share/vm/runtime/hpi.cpp
src/share/vm/runtime/init.cpp
src/share/vm/runtime/jniHandles.cpp
src/share/vm/runtime/vmStructs.cpp
src/share/vm/services/heapDumper.cpp
src/share/vm/utilities/copy.hpp
src/share/vm/utilities/debug.cpp
src/share/vm/utilities/globalDefinitions.cpp
src/share/vm/utilities/globalDefinitions.hpp
src/share/vm/utilities/taskqueue.hpp
src/share/vm/utilities/vmError.cpp
--- a/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Sun Apr 13 17:43:42 2008 -0400
@@ -885,7 +885,12 @@ public class CommandProcessor {
out.println("found at " + addr);
}
}
-
+ public void visitCompOopAddress(Address addr) {
+ Address val = addr.getCompOopAddressAt(0);
+ if (AddressOps.equal(val, value)) {
+ out.println("found at " + addr);
+ }
+ }
public void epilogue() {
}
};
--- a/agent/src/share/classes/sun/jvm/hotspot/HSDB.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/HSDB.java Sun Apr 13 17:43:42 2008 -0400
@@ -1011,8 +1011,21 @@ public class HSDB implements ObjectHisto
Assert.that(addr.andWithMask(VM.getVM().getAddressSize() - 1) == null,
"Address " + addr + "should have been aligned");
}
+ OopHandle handle = addr.getOopHandleAt(0);
+ addAnnotation(addr, handle);
+ }
+
+ public void visitCompOopAddress(Address addr) {
+ if (Assert.ASSERTS_ENABLED) {
+ Assert.that(addr.andWithMask(VM.getVM().getAddressSize() - 1) == null,
+ "Address " + addr + "should have been aligned");
+ }
+ OopHandle handle = addr.getCompOopHandleAt(0);
+ addAnnotation(addr, handle);
+ }
+
+ public void addAnnotation(Address addr, OopHandle handle) {
// Check contents
- OopHandle handle = addr.getOopHandleAt(0);
String anno = "null oop";
if (handle != null) {
// Find location
--- a/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java Sun Apr 13 17:43:42 2008 -0400
@@ -306,6 +306,8 @@ public class HotSpotTypeDataBase extends
entryAddr = entryAddr.addOffsetTo(intConstantEntryArrayStride);
} while (nameAddr != null);
+ String symbol = "heapOopSize"; // global int constant and value is initialized at runtime.
+ addIntConstant(symbol, (int)lookupInProcess(symbol).getCIntegerAt(0, 4, false));
}
private void readVMLongConstants() {
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java Sun Apr 13 17:43:42 2008 -0400
@@ -68,7 +68,8 @@ public class OopMapSet extends VMObject
public void visitValueLocation(Address valueAddr) {
}
- public void visitDeadLocation(Address deadAddr) {
+ public void visitNarrowOopLocation(Address narrowOopAddr) {
+ addressVisitor.visitCompOopAddress(narrowOopAddr);
}
}
@@ -197,9 +198,9 @@ public class OopMapSet extends VMObject
}
}
- // We want dead, value and oop oop_types
+ // We want narow oop, value and oop oop_types
OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[] {
- OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.VALUE_VALUE, OopMapValue.OopTypes.DEAD_VALUE
+ OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.VALUE_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
};
{
@@ -214,8 +215,8 @@ public class OopMapSet extends VMObject
visitor.visitOopLocation(loc);
} else if (omv.getType() == OopMapValue.OopTypes.VALUE_VALUE) {
visitor.visitValueLocation(loc);
- } else if (omv.getType() == OopMapValue.OopTypes.DEAD_VALUE) {
- visitor.visitDeadLocation(loc);
+ } else if (omv.getType() == OopMapValue.OopTypes.NARROWOOP_VALUE) {
+ visitor.visitNarrowOopLocation(loc);
}
}
}
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java Sun Apr 13 17:43:42 2008 -0400
@@ -50,7 +50,7 @@ public class OopMapValue {
static int UNUSED_VALUE;
static int OOP_VALUE;
static int VALUE_VALUE;
- static int DEAD_VALUE;
+ static int NARROWOOP_VALUE;
static int CALLEE_SAVED_VALUE;
static int DERIVED_OOP_VALUE;
@@ -74,7 +74,7 @@ public class OopMapValue {
UNUSED_VALUE = db.lookupIntConstant("OopMapValue::unused_value").intValue();
OOP_VALUE = db.lookupIntConstant("OopMapValue::oop_value").intValue();
VALUE_VALUE = db.lookupIntConstant("OopMapValue::value_value").intValue();
- DEAD_VALUE = db.lookupIntConstant("OopMapValue::dead_value").intValue();
+ NARROWOOP_VALUE = db.lookupIntConstant("OopMapValue::narrowoop_value").intValue();
CALLEE_SAVED_VALUE = db.lookupIntConstant("OopMapValue::callee_saved_value").intValue();
DERIVED_OOP_VALUE = db.lookupIntConstant("OopMapValue::derived_oop_value").intValue();
}
@@ -83,7 +83,7 @@ public class OopMapValue {
public static final OopTypes UNUSED_VALUE = new OopTypes() { int getValue() { return OopMapValue.UNUSED_VALUE; }};
public static final OopTypes OOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.OOP_VALUE; }};
public static final OopTypes VALUE_VALUE = new OopTypes() { int getValue() { return OopMapValue.VALUE_VALUE; }};
- public static final OopTypes DEAD_VALUE = new OopTypes() { int getValue() { return OopMapValue.DEAD_VALUE; }};
+ public static final OopTypes NARROWOOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.NARROWOOP_VALUE; }};
public static final OopTypes CALLEE_SAVED_VALUE = new OopTypes() { int getValue() { return OopMapValue.CALLEE_SAVED_VALUE; }};
public static final OopTypes DERIVED_OOP_VALUE = new OopTypes() { int getValue() { return OopMapValue.DERIVED_OOP_VALUE; }};
@@ -106,7 +106,7 @@ public class OopMapValue {
// Querying
public boolean isOop() { return (getValue() & TYPE_MASK_IN_PLACE) == OOP_VALUE; }
public boolean isValue() { return (getValue() & TYPE_MASK_IN_PLACE) == VALUE_VALUE; }
- public boolean isDead() { return (getValue() & TYPE_MASK_IN_PLACE) == DEAD_VALUE; }
+ public boolean isNarrowOop() { return (getValue() & TYPE_MASK_IN_PLACE) == NARROWOOP_VALUE; }
public boolean isCalleeSaved() { return (getValue() & TYPE_MASK_IN_PLACE) == CALLEE_SAVED_VALUE; }
public boolean isDerivedOop() { return (getValue() & TYPE_MASK_IN_PLACE) == DERIVED_OOP_VALUE; }
@@ -118,7 +118,7 @@ public class OopMapValue {
if (which == UNUSED_VALUE) return OopTypes.UNUSED_VALUE;
else if (which == OOP_VALUE) return OopTypes.OOP_VALUE;
else if (which == VALUE_VALUE) return OopTypes.VALUE_VALUE;
- else if (which == DEAD_VALUE) return OopTypes.DEAD_VALUE;
+ else if (which == NARROWOOP_VALUE) return OopTypes.NARROWOOP_VALUE;
else if (which == CALLEE_SAVED_VALUE) return OopTypes.CALLEE_SAVED_VALUE;
else if (which == DERIVED_OOP_VALUE) return OopTypes.DERIVED_OOP_VALUE;
else throw new InternalError("unknown which " + which + " (TYPE_MASK_IN_PLACE = " + TYPE_MASK_IN_PLACE + ")");
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapVisitor.java Sun Apr 13 17:43:42 2008 -0400
@@ -32,5 +32,5 @@ public interface OopMapVisitor {
public void visitOopLocation(Address oopAddr);
public void visitDerivedOopLocation(Address baseOopAddr, Address derivedOopAddr);
public void visitValueLocation(Address valueAddr);
- public void visitDeadLocation(Address deadAddr);
+ public void visitNarrowOopLocation(Address narrowOopAddr);
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/Address.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/Address.java Sun Apr 13 17:43:42 2008 -0400
@@ -87,6 +87,8 @@ public interface Address {
throws UnmappedAddressException, UnalignedAddressException;
/** This returns null if the address at the given offset is NULL. */
public Address getAddressAt (long offset) throws UnmappedAddressException, UnalignedAddressException;
+ /** Returns the decoded address at the given offset */
+ public Address getCompOopAddressAt (long offset) throws UnmappedAddressException, UnalignedAddressException;
//
// Java-related routines
@@ -103,6 +105,8 @@ public interface Address {
/** This returns null if the address at the given offset is NULL. */
public OopHandle getOopHandleAt (long offset)
throws UnmappedAddressException, UnalignedAddressException, NotInHeapException;
+ public OopHandle getCompOopHandleAt (long offset)
+ throws UnmappedAddressException, UnalignedAddressException, NotInHeapException;
//
// C/C++-related mutators. These throw UnmappedAddressException if
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/Debugger.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/Debugger.java Sun Apr 13 17:43:42 2008 -0400
@@ -118,6 +118,9 @@ public interface Debugger extends Symbol
public long getJIntSize();
public long getJLongSize();
public long getJShortSize();
+ public long getHeapBase();
+ public long getHeapOopSize();
+ public long getLogMinObjAlignmentInBytes();
public ReadResult readBytesFromProcess(long address, long numBytes)
throws DebuggerException;
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/DebuggerBase.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/DebuggerBase.java Sun Apr 13 17:43:42 2008 -0400
@@ -37,6 +37,7 @@ package sun.jvm.hotspot.debugger;
DbxDebugger interfaces. </P> */
public abstract class DebuggerBase implements Debugger {
+
// May be set lazily, but must be set before calling any of the read
// routines below
protected MachineDescription machDesc;
@@ -52,6 +53,11 @@ public abstract class DebuggerBase imple
protected long jlongSize;
protected long jshortSize;
protected boolean javaPrimitiveTypesConfigured;
+ // heap data.
+ protected long oopSize;
+ protected long heapOopSize;
+ protected long heapBase; // heap base for compressed oops.
+ protected long logMinObjAlignmentInBytes; // Used to decode compressed oops.
// Should be initialized if desired by calling initCache()
private PageCache cache;
@@ -153,6 +159,12 @@ public abstract class DebuggerBase imple
javaPrimitiveTypesConfigured = true;
}
+ public void putHeapConst(long heapBase, long heapOopSize, long logMinObjAlignmentInBytes) {
+ this.heapBase = heapBase;
+ this.heapOopSize = heapOopSize;
+ this.logMinObjAlignmentInBytes = logMinObjAlignmentInBytes;
+ }
+
/** May be called by subclasses if desired to initialize the page
cache but may not be overridden */
protected final void initCache(long pageSize, long maxNumPages) {
@@ -442,6 +454,16 @@ public abstract class DebuggerBase imple
return readCInteger(address, machDesc.getAddressSize(), true);
}
+ protected long readCompOopAddressValue(long address)
+ throws UnmappedAddressException, UnalignedAddressException {
+ long value = readCInteger(address, getHeapOopSize(), true);
+ if (value != 0) {
+ // See oop.inline.hpp decode_heap_oop
+ value = (long)(heapBase + (long)(value << logMinObjAlignmentInBytes));
+ }
+ return value;
+ }
+
protected void writeAddressValue(long address, long value)
throws UnmappedAddressException, UnalignedAddressException {
writeCInteger(address, machDesc.getAddressSize(), value);
@@ -518,4 +540,15 @@ public abstract class DebuggerBase imple
public long getJShortSize() {
return jshortSize;
}
+
+ public long getHeapOopSize() {
+ return heapOopSize;
+ }
+
+ public long getHeapBase() {
+ return heapBase;
+ }
+ public long getLogMinObjAlignmentInBytes() {
+ return logMinObjAlignmentInBytes;
+ }
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/JVMDebugger.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/JVMDebugger.java Sun Apr 13 17:43:42 2008 -0400
@@ -42,4 +42,5 @@ public interface JVMDebugger extends Deb
long jintSize,
long jlongSize,
long jshortSize);
+ public void putHeapConst(long heapBase, long heapOopSize, long logMinObjAlignment);
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescription.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescription.java Sun Apr 13 17:43:42 2008 -0400
@@ -35,13 +35,6 @@ public interface MachineDescription exte
able to traverse arrays of pointers or oops. */
public long getAddressSize();
- /** Returns the size of an address in bytes. Currently needed to be
- able to traverse arrays of pointers or oops. (FIXME: since we're
- already reading the Java primitive types' sizes from the remote
- VM, it would be nice to remove this routine, using a similar
- mechanism to how the TypeDataBase deals with primitive types.) */
- public long getOopSize();
-
/** Returns the maximum value of the C integer type with the given
size in bytes and signedness. Throws IllegalArgumentException if
the size in bytes is not legal for a C type (or can not be
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionAMD64.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionAMD64.java Sun Apr 13 17:43:42 2008 -0400
@@ -29,10 +29,6 @@ public class MachineDescriptionAMD64 ext
return 8;
}
- public long getOopSize() {
- return 8;
- }
-
public boolean isLP64() {
return true;
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionIA64.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionIA64.java Sun Apr 13 17:43:42 2008 -0400
@@ -29,10 +29,6 @@ public class MachineDescriptionIA64 exte
return 8;
}
- public long getOopSize() {
- return 8;
- }
-
public boolean isLP64() {
return true;
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionIntelX86.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionIntelX86.java Sun Apr 13 17:43:42 2008 -0400
@@ -29,10 +29,6 @@ public class MachineDescriptionIntelX86
return 4;
}
- public long getOopSize() {
- return 4;
- }
-
public boolean isBigEndian() {
return false;
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionSPARC32Bit.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionSPARC32Bit.java Sun Apr 13 17:43:42 2008 -0400
@@ -29,10 +29,6 @@ public class MachineDescriptionSPARC32Bi
return 4;
}
- public long getOopSize() {
- return 4;
- }
-
public boolean isBigEndian() {
return true;
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionSPARC64Bit.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/MachineDescriptionSPARC64Bit.java Sun Apr 13 17:43:42 2008 -0400
@@ -29,9 +29,6 @@ public class MachineDescriptionSPARC64Bi
return 8;
}
- public long getOopSize() {
- return 8;
- }
public boolean isBigEndian() {
return true;
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxAddress.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxAddress.java Sun Apr 13 17:43:42 2008 -0400
@@ -71,6 +71,9 @@ class DbxAddress implements Address {
public Address getAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
return debugger.readAddress(addr + offset);
}
+ public Address getCompOopAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
+ return debugger.readCompOopAddress(addr + offset);
+ }
//
// Java-related routines
@@ -111,6 +114,11 @@ class DbxAddress implements Address {
public OopHandle getOopHandleAt(long offset)
throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
return debugger.readOopHandle(addr + offset);
+ }
+
+ public OopHandle getCompOopHandleAt(long offset)
+ throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
+ return debugger.readCompOopHandle(addr + offset);
}
// Mutators -- not implemented for now (FIXME)
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxDebugger.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxDebugger.java Sun Apr 13 17:43:42 2008 -0400
@@ -43,7 +43,9 @@ public interface DbxDebugger extends JVM
public long readCInteger(long address, long numBytes, boolean isUnsigned)
throws DebuggerException;
public DbxAddress readAddress(long address) throws DebuggerException;
+ public DbxAddress readCompOopAddress(long address) throws DebuggerException;
public DbxOopHandle readOopHandle(long address) throws DebuggerException;
+ public DbxOopHandle readCompOopHandle(long address) throws DebuggerException;
public long[] getThreadIntegerRegisterSet(int tid) throws DebuggerException;
public Address newAddress(long value) throws DebuggerException;
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxDebuggerLocal.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/dbx/DbxDebuggerLocal.java Sun Apr 13 17:43:42 2008 -0400
@@ -460,10 +460,21 @@ public class DbxDebuggerLocal extends De
return (value == 0 ? null : new DbxAddress(this, value));
}
+ public DbxAddress readCompOopAddress(long address)
+ throws UnmappedAddressException, UnalignedAddressException {
+ long value = readCompOopAddressValue(address);
+ return (value == 0 ? null : new DbxAddress(this, value));
+ }
+
/** From the DbxDebugger interface */
public DbxOopHandle readOopHandle(long address)
throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
long value = readAddressValue(address);
+ return (value == 0 ? null : new DbxOopHandle(this, value));
+ }
+ public DbxOopHandle readCompOopHandle(long address)
+ throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
+ long value = readCompOopAddressValue(address);
return (value == 0 ? null : new DbxOopHandle(this, value));
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/dummy/DummyAddress.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/dummy/DummyAddress.java Sun Apr 13 17:43:42 2008 -0400
@@ -76,6 +76,10 @@ class DummyAddress implements Address {
return new DummyAddress(debugger, badLong);
}
+ public Address getCompOopAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
+ return new DummyAddress(debugger, badLong);
+ }
+
//
// Java-related routines
//
@@ -113,6 +117,10 @@ class DummyAddress implements Address {
}
public OopHandle getOopHandleAt(long offset)
+ throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
+ return new DummyOopHandle(debugger, badLong);
+ }
+ public OopHandle getCompOopHandleAt(long offset)
throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
return new DummyOopHandle(debugger, badLong);
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java Sun Apr 13 17:43:42 2008 -0400
@@ -74,6 +74,11 @@ class LinuxAddress implements Address {
return debugger.readAddress(addr + offset);
}
+ public Address getCompOopAddressAt(long offset)
+ throws UnalignedAddressException, UnmappedAddressException {
+ return debugger.readCompOopAddress(addr + offset);
+ }
+
//
// Java-related routines
//
@@ -113,6 +118,11 @@ class LinuxAddress implements Address {
public OopHandle getOopHandleAt(long offset)
throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
return debugger.readOopHandle(addr + offset);
+ }
+
+ public OopHandle getCompOopHandleAt(long offset)
+ throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
+ return debugger.readCompOopHandle(addr + offset);
}
// Mutators -- not implemented for now (FIXME)
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebugger.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebugger.java Sun Apr 13 17:43:42 2008 -0400
@@ -45,7 +45,9 @@ public interface LinuxDebugger extends J
public long readCInteger(long address, long numBytes, boolean isUnsigned)
throws DebuggerException;
public LinuxAddress readAddress(long address) throws DebuggerException;
+ public LinuxAddress readCompOopAddress(long address) throws DebuggerException;
public LinuxOopHandle readOopHandle(long address) throws DebuggerException;
+ public LinuxOopHandle readCompOopHandle(long address) throws DebuggerException;
public long[] getThreadIntegerRegisterSet(int lwp_id) throws DebuggerException;
public long getAddressValue(Address addr) throws DebuggerException;
public Address newAddress(long value) throws DebuggerException;
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java Sun Apr 13 17:43:42 2008 -0400
@@ -423,12 +423,23 @@ public class LinuxDebuggerLocal extends
long value = readAddressValue(address);
return (value == 0 ? null : new LinuxAddress(this, value));
}
+ public LinuxAddress readCompOopAddress(long address)
+ throws UnmappedAddressException, UnalignedAddressException {
+ long value = readCompOopAddressValue(address);
+ return (value == 0 ? null : new LinuxAddress(this, value));
+ }
/** From the LinuxDebugger interface */
public LinuxOopHandle readOopHandle(long address)
throws UnmappedAddressException, UnalignedAddressException,
NotInHeapException {
long value = readAddressValue(address);
+ return (value == 0 ? null : new LinuxOopHandle(this, value));
+ }
+ public LinuxOopHandle readCompOopHandle(long address)
+ throws UnmappedAddressException, UnalignedAddressException,
+ NotInHeapException {
+ long value = readCompOopAddressValue(address);
return (value == 0 ? null : new LinuxOopHandle(this, value));
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcAddress.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcAddress.java Sun Apr 13 17:43:42 2008 -0400
@@ -72,6 +72,10 @@ class ProcAddress implements Address {
return debugger.readAddress(addr + offset);
}
+ public Address getCompOopAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
+ return debugger.readCompOopAddress(addr + offset);
+ }
+
//
// Java-related routines
//
@@ -111,6 +115,10 @@ class ProcAddress implements Address {
public OopHandle getOopHandleAt(long offset)
throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
return debugger.readOopHandle(addr + offset);
+ }
+ public OopHandle getCompOopHandleAt(long offset)
+ throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
+ return debugger.readCompOopHandle(addr + offset);
}
// Mutators -- not implemented for now (FIXME)
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebugger.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebugger.java Sun Apr 13 17:43:42 2008 -0400
@@ -46,7 +46,9 @@ public interface ProcDebugger extends JV
public long readCInteger(long address, long numBytes, boolean isUnsigned)
throws DebuggerException;
public ProcAddress readAddress(long address) throws DebuggerException;
+ public ProcAddress readCompOopAddress(long address) throws DebuggerException;
public ProcOopHandle readOopHandle(long address) throws DebuggerException;
+ public ProcOopHandle readCompOopHandle(long address) throws DebuggerException;
public long[] getThreadIntegerRegisterSet(int tid) throws DebuggerException;
public long getAddressValue(Address addr) throws DebuggerException;
public Address newAddress(long value) throws DebuggerException;
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java Sun Apr 13 17:43:42 2008 -0400
@@ -53,8 +53,6 @@ import sun.jvm.hotspot.utilities.*;
*/
public class ProcDebuggerLocal extends DebuggerBase implements ProcDebugger {
-
-
protected static final int cacheSize = 16 * 1024 * 1024; // 16 MB
//------------------------------------------------------------------------
@@ -337,10 +335,21 @@ public class ProcDebuggerLocal extends D
return (value == 0 ? null : new ProcAddress(this, value));
}
+ public ProcAddress readCompOopAddress(long address)
+ throws UnmappedAddressException, UnalignedAddressException {
+ long value = readCompOopAddressValue(address);
+ return (value == 0 ? null : new ProcAddress(this, value));
+ }
+
/** From the ProcDebugger interface */
public ProcOopHandle readOopHandle(long address)
throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
- long value = readAddressValue(address);
+ long value = readAddressValue(address);
+ return (value == 0 ? null : new ProcOopHandle(this, value));
+ }
+
+ public ProcOopHandle readCompOopHandle(long address) {
+ long value = readCompOopAddressValue(address);
return (value == 0 ? null : new ProcOopHandle(this, value));
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteAddress.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteAddress.java Sun Apr 13 17:43:42 2008 -0400
@@ -71,6 +71,9 @@ class RemoteAddress implements Address {
public Address getAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
return debugger.readAddress(addr + offset);
}
+ public Address getCompOopAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
+ return debugger.readCompOopAddress(addr + offset);
+ }
//
// Java-related routines
@@ -111,6 +114,10 @@ class RemoteAddress implements Address {
public OopHandle getOopHandleAt(long offset)
throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
return debugger.readOopHandle(addr + offset);
+ }
+ public OopHandle getCompOopHandleAt(long offset)
+ throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
+ return debugger.readCompOopHandle(addr + offset);
}
// Mutators -- not implemented for now (FIXME)
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebugger.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebugger.java Sun Apr 13 17:43:42 2008 -0400
@@ -65,6 +65,9 @@ public interface RemoteDebugger extends
public long getJIntSize() throws RemoteException;
public long getJLongSize() throws RemoteException;
public long getJShortSize() throws RemoteException;
+ public long getHeapBase() throws RemoteException;
+ public long getHeapOopSize() throws RemoteException;
+ public long getLogMinObjAlignmentInBytes() throws RemoteException;
public boolean areThreadsEqual(long addrOrId1, boolean isAddress1,
long addrOrId2, boolean isAddress2) throws RemoteException;
public int getThreadHashCode(long addrOrId, boolean isAddress) throws RemoteException;
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java Sun Apr 13 17:43:42 2008 -0400
@@ -85,6 +85,9 @@ public class RemoteDebuggerClient extend
jlongSize = remoteDebugger.getJLongSize();
jshortSize = remoteDebugger.getJShortSize();
javaPrimitiveTypesConfigured = true;
+ heapBase = remoteDebugger.getHeapBase();
+ heapOopSize = remoteDebugger.getHeapOopSize();
+ logMinObjAlignmentInBytes = remoteDebugger.getLogMinObjAlignmentInBytes();
}
catch (RemoteException e) {
throw new DebuggerException(e);
@@ -298,12 +301,24 @@ public class RemoteDebuggerClient extend
return (value == 0 ? null : new RemoteAddress(this, value));
}
+ RemoteAddress readCompOopAddress(long address)
+ throws UnmappedAddressException, UnalignedAddressException {
+ long value = readCompOopAddressValue(address);
+ return (value == 0 ? null : new RemoteAddress(this, value));
+ }
+
RemoteOopHandle readOopHandle(long address)
throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
long value = readAddressValue(address);
return (value == 0 ? null : new RemoteOopHandle(this, value));
}
+ RemoteOopHandle readCompOopHandle(long address)
+ throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
+ long value = readCompOopAddressValue(address);
+ return (value == 0 ? null : new RemoteOopHandle(this, value));
+ }
+
boolean areThreadsEqual(Address addr1, Address addr2) {
try {
return remoteDebugger.areThreadsEqual(getAddressValue(addr1), true,
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerServer.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerServer.java Sun Apr 13 17:43:42 2008 -0400
@@ -114,6 +114,17 @@ public class RemoteDebuggerServer extend
return debugger.getJShortSize();
}
+ public long getHeapBase() throws RemoteException {
+ return debugger.getHeapBase();
+ }
+
+ public long getHeapOopSize() throws RemoteException {
+ return debugger.getHeapOopSize();
+ }
+
+ public long getLogMinObjAlignmentInBytes() throws RemoteException {
+ return debugger.getLogMinObjAlignmentInBytes();
+ }
public boolean areThreadsEqual(long addrOrId1, boolean isAddress1,
long addrOrId2, boolean isAddress2) throws RemoteException {
ThreadProxy t1 = getThreadProxy(addrOrId1, isAddress1);
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Address.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Address.java Sun Apr 13 17:43:42 2008 -0400
@@ -72,6 +72,10 @@ class Win32Address implements Address {
return debugger.readAddress(addr + offset);
}
+ public Address getCompOopAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
+ return debugger.readCompOopAddress(addr + offset);
+ }
+
//
// Java-related routines
//
@@ -111,6 +115,10 @@ class Win32Address implements Address {
public OopHandle getOopHandleAt(long offset)
throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
return debugger.readOopHandle(addr + offset);
+ }
+ public OopHandle getCompOopHandleAt(long offset)
+ throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
+ return debugger.readCompOopHandle(addr + offset);
}
//
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Debugger.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32Debugger.java Sun Apr 13 17:43:42 2008 -0400
@@ -45,7 +45,9 @@ public interface Win32Debugger extends J
public long readCInteger(long address, long numBytes, boolean isUnsigned)
throws DebuggerException;
public Win32Address readAddress(long address) throws DebuggerException;
+ public Win32Address readCompOopAddress(long address) throws DebuggerException;
public Win32OopHandle readOopHandle(long address) throws DebuggerException;
+ public Win32OopHandle readCompOopHandle(long address) throws DebuggerException;
public void writeJBoolean(long address, boolean value) throws DebuggerException;
public void writeJByte(long address, byte value) throws DebuggerException;
public void writeJChar(long address, char value) throws DebuggerException;
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32DebuggerLocal.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/Win32DebuggerLocal.java Sun Apr 13 17:43:42 2008 -0400
@@ -306,10 +306,20 @@ public class Win32DebuggerLocal extends
return (Win32Address) newAddress(readAddressValue(address));
}
+ public Win32Address readCompOopAddress(long address)
+ throws UnmappedAddressException, UnalignedAddressException {
+ return (Win32Address) newAddress(readCompOopAddressValue(address));
+ }
+
/** From the Win32Debugger interface */
public Win32OopHandle readOopHandle(long address)
throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
long value = readAddressValue(address);
+ return (value == 0 ? null : new Win32OopHandle(this, value));
+ }
+ public Win32OopHandle readCompOopHandle(long address)
+ throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
+ long value = readCompOopAddressValue(address);
return (value == 0 ? null : new Win32OopHandle(this, value));
}
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgAddress.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgAddress.java Sun Apr 13 17:43:42 2008 -0400
@@ -72,6 +72,10 @@ class WindbgAddress implements Address {
return debugger.readAddress(addr + offset);
}
+ public Address getCompOopAddressAt(long offset) throws UnalignedAddressException, UnmappedAddressException {
+ return debugger.readCompOopAddress(addr + offset);
+ }
+
//
// Java-related routines
//
@@ -113,6 +117,10 @@ class WindbgAddress implements Address {
return debugger.readOopHandle(addr + offset);
}
+ public OopHandle getCompOopHandleAt(long offset)
+ throws UnalignedAddressException, UnmappedAddressException, NotInHeapException {
+ return debugger.readCompOopHandle(addr + offset);
+ }
//
// C/C++-related mutators
//
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebugger.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebugger.java Sun Apr 13 17:43:42 2008 -0400
@@ -45,7 +45,9 @@ public interface WindbgDebugger extends
public long readCInteger(long address, long numBytes, boolean isUnsigned)
throws DebuggerException;
public WindbgAddress readAddress(long address) throws DebuggerException;
+ public WindbgAddress readCompOopAddress(long address) throws DebuggerException;
public WindbgOopHandle readOopHandle(long address) throws DebuggerException;
+ public WindbgOopHandle readCompOopHandle(long address) throws DebuggerException;
// The returned array of register contents is guaranteed to be in
// the same order as in the DbxDebugger for Solaris/x86 or amd64; that is,
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java Sun Apr 13 17:43:42 2008 -0400
@@ -39,6 +39,7 @@ import sun.jvm.hotspot.debugger.cdbg.bas
import sun.jvm.hotspot.debugger.cdbg.basic.BasicDebugEvent;
import sun.jvm.hotspot.utilities.*;
import sun.jvm.hotspot.utilities.memo.*;
+import sun.jvm.hotspot.runtime.*;
/** <P> An implementation of the JVMDebugger interface which talks to
windbg and symbol table management is done in Java. </P>
@@ -315,10 +316,20 @@ public class WindbgDebuggerLocal extends
return (WindbgAddress) newAddress(readAddressValue(address));
}
+ public WindbgAddress readCompOopAddress(long address)
+ throws UnmappedAddressException, UnalignedAddressException {
+ return (WindbgAddress) newAddress(readCompOopAddressValue(address));
+ }
+
/** From the WindbgDebugger interface */
public WindbgOopHandle readOopHandle(long address)
throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
long value = readAddressValue(address);
+ return (value == 0 ? null : new WindbgOopHandle(this, value));
+ }
+ public WindbgOopHandle readCompOopHandle(long address)
+ throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
+ long value = readCompOopAddressValue(address);
return (value == 0 ? null : new WindbgOopHandle(this, value));
}
--- a/agent/src/share/classes/sun/jvm/hotspot/memory/Universe.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/memory/Universe.java Sun Apr 13 17:43:42 2008 -0400
@@ -53,6 +53,8 @@ public class Universe {
// system obj array klass object
private static sun.jvm.hotspot.types.OopField systemObjArrayKlassObjField;
+ private static AddressField heapBaseField;
+
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
@@ -83,6 +85,8 @@ public class Universe {
doubleArrayKlassObjField = type.getOopField("_doubleArrayKlassObj");
systemObjArrayKlassObjField = type.getOopField("_systemObjArrayKlassObj");
+
+ heapBaseField = type.getAddressField("_heap_base");
}
public Universe() {
@@ -93,6 +97,14 @@ public class Universe {
return (CollectedHeap) heapConstructor.instantiateWrapperFor(collectedHeapField.getValue());
} catch (WrongTypeException e) {
return new CollectedHeap(collectedHeapField.getValue());
+ }
+ }
+
+ public static long getHeapBase() {
+ if (heapBaseField.getValue() == null) {
+ return 0;
+ } else {
+ return heapBaseField.getValue().minus(null);
}
}
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Array.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Array.java Sun Apr 13 17:43:42 2008 -0400
@@ -47,18 +47,52 @@ public class Array extends Oop {
private static void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("arrayOopDesc");
- length = new CIntField(type.getCIntegerField("_length"), 0);
- headerSize = type.getSize();
+ typeSize = (int)type.getSize();
}
// Size of the arrayOopDesc
- private static long headerSize;
+ private static long headerSize=0;
+ private static long lengthOffsetInBytes=0;
+ private static long typeSize;
- // Fields
- private static CIntField length;
+ private static long headerSizeInBytes() {
+ if (headerSize != 0) {
+ return headerSize;
+ }
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ headerSize = typeSize;
+ } else {
+ headerSize = VM.getVM().alignUp(typeSize + VM.getVM().getIntSize(),
+ VM.getVM().getHeapWordSize());
+ }
+ return headerSize;
+ }
+
+ private static long headerSize(BasicType type) {
+ if (Universe.elementTypeShouldBeAligned(type)) {
+ return alignObjectSize(headerSizeInBytes())/VM.getVM().getHeapWordSize();
+ } else {
+ return headerSizeInBytes()/VM.getVM().getHeapWordSize();
+ }
+ }
+
+ private long lengthOffsetInBytes() {
+ if (lengthOffsetInBytes != 0) {
+ return lengthOffsetInBytes;
+ }
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ lengthOffsetInBytes = typeSize - VM.getVM().getIntSize();
+ } else {
+ lengthOffsetInBytes = typeSize;
+ }
+ return lengthOffsetInBytes;
+ }
// Accessors for declared fields
- public long getLength() { return length.getValue(this); }
+ public long getLength() {
+ boolean isUnsigned = true;
+ return this.getHandle().getCIntegerAt(lengthOffsetInBytes(), VM.getVM().getIntSize(), isUnsigned);
+ }
public long getObjectSize() {
ArrayKlass klass = (ArrayKlass) getKlass();
@@ -72,20 +106,12 @@ public class Array extends Oop {
}
public static long baseOffsetInBytes(BasicType type) {
- if (Universe.elementTypeShouldBeAligned(type)) {
- return (VM.getVM().isLP64()) ? alignObjectSize(headerSize)
- : VM.getVM().alignUp(headerSize, 8);
- } else {
- return headerSize;
- }
+ return headerSize(type) * VM.getVM().getHeapWordSize();
}
public boolean isArray() { return true; }
public void iterateFields(OopVisitor visitor, boolean doVMFields) {
super.iterateFields(visitor, doVMFields);
- if (doVMFields) {
- visitor.doCInt(length, true);
- }
}
}
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Sun Apr 13 17:43:42 2008 -0400
@@ -31,10 +31,10 @@ import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.utilities.*;
-// A ConstantPool is an array containing class constants
+// A ConstantPool is an oop containing class constants
// as described in the class file
-public class ConstantPool extends Array implements ClassConstants {
+public class ConstantPool extends Oop implements ClassConstants {
// Used for debugging this code
private static final boolean DEBUG = false;
@@ -55,8 +55,9 @@ public class ConstantPool extends Array
tags = new OopField(type.getOopField("_tags"), 0);
cache = new OopField(type.getOopField("_cache"), 0);
poolHolder = new OopField(type.getOopField("_pool_holder"), 0);
+ length = new CIntField(type.getCIntegerField("_length"), 0);
headerSize = type.getSize();
- elementSize = db.getOopSize();
+ elementSize = 0;
}
ConstantPool(OopHandle handle, ObjectHeap heap) {
@@ -68,7 +69,7 @@ public class ConstantPool extends Array
private static OopField tags;
private static OopField cache;
private static OopField poolHolder;
-
+ private static CIntField length; // number of elements in oop
private static long headerSize;
private static long elementSize;
@@ -76,12 +77,22 @@ public class ConstantPool extends Array
public TypeArray getTags() { return (TypeArray) tags.getValue(this); }
public ConstantPoolCache getCache() { return (ConstantPoolCache) cache.getValue(this); }
public Klass getPoolHolder() { return (Klass) poolHolder.getValue(this); }
+ public int getLength() { return (int)length.getValue(this); }
+
+ private long getElementSize() {
+ if (elementSize !=0 ) {
+ return elementSize;
+ } else {
+ elementSize = VM.getVM().getOopSize();
+ }
+ return elementSize;
+ }
private long indexOffset(long index) {
if (Assert.ASSERTS_ENABLED) {
- Assert.that(index > 0 && index < getLength(), "invalid cp index");
- }
- return (index * elementSize) + headerSize;
+ Assert.that(index > 0 && index < getLength(), "invalid cp index " + index + " " + getLength());
+ }
+ return (index * getElementSize()) + headerSize;
}
public ConstantTag getTagAt(long index) {
@@ -464,7 +475,7 @@ public class ConstantPool extends Array
}
public long getObjectSize() {
- return alignObjectSize(headerSize + (getLength() * elementSize));
+ return alignObjectSize(headerSize + (getLength() * getElementSize()));
}
//----------------------------------------------------------------------
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCache.java Sun Apr 13 17:43:42 2008 -0400
@@ -31,10 +31,10 @@ import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.utilities.*;
-// A ConstantPool is an array containing class constants
-// as described in the class file
-
-public class ConstantPoolCache extends Array {
+// ConstantPoolCache : A constant pool cache (constantPoolCacheOopDesc).
+// See cpCacheOop.hpp for details about this class.
+//
+public class ConstantPoolCache extends Oop {
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
@@ -47,9 +47,9 @@ public class ConstantPoolCache extends A
Type type = db.lookupType("constantPoolCacheOopDesc");
constants = new OopField(type.getOopField("_constant_pool"), 0);
baseOffset = type.getSize();
-
Type elType = db.lookupType("ConstantPoolCacheEntry");
elementSize = elType.getSize();
+ length = new CIntField(type.getCIntegerField("_length"), 0);
}
ConstantPoolCache(OopHandle handle, ObjectHeap heap) {
@@ -62,6 +62,8 @@ public class ConstantPoolCache extends A
private static long baseOffset;
private static long elementSize;
+ private static CIntField length;
+
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
@@ -87,6 +89,10 @@ public class ConstantPoolCache extends A
tty.print("ConstantPoolCache for " + getConstants().getPoolHolder().getName().asString());
}
+ public int getLength() {
+ return (int) length.getValue(this);
+ }
+
public void iterateFields(OopVisitor visitor, boolean doVMFields) {
super.iterateFields(visitor, doVMFields);
if (doVMFields) {
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCacheKlass.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolCacheKlass.java Sun Apr 13 17:43:42 2008 -0400
@@ -32,7 +32,7 @@ import sun.jvm.hotspot.types.*;
// A ConstantPoolCacheKlass is the klass of a ConstantPoolCache
-public class ConstantPoolCacheKlass extends ArrayKlass {
+public class ConstantPoolCacheKlass extends Klass {
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
@@ -43,13 +43,20 @@ public class ConstantPoolCacheKlass exte
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("constantPoolCacheKlass");
+ headerSize = type.getSize() + Oop.getHeaderSize();
}
ConstantPoolCacheKlass(OopHandle handle, ObjectHeap heap) {
super(handle, heap);
}
+ public long getObjectSize() { return alignObjectSize(headerSize); }
+
public void printValueOn(PrintStream tty) {
tty.print("ConstantPoolCacheKlass");
}
+
+ private static long headerSize;
}
+
+
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolKlass.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPoolKlass.java Sun Apr 13 17:43:42 2008 -0400
@@ -32,7 +32,7 @@ import sun.jvm.hotspot.types.*;
// A ConstantPoolKlass is the klass of a ConstantPool
-public class ConstantPoolKlass extends ArrayKlass {
+public class ConstantPoolKlass extends Klass {
static {
VM.registerVMInitializedObserver(new Observer() {
public void update(Observable o, Object data) {
@@ -43,13 +43,19 @@ public class ConstantPoolKlass extends A
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("constantPoolKlass");
+ headerSize = type.getSize() + Oop.getHeaderSize();
}
ConstantPoolKlass(OopHandle handle, ObjectHeap heap) {
super(handle, heap);
}
+ public long getObjectSize() { return alignObjectSize(headerSize); }
+
public void printValueOn(PrintStream tty) {
tty.print("ConstantPoolKlass");
}
-};
+
+ private static long headerSize;
+}
+
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/DefaultOopVisitor.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/DefaultOopVisitor.java Sun Apr 13 17:43:42 2008 -0400
@@ -46,6 +46,7 @@ public class DefaultOopVisitor implement
// Callback methods for each field type in an object
public void doOop(OopField field, boolean isVMField) {}
+ public void doOop(NarrowOopField field, boolean isVMField) {}
public void doByte(ByteField field, boolean isVMField) {}
public void doChar(CharField field, boolean isVMField) {}
public void doBoolean(BooleanField field, boolean isVMField) {}
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Instance.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Instance.java Sun Apr 13 17:43:42 2008 -0400
@@ -40,13 +40,24 @@ public class Instance extends Oop {
}
});
}
+ private static long typeSize;
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("instanceOopDesc");
+ typeSize = type.getSize();
}
Instance(OopHandle handle, ObjectHeap heap) {
super(handle, heap);
+ }
+
+ // Returns header size in bytes.
+ public static long getHeaderSize() {
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ return typeSize - VM.getVM().getIntSize();
+ } else {
+ return typeSize;
+ }
}
public boolean isInstance() { return true; }
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java Sun Apr 13 17:43:42 2008 -0400
@@ -467,7 +467,6 @@ public class InstanceKlass extends Klass
for (int index = 0; index < length; index += NEXT_OFFSET) {
short accessFlags = fields.getShortAt(index + ACCESS_FLAGS_OFFSET);
short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET);
-
FieldType type = new FieldType((Symbol) getConstants().getObjAt(signatureIndex));
AccessFlags access = new AccessFlags(accessFlags);
if (access.isStatic()) {
@@ -790,7 +789,11 @@ public class InstanceKlass extends Klass
short signatureIndex = fields.getShortAt(index + SIGNATURE_INDEX_OFFSET);
FieldType type = new FieldType((Symbol) getConstants().getObjAt(signatureIndex));
if (type.isOop()) {
- return new OopField(this, index);
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ return new NarrowOopField(this, index);
+ } else {
+ return new OopField(this, index);
+ }
}
if (type.isByte()) {
return new ByteField(this, index);
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java Sun Apr 13 17:43:42 2008 -0400
@@ -171,8 +171,7 @@ public class Klass extends Oop implement
}
public long getObjectSize() {
- System.out.println("should not reach here");
- return 0;
+ throw new RuntimeException("should not reach here");
}
/** Array class with specific rank */
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjArray.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjArray.java Sun Apr 13 17:43:42 2008 -0400
@@ -43,7 +43,7 @@ public class ObjArray extends Array {
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("objArrayOopDesc");
- elementSize = db.getOopSize();
+ elementSize = VM.getVM().getHeapOopSize();
}
ObjArray(OopHandle handle, ObjectHeap heap) {
@@ -54,9 +54,17 @@ public class ObjArray extends Array {
private static long elementSize;
+ public OopHandle getOopHandleAt(long index) {
+ long offset = baseOffsetInBytes(BasicType.T_OBJECT) + (index * elementSize);
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ return getHandle().getCompOopHandleAt(offset);
+ } else {
+ return getHandle().getOopHandleAt(offset);
+ }
+ }
+
public Oop getObjAt(long index) {
- long offset = baseOffsetInBytes(BasicType.T_OBJECT) + (index * elementSize);
- return getHeap().newOop(getHandle().getOopHandleAt(offset));
+ return getHeap().newOop(getOopHandleAt(index));
}
public void printValueOn(PrintStream tty) {
@@ -69,7 +77,13 @@ public class ObjArray extends Array {
long baseOffset = baseOffsetInBytes(BasicType.T_OBJECT);
for (int index = 0; index < length; index++) {
long offset = baseOffset + (index * elementSize);
- visitor.doOop(new OopField(new IndexableFieldIdentifier(index), offset, false), false);
+ OopField field;
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ field = new NarrowOopField(new IndexableFieldIdentifier(index), offset, false);
+ } else {
+ field = new OopField(new IndexableFieldIdentifier(index), offset, false);
+ }
+ visitor.doOop(field, false);
}
}
}
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java Sun Apr 13 17:43:42 2008 -0400
@@ -41,6 +41,12 @@ import sun.jvm.hotspot.utilities.*;
public class ObjectHeap {
+ private static final boolean DEBUG;
+
+ static {
+ DEBUG = System.getProperty("sun.jvm.hotspot.oops.ObjectHeap.DEBUG") != null;
+ }
+
private OopHandle symbolKlassHandle;
private OopHandle methodKlassHandle;
private OopHandle constMethodKlassHandle;
@@ -152,7 +158,7 @@ public class ObjectHeap {
public ObjectHeap(TypeDataBase db) throws WrongTypeException {
// Get commonly used sizes of basic types
- oopSize = db.getOopSize();
+ oopSize = VM.getVM().getOopSize();
byteSize = db.getJByteType().getSize();
charSize = db.getJCharType().getSize();
booleanSize = db.getJBooleanType().getSize();
@@ -440,12 +446,16 @@ public class ObjectHeap {
try {
// Traverses the space from bottom to top
OopHandle handle = bottom.addOffsetToAsOopHandle(0);
+
while (handle.lessThan(top)) {
Oop obj = null;
try {
obj = newOop(handle);
} catch (UnknownOopException exp) {
+ if (DEBUG) {
+ throw new RuntimeException(" UnknownOopException " + exp);
+ }
}
if (obj == null) {
//Find the object size using Printezis bits and skip over
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHistogram.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHistogram.java Sun Apr 13 17:43:42 2008 -0400
@@ -64,8 +64,17 @@ public class ObjectHistogram implements
List list = getElements();
ObjectHistogramElement.titleOn(tty);
Iterator iterator = list.listIterator();
+ int num=0;
+ int totalCount=0;
+ int totalSize=0;
while (iterator.hasNext()) {
- ((ObjectHistogramElement) iterator.next()).printOn(tty);
+ ObjectHistogramElement el = (ObjectHistogramElement) iterator.next();
+ num++;
+ totalCount+=el.getCount();
+ totalSize+=el.getSize();
+ tty.print(num + ":" + "\t\t");
+ el.printOn(tty);
}
+ tty.println("Total : " + "\t" + totalCount + "\t" + totalSize);
}
}
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHistogramElement.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHistogramElement.java Sun Apr 13 17:43:42 2008 -0400
@@ -110,12 +110,12 @@ public class ObjectHistogramElement {
public static void titleOn(PrintStream tty) {
tty.println("Object Histogram:");
tty.println();
- tty.println("Size" + "\t" + "Count" + "\t" + "Class description");
- tty.println("-------------------------------------------------------");
+ tty.println("num " + "\t" + " #instances" + "\t" + "#bytes" + "\t" + "Class description");
+ tty.println("--------------------------------------------------------------------------");
}
public void printOn(PrintStream tty) {
- tty.print(size + "\t" + count + "\t");
+ tty.print(count + "\t" + size + "\t");
tty.print(getDescription());
tty.println();
}
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Oop.java Sun Apr 13 17:43:42 2008 -0400
@@ -47,7 +47,8 @@ public class Oop {
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("oopDesc");
mark = new CIntField(type.getCIntegerField("_mark"), 0);
- klass = new OopField(type.getOopField("_klass"), 0);
+ klass = new OopField(type.getOopField("_metadata._klass"), 0);
+ compressedKlass = new NarrowOopField(type.getOopField("_metadata._compressed_klass"), 0);
headerSize = type.getSize();
}
@@ -67,10 +68,11 @@ public class Oop {
public OopHandle getHandle() { return handle; }
private static long headerSize;
- public static long getHeaderSize() { return headerSize; }
+ public static long getHeaderSize() { return headerSize; } // Header size in bytes.
private static CIntField mark;
private static OopField klass;
+ private static NarrowOopField compressedKlass;
public boolean isShared() {
return CompactingPermGenGen.isShared(handle);
@@ -86,7 +88,13 @@ public class Oop {
// Accessors for declared fields
public Mark getMark() { return new Mark(getHandle()); }
- public Klass getKlass() { return (Klass) klass.getValue(this); }
+ public Klass getKlass() {
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ return (Klass) compressedKlass.getValue(this);
+ } else {
+ return (Klass) klass.getValue(this);
+ }
+ }
public boolean isA(Klass k) {
return getKlass().isSubtypeOf(k);
@@ -120,7 +128,7 @@ public class Oop {
// Align the object size.
public static long alignObjectSize(long size) {
- return VM.getVM().alignUp(size, VM.getVM().getMinObjAlignmentInBytes());
+ return VM.getVM().alignUp(size, VM.getVM().getMinObjAlignment());
}
// All vm's align longs, so pad out certain offsets.
@@ -163,7 +171,11 @@ public class Oop {
void iterateFields(OopVisitor visitor, boolean doVMFields) {
if (doVMFields) {
visitor.doCInt(mark, true);
- visitor.doOop(klass, true);
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ visitor.doOop(compressedKlass, true);
+ } else {
+ visitor.doOop(klass, true);
+ }
}
}
@@ -219,6 +231,10 @@ public class Oop {
if (handle == null) {
return null;
}
- return handle.getOopHandleAt(klass.getOffset());
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ return handle.getCompOopHandleAt(compressedKlass.getOffset());
+ } else {
+ return handle.getOopHandleAt(klass.getOffset());
+ }
}
};
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/OopPrinter.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/OopPrinter.java Sun Apr 13 17:43:42 2008 -0400
@@ -57,6 +57,13 @@ public class OopPrinter implements OopVi
Oop.printOopValueOn(field.getValue(getObj()), tty);
tty.println();
}
+
+ public void doOop(NarrowOopField field, boolean isVMField) {
+ printField(field);
+ Oop.printOopValueOn(field.getValue(getObj()), tty);
+ tty.println();
+ }
+
public void doChar(CharField field, boolean isVMField) {
printField(field);
char c = field.getValue(getObj());
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/OopUtilities.java Sun Apr 13 17:43:42 2008 -0400
@@ -281,8 +281,11 @@ public class OopUtilities implements /*
} catch (RuntimeException re) {
// ignore, currently java_lang_Class::hc_klass_offset is zero
}
-
- hcKlassField = new OopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ hcKlassField = new NarrowOopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
+ } else {
+ hcKlassField = new OopField(new NamedFieldIdentifier("hc_klass"), hcKlassOffset, true);
+ }
}
}
--- a/agent/src/share/classes/sun/jvm/hotspot/oops/OopVisitor.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/oops/OopVisitor.java Sun Apr 13 17:43:42 2008 -0400
@@ -41,6 +41,7 @@ public interface OopVisitor {
// Callback methods for each field type in an object
public void doOop(OopField field, boolean isVMField);
+ public void doOop(NarrowOopField field, boolean isVMField);
public void doByte(ByteField field, boolean isVMField);
public void doChar(CharField field, boolean isVMField);
public void doBoolean(BooleanField field, boolean isVMField);
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/AddressVisitor.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/AddressVisitor.java Sun Apr 13 17:43:42 2008 -0400
@@ -31,4 +31,5 @@ import sun.jvm.hotspot.debugger.*;
public interface AddressVisitor {
public void visitAddress(Address addr);
+ public void visitCompOopAddress(Address addr);
}
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java Sun Apr 13 17:43:42 2008 -0400
@@ -534,7 +534,8 @@ public abstract class Frame implements C
public void visitValueLocation(Address valueAddr) {
}
- public void visitDeadLocation(Address deadAddr) {
+ public void visitNarrowOopLocation(Address compOopAddr) {
+ addressVisitor.visitCompOopAddress(compOopAddr);
}
}
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Sun Apr 13 17:43:42 2008 -0400
@@ -36,6 +36,7 @@ import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.oops.*;
import sun.jvm.hotspot.types.*;
import sun.jvm.hotspot.utilities.*;
+import sun.jvm.hotspot.runtime.*;
/** <P> This class encapsulates the global state of the VM; the
universe, object heap, interpreter, etc. It is a Singleton and
@@ -93,6 +94,10 @@ public class VM {
private boolean isLP64;
private int bytesPerLong;
private int minObjAlignmentInBytes;
+ private int logMinObjAlignmentInBytes;
+ private int heapWordSize;
+ private int heapOopSize;
+ private int oopSize;
/** This is only present in a non-core build */
private CodeCache codeCache;
/** This is only present in a C1 build */
@@ -117,6 +122,7 @@ public class VM {
private static Type uintxType;
private static CIntegerType boolType;
private Boolean sharingEnabled;
+ private Boolean compressedOopsEnabled;
// command line flags supplied to VM - see struct Flag in globals.hpp
public static final class Flag {
@@ -308,6 +314,11 @@ public class VM {
}
bytesPerLong = db.lookupIntConstant("BytesPerLong").intValue();
minObjAlignmentInBytes = db.lookupIntConstant("MinObjAlignmentInBytes").intValue();
+ // minObjAlignment = db.lookupIntConstant("MinObjAlignment").intValue();
+ logMinObjAlignmentInBytes = db.lookupIntConstant("LogMinObjAlignmentInBytes").intValue();
+ heapWordSize = db.lookupIntConstant("HeapWordSize").intValue();
+ oopSize = db.lookupIntConstant("oopSize").intValue();
+ heapOopSize = db.lookupIntConstant("heapOopSize").intValue();
intxType = db.lookupType("intx");
uintxType = db.lookupType("uintx");
@@ -331,6 +342,8 @@ public class VM {
throw new RuntimeException("Attempt to initialize VM twice");
}
soleInstance = new VM(db, debugger, debugger.getMachineDescription().isBigEndian());
+ debugger.putHeapConst(Universe.getHeapBase(), soleInstance.getHeapOopSize(),
+ soleInstance.logMinObjAlignmentInBytes);
for (Iterator iter = vmInitializedObservers.iterator(); iter.hasNext(); ) {
((Observer) iter.next()).update(null, null);
}
@@ -440,11 +453,15 @@ public class VM {
}
public long getOopSize() {
- return db.getOopSize();
+ return oopSize;
}
public long getLogAddressSize() {
return logAddressSize;
+ }
+
+ public long getIntSize() {
+ return db.getJIntType().getSize();
}
/** NOTE: this offset is in BYTES in this system! */
@@ -467,10 +484,24 @@ public class VM {
}
/** Get minimum object alignment in bytes. */
+ public int getMinObjAlignment() {
+ return minObjAlignmentInBytes;
+ }
+
public int getMinObjAlignmentInBytes() {
return minObjAlignmentInBytes;
}
-
+ public int getLogMinObjAlignmentInBytes() {
+ return logMinObjAlignmentInBytes;
+ }
+
+ public int getHeapWordSize() {
+ return heapWordSize;
+ }
+
+ public int getHeapOopSize() {
+ return heapOopSize;
+ }
/** Utility routine for getting data structure alignment correct */
public long alignUp(long size, long alignment) {
return (size + alignment - 1) & ~(alignment - 1);
@@ -701,6 +732,14 @@ public class VM {
return sharingEnabled.booleanValue();
}
+ public boolean isCompressedOopsEnabled() {
+ if (compressedOopsEnabled == null) {
+ Flag flag = getCommandLineFlag("UseCompressedOops");
+ compressedOopsEnabled = (flag == null) ? Boolean.FALSE:
+ (flag.getBool()? Boolean.TRUE: Boolean.FALSE);
+ }
+ return compressedOopsEnabled.booleanValue();
+ }
// returns null, if not available.
public Flag[] getCommandLineFlags() {
--- a/agent/src/share/classes/sun/jvm/hotspot/types/Field.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/types/Field.java Sun Apr 13 17:43:42 2008 -0400
@@ -109,6 +109,8 @@ public interface Field {
public Address getAddress (Address addr) throws UnmappedAddressException, UnalignedAddressException, WrongTypeException;
public OopHandle getOopHandle(Address addr)
throws UnmappedAddressException, UnalignedAddressException, WrongTypeException, NotInHeapException;
+ public OopHandle getNarrowOopHandle(Address addr)
+ throws UnmappedAddressException, UnalignedAddressException, WrongTypeException, NotInHeapException;
/** <P> These accessors require that the field be static; otherwise,
a WrongTypeException will be thrown. Note that type checking is
@@ -138,4 +140,6 @@ public interface Field {
public Address getAddress () throws UnmappedAddressException, UnalignedAddressException;
public OopHandle getOopHandle()
throws UnmappedAddressException, UnalignedAddressException, NotInHeapException;
+ public OopHandle getNarrowOopHandle()
+ throws UnmappedAddressException, UnalignedAddressException, NotInHeapException;
}
--- a/agent/src/share/classes/sun/jvm/hotspot/types/Type.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/types/Type.java Sun Apr 13 17:43:42 2008 -0400
@@ -122,5 +122,6 @@ public interface Type {
public JShortField getJShortField (String fieldName) throws WrongTypeException;
public CIntegerField getCIntegerField (String fieldName) throws WrongTypeException;
public OopField getOopField (String fieldName) throws WrongTypeException;
+ public NarrowOopField getNarrowOopField (String fieldName) throws WrongTypeException;
public AddressField getAddressField (String fieldName);
}
--- a/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicField.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicField.java Sun Apr 13 17:43:42 2008 -0400
@@ -43,6 +43,19 @@ public class BasicField implements Field
/** Used for static fields only */
private Address staticFieldAddress;
+ // Copy constructor to create NarrowOopField from OopField.
+ public BasicField(Field fld) {
+ BasicField field = (BasicField)fld;
+
+ this.db = field.db;
+ this.containingType = field.containingType;
+ this.name = field.name;
+ this.type = field.type;
+ this.size = field.size;
+ this.isStatic = field.isStatic;
+ this.offset = field.offset;
+ this.staticFieldAddress = field.staticFieldAddress;
+ }
/** offsetInBytes is ignored if the field is static;
staticFieldAddress is used only if the field is static. */
public BasicField(BasicTypeDataBase db, Type containingType, String name, Type type,
@@ -161,6 +174,13 @@ public class BasicField implements Field
}
return addr.getOopHandleAt(offset);
}
+ public OopHandle getNarrowOopHandle(Address addr)
+ throws UnmappedAddressException, UnalignedAddressException, WrongTypeException, NotInHeapException {
+ if (isStatic) {
+ throw new WrongTypeException();
+ }
+ return addr.getCompOopHandleAt(offset);
+ }
//--------------------------------------------------------------------------------
// Dereferencing operations for static fields
@@ -234,4 +254,11 @@ public class BasicField implements Field
}
return staticFieldAddress.getOopHandleAt(0);
}
+ public OopHandle getNarrowOopHandle()
+ throws UnmappedAddressException, UnalignedAddressException, WrongTypeException, NotInHeapException {
+ if (!isStatic) {
+ throw new WrongTypeException();
+ }
+ return staticFieldAddress.getCompOopHandleAt(0);
+ }
}
--- a/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicFieldWrapper.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicFieldWrapper.java Sun Apr 13 17:43:42 2008 -0400
@@ -95,6 +95,10 @@ public class BasicFieldWrapper implement
throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
return field.getOopHandle(addr);
}
+ public OopHandle getNarrowOopHandle(Address addr)
+ throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
+ return field.getNarrowOopHandle(addr);
+ }
public boolean getJBoolean () throws UnmappedAddressException, UnalignedAddressException, WrongTypeException {
return field.getJBoolean();
@@ -130,4 +134,8 @@ public class BasicFieldWrapper implement
throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
return field.getOopHandle();
}
+ public OopHandle getNarrowOopHandle()
+ throws UnmappedAddressException, UnalignedAddressException, NotInHeapException {
+ return field.getNarrowOopHandle();
+ }
}
--- a/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicOopField.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicOopField.java Sun Apr 13 17:43:42 2008 -0400
@@ -32,6 +32,12 @@ import sun.jvm.hotspot.types.*;
returning OopHandles. */
public class BasicOopField extends BasicField implements OopField {
+
+
+ public BasicOopField(OopField oopf) {
+ super(oopf);
+ }
+
public BasicOopField(BasicTypeDataBase db, Type containingType, String name, Type type,
boolean isStatic, long offset, Address staticFieldAddress) {
super(db, containingType, name, type, isStatic, offset, staticFieldAddress);
--- a/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicType.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicType.java Sun Apr 13 17:43:42 2008 -0400
@@ -273,6 +273,10 @@ public class BasicType implements Type {
return (OopField) field;
}
+ public NarrowOopField getNarrowOopField(String fieldName) throws WrongTypeException {
+ return (NarrowOopField) new BasicNarrowOopField(getOopField(fieldName));
+ }
+
public AddressField getAddressField(String fieldName) {
// This type can not be inferred (for now), so provide a wrapper
Field field = getField(fieldName);
@@ -287,7 +291,7 @@ public class BasicType implements Type {
name was already present in this class. */
public void addField(Field field) {
if (nameToFieldMap.get(field.getName()) != null) {
- throw new RuntimeException("field of name \"" + field.getName() + "\" already present");
+ throw new RuntimeException("field of name \"" + field.getName() + "\" already present in type " + this);
}
nameToFieldMap.put(field.getName(), field);
--- a/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/types/basic/BasicTypeDataBase.java Sun Apr 13 17:43:42 2008 -0400
@@ -27,6 +27,7 @@ import java.util.*;
import java.util.*;
import sun.jvm.hotspot.debugger.*;
import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.runtime.VM;
/** <P> This is a basic implementation of the TypeDataBase interface.
It allows an external type database builder to add types to be
@@ -146,7 +147,7 @@ public class BasicTypeDataBase implement
}
public long getOopSize() {
- return machDesc.getOopSize();
+ return VM.getVM().getOopSize();
}
public boolean addressTypeIsEqualToType(Address addr, Type type) {
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/FindInHeapPanel.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/FindInHeapPanel.java Sun Apr 13 17:43:42 2008 -0400
@@ -92,7 +92,17 @@ public class FindInHeapPanel extends JPa
iterated += addressSize;
updateProgressBar();
}
-
+ public void visitCompOopAddress(Address addr) {
+ if (error) return;
+
+ Address val = addr.getCompOopAddressAt(0);
+ if (AddressOps.equal(val, value)) {
+ error = reportResult(addr);
+ }
+ iterated += addressSize;
+ updateProgressBar();
+
+ }
public void epilogue() {
iterated = 0;
updateProgressBar();
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Sun Apr 13 17:43:42 2008 -0400
@@ -1077,8 +1077,8 @@ public class HTMLGenerator implements /*
oms = new OopMapStream(map, OopMapValue.OopTypes.VALUE_VALUE);
buf.append(omvIterator.iterate(oms, "Value:", false));
- oms = new OopMapStream(map, OopMapValue.OopTypes.DEAD_VALUE);
- buf.append(omvIterator.iterate(oms, "Dead:", false));
+ oms = new OopMapStream(map, OopMapValue.OopTypes.NARROWOOP_VALUE);
+ buf.append(omvIterator.iterate(oms, "Oop:", false));
oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE);
buf.append(omvIterator.iterate(oms, "Callee saved:", true));
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/AbstractHeapGraphWriter.java Sun Apr 13 17:43:42 2008 -0400
@@ -156,6 +156,9 @@ public abstract class AbstractHeapGraphW
throw new RuntimeException(exp);
}
}
+ public void visitCompOopAddress(Address handleAddr) {
+ throw new RuntimeException("Should not reach here. JNIHandles are not compressed");
+ }
});
} catch (RuntimeException re) {
handleRuntimeException(re);
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java Sun Apr 13 17:43:42 2008 -0400
@@ -574,6 +574,10 @@ public class HeapHprofBinWriter extends
throw new RuntimeException(exp);
}
}
+ public void visitCompOopAddress(Address handleAddr) {
+ throw new RuntimeException(
+ " Should not reach here. JNIHandles are not compressed \n");
+ }
});
} catch (RuntimeException re) {
handleRuntimeException(re);
@@ -601,8 +605,7 @@ public class HeapHprofBinWriter extends
writeObjectID(array.getKlass().getJavaMirror());
final int length = (int) array.getLength();
for (int index = 0; index < length; index++) {
- long offset = OBJECT_BASE_OFFSET + index * OBJ_ID_SIZE;
- OopHandle handle = array.getHandle().getOopHandleAt(offset);
+ OopHandle handle = array.getOopHandleAt(index);
writeObjectID(getAddressValue(handle));
}
}
@@ -803,8 +806,13 @@ public class HeapHprofBinWriter extends
break;
case JVM_SIGNATURE_CLASS:
case JVM_SIGNATURE_ARRAY: {
- OopHandle handle = ((OopField)field).getValueAsOopHandle(oop);
- writeObjectID(getAddressValue(handle));
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ OopHandle handle = ((NarrowOopField)field).getValueAsOopHandle(oop);
+ writeObjectID(getAddressValue(handle));
+ } else {
+ OopHandle handle = ((OopField)field).getValueAsOopHandle(oop);
+ writeObjectID(getAddressValue(handle));
+ }
break;
}
default:
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/ReversePtrsAnalysis.java Sun Apr 13 17:43:42 2008 -0400
@@ -282,6 +282,15 @@ public class ReversePtrsAnalysis {
markAndTraverse(next);
}
+ public void visitCompOopAddress(Address addr) {
+ Oop next = heap.newOop(addr.getCompOopHandleAt(0));
+ LivenessPathElement lp = new LivenessPathElement(null,
+ new NamedFieldIdentifier(baseRootDescription +
+ " @ " + addr));
+ rp.put(lp, next);
+ markAndTraverse(next);
+ }
+
private String baseRootDescription;
}
--- a/agent/src/share/classes/sun/jvm/hotspot/utilities/RobustOopDeterminator.java Fri Apr 11 09:56:35 2008 -0400
+++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/RobustOopDeterminator.java Sun Apr 13 17:43:42 2008 -0400
@@ -51,7 +51,11 @@ public class RobustOopDeterminator {
private static void initialize(TypeDataBase db) {
Type type = db.lookupType("oopDesc");
- klassField = type.getOopField("_klass");
+ if (VM.getVM().isCompressedOopsEnabled()) {
+ klassField = type.getNarrowOopField("_metadata._compressed_klass");
+ } else {
+ klassField = type.getOopField("_metadata._klass");
+ }
}
public static boolean oopLooksValid(OopHandle oop) {
--- a/make/Makefile Fri Apr 11 09:56:35 2008 -0400
+++ b/make/Makefile Sun Apr 13 17:43:42 2008 -0400
@@ -84,6 +84,9 @@ C1_VM_TARGETS=product1 fastdebug1 optimi
C1_VM_TARGETS=product1 fastdebug1 optimized1 jvmg1
C2_VM_TARGETS=product fastdebug optimized jvmg
KERNEL_VM_TARGETS=productkernel fastdebugkernel optimizedkernel jvmgkernel
+
+# JDK directory list
+JDK_DIRS=bin include jre lib demo
all: all_product all_fastdebug
all_product: product product1 productkernel docs export_product
@@ -341,7 +344,7 @@ copy_product_jdk:
$(RM) -r $(JDK_IMAGE_DIR)
$(MKDIR) -p $(JDK_IMAGE_DIR)
($(CD) $(JDK_IMPORT_PATH) && \
- $(TAR) -cf - bin include jre lib) | \
+ $(TAR) -cf - $(JDK_DIRS)) | \
($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xf -)
copy_fastdebug_jdk:
@@ -349,11 +352,11 @@ copy_fastdebug_jdk:
$(MKDIR) -p $(JDK_IMAGE_DIR)/fastdebug
if [ -d $(JDK_IMPORT_PATH)/fastdebug ] ; then \
($(CD) $(JDK_IMPORT_PATH)/fastdebug && \
- $(TAR) -cf - bin include jre lib) | \
+ $(TAR) -cf - $(JDK_DIRS)) | \
($(CD) $(JDK_IMAGE_DIR)/fastdebug && $(TAR) -xf -) ; \
else \
($(CD) $(JDK_IMPORT_PATH) && \
- $(TAR) -cf - bin include jre lib) | \
+ $(TAR) -cf - $(JDK_DIRS)) | \
($(CD) $(JDK_IMAGE_DIR)/fastdebug && $(TAR) -xf -) ; \
fi
@@ -362,15 +365,15 @@ copy_debug_jdk:
$(MKDIR) -p $(JDK_IMAGE_DIR)/debug
if [ -d $(JDK_IMPORT_PATH)/debug ] ; then \
($(CD) $(JDK_IMPORT_PATH)/debug && \
- $(TAR) -cf - bin include jre lib) | \
+ $(TAR) -cf - $(JDK_DIRS)) | \
($(CD) $(JDK_IMAGE_DIR)/debug && $(TAR) -xf -) ; \
elif [ -d $(JDK_IMPORT_PATH)/fastdebug ] ; then \
($(CD) $(JDK_IMPORT_PATH)/fastdebug && \
- $(TAR) -cf - bin include jre lib) | \
+ $(TAR) -cf - $(JDK_DIRS)) | \
($(CD) $(JDK_IMAGE_DIR)/debug && $(TAR) -xf -) ; \
else \
($(CD) $(JDK_IMPORT_PATH) && \
- $(TAR) -cf - bin include jre lib) | \
+ $(TAR) -cf - $(JDK_DIRS)) | \
($(CD) $(JDK_IMAGE_DIR)/debug && $(TAR) -xf -) ; \
fi
--- a/make/solaris/makefiles/sparcWorks.make Fri Apr 11 09:56:35 2008 -0400
+++ b/make/solaris/makefiles/sparcWorks.make Sun Apr 13 17:43:42 2008 -0400
@@ -185,6 +185,12 @@ CFLAGS += $(GAMMADIR)/src/os_cpu/solaris
# no more exceptions
CFLAGS/NOEX=-features=no%except
+
+# avoid compilation problems arising from fact that C++ compiler tries
+# to search for external template definition by just compiling additional
+# source files in th same context
+CFLAGS += -template=no%extdef
+
# Reduce code bloat by reverting back to 5.0 behavior for static initializers
CFLAGS += -features=no%split_init
--- a/src/cpu/sparc/vm/assembler_sparc.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/assembler_sparc.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -1779,7 +1779,7 @@ void MacroAssembler::verify_oop_subrouti
// Check the klassOop of this object for being in the right area of memory.
// Cannot do the load in the delay above slot in case O0 is null
- ld_ptr(Address(O0_obj, 0, oopDesc::klass_offset_in_bytes()), O0_obj);
+ load_klass(O0_obj, O0_obj);
// assert((klass & klass_mask) == klass_bits);
if( Universe::verify_klass_mask() != Universe::verify_oop_mask() )
set(Universe::verify_klass_mask(), O2_mask);
@@ -1788,8 +1788,9 @@ void MacroAssembler::verify_oop_subrouti
and3(O0_obj, O2_mask, O4_temp);
cmp(O4_temp, O3_bits);
brx(notEqual, false, pn, fail);
+ delayed()->nop();
// Check the klass's klass
- delayed()->ld_ptr(Address(O0_obj, 0, oopDesc::klass_offset_in_bytes()), O0_obj);
+ load_klass(O0_obj, O0_obj);
and3(O0_obj, O2_mask, O4_temp);
cmp(O4_temp, O3_bits);
brx(notEqual, false, pn, fail);
@@ -2588,8 +2589,9 @@ void MacroAssembler::biased_locking_ente
and3(mark_reg, markOopDesc::biased_lock_mask_in_place, temp_reg);
cmp(temp_reg, markOopDesc::biased_lock_pattern);
brx(Assembler::notEqual, false, Assembler::pn, cas_label);
-
- delayed()->ld_ptr(Address(obj_reg, 0, oopDesc::klass_offset_in_bytes()), temp_reg);
+ delayed()->nop();
+
+ load_klass(obj_reg, temp_reg);
ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
or3(G2_thread, temp_reg, temp_reg);
xor3(mark_reg, temp_reg, temp_reg);
@@ -2668,7 +2670,7 @@ void MacroAssembler::biased_locking_ente
//
// FIXME: due to a lack of registers we currently blow away the age
// bits in this situation. Should attempt to preserve them.
- ld_ptr(Address(obj_reg, 0, oopDesc::klass_offset_in_bytes()), temp_reg);
+ load_klass(obj_reg, temp_reg);
ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
or3(G2_thread, temp_reg, temp_reg);
casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
@@ -2700,7 +2702,7 @@ void MacroAssembler::biased_locking_ente
//
// FIXME: due to a lack of registers we currently blow away the age
// bits in this situation. Should attempt to preserve them.
- ld_ptr(Address(obj_reg, 0, oopDesc::klass_offset_in_bytes()), temp_reg);
+ load_klass(obj_reg, temp_reg);
ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg);
casx_under_lock(mark_addr.base(), mark_reg, temp_reg,
(address)StubRoutines::Sparc::atomic_memory_operation_lock_addr());
@@ -3406,7 +3408,7 @@ void MacroAssembler::tlab_refill(Label&
// set klass to intArrayKlass
set((intptr_t)Universe::intArrayKlassObj_addr(), t2);
ld_ptr(t2, 0, t2);
- st_ptr(t2, top, oopDesc::klass_offset_in_bytes());
+ store_klass(t2, top);
sub(t1, typeArrayOopDesc::header_size(T_INT), t1);
add(t1, ThreadLocalAllocBuffer::alignment_reserve(), t1);
sll_ptr(t1, log2_intptr(HeapWordSize/sizeof(jint)), t1);
@@ -3534,3 +3536,139 @@ void MacroAssembler::bang_stack_size(Reg
st(G0, Rtsp, Rscratch);
}
}
+
+void MacroAssembler::load_klass(Register s, Register d) {
+ // The number of bytes in this code is used by
+ // MachCallDynamicJavaNode::ret_addr_offset()
+ // if this changes, change that.
+ if (UseCompressedOops) {
+ lduw(s, oopDesc::klass_offset_in_bytes(), d);
+ decode_heap_oop_not_null(d);
+ } else {
+ ld_ptr(s, oopDesc::klass_offset_in_bytes(), d);
+ }
+}
+
+// ??? figure out src vs. dst!
+void MacroAssembler::store_klass(Register d, Register s1) {
+ if (UseCompressedOops) {
+ assert(s1 != d, "not enough registers");
+ encode_heap_oop_not_null(d);
+ // Zero out entire klass field first.
+ st_ptr(G0, s1, oopDesc::klass_offset_in_bytes());
+ st(d, s1, oopDesc::klass_offset_in_bytes());
+ } else {
+ st_ptr(d, s1, oopDesc::klass_offset_in_bytes());
+ }
+}
+
+void MacroAssembler::load_heap_oop(const Address& s, Register d, int offset) {
+ if (UseCompressedOops) {
+ lduw(s, d, offset);
+ decode_heap_oop(d);
+ } else {
+ ld_ptr(s, d, offset);
+ }
+}
+
+void MacroAssembler::load_heap_oop(Register s1, Register s2, Register d) {
+ if (UseCompressedOops) {
+ lduw(s1, s2, d);
+ decode_heap_oop(d, d);
+ } else {
+ ld_ptr(s1, s2, d);
+ }
+}
+
+void MacroAssembler::load_heap_oop(Register s1, int simm13a, Register d) {
+ if (UseCompressedOops) {
+ lduw(s1, simm13a, d);
+ decode_heap_oop(d, d);
+ } else {
+ ld_ptr(s1, simm13a, d);
+ }
+}
+
+void MacroAssembler::store_heap_oop(Register d, Register s1, Register s2) {
+ if (UseCompressedOops) {
+ assert(s1 != d && s2 != d, "not enough registers");
+ encode_heap_oop(d);
+ st(d, s1, s2);
+ } else {
+ st_ptr(d, s1, s2);
+ }
+}
+
+void MacroAssembler::store_heap_oop(Register d, Register s1, int simm13a) {
+ if (UseCompressedOops) {
+ assert(s1 != d, "not enough registers");
+ encode_heap_oop(d);
+ st(d, s1, simm13a);
+ } else {
+ st_ptr(d, s1, simm13a);
+ }
+}
+
+void MacroAssembler::store_heap_oop(Register d, const Address& a, int offset) {
+ if (UseCompressedOops) {
+ assert(a.base() != d, "not enough registers");
+ encode_heap_oop(d);
+ st(d, a, offset);
+ } else {
+ st_ptr(d, a, offset);
+ }
+}
+
+
+void MacroAssembler::encode_heap_oop(Register src, Register dst) {
+ assert (UseCompressedOops, "must be compressed");
+ Label done;
+ if (src == dst) {
+ // optimize for frequent case src == dst
+ bpr(rc_nz, true, Assembler::pt, src, done);
+ delayed() -> sub(src, G6_heapbase, dst); // annuled if not taken
+ bind(done);
+ srlx(src, LogMinObjAlignmentInBytes, dst);
+ } else {
+ bpr(rc_z, false, Assembler::pn, src, done);
+ delayed() -> mov(G0, dst);
+ // could be moved before branch, and annulate delay,
+ // but may add some unneeded work decoding null
+ sub(src, G6_heapbase, dst);
+ srlx(dst, LogMinObjAlignmentInBytes, dst);
+ bind(done);
+ }
+}
+
+
+void MacroAssembler::encode_heap_oop_not_null(Register r) {
+ assert (UseCompressedOops, "must be compressed");
+ sub(r, G6_heapbase, r);
+ srlx(r, LogMinObjAlignmentInBytes, r);
+}
+
+// Same algorithm as oops.inline.hpp decode_heap_oop.
+void MacroAssembler::decode_heap_oop(Register src, Register dst) {
+ assert (UseCompressedOops, "must be compressed");
+ Label done;
+ sllx(src, LogMinObjAlignmentInBytes, dst);
+ bpr(rc_nz, true, Assembler::pt, dst, done);
+ delayed() -> add(dst, G6_heapbase, dst); // annuled if not taken
+ bind(done);
+}
+
+void MacroAssembler::decode_heap_oop_not_null(Register r) {
+ // Do not add assert code to this unless you change vtableStubs_sparc.cpp
+ // pd_code_size_limit.
+ assert (UseCompressedOops, "must be compressed");
+ sllx(r, LogMinObjAlignmentInBytes, r);
+ add(r, G6_heapbase, r);
+}
+
+void MacroAssembler::reinit_heapbase() {
+ if (UseCompressedOops) {
+ // call indirectly to solve generation ordering problem
+ Address base(G6_heapbase, (address)Universe::heap_base_addr());
+ load_ptr_contents(base, G6_heapbase);
+ }
+}
--- a/src/cpu/sparc/vm/assembler_sparc.hpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/assembler_sparc.hpp Sun Apr 13 17:43:42 2008 -0400
@@ -59,6 +59,7 @@ class BiasedLockingCounters;
// This global always holds the current JavaThread pointer:
REGISTER_DECLARATION(Register, G2_thread , G2);
+REGISTER_DECLARATION(Register, G6_heapbase , G6);
// The following globals are part of the Java calling convention:
@@ -1975,6 +1976,29 @@ class MacroAssembler: public Assembler {
inline void tstbool( Register s ) { tst(s); }
inline void movbool( bool boolconst, Register d) { mov( (int) boolconst, d); }
+ // klass oop manipulations if compressed
+ void load_klass(Register src_oop, Register dst);
+ void store_klass(Register dst_oop, Register s1);
+
+ // oop manipulations
+ void load_heap_oop(const Address& s, Register d, int offset = 0);
+ void load_heap_oop(Register s1, Register s2, Register d);
+ void load_heap_oop(Register s1, int simm13a, Register d);
+ void store_heap_oop(Register d, Register s1, Register s2);
+ void store_heap_oop(Register d, Register s1, int simm13a);
+ void store_heap_oop(Register d, const Address& a, int offset = 0);
+
+ void encode_heap_oop(Register src, Register dst);
+ void encode_heap_oop(Register r) {
+ encode_heap_oop(r, r);
+ }
+ void decode_heap_oop(Register src, Register dst);
+ void decode_heap_oop(Register r) {
+ decode_heap_oop(r, r);
+ }
+ void encode_heap_oop_not_null(Register r);
+ void decode_heap_oop_not_null(Register r);
+
// Support for managing the JavaThread pointer (i.e.; the reference to
// thread-local information).
void get_thread(); // load G2_thread
@@ -2049,6 +2073,9 @@ class MacroAssembler: public Assembler {
void push_CPU_state();
void pop_CPU_state();
+
+ // if heap base register is used - reinit it with the correct value
+ void reinit_heapbase();
// Debugging
void _verify_oop(Register reg, const char * msg, const char * file, int line);
--- a/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/c1_MacroAssembler_sparc.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -236,7 +236,7 @@ void C1_MacroAssembler::initialize_objec
Register t1, // temp register
Register t2 // temp register
) {
- const int hdr_size_in_bytes = oopDesc::header_size_in_bytes();
+ const int hdr_size_in_bytes = instanceOopDesc::base_offset_in_bytes();
initialize_header(obj, klass, noreg, t1, t2);
--- a/src/cpu/sparc/vm/copy_sparc.hpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/copy_sparc.hpp Sun Apr 13 17:43:42 2008 -0400
@@ -137,24 +137,20 @@ static void pd_arrayof_conjoint_oops(Hea
}
static void pd_fill_to_words(HeapWord* tohw, size_t count, juint value) {
-#if 0
- if (HeapWordsPerLong == 1 ||
- (HeapWordsPerLong == 2 &&
- mask_bits((uintptr_t)tohw, right_n_bits(LogBytesPerLong)) == 0 &&
- ((count & 1) ? false : count >>= 1))) {
- julong* to = (julong*)tohw;
- julong v = ((julong)value << 32) | value;
- while (count-- > 0) {
- *to++ = v;
- }
- } else {
-#endif
- juint* to = (juint*)tohw;
- count *= HeapWordSize / BytesPerInt;
- while (count-- > 0) {
- *to++ = value;
- }
- // }
+#ifdef _LP64
+ guarantee(mask_bits((uintptr_t)tohw, right_n_bits(LogBytesPerLong)) == 0,
+ "unaligned fill words");
+ julong* to = (julong*)tohw;
+ julong v = ((julong)value << 32) | value;
+ while (count-- > 0) {
+ *to++ = v;
+ }
+#else // _LP64
+ juint* to = (juint*)tohw;
+ while (count-- > 0) {
+ *to++ = value;
+ }
+#endif // _LP64
}
static void pd_fill_to_aligned_words(HeapWord* tohw, size_t count, juint value) {
--- a/src/cpu/sparc/vm/interp_masm_sparc.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -859,7 +859,7 @@ void InterpreterMacroAssembler::get_cach
// Generate a subtype check: branch to ok_is_subtype if sub_klass is
-// a subtype of super_klass. Blows registers Rsub_klass, tmp1, tmp2.
+// a subtype of super_klass. Blows registers Rsuper_klass, Rsub_klass, tmp1, tmp2.
void InterpreterMacroAssembler::gen_subtype_check(Register Rsub_klass,
Register Rsuper_klass,
Register Rtmp1,
@@ -891,6 +891,9 @@ void InterpreterMacroAssembler::gen_subt
// Now do a linear scan of the secondary super-klass chain.
delayed()->ld_ptr( Rsub_klass, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes(), Rtmp2 );
+ // compress superclass
+ if (UseCompressedOops) encode_heap_oop(Rsuper_klass);
+
// Rtmp2 holds the objArrayOop of secondary supers.
ld( Rtmp2, arrayOopDesc::length_offset_in_bytes(), Rtmp1 );// Load the array length
// Check for empty secondary super list
@@ -900,20 +903,28 @@ void InterpreterMacroAssembler::gen_subt
bind( loop );
br( Assembler::equal, false, Assembler::pn, not_subtype );
delayed()->nop();
+
// load next super to check
- ld_ptr( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3 );
-
- // Bump array pointer forward one oop
- add( Rtmp2, wordSize, Rtmp2 );
+ if (UseCompressedOops) {
+ ld( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
+ // Bump array pointer forward one oop
+ add( Rtmp2, 4, Rtmp2 );
+ } else {
+ ld_ptr( Rtmp2, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Rtmp3);
+ // Bump array pointer forward one oop
+ add( Rtmp2, wordSize, Rtmp2);
+ }
// Look for Rsuper_klass on Rsub_klass's secondary super-class-overflow list
cmp( Rtmp3, Rsuper_klass );
// A miss means we are NOT a subtype and need to keep looping
brx( Assembler::notEqual, false, Assembler::pt, loop );
delayed()->deccc( Rtmp1 ); // dec trip counter in delay slot
// Falling out the bottom means we found a hit; we ARE a subtype
+ if (UseCompressedOops) decode_heap_oop(Rsuper_klass);
br( Assembler::always, false, Assembler::pt, ok_is_subtype );
// Update the cache
- delayed()->st_ptr( Rsuper_klass, Rsub_klass, sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() );
+ delayed()->st_ptr( Rsuper_klass, Rsub_klass,
+ sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes() );
bind(not_subtype);
profile_typecheck_failed(Rtmp1);
--- a/src/cpu/sparc/vm/register_definitions_sparc.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/register_definitions_sparc.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -131,6 +131,7 @@ REGISTER_DEFINITION(FloatRegister, Ftos_
REGISTER_DEFINITION(Register, G2_thread);
+REGISTER_DEFINITION(Register, G6_heapbase);
REGISTER_DEFINITION(Register, G5_method);
REGISTER_DEFINITION(Register, G5_megamorphic_method);
REGISTER_DEFINITION(Register, G5_inline_cache_reg);
--- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -160,18 +160,24 @@ OopMap* RegisterSaver::save_live_registe
map->set_callee_saved(VMRegImpl::stack2reg((o5_offset + 4)>>2), O5->as_VMReg());
#endif /* _LP64 */
+
+#ifdef _LP64
+ int debug_offset = 0;
+#else
+ int debug_offset = 4;
+#endif
// Save the G's
__ stx(G1, SP, g1_offset+STACK_BIAS);
- map->set_callee_saved(VMRegImpl::stack2reg((g1_offset + 4)>>2), G1->as_VMReg());
+ map->set_callee_saved(VMRegImpl::stack2reg((g1_offset + debug_offset)>>2), G1->as_VMReg());
__ stx(G3, SP, g3_offset+STACK_BIAS);
- map->set_callee_saved(VMRegImpl::stack2reg((g3_offset + 4)>>2), G3->as_VMReg());
+ map->set_callee_saved(VMRegImpl::stack2reg((g3_offset + debug_offset)>>2), G3->as_VMReg());
__ stx(G4, SP, g4_offset+STACK_BIAS);
- map->set_callee_saved(VMRegImpl::stack2reg((g4_offset + 4)>>2), G4->as_VMReg());
+ map->set_callee_saved(VMRegImpl::stack2reg((g4_offset + debug_offset)>>2), G4->as_VMReg());
__ stx(G5, SP, g5_offset+STACK_BIAS);
- map->set_callee_saved(VMRegImpl::stack2reg((g5_offset + 4)>>2), G5->as_VMReg());
+ map->set_callee_saved(VMRegImpl::stack2reg((g5_offset + debug_offset)>>2), G5->as_VMReg());
// This is really a waste but we'll keep things as they were for now
if (true) {
@@ -182,11 +188,11 @@ OopMap* RegisterSaver::save_live_registe
map->set_callee_saved(VMRegImpl::stack2reg((o3_offset)>>2), O3->as_VMReg()->next());
map->set_callee_saved(VMRegImpl::stack2reg((o4_offset)>>2), O4->as_VMReg()->next());
map->set_callee_saved(VMRegImpl::stack2reg((o5_offset)>>2), O5->as_VMReg()->next());
-#endif /* _LP64 */
map->set_callee_saved(VMRegImpl::stack2reg((g1_offset)>>2), G1->as_VMReg()->next());
map->set_callee_saved(VMRegImpl::stack2reg((g3_offset)>>2), G3->as_VMReg()->next());
map->set_callee_saved(VMRegImpl::stack2reg((g4_offset)>>2), G4->as_VMReg()->next());
map->set_callee_saved(VMRegImpl::stack2reg((g5_offset)>>2), G5->as_VMReg()->next());
+#endif /* _LP64 */
}
@@ -1217,7 +1223,7 @@ AdapterHandlerEntry* SharedRuntime::gene
__ verify_oop(O0);
__ verify_oop(G5_method);
- __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch);
+ __ load_klass(O0, G3_scratch);
__ verify_oop(G3_scratch);
#if !defined(_LP64) && defined(COMPILER2)
@@ -1820,7 +1826,7 @@ nmethod *SharedRuntime::generate_native_
const Register temp_reg = G3_scratch;
Address ic_miss(temp_reg, SharedRuntime::get_ic_miss_stub());
__ verify_oop(O0);
- __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg);
+ __ load_klass(O0, temp_reg);
__ cmp(temp_reg, G5_inline_cache_reg);
__ brx(Assembler::equal, true, Assembler::pt, L);
__ delayed()->nop();
--- a/src/cpu/sparc/vm/sparc.ad Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/sparc.ad Sun Apr 13 17:43:42 2008 -0400
@@ -544,11 +544,19 @@ int MachCallDynamicJavaNode::ret_addr_of
assert(!UseInlineCaches, "expect vtable calls only if not using ICs");
int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
+ int klass_load_size;
+ if (UseCompressedOops) {
+ klass_load_size = 3*BytesPerInstWord; // see MacroAssembler::load_klass()
+ } else {
+ klass_load_size = 1*BytesPerInstWord;
+ }
if( Assembler::is_simm13(v_off) ) {
- return (3*BytesPerInstWord + // ld_ptr, ld_ptr, ld_ptr
+ return klass_load_size +
+ (2*BytesPerInstWord + // ld_ptr, ld_ptr
NativeCall::instruction_size); // call; delay slot
} else {
- return (5*BytesPerInstWord + // ld_ptr, set_hi, set, ld_ptr, ld_ptr
+ return klass_load_size +
+ (4*BytesPerInstWord + // set_hi, set, ld_ptr, ld_ptr
NativeCall::instruction_size); // call; delay slot
}
}
@@ -1591,7 +1599,13 @@ void MachUEPNode::format( PhaseRegAlloc
void MachUEPNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
st->print_cr("\nUEP:");
#ifdef _LP64
- st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
+ if (UseCompressedOops) {
+ st->print_cr("\tLDUW [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check - compressed klass");
+ st->print_cr("\tSLL R_G5,3,R_G5");
+ st->print_cr("\tADD R_G5,R_G6_heap_base,R_G5");
+ } else {
+ st->print_cr("\tLDX [R_O0 + oopDesc::klass_offset_in_bytes],R_G5\t! Inline cache check");
+ }
st->print_cr("\tCMP R_G5,R_G3" );
st->print ("\tTne xcc,R_G0+ST_RESERVED_FOR_USER_0+2");
#else // _LP64
@@ -1610,7 +1624,7 @@ void MachUEPNode::emit(CodeBuffer &cbuf,
assert( G5_ic_reg != temp_reg, "conflicting registers" );
// Load klass from reciever
- __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), temp_reg);
+ __ load_klass(O0, temp_reg);
// Compare against expected klass
__ cmp(temp_reg, G5_ic_reg);
// Branch to miss code, checks xcc or icc depending
@@ -1811,6 +1825,11 @@ bool Matcher::can_be_java_arg( int reg )
reg == R_I3H_num ||
reg == R_I4H_num ||
reg == R_I5H_num ) return true;
+
+ if ((UseCompressedOops) && (reg == R_G6_num || reg == R_G6H_num)) {
+ return true;
+ }
+
#else
// 32-bit builds with longs-in-one-entry pass longs in G1 & G4.
// Longs cannot be passed in O regs, because O regs become I regs
@@ -2474,7 +2493,13 @@ encode %{
// get receiver klass (receiver already checked for non-null)
// If we end up going thru a c2i adapter interpreter expects method in G5
int off = __ offset();
- __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch);
+ __ load_klass(O0, G3_scratch);
+ int klass_load_size;
+ if (UseCompressedOops) {
+ klass_load_size = 3*BytesPerInstWord;
+ } else {
+ klass_load_size = 1*BytesPerInstWord;
+ }
int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
if( __ is_simm13(v_off) ) {
@@ -2484,7 +2509,8 @@ encode %{
__ Assembler::sethi(v_off & ~0x3ff, G5_method);
__ or3(G5_method, v_off & 0x3ff, G5_method);
// ld_ptr, set_hi, set
- assert(__ offset() - off == 3*BytesPerInstWord, "Unexpected instruction size(s)");
+ assert(__ offset() - off == klass_load_size + 2*BytesPerInstWord,
+ "Unexpected instruction size(s)");
__ ld_ptr(G3, G5_method, G5_method);
}
// NOTE: for vtable dispatches, the vtable entry will never be null.
@@ -2860,12 +2886,12 @@ enc_class Fast_Unlock(iRegP oop, iRegP b
int count_offset = java_lang_String:: count_offset_in_bytes();
// load str1 (jchar*) base address into tmp1_reg
- __ ld_ptr(Address(str1_reg, 0, value_offset), tmp1_reg);
+ __ load_heap_oop(Address(str1_reg, 0, value_offset), tmp1_reg);
__ ld(Address(str1_reg, 0, offset_offset), result_reg);
__ add(tmp1_reg, arrayOopDesc::base_offset_in_bytes(T_CHAR), tmp1_reg);
__ ld(Address(str1_reg, 0, count_offset), str1_reg); // hoisted
__ sll(result_reg, exact_log2(sizeof(jchar)), result_reg);
- __ ld_ptr(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted
+ __ load_heap_oop(Address(str2_reg, 0, value_offset), tmp2_reg); // hoisted
__ add(result_reg, tmp1_reg, tmp1_reg);
// load str2 (jchar*) base address into tmp2_reg
@@ -3016,6 +3042,7 @@ enc_class Fast_Unlock(iRegP oop, iRegP b
MacroAssembler _masm(&cbuf);
__ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad) );
%}
+
enc_class enc_repl8b( iRegI src, iRegL dst ) %{
MacroAssembler _masm(&cbuf);
Register src_reg = reg_to_register_object($src$$reg);
@@ -3189,15 +3216,15 @@ frame %{
c_return_value %{
assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
#ifdef _LP64
- static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num };
- static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num};
- static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num };
- static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num};
+ static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num };
+ static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num};
+ static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num };
+ static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num};
#else // !_LP64
- static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
- static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
+ static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num };
+ static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
+ static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num };
+ static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num };
#endif
return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg],
(is_outgoing?lo_out:lo_in)[ideal_reg] );
@@ -3207,15 +3234,15 @@ frame %{
return_value %{
assert( ideal_reg >= Op_RegI && ideal_reg <= Op_RegL, "only return normal values" );
#ifdef _LP64
- static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num };
- static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num};
- static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num };
- static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num};
+ static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_O0_num };
+ static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_O0H_num, OptoReg::Bad, R_F1_num, R_O0H_num};
+ static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_I0_num };
+ static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_I0H_num, OptoReg::Bad, R_F1_num, R_I0H_num};
#else // !_LP64
- static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
- static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num };
- static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
+ static int lo_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_O0_num, R_O0_num, R_O0_num, R_F0_num, R_F0_num, R_G1_num };
+ static int hi_out[Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
+ static int lo_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, R_I0_num, R_I0_num, R_I0_num, R_F0_num, R_F0_num, R_G1_num };
+ static int hi_in [Op_RegL+1] = { OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, R_F1_num, R_G1H_num};
#endif
return OptoRegPair( (is_outgoing?hi_out:hi_in)[ideal_reg],
(is_outgoing?lo_out:lo_in)[ideal_reg] );
@@ -3404,6 +3431,27 @@ operand immP_poll() %{
match(ConP);
// formats are generated automatically for constants and base registers
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
+// Pointer Immediate
+operand immN()
+%{
+ match(ConN);
+
+ op_cost(10);
+ format %{ %}
+ interface(CONST_INTER);
+%}
+
+// NULL Pointer Immediate
+operand immN0()
+%{
+ predicate(n->get_narrowcon() == 0);
+ match(ConN);
+
+ op_cost(0);
format %{ %}
interface(CONST_INTER);
%}
@@ -3667,6 +3715,14 @@ operand o7RegI() %{
operand o7RegI() %{
constraint(ALLOC_IN_RC(o7_regI));
match(iRegI);
+
+ format %{ %}
+ interface(REG_INTER);
+%}
+
+operand iRegN() %{
+ constraint(ALLOC_IN_RC(int_reg));
+ match(RegN);
format %{ %}
interface(REG_INTER);
@@ -5392,9 +5448,30 @@ instruct loadP(iRegP dst, memory mem) %{
ins_pipe(iload_mem);
%}
+// Load Compressed Pointer
+instruct loadN(iRegN dst, memory mem) %{
+ match(Set dst (LoadN mem));
+ ins_cost(MEMORY_REF_COST);
+ size(4);
+
+ format %{ "LDUW $mem,$dst\t! compressed ptr" %}
+ ins_encode %{
+ Register base = as_Register($mem$$base);
+ Register index = as_Register($mem$$index);
+ Register dst = $dst$$Register;
+ if (index != G0) {
+ __ lduw(base, index, dst);
+ } else {
+ __ lduw(base, $mem$$disp, dst);
+ }
+ %}
+ ins_pipe(iload_mem);
+%}
+
// Load Klass Pointer
instruct loadKlass(iRegP dst, memory mem) %{
match(Set dst (LoadKlass mem));
+ predicate(!n->in(MemNode::Address)->bottom_type()->is_narrow());
ins_cost(MEMORY_REF_COST);
size(4);
@@ -5406,6 +5483,30 @@ instruct loadKlass(iRegP dst, memory mem
opcode(Assembler::ldx_op3, 0, REGP_OP);
#endif
ins_encode( form3_mem_reg( mem, dst ) );
+ ins_pipe(iload_mem);
+%}
+
+// Load Klass Pointer
+instruct loadKlassComp(iRegP dst, memory mem) %{
+ match(Set dst (LoadKlass mem));
+ predicate(n->in(MemNode::Address)->bottom_type()->is_narrow());
+ ins_cost(MEMORY_REF_COST);
+
+ format %{ "LDUW $mem,$dst\t! compressed klass ptr" %}
+
+ ins_encode %{
+ Register base = as_Register($mem$$base);
+ Register index = as_Register($mem$$index);
+ Register dst = $dst$$Register;
+ if (index != G0) {
+ __ lduw(base, index, dst);
+ } else {
+ __ 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);
%}
@@ -5508,6 +5609,24 @@ instruct loadConP_poll(iRegP dst, immP_p
ins_pipe(loadConP_poll);
%}
+instruct loadConN(iRegN dst, immN src) %{
+ match(Set dst src);
+ ins_cost(DEFAULT_COST * 2);
+ format %{ "SET $src,$dst\t!ptr" %}
+ ins_encode %{
+ address con = (address)$src$$constant;
+ Register dst = $dst$$Register;
+ if (con == NULL) {
+ __ mov(G0, dst);
+ } else {
+ __ set_oop((jobject)$src$$constant, dst);
+ __ encode_heap_oop(dst);
+ }
+ %}
+ ins_pipe(loadConP);
+
+%}
+
instruct loadConL(iRegL dst, immL src, o7RegL tmp) %{
// %%% maybe this should work like loadConD
match(Set dst src);
@@ -5741,6 +5860,44 @@ instruct storeP0(memory dst, immP0 src)
ins_pipe(istore_mem_zero);
%}
+// Store Compressed Pointer
+instruct storeN(memory dst, iRegN src) %{
+ match(Set dst (StoreN dst src));
+ ins_cost(MEMORY_REF_COST);
+ size(4);
+
+ format %{ "STW $src,$dst\t! compressed ptr" %}
+ ins_encode %{
+ Register base = as_Register($dst$$base);
+ Register index = as_Register($dst$$index);
+ Register src = $src$$Register;
+ if (index != G0) {
+ __ stw(src, base, index);
+ } else {
+ __ stw(src, base, $dst$$disp);
+ }
+ %}
+ ins_pipe(istore_mem_spORreg);
+%}
+
+instruct storeN0(memory dst, immN0 src) %{
+ match(Set dst (StoreN dst src));
+ ins_cost(MEMORY_REF_COST);
+ size(4);
+
+ format %{ "STW $src,$dst\t! compressed ptr" %}
+ ins_encode %{
+ Register base = as_Register($dst$$base);
+ Register index = as_Register($dst$$index);
+ if (index != G0) {
+ __ stw(0, base, index);
+ } else {
+ __ stw(0, base, $dst$$disp);
+ }
+ %}
+ ins_pipe(istore_mem_zero);
+%}
+
// Store Double
instruct storeD( memory mem, regD src) %{
match(Set mem (StoreD mem src));
@@ -5797,6 +5954,26 @@ instruct storeA8B(memory mem, regD src)
ins_encode( form3_mem_reg( mem, src ) );
ins_pipe(fstoreD_mem_reg);
%}
+
+// Convert oop pointer into compressed form
+instruct encodeHeapOop(iRegN dst, iRegP src) %{
+ match(Set dst (EncodeP src));
+ format %{ "SRL $src,3,$dst\t encodeHeapOop" %}
+ ins_encode %{
+ __ encode_heap_oop($src$$Register, $dst$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
+instruct decodeHeapOop(iRegP dst, iRegN src) %{
+ match(Set dst (DecodeN src));
+ format %{ "decode_heap_oop $src, $dst" %}
+ ins_encode %{
+ __ decode_heap_oop($src$$Register, $dst$$Register);
+ %}
+ ins_pipe(ialu_reg);
+%}
+
// Store Zero into Aligned Packed Bytes
instruct storeA8B0(memory mem, immI0 zero) %{
@@ -6434,17 +6611,27 @@ instruct compareAndSwapP_bool(iRegP mem_
instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
effect( USE mem_ptr, KILL ccr, KILL tmp1);
-#ifdef _LP64
format %{
"MOV $newval,O7\n\t"
- "CASXA [$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_PTR [$mem_ptr],$oldval,O7\t! If $oldval==[$mem_ptr] Then store O7 into [$mem_ptr], set O7=[$mem_ptr] in any case\n\t"
"CMP $oldval,O7\t\t! See if we made progress\n\t"
"MOV 1,$res\n\t"
"MOVne xcc,R_G0,$res"
%}
+#ifdef _LP64
ins_encode( enc_casx(mem_ptr, oldval, newval),
enc_lflags_ne_to_boolean(res) );
#else
+ ins_encode( enc_casi(mem_ptr, oldval, newval),
+ enc_iflags_ne_to_boolean(res) );
+#endif
+ ins_pipe( long_memory_op );
+%}
+
+instruct compareAndSwapN_bool_comp(iRegP mem_ptr, iRegN oldval, iRegN newval, iRegI res, o7RegI tmp, flagsReg ccr ) %{
+ match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
+ effect( USE mem_ptr, KILL ccr, KILL tmp);
+
format %{
"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"
@@ -6452,9 +6639,18 @@ instruct compareAndSwapP_bool(iRegP mem_
"MOV 1,$res\n\t"
"MOVne icc,R_G0,$res"
%}
- ins_encode( enc_casi(mem_ptr, oldval, newval),
- enc_iflags_ne_to_boolean(res) );
-#endif
+ ins_encode %{
+ Register Rmem = reg_to_register_object($mem_ptr$$reg);
+ 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 );
%}
@@ -8607,6 +8803,17 @@ instruct partialSubtypeCheck_vs_zero( fl
ins_pipe(partial_subtype_check_pipe);
%}
+
+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
@@ -8648,9 +8855,10 @@ instruct clear_array(iRegX cnt, iRegP ba
ins_pipe(long_memory_op);
%}
-instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result, flagsReg ccr) %{
+instruct string_compare(o0RegP str1, o1RegP str2, g3RegP tmp1, g4RegP tmp2, notemp_iRegI result,
+ o7RegI tmp3, flagsReg ccr) %{
match(Set result (StrComp str1 str2));
- effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr);
+ effect(USE_KILL str1, USE_KILL str2, KILL tmp1, KILL tmp2, KILL ccr, KILL tmp3);
ins_cost(300);
format %{ "String Compare $str1,$str2 -> $result" %}
ins_encode( enc_String_Compare(str1, str2, tmp1, tmp2, result) );
--- a/src/cpu/sparc/vm/stubGenerator_sparc.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/stubGenerator_sparc.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -127,6 +127,7 @@ class StubGenerator: public StubCodeGene
// setup thread register
__ ld_ptr(thread.as_address(), G2_thread);
+ __ reinit_heapbase();
#ifdef ASSERT
// make sure we have no pending exceptions
@@ -896,6 +897,7 @@ class StubGenerator: public StubCodeGene
// super: O2, argument, not changed
// raddr: O7, blown by call
address generate_partial_subtype_check() {
+ __ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", "partial_subtype_check");
address start = __ pc();
Label loop, miss;
@@ -914,7 +916,7 @@ class StubGenerator: public StubCodeGene
#if defined(COMPILER2) && !defined(_LP64)
// Do not use a 'save' because it blows the 64-bit O registers.
- __ add(SP,-4*wordSize,SP); // Make space for 4 temps
+ __ add(SP,-4*wordSize,SP); // Make space for 4 temps (stack must be 2 words aligned)
__ st_ptr(L0,SP,(frame::register_save_words+0)*wordSize);
__ st_ptr(L1,SP,(frame::register_save_words+1)*wordSize);
__ st_ptr(L2,SP,(frame::register_save_words+2)*wordSize);
@@ -934,6 +936,17 @@ class StubGenerator: public StubCodeGene
Register L2_super = L2;
Register L3_index = L3;
+#ifdef _LP64
+ Register L4_ooptmp = L4;
+
+ if (UseCompressedOops) {
+ // this must be under UseCompressedOops check, as we rely upon fact
+ // that L4 not clobbered in C2 on 32-bit platforms, where we do explicit save
+ // on stack, see several lines above
+ __ encode_heap_oop(Rsuper, L4_ooptmp);
+ }
+#endif
+
inc_counter_np(SharedRuntime::_partial_subtype_ctr, L0, L1);
__ ld_ptr( Rsub, sizeof(oopDesc) + Klass::secondary_supers_offset_in_bytes(), L3 );
@@ -942,18 +955,33 @@ class StubGenerator: public StubCodeGene
__ clr(L3_index); // zero index
// Load a little early; will load 1 off the end of the array.
// Ok for now; revisit if we have other uses of this routine.
- __ ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early
- __ align(CodeEntryAlignment);
-
+ if (UseCompressedOops) {
+ __ ld(L1_ary_ptr,0,L2_super);// Will load a little early
+ } else {
+ __ ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early
+ }
+
+ assert(heapOopSize != 0, "heapOopSize should be initialized");
// The scan loop
__ BIND(loop);
- __ add(L1_ary_ptr,wordSize,L1_ary_ptr); // Bump by OOP size
+ __ add(L1_ary_ptr, heapOopSize, L1_ary_ptr); // Bump by OOP size
__ cmp(L3_index,L0_ary_len);
__ br(Assembler::equal,false,Assembler::pn,miss);
__ delayed()->inc(L3_index); // Bump index
- __ subcc(L2_super,Rsuper,Rret); // Check for match; zero in Rret for a hit
- __ brx( Assembler::notEqual, false, Assembler::pt, loop );
- __ delayed()->ld_ptr(L1_ary_ptr,0,L2_super); // Will load a little early
+
+ if (UseCompressedOops) {
+#ifdef _LP64
+ __ subcc(L2_super,L4_ooptmp,Rret); // Check for match; zero in Rret for a hit
+ __ br( Assembler::notEqual, false, Assembler::pt, loop );
+ __ delayed()->ld(L1_ary_ptr,0,L2_super);// Will load a little early
+#else
+ ShouldNotReachHere();
+#endif
+ } else {
+ __ subcc(L2_super,Rsuper,Rret); // Check for match; zero in Rret for a hit
+ __ brx( Assembler::notEqual, false, Assembler::pt, loop );
+ __ delayed()->ld_ptr(L1_ary_ptr,0,L2_super);// Will load a little early
+ }
// Got a hit; report success; set cache. Cache load doesn't
// happen here; for speed it is directly emitted by the compiler.
@@ -1107,7 +1135,6 @@ class StubGenerator: public StubCodeGene
}
#endif // 0
}
-
//
// Generate post-write barrier for array.
//
@@ -1148,8 +1175,8 @@ class StubGenerator: public StubCodeGene
Label L_loop;
- __ sll_ptr(count, LogBytesPerOop, count);
- __ sub(count, BytesPerOop, count);
+ __ sll_ptr(count, LogBytesPerHeapOop, count);
+ __ sub(count, BytesPerHeapOop, count);
__ add(count, addr, count);
// Use two shifts to clear out those low order two bits! (Cannot opt. into 1.)
__ srl_ptr(addr, CardTableModRefBS::card_shift, addr);
@@ -1171,7 +1198,6 @@ class StubGenerator: public StubCodeGene
ShouldNotReachHere();
}
-
}
@@ -2226,7 +2252,12 @@ class StubGenerator: public StubCodeGene
__ mov(count, G5);
gen_write_ref_array_pre_barrier(G1, G5);
#ifdef _LP64
- generate_disjoint_long_copy_core(aligned);
+ assert_clean_int(count, O3); // Make sure 'count' is clean int.
+ if (UseCompressedOops) {
+ generate_disjoint_int_copy_core(aligned);
+ } else {
+ generate_disjoint_long_copy_core(aligned);
+ }
#else
generate_disjoint_int_copy_core(aligned);
#endif
@@ -2274,10 +2305,14 @@ class StubGenerator: public StubCodeGene
StubRoutines::arrayof_oop_disjoint_arraycopy() :
disjoint_oop_copy_entry;
- array_overlap_test(nooverlap_target, LogBytesPerWord);
+ array_overlap_test(nooverlap_target, LogBytesPerHeapOop);
#ifdef _LP64
- generate_conjoint_long_copy_core(aligned);
+ if (UseCompressedOops) {
+ generate_conjoint_int_copy_core(aligned);
+ } else {
+ generate_conjoint_long_copy_core(aligned);
+ }
#else
generate_conjoint_int_copy_core(aligned);
#endif
@@ -2377,8 +2412,6 @@ class StubGenerator: public StubCodeGene
StubCodeMark mark(this, "StubRoutines", name);
address start = __ pc();
- int klass_off = oopDesc::klass_offset_in_bytes();
-
gen_write_ref_array_pre_barrier(G1, G5);
@@ -2395,7 +2428,7 @@ class StubGenerator: public StubCodeGene
{ Label L;
__ mov(O3, G1); // spill: overlap test smashes O3
__ mov(O4, G4); // spill: overlap test smashes O4
- array_overlap_test(L, LogBytesPerWord);
+ array_overlap_test(L, LogBytesPerHeapOop);
__ stop("checkcast_copy within a single array");
__ bind(L);
__ mov(G1, O3);
@@ -2429,18 +2462,18 @@ class StubGenerator: public StubCodeGene
__ bind(store_element);
// deccc(G1_remain); // decrement the count (hoisted)
- __ st_ptr(G3_oop, O1_to, O5_offset); // store the oop
- __ inc(O5_offset, wordSize); // step to next offset
+ __ store_heap_oop(G3_oop, O1_to, O5_offset); // store the oop
+ __ inc(O5_offset, heapOopSize); // step to next offset
__ brx(Assembler::zero, true, Assembler::pt, do_card_marks);
__ delayed()->set(0, O0); // return -1 on success
// ======== loop entry is here ========
__ bind(load_element);
- __ ld_ptr(O0_from, O5_offset, G3_oop); // load the oop
+ __ load_heap_oop(O0_from, O5_offset, G3_oop); // load the oop
__ br_null(G3_oop, true, Assembler::pt, store_element);
__ delayed()->deccc(G1_remain); // decrement the count
- __ ld_ptr(G3_oop, klass_off, G4_klass); // query the object klass
+ __ load_klass(G3_oop, G4_klass); // query the object klass
generate_type_check(G4_klass, O3_ckoff, O4_ckval, G5_super,
// branch to this on success:
@@ -2642,17 +2675,23 @@ class StubGenerator: public StubCodeGene
BLOCK_COMMENT("arraycopy argument klass checks");
// get src->klass()
- __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), G3_src_klass);
+ if (UseCompressedOops) {
+ __ delayed()->nop(); // ??? not good
+ __ load_klass(src, G3_src_klass);
+ } else {
+ __ delayed()->ld_ptr(src, oopDesc::klass_offset_in_bytes(), G3_src_klass);
+ }
#ifdef ASSERT
// assert(src->klass() != NULL);
BLOCK_COMMENT("assert klasses not null");
{ Label L_a, L_b;
__ br_notnull(G3_src_klass, false, Assembler::pt, L_b); // it is broken if klass is NULL
- __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass);
+ __ delayed()->nop();
__ bind(L_a);
__ stop("broken null klass");
__ bind(L_b);
+ __ load_klass(dst, G4_dst_klass);
__ br_null(G4_dst_klass, false, Assembler::pn, L_a); // this would be broken also
__ delayed()->mov(G0, G4_dst_klass); // scribble the temp
BLOCK_COMMENT("assert done");
@@ -2673,12 +2712,19 @@ class StubGenerator: public StubCodeGene
// Load 32-bits signed value. Use br() instruction with it to check icc.
__ lduw(G3_src_klass, lh_offset, G5_lh);
+ if (UseCompressedOops) {
+ __ load_klass(dst, G4_dst_klass);
+ }
// Handle objArrays completely differently...
juint objArray_lh = Klass::array_layout_helper(T_OBJECT);
__ set(objArray_lh, O5_temp);
__ cmp(G5_lh, O5_temp);
__ br(Assembler::equal, false, Assembler::pt, L_objArray);
- __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass);
+ if (UseCompressedOops) {
+ __ delayed()->nop();
+ } else {
+ __ delayed()->ld_ptr(dst, oopDesc::klass_offset_in_bytes(), G4_dst_klass);
+ }
// if (src->klass() != dst->klass()) return -1;
__ cmp(G3_src_klass, G4_dst_klass);
@@ -2777,8 +2823,8 @@ class StubGenerator: public StubCodeGene
__ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset
__ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset
- __ sll_ptr(src_pos, LogBytesPerOop, src_pos);
- __ sll_ptr(dst_pos, LogBytesPerOop, dst_pos);
+ __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos);
+ __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos);
__ add(src, src_pos, from); // src_addr
__ add(dst, dst_pos, to); // dst_addr
__ BIND(L_plain_copy);
@@ -2801,8 +2847,8 @@ class StubGenerator: public StubCodeGene
// Marshal the base address arguments now, freeing registers.
__ add(src, arrayOopDesc::base_offset_in_bytes(T_OBJECT), src); //src offset
__ add(dst, arrayOopDesc::base_offset_in_bytes(T_OBJECT), dst); //dst offset
- __ sll_ptr(src_pos, LogBytesPerOop, src_pos);
- __ sll_ptr(dst_pos, LogBytesPerOop, dst_pos);
+ __ sll_ptr(src_pos, LogBytesPerHeapOop, src_pos);
+ __ sll_ptr(dst_pos, LogBytesPerHeapOop, dst_pos);
__ add(src, src_pos, from); // src_addr
__ add(dst, dst_pos, to); // dst_addr
__ signx(length, count); // length (reloaded)
--- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -591,7 +591,10 @@ address InterpreterGenerator::generate_a
address entry = __ pc();
Label slow_path;
- if ( UseFastAccessorMethods) {
+
+ // XXX: for compressed oops pointer loading and decoding doesn't fit in
+ // delay slot and damages G1
+ if ( UseFastAccessorMethods && !UseCompressedOops ) {
// Check if we need to reach a safepoint and generate full interpreter
// frame if so.
Address sync_state(G3_scratch, SafepointSynchronize::address_of_state());
@@ -953,6 +956,7 @@ address InterpreterGenerator::generate_n
// Back from jni method Lmethod in this frame is DEAD, DEAD, DEAD
__ restore_thread(L7_thread_cache); // restore G2_thread
+ __ reinit_heapbase();
// must we block?
--- a/src/cpu/sparc/vm/templateTable_sparc.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -462,8 +462,8 @@ void TemplateTable::aaload() {
transition(itos, atos);
// Otos_i: index
// tos: array
- __ index_check(O2, Otos_i, LogBytesPerWord, G3_scratch, O3);
- __ ld_ptr(O3, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i);
+ __ index_check(O2, Otos_i, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O3);
+ __ load_heap_oop(O3, arrayOopDesc::base_offset_in_bytes(T_OBJECT), Otos_i);
__ verify_oop(Otos_i);
}
@@ -736,15 +736,16 @@ void TemplateTable::aastore() {
// O2: index
// O3: array
__ verify_oop(Otos_i);
- __ index_check_without_pop(O3, O2, LogBytesPerWord, G3_scratch, O1);
+ __ index_check_without_pop(O3, O2, UseCompressedOops ? 2 : LogBytesPerWord, G3_scratch, O1);
// do array store check - check for NULL value first
__ br_null( Otos_i, false, Assembler::pn, is_null );
- __ delayed()->
- ld_ptr(O3, oopDesc::klass_offset_in_bytes(), O4); // get array klass
+ __ delayed()->nop();
+
+ __ load_klass(O3, O4); // get array klass
+ __ load_klass(Otos_i, O5); // get value klass
// do fast instanceof cache test
- __ ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), O5); // get value klass
__ ld_ptr(O4, sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes(), O4);
@@ -766,7 +767,7 @@ void TemplateTable::aastore() {
// Store is OK.
__ bind(store_ok);
- __ st_ptr(Otos_i, O1, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
+ __ store_heap_oop(Otos_i, O1, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
// Quote from rememberedSet.hpp: For objArrays, the precise card
// corresponding to the pointer store is dirtied so we don't need to
// scavenge the entire array.
@@ -777,7 +778,7 @@ void TemplateTable::aastore() {
__ delayed()->inc(Lesp, 3* Interpreter::stackElementSize()); // adj sp (pops array, index and value)
__ bind(is_null);
- __ st_ptr(Otos_i, element);
+ __ store_heap_oop(Otos_i, element);
__ profile_null_seen(G3_scratch);
__ inc(Lesp, 3* Interpreter::stackElementSize()); // adj sp (pops array, index and value)
__ bind(done);
@@ -1833,7 +1834,7 @@ void TemplateTable::_return(TosState sta
assert(state == vtos, "only valid state");
__ mov(G0, G3_scratch);
__ access_local_ptr(G3_scratch, Otos_i);
- __ ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), O2);
+ __ load_klass(Otos_i, O2);
__ set(JVM_ACC_HAS_FINALIZER, G3);
__ ld(O2, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc), O2);
__ andcc(G3, O2, G0);
@@ -2078,7 +2079,7 @@ void TemplateTable::getfield_or_static(i
__ delayed() ->cmp(Rflags, itos);
// atos
- __ ld_ptr(Rclass, Roffset, Otos_i);
+ __ load_heap_oop(Rclass, Roffset, Otos_i);
__ verify_oop(Otos_i);
__ push(atos);
if (!is_static) {
@@ -2259,7 +2260,7 @@ void TemplateTable::fast_accessfield(Tos
__ ldf(FloatRegisterImpl::D, Otos_i, Roffset, Ftos_d);
break;
case Bytecodes::_fast_agetfield:
- __ ld_ptr(Otos_i, Roffset, Otos_i);
+ __ load_heap_oop(Otos_i, Roffset, Otos_i);
break;
default:
ShouldNotReachHere();
@@ -2448,7 +2449,7 @@ void TemplateTable::putfield_or_static(i
// atos
__ pop_ptr();
__ verify_oop(Otos_i);
- __ st_ptr(Otos_i, Rclass, Roffset);
+ __ store_heap_oop(Otos_i, Rclass, Roffset);
__ store_check(G1_scratch, Rclass, Roffset);
__ ba(false, checkVolatile);
__ delayed()->tst(Lscratch);
@@ -2490,7 +2491,7 @@ void TemplateTable::putfield_or_static(i
__ pop_ptr();
pop_and_check_object(Rclass);
__ verify_oop(Otos_i);
- __ st_ptr(Otos_i, Rclass, Roffset);
+ __ store_heap_oop(Otos_i, Rclass, Roffset);
__ store_check(G1_scratch, Rclass, Roffset);
patch_bytecode(Bytecodes::_fast_aputfield, G3_scratch, G4_scratch);
__ ba(false, checkVolatile);
@@ -2645,7 +2646,7 @@ void TemplateTable::fast_storefield(TosS
__ stf(FloatRegisterImpl::D, Ftos_d, Rclass, Roffset);
break;
case Bytecodes::_fast_aputfield:
- __ st_ptr(Otos_i, Rclass, Roffset);
+ __ store_heap_oop(Otos_i, Rclass, Roffset);
__ store_check(G1_scratch, Rclass, Roffset);
break;
default:
@@ -2688,7 +2689,7 @@ void TemplateTable::fast_xaccess(TosStat
__ verify_oop(Rreceiver);
__ null_check(Rreceiver);
if (state == atos) {
- __ ld_ptr(Rreceiver, Roffset, Otos_i);
+ __ load_heap_oop(Rreceiver, Roffset, Otos_i);
} else if (state == itos) {
__ ld (Rreceiver, Roffset, Otos_i) ;
} else if (state == ftos) {
@@ -2790,7 +2791,7 @@ void TemplateTable::invokevirtual(int by
// get receiver klass
__ null_check(O0, oopDesc::klass_offset_in_bytes());
- __ ld_ptr(Address(O0, 0, oopDesc::klass_offset_in_bytes()), Rrecv);
+ __ load_klass(O0, Rrecv);
__ verify_oop(Rrecv);
__ profile_virtual_call(Rrecv, O4);
@@ -2958,7 +2959,7 @@ void TemplateTable::invokeinterface(int
// get receiver klass
__ null_check(O0, oopDesc::klass_offset_in_bytes());
- __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), RklassOop);
+ __ load_klass(O0, RklassOop);
__ verify_oop(RklassOop);
// Special case of invokeinterface called for virtual method of
@@ -3221,7 +3222,7 @@ void TemplateTable::_new() {
__ set((intptr_t)markOopDesc::prototype(), G4_scratch);
}
__ st_ptr(G4_scratch, RallocatedObject, oopDesc::mark_offset_in_bytes()); // mark
- __ st_ptr(RinstanceKlass, RallocatedObject, oopDesc::klass_offset_in_bytes()); // klass
+ __ store_klass(RinstanceKlass, RallocatedObject); // klass
{
SkipIfEqual skip_if(
@@ -3277,7 +3278,7 @@ void TemplateTable::checkcast() {
__ delayed()->nop();
// Get value klass in RobjKlass
- __ ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), RobjKlass); // get value klass
+ __ load_klass(Otos_i, RobjKlass); // get value klass
// Get constant pool tag
__ get_2_byte_integer_at_bcp(1, Lscratch, Roffset, InterpreterMacroAssembler::Unsigned);
@@ -3295,13 +3296,14 @@ void TemplateTable::checkcast() {
__ pop_ptr(Otos_i, G3_scratch); // restore receiver
__ br(Assembler::always, false, Assembler::pt, resolved);
- __ delayed()->ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), RobjKlass); // get value klass
+ __ delayed()->nop();
// Extract target class from constant pool
__ bind(quicked);
__ add(Roffset, sizeof(constantPoolOopDesc), Roffset);
__ ld_ptr(Lscratch, Roffset, RspecifiedKlass);
__ bind(resolved);
+ __ load_klass(Otos_i, RobjKlass); // get value klass
// Generate a fast subtype check. Branch to cast_ok if no
// failure. Throw exception if failure.
@@ -3334,7 +3336,7 @@ void TemplateTable::instanceof() {
__ delayed()->nop();
// Get value klass in RobjKlass
- __ ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), RobjKlass); // get value klass
+ __ load_klass(Otos_i, RobjKlass); // get value klass
// Get constant pool tag
__ get_2_byte_integer_at_bcp(1, Lscratch, Roffset, InterpreterMacroAssembler::Unsigned);
@@ -3352,7 +3354,7 @@ void TemplateTable::instanceof() {
__ pop_ptr(Otos_i, G3_scratch); // restore receiver
__ br(Assembler::always, false, Assembler::pt, resolved);
- __ delayed()->ld_ptr(Otos_i, oopDesc::klass_offset_in_bytes(), RobjKlass); // get value klass
+ __ delayed()->nop();
// Extract target class from constant pool
@@ -3361,6 +3363,7 @@ void TemplateTable::instanceof() {
__ get_constant_pool(Lscratch);
__ ld_ptr(Lscratch, Roffset, RspecifiedKlass);
__ bind(resolved);
+ __ load_klass(Otos_i, RobjKlass); // get value klass
// Generate a fast subtype check. Branch to cast_ok if no
// failure. Return 0 if failure.
--- a/src/cpu/sparc/vm/vm_version_sparc.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/vm_version_sparc.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -64,6 +64,15 @@ void VM_Version::initialize() {
if (FLAG_IS_DEFAULT(UseInlineCaches)) {
UseInlineCaches = false;
}
+#ifdef _LP64
+ // Single issue niagara1 is slower for CompressedOops
+ // but niagaras after that it's fine.
+ if (!is_niagara1_plus()) {
+ if (FLAG_IS_DEFAULT(UseCompressedOops)) {
+ FLAG_SET_ERGO(bool, UseCompressedOops, false);
+ }
+ }
+#endif // _LP64
#ifdef COMPILER2
// Indirect branch is the same cost as direct
if (FLAG_IS_DEFAULT(UseJumpTables)) {
--- a/src/cpu/sparc/vm/vtableStubs_sparc.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/sparc/vm/vtableStubs_sparc.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -60,7 +60,7 @@ VtableStub* VtableStubs::create_vtable_s
// get receiver klass
address npe_addr = __ pc();
- __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_scratch);
+ __ load_klass(O0, G3_scratch);
// set methodOop (in case of interpreted method), and destination address
int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
@@ -131,7 +131,7 @@ VtableStub* VtableStubs::create_itable_s
// get receiver klass (also an implicit null-check)
address npe_addr = __ pc();
- __ ld_ptr(O0, oopDesc::klass_offset_in_bytes(), G3_klassOop);
+ __ load_klass(O0, G3_klassOop);
__ verify_oop(G3_klassOop);
// Push a new window to get some temp registers. This chops the head of all
@@ -237,11 +237,16 @@ int VtableStub::pd_code_size_limit(bool
else {
const int slop = 2*BytesPerInstWord; // sethi;add (needed for long offsets)
if (is_vtable_stub) {
- const int basic = 5*BytesPerInstWord; // ld;ld;ld,jmp,nop
+ // ld;ld;ld,jmp,nop
+ const int basic = 5*BytesPerInstWord +
+ // shift;add for load_klass
+ (UseCompressedOops ? 2*BytesPerInstWord : 0);
return basic + slop;
} else {
// save, ld, ld, sll, and, add, add, ld, cmp, br, add, ld, add, ld, ld, jmp, restore, sethi, jmpl, restore
- const int basic = (20 LP64_ONLY(+ 6)) * BytesPerInstWord;
+ const int basic = (20 LP64_ONLY(+ 6)) * BytesPerInstWord +
+ // shift;add for load_klass
+ (UseCompressedOops ? 2*BytesPerInstWord : 0);
return (basic + slop);
}
}
--- a/src/cpu/x86/vm/assembler_x86_64.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/x86/vm/assembler_x86_64.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -127,6 +127,7 @@ int AbstractAssembler::code_fill_byte()
bool Assembler::reachable(AddressLiteral adr) {
int64_t disp;
+
// None will force a 64bit literal to the code stream. Likely a placeholder
// for something that will be patched later and we need to certain it will
// always be reachable.
@@ -636,7 +637,7 @@ address Assembler::locate_operand(addres
case 0x8A: // movb r, a
case 0x8B: // movl r, a
case 0x8F: // popl a
- debug_only(has_disp32 = true);
+ debug_only(has_disp32 = true;)
break;
case 0x68: // pushq #32
@@ -2891,13 +2892,21 @@ void Assembler::rep_set() {
}
// scans rcx double words (m64) at [rdi] for occurance of rax
-void Assembler::repne_scan() {
+void Assembler::repne_scanq() {
// REPNE/REPNZ
emit_byte(0xF2);
// SCASQ
prefix(REX_W);
emit_byte(0xAF);
}
+
+void Assembler::repne_scanl() {
+ // REPNE/REPNZ
+ emit_byte(0xF2);
+ // SCASL
+ emit_byte(0xAF);
+}
+
void Assembler::setb(Condition cc, Register dst) {
assert(0 <= cc && cc < 16, "illegal cc");
@@ -4597,7 +4606,6 @@ void MacroAssembler::verify_oop(Register
// pass args on stack, only touch rax
pushq(reg);
-
// avoid using pushptr, as it modifies scratch registers
// and our contract is not to modify anything
ExternalAddress buffer((address)b);
@@ -4664,9 +4672,9 @@ void MacroAssembler::debug(char* msg, in
JavaThread* thread = JavaThread::current();
JavaThreadState saved_state = thread->thread_state();
thread->set_thread_state(_thread_in_vm);
- ttyLocker ttyl;
#ifndef PRODUCT
if (CountBytecodes || TraceBytecodes || StopInterpreterAt) {
+ ttyLocker ttyl;
BytecodeCounter::print();
}
#endif
@@ -4674,6 +4682,7 @@ void MacroAssembler::debug(char* msg, in
// XXX correct this offset for amd64
// This is the value of eip which points to where verify_oop will return.
if (os::message_box(msg, "Execution stopped, print registers?")) {
+ ttyLocker ttyl;
tty->print_cr("rip = 0x%016lx", pc);
tty->print_cr("rax = 0x%016lx", regs[15]);
tty->print_cr("rbx = 0x%016lx", regs[12]);
@@ -4695,6 +4704,7 @@ void MacroAssembler::debug(char* msg, in
}
ThreadStateTransition::transition(thread, _thread_in_vm, saved_state);
} else {
+ ttyLocker ttyl;
::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n",
msg);
}
@@ -4891,7 +4901,7 @@ void MacroAssembler::tlab_refill(Label&
movq(Address(top, arrayOopDesc::length_offset_in_bytes()), t1);
// set klass to intArrayKlass
movptr(t1, ExternalAddress((address) Universe::intArrayKlassObj_addr()));
- movq(Address(top, oopDesc::klass_offset_in_bytes()), t1);
+ store_klass(top, t1);
// refill the tlab with an eden allocation
bind(do_refill);
@@ -4938,7 +4948,6 @@ int MacroAssembler::biased_locking_enter
assert_different_registers(lock_reg, obj_reg, swap_reg, tmp_reg);
assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout");
Address mark_addr (obj_reg, oopDesc::mark_offset_in_bytes());
- Address klass_addr (obj_reg, oopDesc::klass_offset_in_bytes());
Address saved_mark_addr(lock_reg, 0);
if (PrintBiasedLockingStatistics && counters == NULL)
@@ -4962,7 +4971,7 @@ int MacroAssembler::biased_locking_enter
jcc(Assembler::notEqual, cas_label);
// The bias pattern is present in the object's header. Need to check
// whether the bias owner and the epoch are both still current.
- movq(tmp_reg, klass_addr);
+ load_klass(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);
xorq(tmp_reg, swap_reg);
@@ -5037,7 +5046,7 @@ int MacroAssembler::biased_locking_enter
//
// FIXME: due to a lack of registers we currently blow away the age
// bits in this situation. Should attempt to preserve them.
- movq(tmp_reg, klass_addr);
+ load_klass(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);
if (os::is_MP()) {
@@ -5068,7 +5077,7 @@ int MacroAssembler::biased_locking_enter
//
// FIXME: due to a lack of registers we currently blow away the age
// bits in this situation. Should attempt to preserve them.
- movq(tmp_reg, klass_addr);
+ load_klass(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()) {
lock();
@@ -5103,6 +5112,113 @@ void MacroAssembler::biased_locking_exit
jcc(Assembler::equal, done);
}
+
+void MacroAssembler::load_klass(Register dst, Register src) {
+ if (UseCompressedOops) {
+ movl(dst, Address(src, oopDesc::klass_offset_in_bytes()));
+ decode_heap_oop_not_null(dst);
+ } else {
+ movq(dst, Address(src, oopDesc::klass_offset_in_bytes()));
+ }
+}
+
+void MacroAssembler::store_klass(Register dst, Register src) {
+ if (UseCompressedOops) {
+ 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);
+ } else {
+ movq(Address(dst, oopDesc::klass_offset_in_bytes()), src);
+ }
+}
+
+void MacroAssembler::load_heap_oop(Register dst, Address src) {
+ if (UseCompressedOops) {
+ movl(dst, src);
+ decode_heap_oop(dst);
+ } else {
+ movq(dst, src);
+ }
+}
+
+void MacroAssembler::store_heap_oop(Address dst, Register src) {
+ if (UseCompressedOops) {
+ assert(!dst.uses(src), "not enough registers");
+ encode_heap_oop(src);
+ movl(dst, src);
+ } else {
+ movq(dst, src);
+ }
+}
+
+// Algorithm must match oop.inline.hpp encode_heap_oop.
+void MacroAssembler::encode_heap_oop(Register r) {
+ assert (UseCompressedOops, "should be compressed");
+#ifdef ASSERT
+ Label ok;
+ pushq(rscratch1); // cmpptr trashes rscratch1
+ cmpptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
+ jcc(Assembler::equal, ok);
+ stop("MacroAssembler::encode_heap_oop: heap base corrupted?");
+ bind(ok);
+ popq(rscratch1);
+#endif
+ verify_oop(r);
+ testq(r, r);
+ cmovq(Assembler::equal, r, r12_heapbase);
+ subq(r, r12_heapbase);
+ shrq(r, LogMinObjAlignmentInBytes);
+}
+
+void MacroAssembler::encode_heap_oop_not_null(Register r) {
+ assert (UseCompressedOops, "should be compressed");
+#ifdef ASSERT
+ Label ok;
+ testq(r, r);
+ jcc(Assembler::notEqual, ok);
+ stop("null oop passed to encode_heap_oop_not_null");
+ bind(ok);
+#endif
+ verify_oop(r);
+ subq(r, r12_heapbase);
+ shrq(r, LogMinObjAlignmentInBytes);
+}
+
+void MacroAssembler::decode_heap_oop(Register r) {
+ assert (UseCompressedOops, "should be compressed");
+#ifdef ASSERT
+ Label ok;
+ pushq(rscratch1);
+ cmpptr(r12_heapbase,
+ ExternalAddress((address)Universe::heap_base_addr()));
+ jcc(Assembler::equal, ok);
+ stop("MacroAssembler::decode_heap_oop: heap base corrupted?");
+ bind(ok);
+ popq(rscratch1);
+#endif
+
+ Label done;
+ shlq(r, LogMinObjAlignmentInBytes);
+ jccb(Assembler::equal, done);
+ addq(r, r12_heapbase);
+#if 0
+ // alternate decoding probably a wash.
+ testq(r, r);
+ jccb(Assembler::equal, done);
+ leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
+#endif
+ bind(done);
+ verify_oop(r);
+}
+
+void MacroAssembler::decode_heap_oop_not_null(Register r) {
+ assert (UseCompressedOops, "should only be used for compressed headers");
+ // Cannot assert, unverified entry point counts instructions (see .ad file)
+ // vtableStubs also counts instructions in pd_code_size_limit.
+ assert(Address::times_8 == LogMinObjAlignmentInBytes, "decode alg wrong");
+ leaq(r, Address(r12_heapbase, r, Address::times_8, 0));
+}
Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
switch (cond) {
@@ -5173,3 +5289,9 @@ void MacroAssembler::bang_stack_size(Reg
movq(Address(tmp, (-i*os::vm_page_size())), size );
}
}
+
+void MacroAssembler::reinit_heapbase() {
+ if (UseCompressedOops) {
+ movptr(r12_heapbase, ExternalAddress((address)Universe::heap_base_addr()));
+ }
+}
--- a/src/cpu/x86/vm/assembler_x86_64.hpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/x86/vm/assembler_x86_64.hpp Sun Apr 13 17:43:42 2008 -0400
@@ -37,7 +37,7 @@ class Argument VALUE_OBJ_CLASS_SPEC {
#else
n_int_register_parameters_c = 6, // rdi, rsi, rdx, rcx, r8, r9 (c_rarg0, c_rarg1, ...)
n_float_register_parameters_c = 8, // xmm0 - xmm7 (c_farg0, c_farg1, ... )
-#endif
+#endif // _WIN64
n_int_register_parameters_j = 6, // j_rarg0, j_rarg1, ...
n_float_register_parameters_j = 8 // j_farg0, j_farg1, ...
};
@@ -77,7 +77,7 @@ REGISTER_DECLARATION(XMMRegister, c_farg
REGISTER_DECLARATION(XMMRegister, c_farg6, xmm6);
REGISTER_DECLARATION(XMMRegister, c_farg7, xmm7);
-#endif
+#endif // _WIN64
// Symbolically name the register arguments used by the Java calling convention.
// We have control over the convention for java so we can do what we please.
@@ -105,7 +105,7 @@ REGISTER_DECLARATION(Register, j_rarg4,
#else
REGISTER_DECLARATION(Register, j_rarg3, c_rarg4);
REGISTER_DECLARATION(Register, j_rarg4, c_rarg5);
-#endif /* _WIN64 */
+#endif // _WIN64
REGISTER_DECLARATION(Register, j_rarg5, c_rarg0);
REGISTER_DECLARATION(XMMRegister, j_farg0, xmm0);
@@ -120,7 +120,8 @@ REGISTER_DECLARATION(Register, rscratch1
REGISTER_DECLARATION(Register, rscratch1, r10); // volatile
REGISTER_DECLARATION(Register, rscratch2, r11); // volatile
-REGISTER_DECLARATION(Register, r15_thread, r15); // callee-saved
+REGISTER_DECLARATION(Register, r12_heapbase, r12); // callee-saved
+REGISTER_DECLARATION(Register, r15_thread, r15); // callee-saved
#endif // _LP64
@@ -785,7 +786,8 @@ class Assembler : public AbstractAssembl
void rep_movl();
void rep_movq();
void rep_set();
- void repne_scan();
+ void repne_scanl();
+ void repne_scanq();
void setb(Condition cc, Register dst);
void clflush(Address adr);
@@ -1099,6 +1101,17 @@ class MacroAssembler : public Assembler
void movbool(Address dst, Register src);
void testbool(Register dst);
+ // oop manipulations
+ void load_klass(Register dst, Register src);
+ void store_klass(Register dst, Register src);
+
+ void load_heap_oop(Register dst, Address src);
+ void store_heap_oop(Address dst, Register src);
+ void encode_heap_oop(Register r);
+ void decode_heap_oop(Register r);
+ void encode_heap_oop_not_null(Register r);
+ void decode_heap_oop_not_null(Register r);
+
// Stack frame creation/removal
void enter();
void leave();
@@ -1250,6 +1263,9 @@ class MacroAssembler : public Assembler
void verify_oop(Register reg, const char* s = "broken oop");
void verify_oop_addr(Address addr, const char * s = "broken oop addr");
+ // if heap base register is used - reinit it with the correct value
+ void reinit_heapbase();
+
// only if +VerifyFPU
void verify_FPU(int stack_depth, const char* s = "illegal FPU state") {}
--- a/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -218,7 +218,7 @@ void C1_MacroAssembler::initialize_objec
void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) {
assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
"con_size_in_bytes is not multiple of alignment");
- const int hdr_size_in_bytes = oopDesc::header_size_in_bytes();
+ const int hdr_size_in_bytes = instanceOopDesc::base_offset_in_bytes();
initialize_header(obj, klass, noreg, t1, t2);
--- a/src/cpu/x86/vm/interp_masm_x86_64.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -267,15 +267,29 @@ void InterpreterMacroAssembler::gen_subt
addq(rdi, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
// Scan rcx words at [rdi] for occurance of rax
// Set NZ/Z based on last compare
- repne_scan();
- // Not equal?
- jcc(Assembler::notEqual, not_subtype);
+
+ // this part is kind tricky, as values in supers array could be 32 or 64 bit wide
+ // and we store values in objArrays always encoded, thus we need to encode value
+ // before repne
+ if (UseCompressedOops) {
+ encode_heap_oop(rax);
+ repne_scanl();
+ // Not equal?
+ jcc(Assembler::notEqual, not_subtype);
+ // decode heap oop here for movq
+ decode_heap_oop(rax);
+ } else {
+ repne_scanq();
+ jcc(Assembler::notEqual, not_subtype);
+ }
// Must be equal but missed in cache. Update cache.
movq(Address(Rsub_klass, sizeof(oopDesc) +
Klass::secondary_super_cache_offset_in_bytes()), rax);
jmp(ok_is_subtype);
bind(not_subtype);
+ // decode heap oop here for miss
+ if (UseCompressedOops) decode_heap_oop(rax);
profile_typecheck_failed(rcx); // blows rcx
}
--- a/src/cpu/x86/vm/interpreter_x86_64.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/x86/vm/interpreter_x86_64.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -375,7 +375,7 @@ address InterpreterGenerator::generate_a
__ cmpl(rdx, atos);
__ jcc(Assembler::notEqual, notObj);
// atos
- __ movq(rax, field_address);
+ __ load_heap_oop(rax, field_address);
__ jmp(xreturn_path);
__ bind(notObj);
--- a/src/cpu/x86/vm/register_definitions_x86.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/x86/vm/register_definitions_x86.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -106,6 +106,7 @@ REGISTER_DEFINITION(Register, rscratch1)
REGISTER_DEFINITION(Register, rscratch1);
REGISTER_DEFINITION(Register, rscratch2);
+REGISTER_DEFINITION(Register, r12_heapbase);
REGISTER_DEFINITION(Register, r15_thread);
#endif // AMD64
--- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -789,7 +789,7 @@ AdapterHandlerEntry* SharedRuntime::gene
{
__ verify_oop(holder);
- __ movq(temp, Address(receiver, oopDesc::klass_offset_in_bytes()));
+ __ load_klass(temp, receiver);
__ verify_oop(temp);
__ cmpq(temp, Address(holder, compiledICHolderOopDesc::holder_klass_offset()));
@@ -1297,20 +1297,25 @@ nmethod *SharedRuntime::generate_native_
const Register ic_reg = rax;
const Register receiver = j_rarg0;
+ const Register tmp = rdx;
Label ok;
Label exception_pending;
__ verify_oop(receiver);
- __ cmpq(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes()));
+ __ pushq(tmp); // spill (any other registers free here???)
+ __ load_klass(tmp, receiver);
+ __ cmpq(ic_reg, tmp);
__ jcc(Assembler::equal, ok);
+ __ popq(tmp);
__ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
+
+ __ bind(ok);
+ __ popq(tmp);
// Verified entry point must be aligned
__ align(8);
-
- __ bind(ok);
int vep_offset = ((intptr_t)__ pc()) - start;
@@ -1663,6 +1668,7 @@ nmethod *SharedRuntime::generate_native_
__ andq(rsp, -16); // align stack as required by ABI
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)));
__ movq(rsp, r12); // restore sp
+ __ reinit_heapbase();
// Restore any method result value
restore_native_result(masm, ret_type, stack_slots);
__ bind(Continue);
@@ -1725,7 +1731,6 @@ nmethod *SharedRuntime::generate_native_
__ bind(done);
}
-
{
SkipIfEqual skip(masm, &DTraceMethodProbes, false);
save_native_result(masm, ret_type, stack_slots);
@@ -1829,6 +1834,7 @@ nmethod *SharedRuntime::generate_native_
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C)));
__ movq(rsp, r12); // restore sp
+ __ reinit_heapbase();
#ifdef ASSERT
{
Label L;
@@ -1859,6 +1865,7 @@ nmethod *SharedRuntime::generate_native_
__ andq(rsp, -16); // align stack as required by ABI
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages)));
__ movq(rsp, r12); // restore sp
+ __ reinit_heapbase();
restore_native_result(masm, ret_type, stack_slots);
// and continue
__ jmp(reguard_done);
@@ -1941,9 +1948,8 @@ void SharedRuntime::generate_deopt_blob(
map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
// Normal deoptimization. Save exec mode for unpack_frames.
- __ movl(r12, Deoptimization::Unpack_deopt); // callee-saved
+ __ movl(r14, Deoptimization::Unpack_deopt); // callee-saved
__ jmp(cont);
-
int exception_offset = __ pc() - start;
// Prolog for exception case
@@ -1955,7 +1961,7 @@ void SharedRuntime::generate_deopt_blob(
map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
// Deopt during an exception. Save exec mode for unpack_frames.
- __ movl(r12, Deoptimization::Unpack_exception); // callee-saved
+ __ movl(r14, Deoptimization::Unpack_exception); // callee-saved
__ bind(cont);
@@ -2088,7 +2094,7 @@ void SharedRuntime::generate_deopt_blob(
__ set_last_Java_frame(noreg, rbp, NULL);
__ movq(c_rarg0, r15_thread);
- __ movl(c_rarg1, r12); // second arg: exec_mode
+ __ movl(c_rarg1, r14); // second arg: exec_mode
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames)));
// Set an oopmap for the call site
--- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Fri Apr 11 09:56:35 2008 -0400
+++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Sun Apr 13 17:43:42 2008 -0400
@@ -30,6 +30,7 @@
// see the comment in stubRoutines.hpp
#define __ _masm->
+#define TIMES_OOP (UseCompressedOops ? Address::times_4 : Address::times_8)
#ifdef PRODUCT
#define BLOCK_COMMENT(str) /* nothing */
@@ -252,6 +253,7 @@ class StubGenerator: public StubCodeGene
// Load up thread register
__ movq(r15_thread, thread);
+ __ reinit_heapbase();
#ifdef ASSERT
// make sure we have no pending exceptions
@@ -945,7 +947,7 @@ class StubGenerator: public StubCodeGene
__ jcc(Assembler::notZero, error);
// make sure klass is 'reasonable'
- __ movq(rax, Address(rax, oopDesc::klass_offset_in_bytes())); // get klass
+ __ load_klass(rax, rax); // get klass
__ testq(rax, rax);
__ jcc(Assembler::zero, error); // if klass is NULL it is broken
// Check if the klass is in the right area of memory
@@ -957,7 +959,7 @@ class StubGenerator: public StubCodeGene
__ jcc(Assembler::notZero, error);
// make sure klass' klass is 'reasonable'
- __ movq(rax, Address(rax, oopDesc::klass_offset_in_bytes()));
+ __ load_klass(rax, rax);
__ testq(rax, rax);
__ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken
// Check if the klass' klass is in the right area of memory
@@ -1001,6 +1003,7 @@ class StubGenerator: public StubCodeGene
BLOCK_COMMENT("call MacroAssembler::debug");
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug)));
__ movq(rsp, r12); // restore rsp
+ __ reinit_heapbase(); // r12 is heapbase
__ popaq(); // pop registers
__ ret(3 * wordSize); // pop caller saved stuff
@@ -1652,6 +1655,7 @@ class StubGenerator: public StubCodeGene
// Arguments:
// aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
// ignored
+ // is_oop - true => oop array, so generate store check code
// name - stub name string
//
// Inputs:
@@ -1665,9 +1669,9 @@ class StubGenerator: public StubCodeGene
//
// Side Effects:
// disjoint_int_copy_entry is set to the no-overlap entry point
- // used by generate_conjoint_int_copy().
- //
- address generate_disjoint_int_copy(bool aligned, const char *name) {
+ // used by generate_conjoint_int_oop_copy().
+ //
+ address generate_disjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", name);
address start = __ pc();
@@ -1680,18 +1684,29 @@ class StubGenerator: public StubCodeGene
const Register qword_count = count;
const Register end_from = from; // source array end address
const Register end_to = to; // destination array end address
+ const Register saved_to = r11; // saved destination array address
// End pointers are inclusive, and if count is not zero they point
// to the last unit copied: end_to[0] := end_from[0]
__ enter(); // required for proper stackwalking of RuntimeStub frame
assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
- disjoint_int_copy_entry = __ pc();
+ (is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry) = __ pc();
+
+ if (is_oop) {
+ // no registers are destroyed by this call
+ gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2);
+ }
+
BLOCK_COMMENT("Entry:");
// caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
setup_arg_regs(); // from => rdi, to => rsi, count => rdx
// r9 and r10 may be used to save non-volatile registers
+
+ if (is_oop) {
+ __ movq(saved_to, to);
+ }
// 'from', 'to' and 'count' are now valid
__ movq(dword_count, count);
@@ -1718,6 +1733,10 @@ class StubGenerator: public StubCodeGene
__ movl(Address(end_to, 8), rax);
__ BIND(L_exit);
+ if (is_oop) {
+ __ leaq(end_to, Address(saved_to, dword_count, Address::times_4, -4));
+ gen_write_ref_array_post_barrier(saved_to, end_to, rax);
+ }
inc_counter_np(SharedRuntime::_jint_array_copy_ctr);
restore_arg_regs();
__ xorq(rax, rax); // return 0
@@ -1734,6 +1753,7 @@ class StubGenerator: public StubCodeGene
// Arguments:
// aligned - true => Input and output aligned on a HeapWord == 8-byte boundary
// ignored
+ // is_oop - true => oop array, so generate store check code
// name - stub name string
//
// Inputs:
@@ -1745,12 +1765,12 @@ class StubGenerator: public StubCodeGene
// the hardware handle it. The two dwords within qwords that span
// cache line boundaries will still be loaded and stored atomicly.
//
- address generate_conjoint_int_copy(bool aligned, const char *name) {
+ address generate_conjoint_int_oop_copy(bool aligned, bool is_oop, const char *name) {
__ align(CodeEntryAlignment);
StubCodeMark mark(this, "StubRoutines", name);
address start = __ pc();
- Label L_copy_32_bytes, L_copy_8_bytes, L_copy_2_bytes;
+ Label L_copy_32_bytes, L_copy_8_bytes, L_copy_2_bytes, L_exit;
const Register from = rdi; // source array address
const Register to = rsi; // destination array address
const Register count = rdx; // elements count
@@ -1760,14 +1780,21 @@ class StubGenerator: public StubCodeGene
__ enter(); // required for proper stackwalking of RuntimeStub frame
assert_clean_int(c_rarg2, rax); // Make sure 'count' is clean int.
- int_copy_entry = __ pc();
+ if (is_oop) {
+ // no registers are destroyed by this call
+ gen_write_ref_array_pre_barrier(/* dest */ c_rarg1, /* count */ c_rarg2);
+ }
+
+ (is_oop ? oop_copy_entry : int_copy_entry) = __ pc();
BLOCK_COMMENT("Entry:");
// caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
- array_overlap_test(disjoint_int_copy_entry, Address::times_4);
+ array_overlap_test(is_oop ? disjoint_oop_copy_entry : disjoint_int_copy_entry,
+ Address::times_4);
setup_arg_regs(); // from => rdi, to => rsi, count => rdx
// r9 and r10 may be used to save non-volatile registers
+ assert_clean_int(count, rax); // Make sure 'count' is clean int.
// 'from', 'to' and 'count' are now valid
__ movq(dword_count, count);
__ shrq(count, 1); // count => qword_count
@@ -1789,6 +1816,9 @@ class StubGenerator: public StubCodeGene
_