From: <lhe...@us...> - 2010-07-06 21:03:47
|
Revision: 15882 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15882&view=rev Author: lhellyer Date: 2010-07-06 21:03:41 +0000 (Tue, 06 Jul 2010) Log Message: ----------- Add Eclipse project files (but not directories) to assist Eliot Moss Added Paths: ----------- rvmroot/branches/RVM-893-Sapphire/work/.classpath rvmroot/branches/RVM-893-Sapphire/work/.project Added: rvmroot/branches/RVM-893-Sapphire/work/.classpath =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/.classpath (rev 0) +++ rvmroot/branches/RVM-893-Sapphire/work/.classpath 2010-07-06 21:03:41 UTC (rev 15882) @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ This file is part of the Jikes RVM project (http://jikesrvm.org). + ~ + ~ This file is licensed to You under the Eclipse Public License (EPL); + ~ You may not use this file except in compliance with the License. You + ~ may obtain a copy of the License at + ~ + ~ http://www.opensource.org/licenses/eclipse-1.0.php + ~ + ~ See the COPYRIGHT.txt file distributed with this work for information + ~ regarding copyright ownership. + --> +<classpath> + <classpathentry excluding="**/ppc/**|org/jikesrvm/tools/header_gen/GenArch_ppc.java" kind="src" path="rvm/src"/> + <classpathentry kind="src" path="MMTk/ext/vm/jikesrvm"/> + <classpathentry kind="src" path="MMTk/src"/> + <classpathentry kind="src" path="common/options/src"/> + <classpathentry kind="src" path="libraryInterface/Common/src"/> + <classpathentry kind="src" path="libraryInterface/GNUClasspath/EPL/src"/> + <classpathentry kind="src" path="libraryInterface/GNUClasspath/LGPL/src"/> + <classpathentry kind="src" path="tools/bootImageWriter/src"/> + <classpathentry kind="src" path="common/vmmagic/src"/> + <classpathentry kind="src" path="external/tuningforklib/src"/> + + <classpathentry kind="src" path="eclipse/gen-base"/> + <classpathentry kind="src" path="eclipse/gen-config"/> + <classpathentry kind="src" path="eclipse/gen-arch"/> + + <classpathentry kind="lib" path="eclipse/classpath.jar"/> + + <classpathentry kind="output" path="eclipse/bin"/> +</classpath> Added: rvmroot/branches/RVM-893-Sapphire/work/.project =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/.project (rev 0) +++ rvmroot/branches/RVM-893-Sapphire/work/.project 2010-07-06 21:03:41 UTC (rev 15882) @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ This file is part of the Jikes RVM project (http://jikesrvm.org). + ~ + ~ This file is licensed to You under the Eclipse Public License (EPL); + ~ You may not use this file except in compliance with the License. You + ~ may obtain a copy of the License at + ~ + ~ http://www.opensource.org/licenses/eclipse-1.0.php + ~ + ~ See the COPYRIGHT.txt file distributed with this work for information + ~ regarding copyright ownership. + --> +<projectDescription> + <name>JikesRVM ia32-osx ExtremeAssertionsBaseBaseIncrementalSemiSpace</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lhe...@us...> - 2010-07-16 10:46:13
|
Revision: 15915 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15915&view=rev Author: lhellyer Date: 2010-07-16 10:46:07 +0000 (Fri, 16 Jul 2010) Log Message: ----------- Apply r15866 to my branch Workaround to allow the use of locks from soft handshakes by forcing spinning in this case. Avoids a bug, but the right thing to do here is probably not have locks in this case. Modified Paths: -------------- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Lock.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/RVMThread.java Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Lock.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Lock.java 2010-07-16 10:45:39 UTC (rev 15914) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Lock.java 2010-07-16 10:46:07 UTC (rev 15915) @@ -90,7 +90,7 @@ RVMThread me = RVMThread.getCurrentThread(); Offset offset=Entrypoints.lockStateField.getOffset(); boolean acquired=false; - for (int i=0;i<SPIN_LIMIT;++i) { + for (int i=0; me.isOnQueue() || i < SPIN_LIMIT;++i) { int oldState=Magic.prepareInt(this,offset); // NOTE: we could be smart here and break out of the spin if we see // that the state is CLEAR_QUEUED or LOCKED_QUEUED, or we could even Modified: rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/RVMThread.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2010-07-16 10:45:39 UTC (rev 15914) +++ rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2010-07-16 10:46:07 UTC (rev 15915) @@ -354,9 +354,16 @@ * <code>next</code> field is used as a link pointer. */ @Untraced - ThreadQueue queuedOn; + volatile ThreadQueue queuedOn; /** + * @return True if this thread is currently on a queue. + */ + public boolean isOnQueue() { + return queuedOn != null; + } + + /** * Used to handle contention for spin locks */ @Untraced This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lhe...@us...> - 2010-07-16 14:16:28
|
Revision: 15917 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15917&view=rev Author: lhellyer Date: 2010-07-16 14:16:17 +0000 (Fri, 16 Jul 2010) Log Message: ----------- Keep my branch close to RVM-777 Apply most of r15905 to my branch Squashed commit of aaf7ea56e6abdc30cc76b9675d2cf04fcf409f03 Modified Paths: -------------- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Assert.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Barriers.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Debug.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/ObjectModel.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/ReferenceProcessor.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Scanning.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Assert.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ObjectModel.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ScanBootImage.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Statistics.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/Collector.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/Harness.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/Main.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/Mutator.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/Checker.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/Compiler.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/Env.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/Intrinsics.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/PrettyPrinter.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/Trace.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/Visitor.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/ast/AST.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/ast/AbstractAST.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/ast/Alloc.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/ast/Assert.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/pcode/AllocUserOp.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/pcode/ExitOp.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/runtime/AllocationSite.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/runtime/ObjectValue.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/runtime/ReferenceValue.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/runtime/StackFrame.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/type/AbstractType.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/type/Type.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/type/TypeReference.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/type/UserTypeImpl.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/options/HarnessOptionSet.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/sanity/HeapEntry.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/sanity/HeapSnapshot.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/sanity/Sanity.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/sanity/Traversal.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/scheduler/javathreads/CollectorContextThread.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/scheduler/javathreads/CollectorThread.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/scheduler/rawthreads/CollectorThread.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/scheduler/rawthreads/RawThread.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/scheduler/rawthreads/RawThreadModel.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src-generated/org/mmtk/harness/lang/parser/Parser.jj rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/test-scripts/Quicksort.script rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/vmmagic/org/vmmagic/unboxed/Address.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/vmmagic/org/vmmagic/unboxed/ObjectReference.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/vmmagic/org/vmmagic/unboxed/harness/MemoryPage.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/vmmagic/org/vmmagic/unboxed/harness/SimulatedMemory.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/Phase.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/Plan.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/TraceLocal.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/concurrent/Concurrent.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/concurrent/ConcurrentCollector.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/concurrent/ConcurrentMutator.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/concurrent/marksweep/CMSMutator.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/markcompact/MC.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/markcompact/MCCollector.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/markcompact/MCMutator.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/CopySpace.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/MarkCompactLocal.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/MarkCompactSpace.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/MarkSweepSpace.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/SegregatedFreeListSpace.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/Space.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/alloc/BumpPointer.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/heap/Map.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/heap/Mmapper.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/options/Options.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/statistics/Counter.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/statistics/Stats.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/vm/Debug.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/vm/Statistics.java rvmroot/branches/RVM-893-Sapphire/work/NEWS.txt rvmroot/branches/RVM-893-Sapphire/work/bin/buildit rvmroot/branches/RVM-893-Sapphire/work/bin/buildit.base_config rvmroot/branches/RVM-893-Sapphire/work/bin/normalizeSVNProperties.sh rvmroot/branches/RVM-893-Sapphire/work/bin/test-mmtk rvmroot/branches/RVM-893-Sapphire/work/build/components/classpath.xml rvmroot/branches/RVM-893-Sapphire/work/build/components/jsr166-tck.xml rvmroot/branches/RVM-893-Sapphire/work/build/configs/config.properties.defaults rvmroot/branches/RVM-893-Sapphire/work/build/primordials/Classpath-0.97.2.txt rvmroot/branches/RVM-893-Sapphire/work/build.xml rvmroot/branches/RVM-893-Sapphire/work/libraryInterface/Common/src/sun/misc/Unsafe.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/compilers/opt/ssa/LoadElimination.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/objectmodel/JavaHeader.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/objectmodel/ObjectModel.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/runtime/BootRecord.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/runtime/Statics.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/runtime/SysCall.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/RVMThread.java rvmroot/branches/RVM-893-Sapphire/work/testing/tests/mmtk/src/org/vmmagic/unboxed/AddressTest.java rvmroot/branches/RVM-893-Sapphire/work/tools/asm-tasks/src/org/jikesrvm/tools/asm/AnnotationAdder.java rvmroot/branches/RVM-893-Sapphire/work/tools/bootImageRunner/perfctr.C rvmroot/branches/RVM-893-Sapphire/work/tools/bootImageRunner/perfctr.h rvmroot/branches/RVM-893-Sapphire/work/tools/bootImageRunner/sys.C Added Paths: ----------- rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/TimeoutThread.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/lang/ast/TypeLiteral.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/options/AllocDuringCollection.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/sanity/GcSanity.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/sanity/ObjectTable.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/test-scripts/AlignedLists.options rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/test-scripts/AlignedLists.script rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/test-scripts/Concurrent1.script rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/test-scripts/Concurrent2.script rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/test-scripts/OneObject.script rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/test-scripts/TwoObjects.script rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/vmmagic/org/vmmagic/unboxed/harness/Clock.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/Plan.java.orig rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/concurrent/ConcurrentCollector.java.orig rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/CopySpace.java.orig rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/MarkCompactCollector.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/options/PerfEvents.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/statistics/PerfEvent.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/vm/Debug.java.orig rvmroot/branches/RVM-893-Sapphire/work/build/components/patches/classpath-cvs.RVM-889-01.patch rvmroot/branches/RVM-893-Sapphire/work/build/components/patches/classpath-cvs.RVM-889-02.patch rvmroot/branches/RVM-893-Sapphire/work/build/components/patches/classpath-web.RVM-889-01.patch rvmroot/branches/RVM-893-Sapphire/work/build/components/patches/classpath-web.RVM-889-02.patch rvmroot/branches/RVM-893-Sapphire/work/build/configs/BaseAdaptiveMarkCompact.properties rvmroot/branches/RVM-893-Sapphire/work/build/test-runs/mmtk-harness.properties rvmroot/branches/RVM-893-Sapphire/work/testing/tests/mmtk-harness/ rvmroot/branches/RVM-893-Sapphire/work/testing/tests/mmtk-harness/build.xml Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Assert.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Assert.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Assert.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -85,6 +85,7 @@ /** @return true if assertions should be verified */ @Override protected boolean getVerifyAssertionsConstant() { - return true; + String value = System.getProperty("org.mmtk.harness.verify.assertions", "true"); + return Boolean.valueOf(value); } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Barriers.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Barriers.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Barriers.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -12,6 +12,7 @@ */ package org.mmtk.harness.vm; +import org.mmtk.harness.sanity.Sanity; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.unboxed.*; @@ -31,6 +32,8 @@ */ @Override public void booleanWrite(ObjectReference ref, boolean value, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); slot.toAddress().store((byte) (value ? 1 : 0)); } @@ -45,6 +48,8 @@ */ @Override public boolean booleanRead(ObjectReference ref, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().loadByte() != 0; } @@ -59,6 +64,8 @@ */ @Override public void byteWrite(ObjectReference ref, byte value, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); slot.toAddress().store(value); } @@ -73,6 +80,8 @@ */ @Override public byte byteRead(ObjectReference ref, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().loadByte(); } @@ -87,6 +96,8 @@ */ @Override public void charWrite(ObjectReference ref, char value, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); slot.toAddress().store(value); } @@ -101,6 +112,8 @@ */ @Override public char charRead(ObjectReference ref, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().loadChar(); } @@ -115,6 +128,8 @@ */ @Override public void shortWrite(ObjectReference ref, short value, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); slot.toAddress().store(value); } @@ -129,6 +144,8 @@ */ @Override public short shortRead(ObjectReference ref, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().loadShort(); } @@ -143,6 +160,8 @@ */ @Override public void intWrite(ObjectReference ref, int value, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); slot.toAddress().store(value); } @@ -157,10 +176,30 @@ */ @Override public int intRead(ObjectReference ref, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().loadInt(); } /** + * Attempt an atomic compare and exchange in a write barrier sequence. + * + * @param objref The object that has the int field + * @param old The old int to be swapped out + * @param value the new int + * @param slot The address of the field + * @param unused Unused + * @param mode The context in which the write is occurring + * @return True if the compare and swap was successful + */ + @Override + public boolean intTryCompareAndSwap(ObjectReference objref, int old, + int value, Word slot, Word unused, int mode) { + assert unused == null; + return slot.toAddress().attempt(old, value); + } + + /** * Perform the actual write of a long write barrier. * * @param ref The object that has the reference field @@ -171,6 +210,8 @@ */ @Override public void longWrite(ObjectReference ref, long value, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); slot.toAddress().store(value); } @@ -185,10 +226,31 @@ */ @Override public long longRead(ObjectReference ref, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().loadLong(); } /** + * Attempt an atomic compare and exchange in a write barrier sequence. + * + * @param ref The object that has the long field + * @param old The old long to be swapped out + * @param value the new long + * @param slot Opaque, VM-specific, meta-data identifying the slot + * @param unused Opaque, VM-specific, meta-data identifying the slot + * @param mode The context in which the write is occurring + * @return True if the compare and swap was successful + */ + @Override + public boolean longTryCompareAndSwap(ObjectReference ref, long old, + long value, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); + return slot.toAddress().attempt(old, value); + } + + /** * Perform the actual write of a float write barrier. * * @param ref The object that has the reference field @@ -199,6 +261,8 @@ */ @Override public void floatWrite(ObjectReference ref, float value, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); slot.toAddress().store(value); } @@ -213,6 +277,8 @@ */ @Override public float floatRead(ObjectReference ref, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().loadFloat(); } @@ -227,6 +293,8 @@ */ @Override public void doubleWrite(ObjectReference ref, double value, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); slot.toAddress().store(value); } @@ -241,6 +309,8 @@ */ @Override public double doubleRead(ObjectReference ref, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().loadDouble(); } @@ -255,6 +325,8 @@ */ @Override public void objectReferenceWrite(ObjectReference ref, ObjectReference value, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); slot.toAddress().store(value); } @@ -269,6 +341,8 @@ */ @Override public ObjectReference objectReferenceRead(ObjectReference ref,Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().loadObjectReference(); } @@ -284,6 +358,8 @@ */ @Override public void objectReferenceNonHeapWrite(Address slot, ObjectReference target, Word unusedA, Word unusedB) { + assert unusedA == null && unusedB == null; + Sanity.assertValid(target); slot.store(target); } @@ -300,6 +376,8 @@ */ @Override public ObjectReference objectReferenceAtomicWrite(ObjectReference ref, ObjectReference target, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); ObjectReference old; do { old = slot.toAddress().prepareObjectReference(); @@ -320,6 +398,8 @@ */ @Override public boolean objectReferenceTryCompareAndSwap(ObjectReference ref, ObjectReference old, ObjectReference target, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().attempt(old, target); } @@ -335,6 +415,8 @@ */ @Override public void wordWrite(ObjectReference ref, Word target, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); slot.toAddress().store(target); } @@ -352,6 +434,8 @@ @Override public Word wordAtomicWrite(ObjectReference ref, Word target, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); Word old; do { old = slot.toAddress().prepareWord(); @@ -363,7 +447,6 @@ * Attempt an atomic compare and exchange in a write barrier sequence. * * @param ref The object that has the reference field - * @param slot The slot that holds the reference * @param old The old reference to be swapped out * @param target The value that the slot will be updated to * @param slot The address to be written to @@ -374,6 +457,8 @@ @Override public boolean wordTryCompareAndSwap(ObjectReference ref, Word old, Word target, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().attempt(old, target); } @@ -388,10 +473,133 @@ */ @Override public Word wordRead(ObjectReference ref, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); return slot.toAddress().loadWord(); } /** + * Perform the actual write of the write barrier, writing the value as a raw Address. + * + * @param ref The object that has the Address field + * @param target The value that the slot will be updated to + * @param slot Opaque, VM-specific, meta-data identifying the slot + * @param unused Unused + * @param mode The context in which the write is occurring + */ + @Override + public void addressWrite(ObjectReference ref, Address target, Word slot, + Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); + slot.toAddress().store(target); + } + + /** + * Perform the actual read of the read barrier, returning the value as a raw Address. + * + * @param ref The object that has the Address field + * @param slot Opaque, VM-specific, meta-data identifying the slot + * @param unused Opaque, VM-specific, meta-data identifying the slot + * @param mode The context in which the write is occurring + * @return the read value + */ + @Override + public Address addressRead(ObjectReference ref, Word slot, + Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); + return slot.toAddress().loadAddress(); + } + + /** + * Attempt an atomic compare and exchange in a write barrier sequence. + * + * @param ref The object that has the Address field + * @param old The old address to be swapped out + * @param target The value that the slot will be updated to + * @param slot Opaque, VM-specific, meta-data identifying the slot + * @param unused Opaque, VM-specific, meta-data identifying the slot + * @param mode The context in which the write is occurring + * @return True if the compare and swap was successful + */ + @Override + public boolean addressTryCompareAndSwap(ObjectReference ref, Address old, + Address target, Word slot, Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); + return slot.toAddress().attempt(old, target); + } + + /** + * Perform the actual write of the write barrier, writing the value as a raw Offset. + * + * @param ref The object that has the Offset field + * @param target The value that the slot will be updated to + * @param slot Opaque, VM-specific, meta-data identifying the slot + * @param unused Opaque, VM-specific, meta-data identifying the slot + * @param mode The context in which the write is occurring + */ + @Override + public void offsetWrite(ObjectReference ref, Offset target, Word slot, + Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); + slot.toAddress().store(target); + } + + /** + * Perform the actual read of the read barrier, returning the value as a raw Offset. + * + * @param ref The object that has the Offset field + * @param slot Opaque, VM-specific, meta-data identifying the slot + * @param unused Opaque, VM-specific, meta-data identifying the slot + * @param mode The context in which the write is occurring + * @return the read value + */ + @Override + public Offset offsetRead(ObjectReference ref, Word slot, + Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); + return slot.toAddress().loadOffset(); + } + + /** + * Perform the actual write of the write barrier, writing the value as a raw Extent. + * + * @param ref The object that has the Extent field + * @param target The value that the slot will be updated to + * @param slot Opaque, VM-specific, meta-data identifying the slot + * @param unused Unused + * @param mode The context in which the write is occurring + */ + @Override + public void extentWrite(ObjectReference ref, Extent target, Word slot, + Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); + slot.toAddress().store(target); + } + + /** + * Perform the actual read of the read barrier, returning the value as a raw Extent. + * + * @param ref The object that has the Extent field + * @param slot Opaque, VM-specific, meta-data identifying the slot + * @param unused Unused + * @param mode The context in which the write is occurring + * @return the read value + */ + @Override + public Extent extentRead(ObjectReference ref, Word slot, + Word unused, int mode) { + assert unused == null; + Sanity.assertValid(ref); + return slot.toAddress().loadExtent(); + } + + /** * Sets an element of an object array without invoking any write * barrier. This method is called by the Map class to ensure * potentially-allocation-triggering write barriers do not occur in @@ -405,4 +613,5 @@ public void objectArrayStoreNoGCBarrier(Object [] dst, int index, Object value) { dst[index] = value; } + } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Debug.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Debug.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Debug.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -65,7 +65,12 @@ */ @Override public void remsetEntry(Address slot) { + try { Trace.trace(Item.REMSET, "remset: %s->%s", format(slot), format(slot.loadObjectReference())); + } catch (Throwable e) { + System.err.printf("Error encountered processing remset entry %s%n", slot); + throw new RuntimeException(e); + } } /** @@ -86,5 +91,41 @@ Trace.trace(Item.TRACEOBJECT, "traceObject: %s", format(object)); } + /** + * Trace insertions at the head of a queue + * @param value Value inserted + */ + @Override + public void queueHeadInsert(String queueName, Address value) { + Trace.trace(Item.QUEUE, "head insert %s to %s", value, queueName); + } + /** + * Trace removals from the head of a queue + * @param value Value inserted + */ + @Override + public void queueHeadRemove(String queueName, Address value) { + Trace.trace(Item.QUEUE, "head remove %s from %s", value, queueName); + } + + /** + * Trace insertions at the tail of a queue + * @param value Value inserted + */ + @Override + public void queueTailInsert(String queueName, Address value) { + Trace.trace(Item.QUEUE, "tail insert %s to %s", value, queueName); + } + + /** + * Trace removals from the tail of a queue + * @param value Value removed + */ + @Override + public void queueTailRemove(String queueName, Address value) { + Trace.trace(Item.QUEUE, "tail remove %s from %s", value, queueName); + } + + } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/ObjectModel.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/ObjectModel.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/ObjectModel.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -23,10 +23,12 @@ import org.mmtk.harness.Mutator; import org.mmtk.harness.lang.Trace; import org.mmtk.harness.lang.Trace.Item; +import org.mmtk.harness.sanity.Sanity; import org.mmtk.plan.CollectorContext; import org.mmtk.plan.MutatorContext; import org.mmtk.plan.Plan; import org.mmtk.policy.Space; +import org.mmtk.utility.alloc.Allocator; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.unboxed.*; import org.vmmagic.unboxed.harness.ArchitecturalWord; @@ -35,11 +37,12 @@ /** * MMTk Harness implementation of MMTk object model - * Object id (age in allocations); (Word) - * Allocation site (Word) - * The size of the data section in words. (UInt16) - * The number of reference words. (UInt16) - * Status Word (includes GC) + * GC header (determined by MMTk) + * Object id (age in allocations); (int) + * Allocation site (int) + * The size of the data section in words. (int) + * The number of reference words. (int) + * Status Word (includes GC) (WORD) * References * Data */ @@ -61,9 +64,9 @@ private static final Offset ID_OFFSET = GC_OFFSET.plus(GC_HEADER_BYTES); /** The offset of the allocation site */ private static final Offset SITE_OFFSET = ID_OFFSET.plus(MemoryConstants.BYTES_IN_INT); - /** The offset of the UInt16 storing the number of data fields */ + /** The offset of the UInt32 storing the number of data fields */ private static final Offset DATACOUNT_OFFSET = SITE_OFFSET.plus(MemoryConstants.BYTES_IN_INT); - /** The offset of the UInt16 storing the number of reference fields */ + /** The offset of the UInt32 storing the number of reference fields */ private static final Offset REFCOUNT_OFFSET = DATACOUNT_OFFSET.plus(MemoryConstants.BYTES_IN_INT); /** The offset of the status word */ private static final Offset STATUS_OFFSET = REFCOUNT_OFFSET.plus(MemoryConstants.BYTES_IN_INT); @@ -168,11 +171,17 @@ // Create an object reference. ObjectReference ref = region.toObjectReference(); + + if (SimulatedMemory.isWatched(region,bytes)) { + Trace.printf("%4d alloc %s [%s-%s]%n", Thread.currentThread().getId(), + region.toObjectReference(), region, region.plus(bytes)); + } if (doubleAlign) region.store(DOUBLE_ALIGN, STATUS_OFFSET); setId(ref, allocateObjectId()); setSite(ref, site); setRefCount(ref, refCount); setDataCount(ref, dataCount); + Sanity.getObjectTable().alloc(region, bytes); if (isWatched(ref)) { System.err.printf("WATCH: Object %s created%n",objectIdString(ref)); @@ -180,6 +189,7 @@ // Call MMTk postAlloc context.postAlloc(ref, null, bytes, allocator); + return ref; } @@ -208,6 +218,10 @@ object.toAddress().store(value << 2, ID_OFFSET); } + public static boolean hasValidId(ObjectReference object) { + return getId(object) > 0 && getId(object) < nextObjectId; + } + /** * Set the call site identifier. */ @@ -325,6 +339,7 @@ * @return The hash code */ public static int getHashCode(ObjectReference ref) { + Sanity.assertValid(ref); Address addr = ref.toAddress(); int status = addr.loadInt(STATUS_OFFSET) & HASHED_AND_MOVED; if (status == 0) { @@ -361,8 +376,12 @@ allocator = c.copyCheckAllocator(from, newBytes, align, allocator); Address toRegion = c.allocCopy(from, newBytes, align, getAlignOffsetWhenCopied(from), allocator); ObjectReference to = toRegion.toObjectReference(); - Trace.trace(Item.COLLECT,"Copying object %s from %s to %s", objectIdString(from), - addressAndSpaceString(from),addressAndSpaceString(to)); + if (isWatched(from) || Trace.isEnabled(Item.COLLECT)) { + Trace.printf(Item.COLLECT,"Copying object %s from %s to %s%n", objectIdString(from), + getString(from), getString(to)); + } + Sanity.assertValid(from); + Sanity.getObjectTable().copy(from, to); Address fromRegion = from.toAddress(); for(int i=0; i < oldBytes; i += MemoryConstants.BYTES_IN_INT) { @@ -379,7 +398,7 @@ if (isWatched(from)) { System.err.printf("WATCH: Object %d copied from %s to %s%n",getId(from), addressAndSpaceString(from),addressAndSpaceString(to)); - dumpObject(to); + dumpObjectHeader("after copy: ", to); } return to; @@ -399,33 +418,51 @@ */ @Override public Address copyTo(ObjectReference from, ObjectReference to, Address toRegion) { - Trace.trace(Item.COLLECT,"Copying object %s from %s/%s to %s/%s", objectIdString(from), + boolean traceThisObject = Trace.isEnabled(Item.COLLECT) || isWatched(from); + if (traceThisObject) { + Trace.printf(Item.COLLECT,"Copying object %s explicitly from %s/%s to %s/%s, region %s%n", objectIdString(from), from,Space.getSpaceForObject(from).getName(), - to,Space.getSpaceForObject(to).getName()); - if (Trace.isEnabled(Item.COLLECT)) { - dumpObjectHeader(from); + to,Space.getSpaceForObject(to).getName(), + toRegion); + dumpObjectHeader("Before copy: ", from); } + Sanity.assertValid(from); + Sanity.getObjectTable().copy(from, to); + + boolean doCopy = !from.equals(to); int bytes = getSize(from); - Address fromRegion = from.toAddress(); - for(int i=0; i < bytes; i += MemoryConstants.BYTES_IN_WORD) { - toRegion.plus(i).store(fromRegion.plus(i).loadInt()); - } - int status = toRegion.loadInt(STATUS_OFFSET); - if ((status & HASHED_AND_MOVED) == HASHED) { - toRegion.store(status | HASHED_AND_MOVED, STATUS_OFFSET); - toRegion.store(getHashCode(from), Offset.fromIntZeroExtend(bytes)); - bytes += MemoryConstants.BYTES_IN_WORD; - } + if (doCopy) { + Address srcRegion = from.toAddress(); + Address dstRegion = to.toAddress(); + for(int i=0; i < bytes; i += MemoryConstants.BYTES_IN_INT) { + int before = srcRegion.plus(i).loadInt(); + dstRegion.plus(i).store(before); + int after = dstRegion.plus(i).loadInt(); + if (traceThisObject) { + System.err.printf("copy %s/%08x -> %s/%08x%n", + srcRegion.plus(i),before,dstRegion.plus(i),after); + } + } - if (Trace.isEnabled(Item.COLLECT)) { - dumpObjectHeader(to); + int status = dstRegion.loadInt(STATUS_OFFSET); + if ((status & HASHED_AND_MOVED) == HASHED) { + dstRegion.store(status | HASHED_AND_MOVED, STATUS_OFFSET); + dstRegion.store(getHashCode(from), Offset.fromIntZeroExtend(bytes)); + bytes += MemoryConstants.BYTES_IN_WORD; + } + Allocator.fillAlignmentGap(toRegion, dstRegion); + } else { + if (traceThisObject) { + Trace.printf(Item.COLLECT,"%s: no copy required%n", getString(from)); + } } - if (isWatched(from)) { - System.err.printf("WATCH: Object %d copied from %s to %s%n",objectIdString(from), - addressAndSpaceString(from),addressAndSpaceString(to)); + Address objectEndAddress = getObjectEndAddress(to); + if (traceThisObject) { + dumpObjectHeader("After copy: ", to); } - return toRegion.plus(bytes); + Sanity.assertValid(to); + return objectEndAddress; } /** @@ -515,6 +552,13 @@ } /** + * Return the start address from an object reference + */ + public static Address getStartAddressFromObject(ObjectReference object) { + return object.toAddress(); + } + + /** * Gets a pointer to the address just past the end of the object. * * @param object The object. @@ -585,7 +629,8 @@ @Override public boolean attemptAvailableBits(ObjectReference object, Word oldVal, Word newVal) { if (Trace.isEnabled(Item.AVBYTE) || isWatched(object)) { - Trace.printf(Item.AVBYTE,"%s.status:%s->%s%n", getString(object),oldVal,newVal); + Word actual = object.toAddress().loadWord(STATUS_OFFSET); + Trace.printf(Item.AVBYTE,"%s.status:%s=%s ? ->%s%n", getString(object),actual,oldVal,newVal); } return object.toAddress().attempt(oldVal, newVal, STATUS_OFFSET); } @@ -599,6 +644,10 @@ */ @Override public Word prepareAvailableBits(ObjectReference object) { + if (Trace.isEnabled(Item.AVBYTE) || isWatched(object)) { + Word old = object.toAddress().loadWord(STATUS_OFFSET); + Trace.printf(Item.AVBYTE,"%s.gcword=%s (prepare)%n", getString(object),old); + } return object.toAddress().prepareWord(STATUS_OFFSET); } @@ -625,6 +674,10 @@ */ @Override public byte readAvailableByte(ObjectReference object) { + if (Trace.isEnabled(Item.AVBYTE) || isWatched(object)) { + byte old = object.toAddress().loadByte(STATUS_OFFSET); + Trace.printf(Item.AVBYTE,"%s.gcbyte=%d%n", getString(object),old); + } return object.toAddress().loadByte(STATUS_OFFSET); } @@ -637,8 +690,8 @@ @Override public void writeAvailableBitsWord(ObjectReference object, Word val) { if (Trace.isEnabled(Item.AVBYTE) || isWatched(object)) { - byte old = object.toAddress().loadByte(STATUS_OFFSET); - Trace.printf(Item.AVBYTE,"%s.gcbyte:%d->%d%n", getString(object),old,val.and(Word.fromIntZeroExtend(0xFF)).toInt()); + Word old = object.toAddress().loadWord(STATUS_OFFSET); + Trace.printf(Item.AVBYTE,"%s.gcword:%s->%s%n", getString(object),old,val); } object.toAddress().store(val, STATUS_OFFSET); } @@ -651,6 +704,10 @@ */ @Override public Word readAvailableBitsWord(ObjectReference object) { + if (Trace.isEnabled(Item.AVBYTE) || isWatched(object)) { + Word old = object.toAddress().loadWord(STATUS_OFFSET); + Trace.printf(Item.AVBYTE,"%s.gcword=%s%n", getString(object),old); + } return object.toAddress().loadWord(STATUS_OFFSET); } @@ -739,12 +796,13 @@ /** * Print an object's header + * @param prefix TODO * @param object The object reference */ - public static void dumpObjectHeader(ObjectReference object) { + public static void dumpObjectHeader(String prefix, ObjectReference object) { int gcWord = object.toAddress().loadInt(GC_OFFSET); int statusWord = object.toAddress().loadInt(STATUS_OFFSET); - System.err.printf("Object %s[%d@%s]<%x,%x>%n",object,getId(object),Mutator.getSiteName(object),gcWord,statusWord); + System.err.printf("%sObject %s[%d@%s]<%x,%x>%n",prefix,object,getId(object),Mutator.getSiteName(object),gcWord,statusWord); } /** @@ -811,6 +869,6 @@ * @return "address/space" */ public static String addressAndSpaceString(Address addr) { - return addressAndSpaceString(addr.toObjectReference()); + return String.format("%s/%s",addr, Space.getSpaceForAddress(addr).getName()); } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/ReferenceProcessor.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/ReferenceProcessor.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/ReferenceProcessor.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -92,6 +92,7 @@ * Clear the contents of the table. This is called when reference types are * disabled to make it easier for VMs to change this setting at runtime. */ + @Override public void clear() { Trace.trace(Item.REFERENCES, "Clearing %s references", semantics); currentRefs.clear(); @@ -108,6 +109,7 @@ * @param trace the thread local trace element. * @param nursery true if it is safe to only scan new references. */ + @Override public synchronized void scan(TraceLocal trace, boolean nursery) { Trace.trace(Item.REFERENCES, "Scanning %s references: current = %d, new = %d, %s", semantics,currentRefs.size(), newRefs.size(), nursery ? "nursery" : "full-heap"); @@ -126,7 +128,7 @@ for (ReferenceValue value : set) { ObjectReference referent = value.getObjectValue(); if (trace.isReferentLive(referent)) { - value.traceObject(trace); + value.processReference(trace); } else { value.clear(); } @@ -134,17 +136,24 @@ } /** - * Iterate over all references and forward. + * Iterate over all references and forward. Only relevant to collectors like + * MarkCompact. * @param trace The MMTk trace to forward to * @param nursery The nursery collection hint */ + @Override public void forward(TraceLocal trace, boolean nursery) { - Assert.notImplemented(); + Trace.trace(Item.REFERENCES, "Forwarding %s references: %s", + semantics,nursery ? "nursery" : "full-heap"); + for (ReferenceValue value : oldRefs) { + value.forwardReference(trace); + } } /** * @return the number of references objects on the queue */ + @Override public int countWaitingReferences() { return currentRefs.size() + newRefs.size(); } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Scanning.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Scanning.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/harness/org/mmtk/harness/vm/Scanning.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -12,12 +12,20 @@ */ package org.mmtk.harness.vm; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; import java.util.concurrent.BlockingQueue; +import org.mmtk.harness.Harness; import org.mmtk.harness.Mutator; import org.mmtk.harness.Mutators; import org.mmtk.harness.lang.Trace; import org.mmtk.harness.lang.Trace.Item; +import org.mmtk.harness.lang.runtime.AllocationSite; +import org.mmtk.harness.lang.runtime.ObjectValue; +import org.mmtk.harness.lang.runtime.StackFrame; import org.mmtk.plan.TraceLocal; import org.mmtk.plan.TransitiveClosure; @@ -30,7 +38,42 @@ */ @Uninterruptible public class Scanning extends org.mmtk.vm.Scanning { + public static final int THREAD_ITERATOR_TABLE_ENTRIES = 2048; + /** + * Table of thread iterator objects (to simulate JikesRVM thread iterator objects) + */ + private static volatile ObjectValue threadIteratorTable = null; + + /** + * Initialize the thread iterator table + * @param m Calling mutator + */ + public static void initThreadIteratorTable(Mutator m) { + if (Harness.allocDuringCollection.getValue() && threadIteratorTable == null) { + threadIteratorTable = new ObjectValue(m.allocThreadIteratorTable()); + } + } + + /** + * @param m Mutator + * @param obj The iterator object + */ + public static void setThreadIteratorObject(Mutator m, ObjectReference obj) { + m.storeReferenceField(threadIteratorTable.getObjectValue(), m.getContext().getId() % THREAD_ITERATOR_TABLE_ENTRIES, obj); + } + + /** + * Internal harness method to get all non-stack roots + * @return The set of roots + */ + public static Set<ObjectValue> getRoots() { + if (threadIteratorTable == null) + return Collections.emptySet(); + return new HashSet<ObjectValue>(Arrays.asList(threadIteratorTable)); + } + + /** * Delegated scanning of a object, processing each pointer field * encountered. * @param trace The trace @@ -39,10 +82,12 @@ */ @Override public void scanObject(TransitiveClosure trace, ObjectReference object) { + Trace.trace(Item.SCAN, "Scanning object %s", ObjectModel.addressAndSpaceString(object)); int refs = ObjectModel.getRefs(object); Address first = object.toAddress().plus(ObjectModel.REFS_OFFSET); for (int i=0; i < refs; i++) { + Trace.trace(Item.SCAN, " Edge %s", first.plus(i << LOG_BYTES_IN_ADDRESS).loadObjectReference()); trace.processEdge(object, first.plus(i << LOG_BYTES_IN_ADDRESS)); } } @@ -71,6 +116,7 @@ public synchronized void resetThreadCounter() { assert mutatorsToScan.size() == 0; mutatorsToScan = null; + ObjectValue.startRootDiscoveryPhase(); } /** @@ -90,7 +136,19 @@ */ @Override public void computeStaticRoots(TraceLocal trace) { - /* None */ + if (threadIteratorTable != null) { + if (Trace.isEnabled(Item.ROOTS)) { + Trace.trace(Item.ROOTS, "Tracing root %s", ObjectModel.getString(threadIteratorTable.getObjectValue())); + } + threadIteratorTable.traceObject(trace); + if (StackFrame.ASSERT_WILL_NOT_MOVE) { + assert trace.willNotMoveInCurrentCollection(threadIteratorTable.getObjectValue()) : + threadIteratorTable.getObjectValue()+" has been traced but willNotMoveInCurrentCollection is still false"; + } + if (Trace.isEnabled(Item.ROOTS)) { + Trace.trace(Item.ROOTS, "new value of %s", ObjectModel.getString(threadIteratorTable.getObjectValue())); + } + } } /** @@ -110,7 +168,7 @@ */ @Override public void computeGlobalRoots(TraceLocal trace) { - /* None */ + // none } private BlockingQueue<Mutator> mutatorsToScan = null; @@ -144,8 +202,15 @@ Mutator m = mutatorsToScan.poll(); if (m == null) break; + if (Harness.allocDuringCollection.getValue()) { + Trace.trace(Item.COLLECT,"Allocating thread iterator object"); + setThreadIteratorObject(m, m.alloc(0, 0, false, AllocationSite.INTERNAL_SITE_ID)); + } Trace.trace(Item.COLLECT,"Computing roots for mutator"); m.computeThreadRoots(trace); + if (Harness.allocDuringCollection.getValue()) { + setThreadIteratorObject(m, ObjectReference.nullReference()); + } } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Assert.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Assert.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Assert.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -42,6 +42,8 @@ * @param message the string to log */ public final void fail(String message) { + Space.printUsagePages(); + Space.printUsageMB(); VM.sysFail(message); } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ObjectModel.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ObjectModel.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ObjectModel.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -65,7 +65,7 @@ allocator = context.copyCheckAllocator(from, bytes, align, allocator); Address region = MemoryManager.allocateSpace(context, bytes, align, offset, allocator, from); - Object toObj = org.jikesrvm.objectmodel.ObjectModel.moveObject(region, from.toObject(), bytes, false, type); + Object toObj = org.jikesrvm.objectmodel.ObjectModel.moveObject(region, from.toObject(), bytes, type); ObjectReference to = ObjectReference.fromObject(toObj); context.postCopy(to, ObjectReference.fromObject(tib), bytes, allocator); return to; @@ -81,7 +81,7 @@ allocator = context.copyCheckAllocator(from, bytes, align, allocator); Address region = MemoryManager.allocateSpace(context, bytes, align, offset, allocator, from); - Object toObj = org.jikesrvm.objectmodel.ObjectModel.moveObject(region, from.toObject(), bytes, false, type); + Object toObj = org.jikesrvm.objectmodel.ObjectModel.moveObject(region, from.toObject(), bytes, type); ObjectReference to = ObjectReference.fromObject(toObj); context.postCopy(to, ObjectReference.fromObject(tib), bytes, allocator); if (type == RVMType.CodeArrayType) { @@ -133,12 +133,12 @@ if (type.isClassType()) { RVMClass classType = type.asClass(); bytes = org.jikesrvm.objectmodel.ObjectModel.bytesRequiredWhenCopied(from.toObject(), classType); - org.jikesrvm.objectmodel.ObjectModel.moveObject(from.toObject(), to.toObject(), bytes, false, classType); + org.jikesrvm.objectmodel.ObjectModel.moveObject(from.toObject(), to.toObject(), bytes, classType); } else { RVMArray arrayType = type.asArray(); int elements = Magic.getArrayLength(from.toObject()); bytes = org.jikesrvm.objectmodel.ObjectModel.bytesRequiredWhenCopied(from.toObject(), arrayType, elements); - org.jikesrvm.objectmodel.ObjectModel.moveObject(from.toObject(), to.toObject(), bytes, false, arrayType); + org.jikesrvm.objectmodel.ObjectModel.moveObject(from.toObject(), to.toObject(), bytes, arrayType); } } else { bytes = getCurrentSize(to); Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -23,6 +23,7 @@ import org.jikesrvm.mm.mminterface.DebugUtil; import org.jikesrvm.mm.mminterface.Selected; import org.jikesrvm.runtime.Entrypoints; +import org.jikesrvm.runtime.Magic; import org.jikesrvm.scheduler.RVMThread; import java.lang.ref.Reference; @@ -89,6 +90,14 @@ private volatile AddressArray references = AddressArray.create(INITIAL_SIZE); /** + * In a MarkCompact (or similar) collector, we need to update the {@code references} + * field, and then update its contents. We implement this by saving the pointer in + * this untraced field for use during the {@code forward} pass. + */ + @Untraced + private volatile AddressArray unforwardedReferences = null; + + /** * Index into the <code>references</code> table for the start of * the reference nursery. */ @@ -158,6 +167,10 @@ * @param ref The reference to insert */ private void setReference(int i, ObjectReference ref) { + if (TRACE_DETAIL) { + VM.sysWrite("slot ",i); + VM.sysWriteln(" => ",ref); + } references.set(i,ref.toAddress()); } @@ -264,15 +277,24 @@ */ @Override public void forward(TraceLocal trace, boolean nursery) { + if (VM.VerifyAssertions) VM._assert(unforwardedReferences != null); if (TRACE) VM.sysWriteln("Starting ReferenceGlue.forward(",semanticsStr,")"); - + if (TRACE_DETAIL) { + VM.sysWrite(semanticsStr," Reference table is ", + Magic.objectAsAddress(references)); + VM.sysWriteln("unforwardedReferences is ", + Magic.objectAsAddress(unforwardedReferences)); + } for (int i=0; i < maxIndex; i++) { - ObjectReference reference = getReference(i); + if (TRACE_DETAIL) VM.sysWrite("slot ",i,": "); + ObjectReference reference = unforwardedReferences.get(i).toObjectReference(); + if (TRACE_DETAIL) VM.sysWriteln("forwarding ",reference); setReferent(reference, trace.getForwardedReferent(getReferent(reference))); ObjectReference newReference = trace.getForwardedReference(reference); - setReference(i, newReference); + unforwardedReferences.set(i, newReference.toAddress()); } if (TRACE) VM.sysWriteln("Ending ReferenceGlue.forward(",semanticsStr,")"); + unforwardedReferences = null; } /** @@ -298,8 +320,12 @@ */ @Override public void scan(TraceLocal trace, boolean nursery) { + unforwardedReferences = references; + + if (TRACE) VM.sysWriteln("Starting ReferenceGlue.scan(",semanticsStr,")"); int toIndex = nursery ? nurseryIndex : 0; + if (TRACE_DETAIL) VM.sysWriteln(semanticsStr," Reference table is ",Magic.objectAsAddress(references)); for (int fromIndex = toIndex; fromIndex < maxIndex; fromIndex++) { ObjectReference reference = getReference(fromIndex); @@ -307,6 +333,13 @@ ObjectReference newReference = processReference(trace,reference); if (!newReference.isNull()) { setReference(toIndex++,newReference); + if (TRACE_DETAIL) { + int index = toIndex-1; + VM.sysWrite("SCANNED ",index); + VM.sysWrite(" ",references.get(index)); + VM.sysWrite(" -> "); + VM.sysWriteln(getReferent(references.get(index).toObjectReference())); + } } } if (Options.verbose.getValue() >= 3) { @@ -317,6 +350,7 @@ /* flush out any remset entries generated during the above activities */ Selected.Mutator.get().flushRememberedSets(); + if (TRACE) VM.sysWriteln("Ending ReferenceGlue.scan(",semanticsStr,")"); } /** @@ -514,6 +548,7 @@ * @return the referent object reference. */ protected ObjectReference getReferent(ObjectReference object) { + if (VM.VerifyAssertions) VM._assert(!object.isNull()); return object.toAddress().loadObjectReference(Entrypoints.referenceReferentField.getOffset()); } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ScanBootImage.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ScanBootImage.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ScanBootImage.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -192,7 +192,7 @@ * * Build-time encoding (assumed to be single-threaded) */ - private static int lastOffset = 0; + private static int lastOffset = Integer.MIN_VALUE / 2; /* bootstrap value */ private static int oldIndex = 0; private static int codeIndex = 0; Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Statistics.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Statistics.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Statistics.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -13,12 +13,14 @@ package org.jikesrvm.mm.mmtk; import org.mmtk.utility.Constants; +import org.mmtk.utility.statistics.PerfEvent; import org.jikesrvm.runtime.Time; import static org.jikesrvm.runtime.SysCall.sysCall; import org.vmmagic.pragma.*; -@Uninterruptible public final class Statistics extends org.mmtk.vm.Statistics implements Constants { +@Uninterruptible +public final class Statistics extends org.mmtk.vm.Statistics implements Constants { /** * Returns the number of collections that have occurred. * @@ -75,33 +77,34 @@ return (long)(t * 1e9); } - /** - * Initialize performance counters - * - * @param metric An integer identifying the metric being read - */ - public void perfCtrInit(int metric) { - sysCall.sysPerfCtrInit(metric); -} + private PerfEvent[] perfEvents; /** - * Read the current cycle count from the perfctr libraries - * - * @return the current cycle count from the perfctr libraries + * Initialize performance events */ - public long perfCtrReadCycles() { - return sysCall.sysPerfCtrReadCycles(); + @Interruptible + public void perfEventInit(String events) { + if (events.length() == 0) { + // no initialization needed + return; + } + // initialize perf event + String[] perfEventNames = events.split(","); + int n = perfEventNames.length; + sysCall.sysPerfEventInit(n); + perfEvents = new PerfEvent[n]; + for (int i = 0; i < n; i++) { + sysCall.sysPerfEventCreate(i, perfEventNames[i].getBytes()); + perfEvents[i] = new PerfEvent(i, perfEventNames[i]); + } + sysCall.sysPerfEventEnable(); } /** - * Read the current event count for the metric being measured by the - * perfctr libraries - * - * @return the current event count for the metric being measured by the - * perfctr libraries + * Read a performance event */ - public long perfCtrReadMetric() { - return sysCall.sysPerfCtrReadMetric(); + public void perfEventRead(int id, long[] values) { + sysCall.sysPerfEventRead(id, values); + } } -} Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/Collector.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/Collector.java 2010-07-16 13:56:34 UTC (rev 15916) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/harness/src/org/mmtk/harness/Collector.java 2010-07-16 14:16:17 UTC (rev 15917) @@ -14,6 +14,9 @@ import java.util.ArrayList; +import org.mmtk.harness.lang.Trace; +import org.mmtk.harness.lang.Trace.Item; +import org.mmtk.harness.sanity.GcSanity; import org.mmtk.harness.sanity.Sanity; import org.mmtk.harness.scheduler.Scheduler; import org.mmtk.harness.vm.ActivePlan; @@ -97,7 +100,7 @@ public void uncaughtException(Thread t, Throwable e) { System.err.print("Collector " + context.getId() + " caused unexpected exception: "); e.printStackTrace(); - System.exit(1); + Main.exitWithFailure(); } }); } @@ -172,7 +175,7 @@ collect(); } catch (Exception e) { e.printStackTrace(); - System.exit(1); + Main.exitWithFailure(); } Scheduler.exitGC(); @@ -180,88 +183,17 @@ } /** - * A timeout thread. Exit the harness if it isn't cancelled in time. - */ - private static final class TimeoutThread implements Runnable { - private static final boolean VERBOSE = false; - private static final int MILLIS_PER_SECOND = 1000; - private final long timeout; - private boolean cancelled = false; - private volatile boolean started = false; - - /** - * Create a timeout object and start it running in its own - * thread. - * @param seconds Timeout in seconds - */ - private TimeoutThread(int seconds) { - this.timeout = seconds * MILLIS_PER_SECOND; - new Thread(this).start(); - synchronized (this) { - while (!started) { - try { - /* Wait for the timeout thread to start running */ - wait(); - } catch (InterruptedException e) { - } - } - } - } - - /** - * @see java.lang.Thread#run() - */ - @Override - public void run() { - long startTime = System.currentTimeMillis(); - synchronized (this) { - /* Inform the caller that the timeout thread has started */ - started = true; - notify(); - - while (!cancelled) { - try { - /* Sleep until woken by a cancel or the timer has expired */ - long now = System.currentTimeMillis(); - if (now - startTime >= timeout) { - System.err.printf("Collection exceeded timeout %dms%n",timeout); - System.exit(1); - } - long sleepTime = Math.max(1,timeout - (now - startTime)); - if (VERBOSE) { - System.err.printf("Collection timeout: sleeping for %dms%n",sleepTime); - } - wait(sleepTime); - } catch (InterruptedException e) { - // Ignore interruptions - } - } - } - } - - /** Cancel the timeout */ - public void cancel() { ... [truncated message content] |
From: <lhe...@us...> - 2010-07-20 14:18:32
|
Revision: 15926 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15926&view=rev Author: lhellyer Date: 2010-07-20 14:18:25 +0000 (Tue, 20 Jul 2010) Log Message: ----------- An incremental copying collector that treats toSpace copied objects as white Squashed commit up to 32c1b641393f750097f435844020b1ab9e5bbbc7 Modified Paths: -------------- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Scanning.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/Simple.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/SimpleMutator.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SS.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSCollector.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSConstraints.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSMutator.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSTraceLocal.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/alloc/BumpPointer.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/vm/Scanning.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/mm/mminterface/SpecializedScanMethod.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/ThinLock.java Added Paths: ----------- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCFromSpaceLinearSanityScan.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCToSpaceLinearSanityScan.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCFromSpaceLinearSanityScan.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCToSpaceLinearSanityScan.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/ToSpaceLinearScanTrace.java Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Scanning.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Scanning.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Scanning.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -66,6 +66,16 @@ SpecializedScanMethod.fallback(object.toObject(), trace); } + @Inline + public boolean pointsTo(ObjectReference object, int descriptor) { + return SpecializedScanMethod.pointsTo(object, descriptor); + } + + @Inline + public boolean pointsToForwardedObjects(ObjectReference object) { + return SpecializedScanMethod.pointsToForwardedObjects(object); + } + /** * Invoke a specialized scan method. Note that these methods must have been allocated * explicitly through Plan and PlanConstraints. Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/Simple.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/Simple.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/Simple.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -127,6 +127,7 @@ Phase.scheduleCollector (ROOTS), Phase.scheduleGlobal (ROOTS), Phase.scheduleGlobal (CLOSURE), + Phase.scheduleMutator(CLOSURE), Phase.scheduleCollector (CLOSURE)); /** @@ -167,6 +168,7 @@ protected static final short finishPhase = Phase.createComplex("finish", Phase.schedulePlaceholder(POST_SANITY_PLACEHOLDER), Phase.scheduleCollector (COMPLETE), + Phase.scheduleMutator(COMPLETE), Phase.scheduleGlobal (COMPLETE), Phase.scheduleGlobal (CONSIDER_GROW_HEAP), Phase.scheduleGlobal (RESET_COLLECTION), Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/SimpleMutator.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/SimpleMutator.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/SimpleMutator.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -54,6 +54,10 @@ return; } + if (phaseId == Simple.CLOSURE) { + return; + } + if (phaseId == Simple.PREPARE) { los.prepare(true); lgcode.prepare(true); @@ -72,6 +76,10 @@ return; } + if (phaseId == Simple.COMPLETE) { + return; // nothing to do here + } + Log.write("Per-mutator phase \""); Phase.getPhase(phaseId).logPhase(); Log.writeln("\" not handled."); VM.assertions.fail("Per-mutator phase not handled!"); Added: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCFromSpaceLinearSanityScan.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCFromSpaceLinearSanityScan.java (rev 0) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCFromSpaceLinearSanityScan.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -0,0 +1,48 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Eclipse Public License (EPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/eclipse-1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.mmtk.plan.semispace.incremental; + +import org.mmtk.policy.Space; +import org.mmtk.utility.Log; +import org.mmtk.utility.alloc.LinearScan; +import org.mmtk.vm.VM; +import org.vmmagic.unboxed.*; +import org.vmmagic.pragma.*; + +/** + * Callbacks from BumpPointer during a linear scan are dispatched through + * a subclass of this object. + */ +@Uninterruptible +public class PostGCFromSpaceLinearSanityScan extends LinearScan { + /** + * Scan an object. ToSpace must not contain pointers to fromSpace after a complete trace + * @param object The object to scan + */ + public void scan(ObjectReference object) { + if (VM.VERIFY_ASSERTIONS) { + if (!object.isNull()) { + // Log.write("Scanning... "); Log.writeln(object); + VM.assertions._assert(!SS.copyingAllComplete); // If copying is complete space should be empty + VM.assertions._assert(Space.isInSpace(SS.fromSpace().getDescriptor(), object)); // flip can't have happened as not all + // copying is complete + if (VM.scanning.pointsToForwardedObjects(object)) { + Log.write("PreGCFromSpaceLinearSanityScan: Object "); + Log.write(object); + Log.writeln(" contained references to a forwarded fromSpace object"); + VM.assertions.fail("Died during linear sanity scan"); + } + } + } + } +} Added: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCToSpaceLinearSanityScan.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCToSpaceLinearSanityScan.java (rev 0) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCToSpaceLinearSanityScan.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -0,0 +1,57 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Eclipse Public License (EPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/eclipse-1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.mmtk.plan.semispace.incremental; + +import org.mmtk.policy.Space; +import org.mmtk.utility.Log; +import org.mmtk.utility.alloc.LinearScan; +import org.mmtk.vm.VM; +import org.vmmagic.unboxed.*; +import org.vmmagic.pragma.*; + +/** + * Callbacks from BumpPointer during a linear scan are dispatched through + * a subclass of this object. + */ +@Uninterruptible +public class PostGCToSpaceLinearSanityScan extends LinearScan { + /** + * Scan an object. ToSpace must not contain pointers to fromSpace after a complete trace + * @param object The object to scan + */ + public void scan(ObjectReference object) { + if (VM.VERIFY_ASSERTIONS) { + if (!object.isNull()) { + // Log.write("Scanning... "); Log.writeln(object); + if (VM.scanning.pointsToForwardedObjects(object)) { + Log.write("PostGCToSpaceLinearSanityScan: Object "); + Log.write(object); + Log.writeln(" contained references to a forwarded fromSpace"); + VM.assertions.fail("Died during linear sanity scan"); + } + if (SS.copyingAllComplete) { + VM.assertions._assert(Space.isInSpace(SS.fromSpace().getDescriptor(), object)); // flip has occured + if (VM.scanning.pointsTo(object, SS.toSpace().getDescriptor())) { + Log.write("PostGCToSpaceLinearSanityScan: Object "); + Log.write(object); + Log.writeln(" contained references to toSpace"); + VM.assertions.fail("Died during linear sanity scan"); + } + } else { + // copying not complete, therefore not flipped yet + VM.assertions._assert(Space.isInSpace(SS.toSpace().getDescriptor(), object)); // check in right space + } + } + } + } +} Added: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCFromSpaceLinearSanityScan.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCFromSpaceLinearSanityScan.java (rev 0) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCFromSpaceLinearSanityScan.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -0,0 +1,47 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Eclipse Public License (EPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/eclipse-1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.mmtk.plan.semispace.incremental; + +import org.mmtk.policy.Space; +import org.mmtk.utility.Log; +import org.mmtk.utility.alloc.LinearScan; +import org.mmtk.vm.VM; +import org.vmmagic.unboxed.*; +import org.vmmagic.pragma.*; + +/** + * Callbacks from BumpPointer during a linear scan are dispatched through + * a subclass of this object. + */ +@Uninterruptible +public class PreGCFromSpaceLinearSanityScan extends LinearScan { + /** + * Scan an object. ToSpace must not contain pointers to fromSpace after a complete trace + * @param object The object to scan + */ + public void scan(ObjectReference object) { + if (VM.VERIFY_ASSERTIONS) { + if (!object.isNull()) { + // Log.write("Scanning... "); Log.writeln(object); + VM.assertions._assert(Space.isInSpace(SS.fromSpace().getDescriptor(), object)); // ensure in right space + if (VM.scanning.pointsToForwardedObjects(object)) { + Log.write("PreGCFromSpaceLinearSanityScan: Object "); + Log.write(object); + Log.writeln(" contained references to a forwarded fromSpace object"); + VM.assertions.fail("Died during linear sanity scan"); + } + } + } + } +} + Added: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCToSpaceLinearSanityScan.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCToSpaceLinearSanityScan.java (rev 0) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCToSpaceLinearSanityScan.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -0,0 +1,45 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Eclipse Public License (EPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/eclipse-1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.mmtk.plan.semispace.incremental; + +import org.mmtk.utility.Log; +import org.mmtk.utility.alloc.LinearScan; +import org.mmtk.vm.VM; +import org.vmmagic.unboxed.*; +import org.vmmagic.pragma.*; + +/** + * Callbacks from BumpPointer during a linear scan are dispatched through + * a subclass of this object. + */ +@Uninterruptible +public class PreGCToSpaceLinearSanityScan extends LinearScan { + /** + * Scan an object. ToSpace must not contain pointers to fromSpace after a complete trace + * @param object The object to scan + */ + public void scan(ObjectReference object) { + if (VM.VERIFY_ASSERTIONS) { + if (!object.isNull()) { + VM.assertions._assert(!SS.copyingAllComplete); // If copying is complete space should be empty + // Log.write("Scanning... "); Log.writeln(object); + if (VM.scanning.pointsToForwardedObjects(object)) { + Log.write("PreGCToSpaceLinearSanityScan: Object "); + Log.write(object); + Log.writeln(" contained references to a forwarded fromSpace object"); + VM.assertions.fail("Died during linear sanity scan"); + } + } + } + } +} Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SS.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SS.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SS.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -12,10 +12,13 @@ */ package org.mmtk.plan.semispace.incremental; +import org.mmtk.policy.CopyLocal; import org.mmtk.policy.CopySpace; import org.mmtk.policy.Space; import org.mmtk.plan.*; import org.mmtk.utility.heap.VMRequest; +import org.mmtk.vm.Lock; +import org.mmtk.vm.VM; import org.vmmagic.pragma.*; import org.vmmagic.unboxed.*; @@ -41,11 +44,17 @@ public final Trace ssTrace; + public static volatile boolean copyingAllComplete = true; + public static volatile int linearScannedSoFar = 0; + public static CopyLocal deadThreadsBumpPointer = new CopyLocal(); + static { fromSpace().prepare(true); toSpace().prepare(false); } + static Lock tackOnLock = VM.newLock("tackOnLock"); + /**************************************************************************** * * Initialization @@ -96,22 +105,33 @@ public void collectionPhase(short phaseId) { if (phaseId == SS.PREPARE) { ssTrace.prepare(); + fromSpace().prepare(true); // Make fromSpace moveable whilst GC in progress + deadThreadsBumpPointer.linearScan(SSMutator.preGCSanity); super.collectionPhase(phaseId); return; } if (phaseId == CLOSURE) { + copyingAllComplete = false; + // Log.writeln("Closure for dead Thread mutator context"); + deadThreadsBumpPointer.linearScan(SSCollector.linearTrace); + // Log.writeln("Linear scanned so far: ", SS.linearScannedSoFar); ssTrace.prepare(); + fromSpace().prepare(false); // no more objects can be copied from fromSpace in this GC cycle return; } if (phaseId == SS.RELEASE) { - low = !low; // flip the semi-spaces - fromSpace().prepare(true); - toSpace().release(); - + if (copyingAllComplete) { + low = !low; // flip the semi-spaces + toSpace().release(); + deadThreadsBumpPointer.rebind(fromSpace()); + } + deadThreadsBumpPointer.linearScan(SSMutator.postGCSanity); super.collectionPhase(phaseId); return; } - + if (phaseId == SS.COMPLETE) { + fromSpace().prepare(true); // make from space moving at last minute + } super.collectionPhase(phaseId); } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSCollector.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSCollector.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSCollector.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -17,6 +17,7 @@ import org.mmtk.policy.LargeObjectLocal; import org.mmtk.policy.Space; import org.mmtk.utility.ForwardingWord; +import org.mmtk.utility.Log; import org.mmtk.vm.VM; import org.vmmagic.unboxed.*; @@ -33,6 +34,10 @@ protected final CopyLocal ss; protected final LargeObjectLocal los; + private static final PreGCToSpaceLinearSanityScan preGCSanity = new PreGCToSpaceLinearSanityScan(); + private static final PostGCToSpaceLinearSanityScan postGCSanity = new PostGCToSpaceLinearSanityScan(); + public static final ToSpaceLinearScanTrace linearTrace = new ToSpaceLinearScanTrace(); + /**************************************************************************** * * Initialization @@ -98,6 +103,10 @@ ForwardingWord.clearForwardingBits(object); if (allocator == Plan.ALLOC_LOS) Plan.loSpace.initializeHeader(object, false); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(getCurrentTrace().isLive(object)); + VM.assertions._assert(getCurrentTrace().willNotMoveInCurrentCollection(object)); + } } /**************************************************************************** @@ -115,14 +124,24 @@ public void collectionPhase(short phaseId, boolean primary) { if (phaseId == SS.PREPARE) { // rebind the copy bump pointer to the appropriate semispace. - ss.rebind(SS.toSpace()); + if (SS.copyingAllComplete) + ss.rebind(SS.toSpace()); + ss.linearScan(preGCSanity); los.prepare(true); + trace.numObjectsCopied = 0; super.collectionPhase(phaseId, primary); return; } if (phaseId == SS.CLOSURE) { + ss.linearScan(linearTrace); trace.completeTrace(); + int max = SSTraceLocal.numCopiesPerGCAllowed; + int copied = trace.getNumObjectsCopied(); + if (copied < max) { + Log.writeln("Everything copied ", copied); + SS.copyingAllComplete = true; // no more possible objects left to copy + } return; } @@ -132,6 +151,17 @@ super.collectionPhase(phaseId, primary); return; } + + if (phaseId == SS.COMPLETE) { + ss.linearScan(postGCSanity); + if (SS.copyingAllComplete) { + SS.tackOnLock.acquire(); + SS.deadThreadsBumpPointer.tackOn(ss); + SS.tackOnLock.release(); + } + super.collectionPhase(phaseId, primary); + return; + } super.collectionPhase(phaseId, primary); } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSConstraints.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSConstraints.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSConstraints.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -26,4 +26,6 @@ public int gcHeaderWords() { return CopySpace.GC_HEADER_WORDS_REQUIRED; } @Override public int numSpecializedScans() { return 1; } + public boolean needsObjectReferenceReadBarrier() { return true; } + public boolean needsObjectReferenceWriteBarrier() { return true; } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSMutator.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSMutator.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSMutator.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -15,13 +15,21 @@ import org.mmtk.plan.*; import org.mmtk.policy.CopyLocal; import org.mmtk.policy.Space; +import org.mmtk.utility.ForwardingWord; +import org.mmtk.utility.Log; import org.mmtk.utility.alloc.Allocator; +import org.mmtk.vm.Lock; +import org.mmtk.vm.VM; import org.vmmagic.unboxed.*; import org.vmmagic.pragma.*; @Uninterruptible public class SSMutator extends StopTheWorldMutator { + + static final PreGCFromSpaceLinearSanityScan preGCSanity = new PreGCFromSpaceLinearSanityScan(); + static final PostGCFromSpaceLinearSanityScan postGCSanity = new PostGCFromSpaceLinearSanityScan(); + /**************************************************************************** * Instance fields */ @@ -65,8 +73,13 @@ */ @Inline public Address alloc(int bytes, int align, int offset, int allocator, int site) { - if (allocator == SS.ALLOC_SS) - return ss.alloc(bytes, align, offset); + if (allocator == SS.ALLOC_SS) { + Address addy = ss.alloc(bytes, align, offset); + // Log.write("Allocating... "); + // Log.write(addy); + // Log.writeln(" as thread", VM.activePlan.mutator().getId()); + return addy; + } else return super.alloc(bytes, align, offset, allocator, site); } @@ -116,15 +129,30 @@ public void collectionPhase(short phaseId, boolean primary) { if (phaseId == SS.PREPARE) { super.collectionPhase(phaseId, primary); + ss.linearScan(preGCSanity); return; } + if (phaseId == SS.CLOSURE) { + // Log.writeln("Closure for a mutator context"); + ss.linearScan(SSCollector.linearTrace); + // Log.writeln("Linear scanned so far: ", SS.linearScannedSoFar); + return; + } + if (phaseId == SS.RELEASE) { super.collectionPhase(phaseId, primary); // rebind the allocation bump pointer to the appropriate semispace. - ss.rebind(SS.toSpace()); // flip hasn't happened yet + if (SS.copyingAllComplete) + ss.rebind(SS.toSpace()); // flip hasn't happened yet return; } + + if (phaseId == SS.COMPLETE) { + super.collectionPhase(phaseId, primary); + ss.linearScan(postGCSanity); + return; + } super.collectionPhase(phaseId, primary); } @@ -144,4 +172,71 @@ immortal.show(); } + /** + * The mutator is about to be cleaned up, make sure all local data is returned. + */ + public void deinitMutator() { + SS.tackOnLock.acquire(); + // Log.writeln("Deiniting mutator thread ", VM.activePlan.mutator().getId()); + // Log.flush(); + SS.deadThreadsBumpPointer.tackOn(ss); // thread is dying, ensure everything it allocated is still scanable + SS.tackOnLock.release(); + super.deinitMutator(); + } + + /** + * Read a reference. Take appropriate read barrier action, and return the value that was read. + * <p> + * This is a <b>substituting<b> barrier. The call to this barrier takes the place of a load. + * <p> + * @param src The object reference holding the field being read. + * @param slot The address of the slot being read. + * @param metaDataA A value that assists the host VM in creating a load + * @param metaDataB A value that assists the host VM in creating a load + * @param mode The context in which the load occurred + * @return The reference that was read. + */ + @Inline + @Override + public ObjectReference objectReferenceRead(ObjectReference src, Address slot, Word metaDataA, Word metaDataB, int mode) { + ObjectReference obj = VM.barriers.objectReferenceRead(src, metaDataA, metaDataB, mode); + if (!obj.isNull() && (Space.isInSpace(SS.SS0, obj) || Space.isInSpace(SS.SS1, obj)) && ForwardingWord.isForwarded(obj)) { + Log.writeln("Caught loading a reference to SS0 or SS1 where the object has a forwading pointer"); + Log.write("The caught reference was "); + Log.write(obj); + Log.write(" and was loaded from object "); + Log.write(src); + if (VM.scanning.pointsToForwardedObjects(src)) { + Log.write(" which was correctly detected as containing reference to a forwarded object"); + } + Log.writeln(""); + // VM.assertions.fail("Loaded a stale ref"); + } + return obj; + } + + /** + * A new reference is about to be created. Take appropriate write barrier actions. + * <p> + * In this case, we remember the address of the source of the pointer if the new reference points into the nursery from nonnursery + * space. + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param tgt The target of the new reference + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The mode of the store (eg putfield, putstatic etc) + */ + @Inline + public final void objectReferenceWrite(ObjectReference src, Address slot, ObjectReference tgt, Word metaDataA, Word metaDataB, + int mode) { + if (!tgt.isNull() && (Space.isInSpace(SS.SS0, tgt) || Space.isInSpace(SS.SS1, tgt)) && ForwardingWord.isForwarded(tgt)) { + Log.writeln("Caught writing a reference to SS0 or SS1 where the tgt is already forwarded"); + Log.write("The caught reference was "); + Log.write(tgt); + Log.write(" and it being written into object "); + Log.writeln(src); + } + VM.barriers.objectReferenceWrite(src, tgt, metaDataA, metaDataB, mode); + } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSTraceLocal.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSTraceLocal.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSTraceLocal.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -14,7 +14,12 @@ import org.mmtk.plan.TraceLocal; import org.mmtk.plan.Trace; +import org.mmtk.plan.TransitiveClosure; import org.mmtk.policy.Space; +import org.mmtk.utility.ForwardingWord; +import org.mmtk.utility.Log; +import org.mmtk.utility.options.Options; +import org.mmtk.vm.VM; import org.vmmagic.pragma.*; import org.vmmagic.unboxed.*; @@ -35,6 +40,13 @@ this(trace, true); } + final static int numCopiesPerGCAllowed = 80000; // total number of objects copied is allowed to be 1 more than this + volatile int numObjectsCopied = 0; + + public int getNumObjectsCopied() { + return numObjectsCopied; + } + /**************************************************************************** * * Externally visible Object processing and tracing @@ -48,8 +60,12 @@ */ public boolean isLive(ObjectReference object) { if (object.isNull()) return false; - if (Space.isInSpace(SS.fromSpace().getDescriptor(), object)) - return SS.copySpace0.isLive(object); // isLive could be called in a static way + if (Space.isInSpace(SS.fromSpace().getDescriptor(), object)) { + if (SS.copyingAllComplete == true) { + return ForwardingWord.isForwarded(object); + } else + return true; + } if (Space.isInSpace(SS.toSpace().getDescriptor(), object)) return true; return super.isLive(object); @@ -70,10 +86,10 @@ @Inline public ObjectReference traceObject(ObjectReference object) { if (object.isNull()) return object; - if (Space.isInSpace(SS.SS0, object)) - return SS.copySpace0.traceObject(this, object, SS.ALLOC_SS); - if (Space.isInSpace(SS.SS1, object)) - return SS.copySpace1.traceObject(this, object, SS.ALLOC_SS); + if (Space.isInSpace(SS.fromSpace().getDescriptor(), object)) + return traceObject(this, object, SS.ALLOC_SS, true); + if (Space.isInSpace(SS.toSpace().getDescriptor(), object)) + return traceObject(this, object, SS.ALLOC_SS, false); return super.traceObject(object); } @@ -84,6 +100,76 @@ * @return True if the object will not move. */ public boolean willNotMoveInCurrentCollection(ObjectReference object) { - return !Space.isInSpace(SS.fromSpace().getDescriptor(), object); + // return !Space.isInSpace(SS.fromSpace().getDescriptor(), object); + return true; } + + /** + * Trace an object under a copying collection policy. We use a tri-state algorithm to deal with races to forward the object. The + * tracer must wait if the object is concurrently being forwarded by another thread. If the object is already forwarded, the copy + * is returned. Otherwise, the object is forwarded and the copy is returned. + * @param trace The trace being conducted. + * @param object The object to be forwarded. + * @param allocator The allocator to use when copying. + * @param fromSpace if we are tracing an object in fromSpace + * @return The forwarded object. + */ + @Inline + public ObjectReference traceObject(TransitiveClosure trace, ObjectReference object, int allocator, boolean fromSpace) { + /* If the object in question is already in to-space, then do nothing */ + if (!fromSpace) + return object; + + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(Space.isInSpace(SS.fromSpace().getDescriptor(), object)); + } + + // Check if already has FP + if (ForwardingWord.isForwardedOrBeingForwarded(object)) { + Word forwardingWord; + do { + forwardingWord = VM.objectModel.readAvailableBitsWord(object); + } while (ForwardingWord.stateIsBeingForwarded(forwardingWord)); + return ForwardingWord.extractForwardingPointer(forwardingWord); + } + + // Not yet copied - Check copying budget for this GC cycle + if (SS.copyingAllComplete || numObjectsCopied <= numCopiesPerGCAllowed) { + /* Try to forward the object */ + Word forwardingWord = ForwardingWord.attemptToForward(object); + + if (ForwardingWord.stateIsForwardedOrBeingForwarded(forwardingWord)) { + /* Somebody else got to it first. */ + + /* We must wait (spin) if the object is not yet fully forwarded */ + while (ForwardingWord.stateIsBeingForwarded(forwardingWord)) + forwardingWord = VM.objectModel.readAvailableBitsWord(object); + + /* Now extract the object reference from the forwarding word and return it */ + return ForwardingWord.extractForwardingPointer(forwardingWord); + } else { + /* We are the designated copier, so forward it and enqueue it */ + numObjectsCopied++; // increment count of objects copied + ObjectReference newObject = VM.objectModel.copy(object, allocator); + ForwardingWord.setForwardingPointer(object, newObject); + trace.processNode(newObject); // Scan it later + + if (VM.VERIFY_ASSERTIONS && Options.verbose.getValue() >= 9) { + Log.write("C["); + Log.write(object); + Log.write("/"); + Log.write(SS.fromSpace().getName()); + Log.write("] -> "); + Log.write(newObject); + Log.write("/"); + Log.write(Space.getSpaceForObject(newObject).getName()); + Log.writeln("]"); + } + return newObject; + } + } + + // Copy not allowed at this stage + return object; + } } Added: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/ToSpaceLinearScanTrace.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/ToSpaceLinearScanTrace.java (rev 0) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/ToSpaceLinearScanTrace.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -0,0 +1,40 @@ +/* + * This file is part of the Jikes RVM project (http://jikesrvm.org). + * + * This file is licensed to You under the Eclipse Public License (EPL); + * You may not use this file except in compliance with the License. You + * may obtain a copy of the License at + * + * http://www.opensource.org/licenses/eclipse-1.0.php + * + * See the COPYRIGHT.txt file distributed with this work for information + * regarding copyright ownership. + */ +package org.mmtk.plan.semispace.incremental; + +import org.mmtk.plan.ParallelCollector; +import org.mmtk.utility.Log; +import org.mmtk.utility.alloc.LinearScan; +import org.mmtk.vm.VM; +import org.vmmagic.unboxed.*; +import org.vmmagic.pragma.*; + +/** + * Callbacks from BumpPointer during a linear scan are dispatched through + * a subclass of this object. + */ +@Uninterruptible +public class ToSpaceLinearScanTrace extends LinearScan { + /** + * Scan an object. ToSpace must not contain pointers to fromSpace after a complete trace + * @param object The object to scan + */ + public void scan(ObjectReference object) { + // Log.write("Scanning... "); + // Log.writeln(object); + if (!object.isNull()) { + ((ParallelCollector) VM.activePlan.collector()).getCurrentTrace().processNode(object); + SS.linearScannedSoFar++; + } + } +} Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/alloc/BumpPointer.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/alloc/BumpPointer.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/alloc/BumpPointer.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -487,6 +487,25 @@ setRegionLimit(region,limit); } + // Doesn't leave either bump pointer is a useable state for allocation. + public void tackOn(BumpPointer bump) { + if (initialRegion.isZero()) { + /* the first mutator thread has died and we are preserving it's bump pointer */ + initialRegion = bump.initialRegion; + region = bump.region; + cursor = bump.cursor; + } else { + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(space == bump.space); + } + // tack on another bump pointer + setDataEnd(region, cursor); // no more data will be allocated in this region of the old bump pointer + setNextRegion(region, bump.initialRegion); // next Region is the beginning of the next bump pointer + region = bump.region; // fast forward to end of tacked on bump pointer + cursor = bump.cursor; // fast forward to end of tacked on bump pointer + } + } + /** * Gather data for GCspy. <p> * This method calls the drivers linear scanner to scan through Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/vm/Scanning.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/vm/Scanning.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/vm/Scanning.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -28,6 +28,10 @@ */ public abstract void scanObject(TransitiveClosure trace, ObjectReference object); + public abstract boolean pointsTo(ObjectReference object, int descriptor); + + public abstract boolean pointsToForwardedObjects(ObjectReference object); + /** * Invoke a specialized scan method. Note that these methods must have been allocated * explicitly through Plan and PlanConstraints. Modified: rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/mm/mminterface/SpecializedScanMethod.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/mm/mminterface/SpecializedScanMethod.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/mm/mminterface/SpecializedScanMethod.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -26,6 +26,9 @@ import org.jikesrvm.objectmodel.ObjectModel; import org.jikesrvm.runtime.Magic; import org.mmtk.plan.TransitiveClosure; +import org.mmtk.plan.semispace.incremental.SS; +import org.mmtk.policy.Space; +import org.mmtk.utility.ForwardingWord; import org.vmmagic.pragma.Inline; import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.NoInline; @@ -208,6 +211,50 @@ } } + public static boolean pointsTo(ObjectReference objectRef, int descriptor) { + RVMType type = ObjectModel.getObjectType(objectRef.toObject()); + if (type.isClassType()) { + RVMClass klass = type.asClass(); + int[] offsets = klass.getReferenceOffsets(); + for (int i = 0; i < offsets.length; i++) { + ObjectReference obj = Selected.Plan.get().loadObjectReference(objectRef.toAddress().plus(offsets[i])); + if (!obj.isNull() && Space.isInSpace(descriptor, obj)) + return true; + } + } else if (type.isArrayType() && type.asArray().getElementType().isReferenceType()) { + for (int i = 0; i < ObjectModel.getArrayLength(objectRef.toObject()); i++) { + ObjectReference obj = Selected.Plan.get().loadObjectReference(objectRef.toAddress().plus(i << LOG_BYTES_IN_ADDRESS)); + if (!obj.isNull() && Space.isInSpace(descriptor, obj)) + return true; + } + } + return false; // no references in objectRef point to the space identified by desciptor + } + + public static boolean pointsToForwardedObjects(ObjectReference objectRef) { + RVMType type = ObjectModel.getObjectType(objectRef.toObject()); + if (type.isClassType()) { + RVMClass klass = type.asClass(); + int[] offsets = klass.getReferenceOffsets(); + for (int i = 0; i < offsets.length; i++) { + ObjectReference obj = Selected.Plan.get().loadObjectReference(objectRef.toAddress().plus(offsets[i])); + if (!obj.isNull() + && (Space.getSpaceForObject(obj).getDescriptor() == SS.SS0 || Space.getSpaceForObject(obj).getDescriptor() == SS.SS1) + && ForwardingWord.isForwardedOrBeingForwarded(obj)) + return true; + } + } else if (type.isArrayType() && type.asArray().getElementType().isReferenceType()) { + for (int i = 0; i < ObjectModel.getArrayLength(objectRef.toObject()); i++) { + ObjectReference obj = Selected.Plan.get().loadObjectReference(objectRef.toAddress().plus(i << LOG_BYTES_IN_ADDRESS)); + if (!obj.isNull() + && (Space.getSpaceForObject(obj).getDescriptor() == SS.SS0 || Space.getSpaceForObject(obj).getDescriptor() == SS.SS1) + && ForwardingWord.isForwardedOrBeingForwarded(obj)) + return true; + } + } + return false; // no references in objectRef point to an obj in a copyspace that has been forwarded + } + /** All Scalars */ public static void scalar(Object object, TransitiveClosure trace) { Address base = Magic.objectAsAddress(object); Modified: rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/ThinLock.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2010-07-20 14:17:35 UTC (rev 15925) +++ rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2010-07-20 14:18:25 UTC (rev 15926) @@ -16,11 +16,15 @@ import org.jikesrvm.Services; import org.jikesrvm.objectmodel.ThinLockConstants; import org.jikesrvm.runtime.Magic; +import org.mmtk.plan.semispace.incremental.SS; +import org.mmtk.policy.Space; +import org.mmtk.utility.ForwardingWord; import org.vmmagic.pragma.Inline; import org.vmmagic.pragma.NoInline; import org.vmmagic.pragma.NoNullCheck; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.pragma.Unpreemptible; +import org.vmmagic.unboxed.ObjectReference; import org.vmmagic.unboxed.Offset; import org.vmmagic.unboxed.Word; @@ -81,6 +85,13 @@ @Unpreemptible public static void lock(Object o, Offset lockOffset) { if (STATS) fastLocks++; + if (Space.isInSpace(SS.fromSpace().getDescriptor(), ObjectReference.fromObject(o))) { + if (ForwardingWord.isForwarded(ObjectReference.fromObject(o))) { + VM.sysWrite("Locking "); + VM.sysWrite(ObjectReference.fromObject(o)); + VM.sysWriteln(" Which is in fromSpace and is a forwarded object - uh oh I smell trouble..."); + } + } Word threadId = Word.fromIntZeroExtend(RVMThread.getCurrentThread().getLockingId()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <lhe...@us...> - 2010-07-31 11:37:04
|
Revision: 15960 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15960&view=rev Author: lhellyer Date: 2010-07-31 11:36:56 +0000 (Sat, 31 Jul 2010) Log Message: ----------- STW and replicate objects. Primitive write barriers maintain consistency Does not actually ever throw away fromSpace so still not a useable GC. Lots of sanity checking ensures replicas are consistent. Squashed commit up to 3409864dbff12c98e47c3f8e9deca14274318a8c Modified Paths: -------------- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Assert.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ObjectModel.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/CollectorContext.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/MutatorContext.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/PlanConstraints.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCFromSpaceLinearSanityScan.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCToSpaceLinearSanityScan.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCFromSpaceLinearSanityScan.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCToSpaceLinearSanityScan.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SS.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSCollector.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSConstraints.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSMutator.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSTraceLocal.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/CopySpace.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/ForwardingWord.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/vm/Assert.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/vm/ObjectModel.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/CommandLineArgs.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/classloader/AnnotatedElement.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/classloader/Primitive.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/classloader/RVMArray.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/classloader/RVMClass.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/classloader/RVMField.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/classloader/RVMMethod.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/classloader/RVMType.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/classloader/TypeReference.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/classloader/UnboxedType.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/compilers/baseline/EdgeCounts.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/mm/mminterface/Barriers.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/mm/mminterface/MemoryManager.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/objectmodel/JavaHeader.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/objectmodel/ObjectModel.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/Synchronization.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/ThinLock.java Added Paths: ----------- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/ReplicatingSpace.java rvmroot/branches/RVM-893-Sapphire/work/common/vmmagic/src/org/vmmagic/pragma/NonReplicatingAllocation.java rvmroot/branches/RVM-893-Sapphire/work/testing/tests/Sapphire/ rvmroot/branches/RVM-893-Sapphire/work/testing/tests/Sapphire/replicateHashLockTest.java Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Assert.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Assert.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Assert.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -15,9 +15,11 @@ import org.mmtk.policy.Space; import org.jikesrvm.VM; +import org.jikesrvm.mm.mminterface.DebugUtil; import org.jikesrvm.scheduler.RVMThread; import org.vmmagic.pragma.*; +import org.vmmagic.unboxed.ObjectReference; @Uninterruptible public class Assert extends org.mmtk.vm.Assert { /** @@ -85,4 +87,8 @@ public final void dumpStack() { RVMThread.dumpStack(); } + + public boolean validRef(ObjectReference ref) { + return DebugUtil.validObject(ref); + } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ObjectModel.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ObjectModel.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ObjectModel.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -67,7 +67,7 @@ allocator, from); Object toObj = org.jikesrvm.objectmodel.ObjectModel.moveObject(region, from.toObject(), bytes, type); ObjectReference to = ObjectReference.fromObject(toObj); - context.postCopy(to, ObjectReference.fromObject(tib), bytes, allocator); + context.postCopy(from, to, ObjectReference.fromObject(tib), bytes, allocator); return to; } @@ -83,7 +83,7 @@ allocator, from); Object toObj = org.jikesrvm.objectmodel.ObjectModel.moveObject(region, from.toObject(), bytes, type); ObjectReference to = ObjectReference.fromObject(toObj); - context.postCopy(to, ObjectReference.fromObject(tib), bytes, allocator); + context.postCopy(from, to, ObjectReference.fromObject(tib), bytes, allocator); if (type == RVMType.CodeArrayType) { // sync all moved code arrays to get icache and dcache in sync // immediately. @@ -361,6 +361,14 @@ org.jikesrvm.objectmodel.ObjectModel.writeAvailableBitsWord(object.toObject(), val); } + public void writeReplicatingFP(ObjectReference o, ObjectReference ptr) { + org.jikesrvm.objectmodel.JavaHeader.writeReplicatingFP(o, ptr); + } + + public ObjectReference getReplicatingFP(ObjectReference obj) { + return ObjectReference.fromObject(org.jikesrvm.objectmodel.JavaHeader.getReplicatingFP(obj)); + } + /** * Read the bits available for memory manager use in an object. * @@ -428,5 +436,15 @@ public void dumpObject(ObjectReference object) { DebugUtil.dumpRef(object); } + + @Override + public void checkFromSpaceReplicatedObject(ObjectReference fromSpace, ObjectReference toSpace) { + org.jikesrvm.objectmodel.ObjectModel.checkFromSpaceReplicatedObject(fromSpace, toSpace); + } + + @Override + public void checkFromSpaceNotYetReplicatedObject(ObjectReference fromSpace) { + org.jikesrvm.objectmodel.ObjectModel.checkFromSpaceNotYetReplicatedObject(fromSpace); + } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -511,7 +511,7 @@ */ /* Update the referent */ - setReferent(newReference, newReferent); + setReferentDuringGC(newReference, newReferent); return newReference; } else { /* Referent is unreachable. Clear the referent and enqueue the reference object. */ @@ -533,7 +533,7 @@ * occur. */ protected void clearReferent(ObjectReference newReference) { - setReferent(newReference, ObjectReference.nullReference()); + setReferentDuringGC(newReference, ObjectReference.nullReference()); } /*********************************************************************** @@ -559,9 +559,16 @@ * @param referent the referent object reference. */ protected void setReferent(ObjectReference ref, ObjectReference referent) { - ref.toAddress().store(referent, Entrypoints.referenceReferentField.getOffset()); + org.jikesrvm.mm.mminterface.Barriers.wordFieldWrite(ref.toObject(), referent.toAddress().toWord(), + Entrypoints.referenceReferentField.getOffset(), 0); } + protected void setReferentDuringGC(ObjectReference ref, ObjectReference referent) { + // avoid certain Sapphire assertions because ref might be in toSpace + org.jikesrvm.mm.mminterface.Barriers.wordFieldWriteDuringGC(ref.toObject(), referent.toAddress().toWord(), + Entrypoints.referenceReferentField.getOffset(), 0); + } + /*********************************************************************** * * Statistics and debugging Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/CollectorContext.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/CollectorContext.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/CollectorContext.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -119,10 +119,14 @@ * @param bytes The size of the space to be allocated (in bytes). * @param allocator The allocator statically assigned to this allocation. */ - public void postCopy(ObjectReference ref, ObjectReference typeRef, int bytes, int allocator) { + public void postCopy(ObjectReference to, ObjectReference typeRef, int bytes, int allocator) { VM.assertions.fail("Collector has not implemented postCopy"); } + public void postCopy(ObjectReference from, ObjectReference to, ObjectReference typeRef, int bytes, int allocator) { + VM.assertions.fail("Collector has not implemented postCopy"); + } + /** * Run-time check of the allocator to use for a given copy allocation * Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/MutatorContext.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/MutatorContext.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/MutatorContext.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -892,6 +892,41 @@ } /** + * Attempt to atomically exchange the value in the given slot with the passed replacement value. + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param old The old long to be swapped out + * @param value The new long + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + * @return True if the swap was successful. + */ + public boolean wordTryCompareAndSwapInLock(ObjectReference src, Address slot, Word old, Word value, Word metaDataA, + Word metaDataB, int mode) { + // Either: write barriers are used and this is overridden, or + // write barriers are not used and this is never called + if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(false); + return false; + } + + /** + * Write a Word during GC into toSpace. Take appropriate write barrier actions. + * <p> + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param value The value of the new Word + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + */ + public void wordWriteDuringGC(ObjectReference src, Address slot, Word value, Word metaDataA, Word metaDataB, int mode) { + // Either: write barriers are used and this is overridden, or + // write barriers are not used and this is never called + if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(false); + } + + /** * Write an Address. Take appropriate write barrier actions.<p> * * <b>By default do nothing, override if appropriate.</b> Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/PlanConstraints.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/PlanConstraints.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/PlanConstraints.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -193,4 +193,8 @@ /** @return True if this Plan will definitely stop mutator threads at a GC request */ public boolean gcRequestWillBlockMutator() { return true; } + + /** @return True if this Plan replicates objects */ + public boolean replicatingGC() { return false;} + } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCFromSpaceLinearSanityScan.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCFromSpaceLinearSanityScan.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCFromSpaceLinearSanityScan.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -13,6 +13,7 @@ package org.mmtk.plan.semispace.incremental; import org.mmtk.policy.Space; +import org.mmtk.utility.ForwardingWord; import org.mmtk.utility.Log; import org.mmtk.utility.alloc.LinearScan; import org.mmtk.vm.VM; @@ -36,11 +37,28 @@ VM.assertions._assert(!SS.copyingAllComplete); // If copying is complete space should be empty VM.assertions._assert(Space.isInSpace(SS.fromSpace().getDescriptor(), object)); // flip can't have happened as not all // copying is complete - if (VM.scanning.pointsToForwardedObjects(object)) { - Log.write("PreGCFromSpaceLinearSanityScan: Object "); - Log.write(object); - Log.writeln(" contained references to a forwarded fromSpace object"); - VM.assertions.fail("Died during linear sanity scan"); + + // if (VM.scanning.pointsToForwardedObjects(object)) { + // Log.write("PostGCFromSpaceLinearSanityScan: Object "); + // Log.write(object); + // Log.writeln(" contained references to a forwarded fromSpace object"); + // VM.assertions.fail("Died during linear sanity scan"); + // } + + VM.assertions._assert(!ForwardingWord.isBusy(object)); + + if (ForwardingWord.isForwardedOrBeingForwarded(object)) { + VM.assertions._assert(ForwardingWord.isForwarded(object)); // can't be half way through copying the object + ObjectReference forwarded = ForwardingWord.getReplicatingFP(object); + VM.assertions._assert(Space.isInSpace(SS.toSpace().getDescriptor(), forwarded)); + VM.assertions._assert(!forwarded.isNull()); + VM.assertions._assert(VM.assertions.validRef(forwarded)); + // follow FP and then follow BP - hope we end up at the same object! + ObjectReference bpObj = ForwardingWord.getReplicatingFP(forwarded); + VM.assertions._assert(object == bpObj); + VM.objectModel.checkFromSpaceReplicatedObject(object, forwarded); + } else { + VM.objectModel.checkFromSpaceNotYetReplicatedObject(object); } } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCToSpaceLinearSanityScan.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCToSpaceLinearSanityScan.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PostGCToSpaceLinearSanityScan.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -13,6 +13,7 @@ package org.mmtk.plan.semispace.incremental; import org.mmtk.policy.Space; +import org.mmtk.utility.ForwardingWord; import org.mmtk.utility.Log; import org.mmtk.utility.alloc.LinearScan; import org.mmtk.vm.VM; @@ -33,12 +34,15 @@ if (VM.VERIFY_ASSERTIONS) { if (!object.isNull()) { // Log.write("Scanning... "); Log.writeln(object); - if (VM.scanning.pointsToForwardedObjects(object)) { - Log.write("PostGCToSpaceLinearSanityScan: Object "); - Log.write(object); - Log.writeln(" contained references to a forwarded fromSpace"); - VM.assertions.fail("Died during linear sanity scan"); - } + // if (VM.scanning.pointsToForwardedObjects(object)) { + // Log.write("PostGCToSpaceLinearSanityScan: Object "); + // Log.write(object); + // Log.writeln(" contained references to a forwarded fromSpace"); + // VM.assertions.fail("Died during linear sanity scan"); + // } + + VM.assertions._assert(!ForwardingWord.isBusy(object)); + if (SS.copyingAllComplete) { VM.assertions._assert(Space.isInSpace(SS.fromSpace().getDescriptor(), object)); // flip has occured if (VM.scanning.pointsTo(object, SS.toSpace().getDescriptor())) { @@ -50,6 +54,19 @@ } else { // copying not complete, therefore not flipped yet VM.assertions._assert(Space.isInSpace(SS.toSpace().getDescriptor(), object)); // check in right space + ObjectReference bp = ForwardingWord.getReplicatingFP(object); + if (ForwardingWord.isForwarded(object)) { + VM.assertions._assert(!bp.isNull()); + VM.assertions._assert(Space.isInSpace(SS.fromSpace().getDescriptor(), bp)); + VM.assertions._assert(VM.assertions.validRef(bp)); + // follow BP and then follow FP - hope we end up at the same object! + ObjectReference bpObj = ForwardingWord.getReplicatingFP(bp); + VM.assertions._assert(object == bpObj); + } else { + // an object in toSpace with no fromSpace replica + VM.assertions._assert(bp.isNull()); + VM.objectModel.checkFromSpaceNotYetReplicatedObject(object); + } } } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCFromSpaceLinearSanityScan.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCFromSpaceLinearSanityScan.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCFromSpaceLinearSanityScan.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -13,6 +13,7 @@ package org.mmtk.plan.semispace.incremental; import org.mmtk.policy.Space; +import org.mmtk.utility.ForwardingWord; import org.mmtk.utility.Log; import org.mmtk.utility.alloc.LinearScan; import org.mmtk.vm.VM; @@ -34,11 +35,27 @@ if (!object.isNull()) { // Log.write("Scanning... "); Log.writeln(object); VM.assertions._assert(Space.isInSpace(SS.fromSpace().getDescriptor(), object)); // ensure in right space - if (VM.scanning.pointsToForwardedObjects(object)) { - Log.write("PreGCFromSpaceLinearSanityScan: Object "); - Log.write(object); - Log.writeln(" contained references to a forwarded fromSpace object"); - VM.assertions.fail("Died during linear sanity scan"); + // if (VM.scanning.pointsToForwardedObjects(object)) { + // Log.write("PreGCFromSpaceLinearSanityScan: Object "); + // Log.write(object); + // Log.writeln(" contained references to a forwarded fromSpace object"); + // VM.assertions.fail("Died during linear sanity scan"); + // } + + VM.assertions._assert(!ForwardingWord.isBusy(object)); + + if (ForwardingWord.isForwardedOrBeingForwarded(object)) { + VM.assertions._assert(ForwardingWord.isForwarded(object)); // can't be half way through copying the object + ObjectReference forwarded = ForwardingWord.getReplicatingFP(object); + VM.assertions._assert(Space.isInSpace(SS.toSpace().getDescriptor(), forwarded)); + VM.assertions._assert(!forwarded.isNull()); + VM.assertions._assert(VM.assertions.validRef(forwarded)); + // follow FP and then follow BP - hope we end up at the same object! + ObjectReference bpObj = ForwardingWord.getReplicatingFP(forwarded); + VM.assertions._assert(object == bpObj); + VM.objectModel.checkFromSpaceReplicatedObject(object, forwarded); + } else { + VM.objectModel.checkFromSpaceNotYetReplicatedObject(object); } } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCToSpaceLinearSanityScan.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCToSpaceLinearSanityScan.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/PreGCToSpaceLinearSanityScan.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -12,6 +12,8 @@ */ package org.mmtk.plan.semispace.incremental; +import org.mmtk.policy.Space; +import org.mmtk.utility.ForwardingWord; import org.mmtk.utility.Log; import org.mmtk.utility.alloc.LinearScan; import org.mmtk.vm.VM; @@ -33,11 +35,26 @@ if (!object.isNull()) { VM.assertions._assert(!SS.copyingAllComplete); // If copying is complete space should be empty // Log.write("Scanning... "); Log.writeln(object); - if (VM.scanning.pointsToForwardedObjects(object)) { - Log.write("PreGCToSpaceLinearSanityScan: Object "); - Log.write(object); - Log.writeln(" contained references to a forwarded fromSpace object"); - VM.assertions.fail("Died during linear sanity scan"); + // if (VM.scanning.pointsToForwardedObjects(object)) { + // Log.write("PreGCToSpaceLinearSanityScan: Object "); + // Log.write(object); + // Log.writeln(" contained references to a forwarded fromSpace object"); + // VM.assertions.fail("Died during linear sanity scan"); + // } + + VM.assertions._assert(!ForwardingWord.isBusy(object)); + ObjectReference bp = ForwardingWord.getReplicatingFP(object); + if (ForwardingWord.isForwarded(object)) { + VM.assertions._assert(!bp.isNull()); + VM.assertions._assert(Space.isInSpace(SS.fromSpace().getDescriptor(), bp)); + VM.assertions._assert(VM.assertions.validRef(bp)); + // follow BP and then follow FP - hope we end up at the same object! + ObjectReference bpObj = ForwardingWord.getReplicatingFP(bp); + VM.assertions._assert(object == bpObj); + } else { + // an object in toSpace with no fromSpace replica + VM.assertions._assert(bp.isNull()); + VM.objectModel.checkFromSpaceNotYetReplicatedObject(object); } } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SS.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SS.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SS.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -13,7 +13,7 @@ package org.mmtk.plan.semispace.incremental; import org.mmtk.policy.CopyLocal; -import org.mmtk.policy.CopySpace; +import org.mmtk.policy.ReplicatingSpace; import org.mmtk.policy.Space; import org.mmtk.plan.*; import org.mmtk.utility.heap.VMRequest; @@ -35,12 +35,12 @@ public static boolean low = true; // True if allocing to "lower" semispace /** One of the two semi spaces that alternate roles at each collection */ - public static final CopySpace copySpace0 = new CopySpace("ss0", DEFAULT_POLL_FREQUENCY, VMRequest.create()); - public static final int SS0 = copySpace0.getDescriptor(); + public static final ReplicatingSpace repSpace0 = new ReplicatingSpace("rep-ss0", DEFAULT_POLL_FREQUENCY, VMRequest.create()); + public static final int SS0 = repSpace0.getDescriptor(); /** One of the two semi spaces that alternate roles at each collection */ - public static final CopySpace copySpace1 = new CopySpace("ss1", DEFAULT_POLL_FREQUENCY, VMRequest.create()); - public static final int SS1 = copySpace1.getDescriptor(); + public static final ReplicatingSpace repSpace1 = new ReplicatingSpace("rep-ss1", DEFAULT_POLL_FREQUENCY, VMRequest.create()); + public static final int SS1 = repSpace1.getDescriptor(); public final Trace ssTrace; @@ -78,16 +78,16 @@ * @return The to space for the current collection. */ @Inline - public static CopySpace toSpace() { - return low ? copySpace1 : copySpace0; + public static ReplicatingSpace toSpace() { + return low ? repSpace1 : repSpace0; } /** * @return The from space for the current collection. */ @Inline - public static CopySpace fromSpace() { - return low ? copySpace0 : copySpace1; + public static ReplicatingSpace fromSpace() { + return low ? repSpace0 : repSpace1; } @@ -196,4 +196,12 @@ TransitiveClosure.registerSpecializedScan(SCAN_SS, SSTraceLocal.class); super.registerSpecializedMethods(); } + + public static boolean inFromSpace(Address slot) { + return Space.isInSpace(fromSpace().getDescriptor(), slot); + } + + public static boolean inToSpace(Address slot) { + return Space.isInSpace(toSpace().getDescriptor(), slot); + } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSCollector.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSCollector.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSCollector.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -98,14 +98,22 @@ * @param bytes The size of the space to be allocated (in bytes) */ @Inline - public void postCopy(ObjectReference object, ObjectReference typeRef, + public void postCopy(ObjectReference from, ObjectReference to, ObjectReference typeRef, int bytes, int allocator) { - ForwardingWord.clearForwardingBits(object); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(ForwardingWord.isBusy(to)); + VM.assertions._assert(!ForwardingWord.isForwarded(to)); + } + ForwardingWord.clearForwardingBits(to); + ForwardingWord.setReplicatingBP(from, to); // set back pointer + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!ForwardingWord.isBusy(to)); + } if (allocator == Plan.ALLOC_LOS) - Plan.loSpace.initializeHeader(object, false); + Plan.loSpace.initializeHeader(to, false); if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(getCurrentTrace().isLive(object)); - VM.assertions._assert(getCurrentTrace().willNotMoveInCurrentCollection(object)); + VM.assertions._assert(getCurrentTrace().isLive(to)); + VM.assertions._assert(getCurrentTrace().willNotMoveInCurrentCollection(to)); } } @@ -140,7 +148,7 @@ int copied = trace.getNumObjectsCopied(); if (copied < max) { Log.writeln("Everything copied ", copied); - SS.copyingAllComplete = true; // no more possible objects left to copy + // SS.copyingAllComplete = true; // no more possible objects left to copy } return; } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSConstraints.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSConstraints.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSConstraints.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -13,7 +13,7 @@ package org.mmtk.plan.semispace.incremental; import org.mmtk.plan.*; -import org.mmtk.policy.CopySpace; +import org.mmtk.policy.ReplicatingSpace; import org.vmmagic.pragma.*; @Uninterruptible @@ -21,11 +21,82 @@ @Override public boolean movesObjects() { return true; } @Override - public int gcHeaderBits() { return CopySpace.LOCAL_GC_BITS_REQUIRED; } + public int gcHeaderBits() { + return ReplicatingSpace.LOCAL_GC_BITS_REQUIRED; + } @Override - public int gcHeaderWords() { return CopySpace.GC_HEADER_WORDS_REQUIRED; } + public int gcHeaderWords() { + return ReplicatingSpace.GC_HEADER_WORDS_REQUIRED; + } @Override public int numSpecializedScans() { return 1; } - public boolean needsObjectReferenceReadBarrier() { return true; } + public boolean needsObjectReferenceReadBarrier() { return false; } + + // LPJH: later implement bulkCopy support + + /** @return True if this Plan replicates objects */ + public boolean replicatingGC() { return true;} + + /** @return True if this Plan requires write barriers on booleans. */ + public boolean needsBooleanWriteBarrier() { return true; } + + /** @return True if this Plan can perform bulk boolean arraycopy barriers. */ + public boolean booleanBulkCopySupported() { return false; } + + /** @return True if this Plan requires write barriers on bytes. */ + public boolean needsByteWriteBarrier() { return true; } + + /** @return True if this Plan can perform bulk byte arraycopy barriers. */ + public boolean byteBulkCopySupported() { return false; } + + /** @return True if this Plan requires write barriers on chars. */ + public boolean needsCharWriteBarrier() { return true; } + + /** @return True if this Plan can perform bulk char arraycopy barriers. */ + public boolean charBulkCopySupported() { return false; } + + /** @return True if this Plan requires write barriers on shorts. */ + public boolean needsShortWriteBarrier() { return true; } + + /** @return True if this Plan can perform bulk short arraycopy barriers. */ + public boolean shortBulkCopySupported() { return false; } + + /** @return True if this Plan requires write barriers on ints. */ + public boolean needsIntWriteBarrier() { return true; } + + /** @return True if this Plan can perform bulk int arraycopy barriers. */ + public boolean intBulkCopySupported() { return false; } + + /** @return True if this Plan requires write barriers on longs. */ + public boolean needsLongWriteBarrier() { return true; } + + /** @return True if this Plan can perform bulk long arraycopy barriers. */ + public boolean longBulkCopySupported() { return false; } + + /** @return True if this Plan requires write barriers on floats. */ + public boolean needsFloatWriteBarrier() { return true; } + + /** @return True if this Plan can perform bulk float arraycopy barriers. */ + public boolean floatBulkCopySupported() { return false; } + + /** @return True if this Plan requires write barriers on doubles. */ + public boolean needsDoubleWriteBarrier() { return true; } + + /** @return True if this Plan can perform bulk double arraycopy barriers. */ + public boolean doubleBulkCopySupported() { return false; } + + /** @return True if this Plan requires write barriers on Words. */ + public boolean needsWordWriteBarrier() { return true; } + + /** @return True if this Plan requires write barriers on Address's. */ + public boolean needsAddressWriteBarrier() { return true; } + + /** @return True if this Plan requires write barriers on Extents. */ + public boolean needsExtentWriteBarrier() { return true; } + + /** @return True if this Plan requires write barriers on Offsets. */ + public boolean needsOffsetWriteBarrier() { return true; } + + /** @return True if this Plan requires write barriers on object references. */ public boolean needsObjectReferenceWriteBarrier() { return true; } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSMutator.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSMutator.java 2010-07-28 13:38:53 UTC (rev 15959) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/semispace/incremental/SSMutator.java 2010-07-31 11:36:56 UTC (rev 15960) @@ -110,7 +110,8 @@ * if no appropriate allocator can be established. */ public Allocator getAllocatorFromSpace(Space space) { - if (space == SS.copySpace0 || space == SS.copySpace1) return ss; + if (space == SS.repSpace0 || space == SS.repSpace1) + return ss; return super.getAllocatorFromSpace(space); } @@ -185,6 +186,621 @@ } /** + * Write a boolean. Take appropriate write barrier actions. + * <p> + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param value The value of the new boolean + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + */ + public void booleanWrite(ObjectReference src, Address slot, boolean value, Word metaDataA, Word metaDataB, int mode) { + VM.barriers.booleanWrite(src, value, metaDataA, metaDataB, mode); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!Space.isInSpace(SS.toSpace().getDescriptor(), slot)); + } + if (SS.inFromSpace(slot)) { + // writing to an object in Sapphire fromSpace - it might be replicated + ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); + if (forwarded != null) { + if (VM.VERIFY_ASSERTIONS) + VM.assertions._assert(ForwardingWord.isForwarded(src)); + VM.barriers.booleanWrite(forwarded, value, metaDataA, metaDataB, mode); + } + } + } + + /** + * A number of booleans are about to be copied from object <code>src</code> to object <code>dst</code> (as in an array copy). + * Thus, <code>dst</code> is the mutated object. Take appropriate write barrier actions. + * <p> + * @param src The source array + * @param srcOffset The starting source offset + * @param dst The destination array + * @param dstOffset The starting destination offset + * @param bytes The number of bytes to be copied + * @return True if the update was performed by the barrier, false if left to the caller + */ + public boolean booleanBulkCopy(ObjectReference src, Offset srcOffset, ObjectReference dst, Offset dstOffset, int bytes) { + // Not actually called yet - something to optimise later + return false; + } + + /** + * Write a byte. Take appropriate write barrier actions. + * <p> + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param value The value of the new byte + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + */ + public void byteWrite(ObjectReference src, Address slot, byte value, Word metaDataA, Word metaDataB, int mode) { + VM.barriers.byteWrite(src, value, metaDataA, metaDataB, mode); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!Space.isInSpace(SS.toSpace().getDescriptor(), slot)); + } + if (SS.inFromSpace(slot)) { + // writing to an object in Sapphire fromSpace - it might be replicated + ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); + if (forwarded != null) { + if (VM.VERIFY_ASSERTIONS) + VM.assertions._assert(ForwardingWord.isForwarded(src)); + VM.barriers.byteWrite(forwarded, value, metaDataA, metaDataB, mode); + } + } + } + + /** + * A number of bytes are about to be copied from object <code>src</code> to object <code>dst</code> (as in an array copy). Thus, + * <code>dst</code> is the mutated object. Take appropriate write barrier actions. + * <p> + * @param src The source array + * @param srcOffset The starting source offset + * @param dst The destination array + * @param dstOffset The starting destination offset + * @param bytes The number of bytes to be copied + * @return True if the update was performed by the barrier, false if left to the caller + */ + public boolean byteBulkCopy(ObjectReference src, Offset srcOffset, ObjectReference dst, Offset dstOffset, int bytes) { + // Not actually called yet - something to optimise later + return false; + } + + /** + * Write a char. Take appropriate write barrier actions. + * <p> + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param value The value of the new char + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + */ + public void charWrite(ObjectReference src, Address slot, char value, Word metaDataA, Word metaDataB, int mode) { + VM.barriers.charWrite(src, value, metaDataA, metaDataB, mode); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!Space.isInSpace(SS.toSpace().getDescriptor(), slot)); + } + if (SS.inFromSpace(slot)) { + // writing to an object in Sapphire fromSpace - it might be replicated + ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); + if (forwarded != null) { + if (VM.VERIFY_ASSERTIONS) + VM.assertions._assert(ForwardingWord.isForwarded(src)); + VM.barriers.charWrite(forwarded, value, metaDataA, metaDataB, mode); + } + } + } + + /** + * A number of chars are about to be copied from object <code>src</code> to object <code>dst</code> (as in an array copy). Thus, + * <code>dst</code> is the mutated object. Take appropriate write barrier actions. + * <p> + * @param src The source array + * @param srcOffset The starting source offset + * @param dst The destination array + * @param dstOffset The starting destination offset + * @param bytes The number of bytes to be copied + * @return True if the update was performed by the barrier, false if left to the caller + */ + public boolean charBulkCopy(ObjectReference src, Offset srcOffset, ObjectReference dst, Offset dstOffset, int bytes) { + // Not actually called yet - something to optimise later + return false; + } + + /** + * Write a double. Take appropriate write barrier actions. + * <p> + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param value The value of the new double + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + */ + public void doubleWrite(ObjectReference src, Address slot, double value, Word metaDataA, Word metaDataB, int mode) { + VM.barriers.doubleWrite(src, value, metaDataA, metaDataB, mode); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!Space.isInSpace(SS.toSpace().getDescriptor(), slot)); + } + if (SS.inFromSpace(slot)) { + // writing to an object in Sapphire fromSpace - it might be replicated + ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); + if (forwarded != null) { + if (VM.VERIFY_ASSERTIONS) + VM.assertions._assert(ForwardingWord.isForwarded(src)); + VM.barriers.doubleWrite(forwarded, value, metaDataA, metaDataB, mode); + } + } + } + + /** + * A number of doubles are about to be copied from object <code>src</code> to object <code>dst</code> (as in an array copy). Thus, + * <code>dst</code> is the mutated object. Take appropriate write barrier actions. + * <p> + * @param src The source array + * @param srcOffset The starting source offset + * @param dst The destination array + * @param dstOffset The starting destination offset + * @param bytes The number of bytes to be copied + * @return True if the update was performed by the barrier, false if left to the caller + */ + public boolean doubleBulkCopy(ObjectReference src, Offset srcOffset, ObjectReference dst, Offset dstOffset, int bytes) { + // Not actually called yet - something to optimise later + return false; + } + + /** + * Write a float. Take appropriate write barrier actions. + * <p> + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param value The value of the new float + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + */ + public void floatWrite(ObjectReference src, Address slot, float value, Word metaDataA, Word metaDataB, int mode) { + VM.barriers.floatWrite(src, value, metaDataA, metaDataB, mode); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!Space.isInSpace(SS.toSpace().getDescriptor(), slot)); + } + if (SS.inFromSpace(slot)) { + // writing to an object in Sapphire fromSpace - it might be replicated + ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); + if (forwarded != null) { + if (VM.VERIFY_ASSERTIONS) + VM.assertions._assert(ForwardingWord.isForwarded(src)); + VM.barriers.floatWrite(forwarded, value, metaDataA, metaDataB, mode); + } + } + } + + /** + * A number of floats are about to be copied from object <code>src</code> to object <code>dst</code> (as in an array copy). Thus, + * <code>dst</code> is the mutated object. Take appropriate write barrier actions. + * <p> + * @param src The source array + * @param srcOffset The starting source offset + * @param dst The destination array + * @param dstOffset The starting destination offset + * @param bytes The number of bytes to be copied + * @return True if the update was performed by the barrier, false if left to the caller + */ + public boolean floatBulkCopy(ObjectReference src, Offset srcOffset, ObjectReference dst, Offset dstOffset, int bytes) { + // Not actually called yet - something to optimise later + return false; + } + + /** + * Write a int. Take appropriate write barrier actions. + * <p> + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param value The value of the new int + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + */ + public void intWrite(ObjectReference src, Address slot, int value, Word metaDataA, Word metaDataB, int mode) { + VM.barriers.intWrite(src, value, metaDataA, metaDataB, mode); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!Space.isInSpace(SS.toSpace().getDescriptor(), slot)); + } + if (SS.inFromSpace(slot)) { + // writing to an object in Sapphire fromSpace - it might be replicated + ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); + if (forwarded != null) { + if (VM.VERIFY_ASSERTIONS) + VM.assertions._assert(ForwardingWord.isForwarded(src)); + VM.barriers.intWrite(forwarded, value, metaDataA, metaDataB, mode); + } + } + } + + /** + * A number of ints are about to be copied from object <code>src</code> to object <code>dst</code> (as in an array copy). Thus, + * <code>dst</code> is the mutated object. Take appropriate write barrier actions. + * <p> + * @param src The source array + * @param srcOffset The starting source offset + * @param dst The destination array + * @param dstOffset The starting destination offset + * @param bytes The number of bytes to be copied + * @return True if the update was performed by the barrier, false if left to the caller + */ + public boolean intBulkCopy(ObjectReference src, Offset srcOffset, ObjectReference dst, Offset dstOffset, int bytes) { + // Not actually called yet - something to optimise later + return false; + } + + /** + * Attempt to atomically exchange the value in the given slot with the passed replacement value. + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param old The old int to be swapped out + * @param value The new int + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + * @return True if the swap was successful. + */ + public boolean intTryCompareAndSwap(ObjectReference src, Address slot, int old, int value, Word metaDataA, Word metaDataB, + int mode) { + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!Space.isInSpace(SS.toSpace().getDescriptor(), slot)); + if (SS.inFromSpace(slot)) + VM.assertions.fail("Warning attempting intTryCompareAndSwap on object in Sapphire fromSpace"); + } + return VM.barriers.intTryCompareAndSwap(src, old, value, metaDataA, metaDataB, mode); + } + + /** + * Write a long. Take appropriate write barrier actions. + * <p> + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param value The value of the new long + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + */ + public void longWrite(ObjectReference src, Address slot, long value, Word metaDataA, Word metaDataB, int mode) { + VM.barriers.longWrite(src, value, metaDataA, metaDataB, mode); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!Space.isInSpace(SS.toSpace().getDescriptor(), slot)); + } + if (SS.inFromSpace(slot)) { + // writing to an object in Sapphire fromSpace - it might be replicated + ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); + if (forwarded != null) { + if (VM.VERIFY_ASSERTIONS) + VM.assertions._assert(ForwardingWord.isForwarded(src)); + VM.barriers.longWrite(forwarded, value, metaDataA, metaDataB, mode); + } + } + } + + /** + * A number of longs are about to be copied from object <code>src</code> to object <code>dst</code> (as in an array copy). Thus, + * <code>dst</code> is the mutated object. Take appropriate write barrier actions. + * <p> + * @param src The source array + * @param srcOffset The starting source offset + * @param dst The destination array + * @param dstOffset The starting destination offset + * @param bytes The number of bytes to be copied + * @return True if the update was performed by the barrier, false if left to the caller + */ + public boolean longBulkCopy(ObjectReference src, Offset srcOffset, ObjectReference dst, Offset dstOffset, int bytes) { + // Not actually called yet - something to optimise later + return false; + } + + /** + * Attempt to atomically exchange the value in the given slot with the passed replacement value. + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param old The old long to be swapped out + * @param value The new long + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + * @return True if the swap was successful. + */ + public boolean longTryCompareAndSwap(ObjectReference src, Address slot, long old, long value, Word metaDataA, Word metaDataB, + int mode) { + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!Space.isInSpace(SS.toSpace().getDescriptor(), slot)); + if (SS.inFromSpace(slot)) + VM.assertions.fail("Warning attempting longTryCompareAndSwap on object in Sapphire fromSpace"); + } + return VM.barriers.longTryCompareAndSwap(src, old, value, metaDataA, metaDataB, mode); + } + + /** + * Write a short. Take appropriate write barrier actions. + * <p> + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param value The value of the new short + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + */ + public void shortWrite(ObjectReference src, Address slot, short value, Word metaDataA, Word metaDataB, int mode) { + VM.barriers.shortWrite(src, value, metaDataA, metaDataB, mode); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!Space.isInSpace(SS.toSpace().getDescriptor(), slot)); + } + if (SS.inFromSpace(slot)) { + // writing to an object in Sapphire fromSpace - it might be replicated + ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); + if (forwarded != null) { + if (VM.VERIFY_ASSERTIONS) + VM.assertions._assert(ForwardingWord.isForwarded(src)); + VM.barriers.shortWrite(forwarded, value, metaDataA, metaDataB, mode); + } + } + } + + /** + * A number of shorts are about to be copied from object <code>src</code> to object <code>dst</code> (as in an array copy). Thus, + * <code>dst</code> is the mutated object. Take appropriate write barrier actions. + * <p> + * @param src The source array + * @param srcOffset The starting source offset + * @param dst The destination array + * @param dstOffset The starting destination offset + * @param bytes The number of bytes to be copied + * @return True if the update was performed by the barrier, false if left to the caller + */ + public boolean shortBulkCopy(ObjectReference src, Offset srcOffset, ObjectReference dst, Offset dstOffset, int bytes) { + // Not actually called yet - something to optimise later + return false; + } + + /** + * Write a Word. Take appropriate write barrier actions. + * <p> + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param value The value of the new Word + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + */ + public void wordWrite(ObjectReference src, Address slot, Word value, Word metaDataA, Word metaDataB, int mode) { + VM.barriers.wordWrite(src, value, metaDataA, metaDataB, mode); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!Space.isInSpace(SS.toSpace().getDescriptor(), slot)); + } + if (SS.inFromSpace(slot)) { + // writing to an object in Sapphire fromSpace - it might be replicated + ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); + if (forwarded != null) { + if (VM.VERIFY_ASSERTIONS) + VM.assertions._assert(ForwardingWord.isForwarded(src)); + VM.barriers.wordWrite(forwarded, value, metaDataA, metaDataB, mode); + } + } + } + + /** + * Write a Word during GC into toSpace. Take appropriate write barrier actions. + * <p> + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param value The value of the new Word + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + */ + public void wordWriteDuringGC(ObjectReference src, Address slot, Word value, Word metaDataA, Word metaDataB, int mode) { + VM.barriers.wordWrite(src, value, metaDataA, metaDataB, mode); + // during GC might have a reference to toSpace, avoid certain assertions + if (SS.inFromSpace(slot)) { + // writing to an object in Sapphire fromSpace - it might be replicated + ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); + if (forwarded != null) { + if (VM.VERIFY_ASSERTIONS) + VM.assertions._assert(ForwardingWord.isForwarded(src)); + // object is already forwarded, update both copies and return + VM.barriers.wordWrite(forwarded, value, metaDataA, metaDataB, mode); + } + } + } + + /** + * Attempt to atomically exchange the value in the given slot with the passed replacement value. + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param old The old long to be swapped out + * @param value The new long + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + * @return True if the swap was successful. + */ + public boolean wordTryCompareAndSwap(ObjectReference src, Address slot, Word old, Word value, Word metaDataA, Word metaDataB, + int mode) { + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!SS.inToSpace(slot)); + VM.assertions._assert(!SS.inFromSpace(slot), "Warning attempting wordTryCompareAndSwap on object in Sapphire fromSpace"); + } + return VM.barriers.wordTryCompareAndSwap(src, old, value, metaDataA, metaDataB, mode); + } + + /** + * Attempt to atomically exchange the value in the given slot with the passed replacement value. + * @param src The object into which the new reference will be stored + * @param slot The address into which the new reference will be stored. + * @param old The old long to be swapped out + * @param value The new long + * @param metaDataA A value that assists the host VM in creating a store + * @param metaDataB A value that assists the host VM in creating a store + * @param mode The context in which the store occurred + * @return True if the swap was successful. + */ + /* + * Stuff for address based hashing LPJH: nasty quick hack + */Word HASH_STATE_UNHASHED = Word.zero(); + Word HASH_STATE_HASHED = Word.one().lsh(8); // 0x00000100 + Word HASH_STATE_HASHED_AND_MOVED = Word.fromIntZeroExtend(3).lsh(8); // 0x0000300 + Word HASH_STATE_MASK = HASH_STATE_UNHASHED.or(HASH_STATE_HASHED).or(HASH_STATE_HASHED_AND_MOVED); + + public boolean wordTryCompareAndSwapInLock(ObjectReference src, Address slot, Word old, Word value, Word metaDataA, + Word metaDataB, int mode) { + // LPJH: rename this and other methods *statusWord + // does not need to be replicated (used for locking) + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!SS.inToSpace(slot)); + } + if (SS.inFromSpace(slot)) { + // in possibly replicated fromSpace + // mark object as being forwarded, attempt fromSpace write, if successful and has FP then do forwarded write + // (preserving hash bits) + ForwardingWord.markBusy(src); + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(SS.inFromSpace(slot)); + VM.assertions._assert(ForwardingWord.isBusy(src)); + } + old = old.or(Word.fromIntZeroExtend(ForwardingWord.BUSY)); + value = value.or(Word.fromIntZeroExtend(ForwardingWord.BUSY)); + if (VM.barriers.wordTryCompareAndSwap(src, old, value, metaDataA, metaDataB, mode)) { + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(ForwardingWord.isBusy(src)); + } + // cas succeeded update any replica + ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); + if (forwarded != null) { + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(ForwardingWord.isForwarded(src)); + VM.assertions._assert(SS.inToSpace(forwarded.toAddress())); + VM.assertions._assert(!ForwardingWord.isBusy(forwarded)); + // check that the hash status is correct in replica before we consider rewriting it + // (ensure hashcode status updates go via this barrier) + Word fromStatusWord = VM.objectModel.readAvailableBitsWord(src); + if (fromStatusWord.and(HASH_STATE_MASK).EQ(HASH_STATE_HASHED)) { + Word toStatusWord = VM.objectModel.readAvailableBitsWord(forwarded); + VM.assertions._assert(toStatusWord.and(HASH_STATE_MASK).EQ(HASH_STATE_HASHED_AND_MOVED)); + } + } + // object is already forwarded, update copy with difference between old and value + Word diff = old.xor(value); + Word toSpaceStatusWord = VM.objectModel.readAvailableBitsWord(forwarded); + VM.barriers.wordWrite(forwarded, toSpaceStatusWord.xor(diff), metaDataA, metaDataB, mode); + // LPJH: do we need a StoreLoad fence here? + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!ForwardingWord.isBusy(forwarded)); + Word fromStatusWord = VM.objectModel.readAvailableBitsWord(src); + if (fromStatusWord.and(HASH_STATE_MASK).EQ(HASH_STATE_HASHED)) { + Word toStatusWord = VM.objectModel.readAvailableBitsWord(forwarded); + VM.assertions._assert(toStatusWord.and(HASH_STATE_MASK).EQ(HASH_STATE_HASHED_AND_MOVED)); + } + } + } + ForwardingWord.markNotBusy(src); + return true; + } else { + // failed to update statusWord, unmark busy state + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(ForwardingWord.isBusy(src)); + } + ForwardingWord.markNotBusy(src); + return false; + } + } else { + if (VM.VERIFY_ASSERTIONS) { + VM.assertions._assert(!SS.inToSpace(slot)); + VM.assertions._assert(!SS.inFromSpace(slot)); + } + return VM.barriers.wordTryCompareAndSwap(src, old, value, metaDataA, metaDataB, mode); + } + } + + /** + * Write a Address. Take appropriate write barrier actions. + * <p> +... [truncated message content] |
From: <lhe...@us...> - 2010-09-17 09:45:43
|
Revision: 15994 http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=15994&view=rev Author: lhellyer Date: 2010-09-17 09:45:36 +0000 (Fri, 17 Sep 2010) Log Message: ----------- Improve safety of some assertions Merge commits up to fa385488af164f089cf6dad523247717faf9b769 Modified Paths: -------------- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/Sapphire.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireMutator.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireTraceLocalFirst.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireTraceLocalSecond.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/ReplicatingSpace.java rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/ForwardingWord.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/objectmodel/JavaHeader.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/runtime/Magic.java rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/ThinLock.java Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/Sapphire.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/Sapphire.java 2010-09-17 09:44:53 UTC (rev 15993) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/Sapphire.java 2010-09-17 09:45:36 UTC (rev 15994) @@ -225,11 +225,11 @@ } public static boolean inFromSpace(ObjectReference obj) { - return inFromSpace(obj.toAddress()); + return inFromSpace(VM.objectModel.refToAddress(obj)); } public static boolean inToSpace(ObjectReference obj) { - return inToSpace(obj.toAddress()); + return inToSpace(VM.objectModel.refToAddress(obj)); } public static boolean inFromSpace(Address slot) { Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireMutator.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireMutator.java 2010-09-17 09:44:53 UTC (rev 15993) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireMutator.java 2010-09-17 09:45:36 UTC (rev 15994) @@ -236,7 +236,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.booleanWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -278,7 +278,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.byteWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -320,7 +320,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.charWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -362,7 +362,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.doubleWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -404,7 +404,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.floatWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -446,7 +446,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.intWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -509,7 +509,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.longWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -572,7 +572,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.shortWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -614,7 +614,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.wordWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -643,7 +643,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); // object is already forwarded, update both copies and return VM.barriers.wordWrite(forwarded, value, metaDataA, metaDataB, mode); } @@ -664,7 +664,7 @@ public boolean wordTryCompareAndSwap(ObjectReference src, Address slot, Word old, Word value, Word metaDataA, Word metaDataB, int mode) { if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(!Sapphire.inToSpace(slot)); + VM.assertions._assert(!Sapphire.inToSpace(slot), "Warning attempting wordTryCompareAndSwap on object in Sapphire toSpace"); VM.assertions._assert(!Sapphire.inFromSpace(slot), "Warning attempting wordTryCompareAndSwap on object in Sapphire fromSpace"); } return VM.barriers.wordTryCompareAndSwap(src, old, value, metaDataA, metaDataB, mode); @@ -689,7 +689,6 @@ Word HASH_STATE_MASK = HASH_STATE_UNHASHED.or(HASH_STATE_HASHED).or(HASH_STATE_HASHED_AND_MOVED); public boolean tryStatusWordCompareAndSwap(ObjectReference src, Word old, Word value) { - // LPJH: rename this and other methods *statusWord // does not need to be replicated (used for locking) if (VM.VERIFY_ASSERTIONS) { VM.assertions._assert(!Sapphire.inToSpace(src)); @@ -713,7 +712,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.assertions._assert(!ForwardingWord.isBusy(forwarded)); // toSpace should not be marked busy // check that the hash status is correct in replica before we consider rewriting it // (ensure hashcode status updates go via this barrier) @@ -721,8 +720,11 @@ Word toStatusHashState = VM.objectModel.readAvailableBitsWord(forwarded).and(HASH_STATE_MASK); if (fromStatusHashState.EQ(HASH_STATE_HASHED)) { VM.assertions._assert(toStatusHashState.EQ(HASH_STATE_HASHED_AND_MOVED)); + } else if (fromStatusHashState.EQ(HASH_STATE_HASHED_AND_MOVED)) { + VM.assertions._assert(toStatusHashState.EQ(HASH_STATE_HASHED_AND_MOVED)); } else { // toSpace might be marked hashed and fromSpace might not be marked at all + // nothing else to assert } } // object is already forwarded, update copy with difference between old and value @@ -731,21 +733,24 @@ do { toSpaceStatusWord = VM.objectModel.readAvailableBitsWord(forwarded); } while (!VM.barriers.statusWordTryCompareAndSwap(forwarded, toSpaceStatusWord, toSpaceStatusWord.xor(diff))); // LPJH: optimise this stupid making a CAS when we don't have to - // LPJH: do we need a StoreLoad fence here? + // LPJH: do we need a StoreLoad fence here? not whilst the above is atomic if (VM.VERIFY_ASSERTIONS) { VM.assertions._assert(!ForwardingWord.isBusy(forwarded)); Word fromStatusHashState = VM.objectModel.readAvailableBitsWord(src).and(HASH_STATE_MASK); Word toStatusHashState = VM.objectModel.readAvailableBitsWord(forwarded).and(HASH_STATE_MASK); if (fromStatusHashState.EQ(HASH_STATE_HASHED)) { VM.assertions._assert(toStatusHashState.EQ(HASH_STATE_HASHED_AND_MOVED)); + } else if (fromStatusHashState.EQ(HASH_STATE_HASHED_AND_MOVED)) { + VM.assertions._assert(toStatusHashState.EQ(HASH_STATE_HASHED_AND_MOVED)); } else { // toSpace might be marked hashed and fromSpace might not be marked at all + // nothing else to assert } } } // if (VM.VERIFY_ASSERTIONS) // VM.assertions._assert(ForwardingWord.isBusy(src)); - ForwardingWord.markNotBusy(src, debugPrevValue); + ForwardingWord.markNotBusy(src, value); return true; } else { // failed to update statusWord, unmark busy state @@ -785,7 +790,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.addressWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -811,7 +816,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.extentWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -837,7 +842,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.offsetWrite(forwarded, value, metaDataA, metaDataB, mode); } } @@ -891,7 +896,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(src); if (forwarded != null) { if (VM.VERIFY_ASSERTIONS) - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.barriers.objectReferenceWrite(forwarded, value, metaDataA, metaDataB, mode); } } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireTraceLocalFirst.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireTraceLocalFirst.java 2010-09-17 09:44:53 UTC (rev 15993) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireTraceLocalFirst.java 2010-09-17 09:45:36 UTC (rev 15994) @@ -81,7 +81,7 @@ if (Space.isInSpace(Sapphire.fromSpace().getDescriptor(), object)) { ObjectReference obj = Sapphire.fromSpace().traceObject(this, object, Sapphire.ALLOC_SS, true); if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inFromSpace(obj.toAddress())); + VM.assertions._assert(Sapphire.inFromSpace(obj)); } return obj; } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireTraceLocalSecond.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireTraceLocalSecond.java 2010-09-17 09:44:53 UTC (rev 15993) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/plan/sapphire/SapphireTraceLocalSecond.java 2010-09-17 09:45:36 UTC (rev 15994) @@ -80,14 +80,14 @@ if (Space.isInSpace(Sapphire.fromSpace().getDescriptor(), object)) { ObjectReference obj = Sapphire.fromSpace().traceObject2(this, object, Sapphire.ALLOC_SS, true); if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inToSpace(obj.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(obj)); } return obj; } if (Space.isInSpace(Sapphire.toSpace().getDescriptor(), object)) { ObjectReference obj = Sapphire.toSpace().traceObject2(this, object, Sapphire.ALLOC_SS, false); if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inToSpace(obj.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(obj)); } return obj; } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/ReplicatingSpace.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/ReplicatingSpace.java 2010-09-17 09:44:53 UTC (rev 15993) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/policy/ReplicatingSpace.java 2010-09-17 09:45:36 UTC (rev 15994) @@ -110,7 +110,7 @@ ObjectReference forwarded = ForwardingWord.getReplicatingFP(object); if (!forwarded.isNull()) { if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.assertions._assert(isLive(object)); } return object; // return fromSpace reference @@ -123,7 +123,7 @@ // we are designated copier ObjectReference newObject = VM.objectModel.copy(object, allocator); // LPJH: this needs optimising (this is doing the copy) if (VM.VERIFY_ASSERTIONS) { - if (!Sapphire.inToSpace(newObject.toAddress())) { + if (!Sapphire.inToSpace(newObject)) { Log.writeln("Copy returned an object with an address not in toSpace:"); Log.writeln(newObject.toAddress()); Space.printVMMap(); @@ -134,7 +134,7 @@ if (VM.VERIFY_ASSERTIONS) { VM.assertions._assert(ForwardingWord.isBusy(object)); VM.assertions._assert(!newObject.isNull()); - VM.assertions._assert(Sapphire.inToSpace(newObject.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(newObject)); VM.assertions._assert(isLive(object)); if (Options.verbose.getValue() >= 9) { Log.write("Trace 1 C["); @@ -156,7 +156,7 @@ if (VM.VERIFY_ASSERTIONS) { VM.assertions._assert(ForwardingWord.isBusy(object)); VM.assertions._assert(!ForwardingWord.isBusy(forwarded)); // toSpace should not be busy - VM.assertions._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(forwarded)); VM.assertions._assert(isLive(object)); } ForwardingWord.markNotBusy(object); @@ -184,7 +184,7 @@ /* If the object in question is already in to-space, then do nothing */ if (!fromSpace) { if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inToSpace(object.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(object)); VM.assertions._assert(!ForwardingWord.isBusy(object)); // toSpace should not be marked busy if (Options.verbose.getValue() >= 9) { Log.write("2 Tracing ToSpace... "); Log.writeln(object); @@ -212,7 +212,7 @@ /* Now extract the object reference from the forwarding word and return it */ ObjectReference obj = ForwardingWord.getReplicatingFP(object); if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inToSpace(obj.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(obj)); VM.assertions._assert(isLive(object)); VM.assertions._assert(!ForwardingWord.isBusy(object)); } @@ -225,7 +225,7 @@ // LPJH: must add copying logic here ObjectReference newObject = ForwardingWord.getReplicatingFP(object); if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inToSpace(newObject.toAddress())); + VM.assertions._assert(Sapphire.inToSpace(newObject)); VM.assertions._assert(isLive(object)); VM.assertions._assert(!ForwardingWord.isBusy(object)); // we should have never set BUSY flag } Modified: rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/ForwardingWord.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/ForwardingWord.java 2010-09-17 09:44:53 UTC (rev 15993) +++ rvmroot/branches/RVM-893-Sapphire/work/MMTk/src/org/mmtk/utility/ForwardingWord.java 2010-09-17 09:45:36 UTC (rev 15994) @@ -13,6 +13,7 @@ package org.mmtk.utility; import org.mmtk.plan.sapphire.Sapphire; +import org.mmtk.policy.Space; import org.mmtk.vm.VM; import org.vmmagic.pragma.Inline; import org.vmmagic.pragma.Uninterruptible; @@ -85,7 +86,7 @@ public static Word atomicMarkBusy(ObjectReference object) { if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inFromSpace(object.toAddress())); + VM.assertions._assert(Sapphire.inFromSpace(object)); } Word oldValue; do { @@ -93,12 +94,13 @@ if ((byte) (oldValue.toInt() & BUSY_MASK) == BUSY) continue; } while (!VM.objectModel.attemptAvailableBits(object, oldValue, oldValue.or(Word.fromIntZeroExtend(BUSY)))); + if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(isBusy(object)); return oldValue.or(Word.fromIntZeroExtend(BUSY)); } public static void nonAtomicMarkForwarded(ObjectReference object) { if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inFromSpace(object.toAddress())); + VM.assertions._assert(Sapphire.inFromSpace(object)); } Word oldValue = VM.objectModel.readAvailableBitsWord(object); if (VM.VERIFY_ASSERTIONS) @@ -108,7 +110,7 @@ public static void markNotBusy(ObjectReference object) { if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inFromSpace(object.toAddress())); + VM.assertions._assert(Sapphire.inFromSpace(object)); VM.assertions._assert(isBusy(object)); } Word oldValue = VM.objectModel.readAvailableBitsWord(object); @@ -117,11 +119,15 @@ public static void markNotBusy(ObjectReference object, Word lastValue) { if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inFromSpace(object.toAddress())); + VM.assertions._assert(Sapphire.inFromSpace(object)); if(!isBusy(object)) { Log.writeln("Oh dear object should still be marked busy and is not"); - Log.write("Previous value was "); Log.writeln(lastValue); + Log.write("Last known value was "); Log.writeln(lastValue); Log.write("Current value is "); Log.writeln(VM.objectModel.readAvailableBitsWord(object)); + Log.write("Address of object is "); Log.writeln(object); + Log.flush(); + Space.printVMMap(); + VM.assertions.dumpStack(); VM.assertions.fail("DEAD"); } } @@ -167,8 +173,8 @@ public static void setReplicatingFP(ObjectReference fromSpace, ObjectReference toSpace) { // busy should be set for us, write FP, cancel busy then set FORWARDED if (VM.VERIFY_ASSERTIONS) { - VM.assertions._assert(Sapphire.inFromSpace(fromSpace.toAddress())); - VM.assertions._assert(!Sapphire.inFromSpace(toSpace.toAddress())); // toSpace might be los or some other space + VM.assertions._assert(Sapphire.inFromSpace(fromSpace)); + VM.assertions._assert(!Sapphire.inFromSpace(toSpace)); // toSpace might be los or some other space VM.assertions._assert(isBusy(fromSpace)); VM.assertions._assert(!isForwarded(fromSpace)); VM.assertions._assert(!isBusy(toSpace)); Modified: rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/objectmodel/JavaHeader.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/objectmodel/JavaHeader.java 2010-09-17 09:44:53 UTC (rev 15993) +++ rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/objectmodel/JavaHeader.java 2010-09-17 09:45:36 UTC (rev 15994) @@ -494,15 +494,15 @@ @Inline public static int getObjectHashCode(Object o) { if (VM.VerifyAssertions) { - VM._assert(!Sapphire.inToSpace(ObjectReference.fromObject(o).toAddress())); + VM._assert(!Sapphire.inToSpace(ObjectReference.fromObject(o))); } if (ADDRESS_BASED_HASHING) { if (MemoryManagerConstants.MOVES_OBJECTS) { - Word forwardedHashState = Magic.getWordAtOffset(o, STATUS_OFFSET).and(HASH_STATE_MASK); - if (forwardedHashState.EQ(HASH_STATE_HASHED)) { + Word originalHashState = Magic.getWordAtOffset(o, STATUS_OFFSET).and(HASH_STATE_MASK); + if (originalHashState.EQ(HASH_STATE_HASHED)) { // HASHED, NOT MOVED return Magic.objectAsAddress(o).toWord().rshl(SizeConstants.LOG_BYTES_IN_ADDRESS).toInt(); - } else if (forwardedHashState.EQ(HASH_STATE_HASHED_AND_MOVED)) { + } else if (originalHashState.EQ(HASH_STATE_HASHED_AND_MOVED)) { // HASHED AND MOVED if (DYNAMIC_HASH_OFFSET) { // Read the size of this object. @@ -518,7 +518,7 @@ // UNHASHED // at least the fromSpace object isn't hashed, maybe a toSpace replica exists, if so we should return the address of that // object as it does not have the room to store the hash at a dynamic offset - if (!Sapphire.inFromSpace(ObjectReference.fromObject(o).toAddress())) { + if (!Sapphire.inFromSpace(ObjectReference.fromObject(o))) { // not in fromSpace Word tmp; do { @@ -532,29 +532,28 @@ // lock object, then check if possible replica ObjectReference obj = ObjectReference.fromObject(o); if (VM.VerifyAssertions) { - VM._assert(Sapphire.inFromSpace(obj.toAddress())); + VM._assert(Sapphire.inFromSpace(obj)); } ObjectReference forwarded = ForwardingWord.getReplicatingFP(obj); if (forwarded != null) { // already forwarded (but forwarded bit might not be set in status word) if (VM.VerifyAssertions) { - VM._assert(Sapphire.inToSpace(forwarded.toAddress())); + VM._assert(Sapphire.inToSpace(forwarded)); } - forwardedHashState = Magic.getWordAtOffset(forwarded, STATUS_OFFSET).and(HASH_STATE_MASK); // reread incase someone else hashed + originalHashState = Magic.getWordAtOffset(forwarded, STATUS_OFFSET).and(HASH_STATE_MASK); // reread incase someone else hashed // for us - if (forwardedHashState.EQ(HASH_STATE_HASHED)) { + if (originalHashState.EQ(HASH_STATE_HASHED)) { // someone has hashed toSpace replica for us return Magic.objectAsAddress(forwarded).toWord().rshl(SizeConstants.LOG_BYTES_IN_ADDRESS).toInt(); } - // lock fromSpace replica, set hashed state in toSpace copy - ForwardingWord.atomicMarkBusy(obj); + // check if toSpace is already hashed before we go to the expense of locking fromSpace replica Word toSpaceStatusWord = Magic.getWordAtOffset(forwarded, STATUS_OFFSET); if (toSpaceStatusWord.and(HASH_STATE_MASK).EQ(HASH_STATE_HASHED)) { - // now that we have the lock we see someone else hashed the object - if (VM.VerifyAssertions) VM._assert(ForwardingWord.isBusy(obj)); - ForwardingWord.markNotBusy(obj); return getObjectHashCode(o); } + // toSpace was not hashed, mark fromSpace status word busy and then mark toSpace as hashed + ForwardingWord.atomicMarkBusy(obj); + toSpaceStatusWord = Magic.getWordAtOffset(forwarded, STATUS_OFFSET); Magic.setWordAtOffset(forwarded, STATUS_OFFSET, toSpaceStatusWord.or(HASH_STATE_HASHED)); if (VM.VerifyAssertions) { VM._assert(ForwardingWord.isBusy(obj)); Modified: rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/runtime/Magic.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/runtime/Magic.java 2010-09-17 09:44:53 UTC (rev 15993) +++ rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/runtime/Magic.java 2010-09-17 09:45:36 UTC (rev 15994) @@ -1030,6 +1030,7 @@ /** * Wait for preceeding cache flush/invalidate instructions to * complete on all processors. + * May have the effect of a StoreLoad barrier (mfence on x86) */ public static void sync() { if (VM.runningVM && VM.VerifyAssertions) { @@ -1040,6 +1041,7 @@ /** * Wait for all preceeding instructions to complete and discard any * prefetched instructions on this processor. + * May have the effect of a LoadStore or LoadLoad barrier (no-op on x86) */ public static void isync() { if (VM.runningVM && VM.VerifyAssertions) { Modified: rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/ThinLock.java =================================================================== --- rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2010-09-17 09:44:53 UTC (rev 15993) +++ rvmroot/branches/RVM-893-Sapphire/work/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2010-09-17 09:45:36 UTC (rev 15994) @@ -104,6 +104,7 @@ Word id = old.and(TL_THREAD_ID_MASK); if (id.isZero()) { if (ENABLE_BIASED_LOCKING) { + VM.sysFail("Opps shoud not have reached this path - biased locking should be disabled"); // lock is unbiased, bias it in our favor and grab it if (Synchronization.tryStatusWordCompareAndSwap( o, lockOffset, @@ -417,6 +418,7 @@ return Synchronization.tryStatusWordCompareAndSwap( o, lockOffset, oldLockWord, changed); } else { + VM.sysFail("Opps shouldn't have reached this path"); // LPJH: Sapphire debugging return casFromBiased(o, lockOffset, oldLockWord, changed, cnt); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |