Mercurial > hg > Members > kono > jpf-core
view src/main/gov/nasa/jpf/vm/PSIMHeap.java @ 0:61d41facf527
initial v8 import (history reset)
author | Peter Mehlitz <Peter.C.Mehlitz@nasa.gov> |
---|---|
date | Fri, 23 Jan 2015 10:14:01 -0800 |
parents | |
children |
line wrap: on
line source
/* * Copyright (C) 2014, United States Government, as represented by the * Administrator of the National Aeronautics and Space Administration. * All rights reserved. * * The Java Pathfinder core (jpf-core) platform is licensed under the * Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package gov.nasa.jpf.vm; import gov.nasa.jpf.Config; import gov.nasa.jpf.util.PSIntMap; import gov.nasa.jpf.util.Predicate; import java.util.Iterator; /** * heap implementation that uses a PersistentStagingMsbIntMap as the underlying container * * This is intended for large state spaces, to minimize store/restore costs. While those * are negligible for PersistentMaps, the per-change overhead is not since the container * has to duplicate the access path to the changed node on every modification. Efficiency * of PSIMHeap therefore relies on accessing objects in a consecutive pattern, i.e. * depends on clustered access. * * <2do> this should not be a GenericSGOIDHeap derived class since this includes * a number of non-persistent data structures (allocCounts, intern strings, pinDowns) that * are not persistent, i.e. still requires a memento that creates/restores snapshots of these * and hence looses a lot of the benefit we use a persistent map for * * NOTE - a reference value of 0 represents null and therefore is not a valid SGOID */ public class PSIMHeap extends GenericSGOIDHeap { /** * this sucks - we need a memento in order to store/restore allocCounts, internStrings and pinDownList */ static class PSIMMemento extends GenericSGOIDHeapMemento { PSIntMap<ElementInfo> eiSnap; PSIMMemento (PSIMHeap heap) { super(heap); heap.elementInfos.process(ElementInfo.storer); eiSnap = heap.elementInfos; // no need to transform anything, it's persistent } @Override public Heap restore(Heap inSitu) { super.restore( inSitu); PSIMHeap heap = (PSIMHeap) inSitu; heap.elementInfos = eiSnap; heap.elementInfos.process(ElementInfo.restorer); return heap; } } class SweepPredicate implements Predicate<ElementInfo>{ ThreadInfo ti; int tid; boolean isThreadTermination; protected void setContext() { ti = vm.getCurrentThread(); tid = ti.getId(); isThreadTermination = ti.isTerminated(); } @Override public boolean isTrue (ElementInfo ei) { if (ei.isMarked()){ // live object, prepare for next transition & gc cycle ei.setUnmarked(); ei.setAlive( liveBitValue); ei.cleanUp( PSIMHeap.this, isThreadTermination, tid); return false; } else { // object is no longer reachable // no finalizer support yet ei.processReleaseActions(); // <2do> still have to process finalizers here, which might make the object live again vm.notifyObjectReleased( ti, ei); return true; } } } SweepPredicate sweepPredicate; PSIntMap<ElementInfo> elementInfos; public PSIMHeap (Config config, KernelState ks) { super(config,ks); elementInfos = new PSIntMap<ElementInfo>(); sweepPredicate = new SweepPredicate(); } @Override public int size() { return elementInfos.size(); } @Override protected void set(int index, ElementInfo ei) { elementInfos = elementInfos.set(index, ei); } @Override public ElementInfo get(int ref) { if (ref <= 0) { return null; } else { return elementInfos.get(ref); } } @Override public ElementInfo getModifiable(int ref) { // <2do> this could probably use a specialized replaceValue() method if (ref <= 0) { return null; } else { ElementInfo ei = elementInfos.get(ref); if (ei != null && ei.isFrozen()) { ei = ei.deepClone(); // freshly created ElementInfos are not frozen, so we don't have to defreeze elementInfos = elementInfos.set(ref, ei); } return ei; } } @Override protected void remove(int ref) { elementInfos = elementInfos.remove(ref); } @Override protected void sweep () { sweepPredicate.setContext(); elementInfos = elementInfos.removeAllSatisfying( sweepPredicate); } @Override public Iterator<ElementInfo> iterator() { return elementInfos.iterator(); } @Override public Iterable<ElementInfo> liveObjects() { return elementInfos; } @Override public void resetVolatiles() { // we don't have any } @Override public void restoreVolatiles() { // we don't have any } @Override public Memento<Heap> getMemento(MementoFactory factory) { return factory.getMemento(this); } @Override public Memento<Heap> getMemento() { return new PSIMMemento(this); } }