//
// Copyright (C) 2012 United States Government as represented by the
// Administrator of the National Aeronautics and Space Administration
// (NASA). All Rights Reserved.
//
// This software is distributed under the NASA Open Source Agreement
// (NOSA), version 1.3. The NOSA has been approved by the Open Source
// Initiative. See the file NOSA-1.3-JPF at the top of the distribution
// directory tree for the complete NOSA document.
//
// THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
// KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
// LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
// SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
// A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
// THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
// DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
//
package gov.nasa.jpf.vm;
import de.fosd.typechef.featureexpr.FeatureExpr;
import gov.nasa.jpf.Config;
import gov.nasa.jpf.util.IntTable;
/**
* abstract Heap trait that implements SGOIDs by means of a search global
* Allocation map and a state managed allocCount map
*
* NOTE - a reference value of 0 represents null and therefore is not a valid SGOID
*/
public abstract class GenericSGOIDHeap extends GenericHeap {
static class GenericSGOIDHeapMemento extends GenericHeapMemento {
IntTable.Snapshot<AllocationContext> ctxSnap;
GenericSGOIDHeapMemento (GenericSGOIDHeap heap) {
super(heap);
ctxSnap = heap.allocCounts.getSnapshot();
}
@Override
public Heap restore(Heap inSitu) {
super.restore( inSitu);
GenericSGOIDHeap heap = (GenericSGOIDHeap) inSitu;
heap.allocCounts.restore(ctxSnap);
return heap;
}
}
// these are search global
protected int nextSgoid;
protected IntTable<Allocation> sgoids;
// this is state managed
// NOTE - this has to be included in the mementos of concrete Heap implementations
protected IntTable<AllocationContext> allocCounts;
protected GenericSGOIDHeap (Config config, KernelState ks){
super(config, ks);
// static inits
initAllocationContext(config);
sgoids = new IntTable<Allocation>();
nextSgoid = 0;
allocCounts = new IntTable<AllocationContext>();
}
//--- to be overridden by subclasses that use different AllocationContext implementations
protected void initAllocationContext(Config config) {
HashedAllocationContext.init(config);
//PreciseAllocationContext.init(config);
}
// these are always called directly from the allocation primitive, i.e. the allocating site is at a fixed
// stack offset (callers caller)
protected AllocationContext getSUTAllocationContext (FeatureExpr ctx, ClassInfo ci, ThreadInfo ti) {
return HashedAllocationContext.getSUTAllocationContext(ctx, ci, ti);
//return PreciseAllocationContext.getSUTAllocationContext(ci, ti);
}
protected AllocationContext getSystemAllocationContext (ClassInfo ci, ThreadInfo ti, int anchor) {
return HashedAllocationContext.getSystemAllocationContext(ci, ti, anchor);
//return PreciseAllocationContext.getSystemAllocationContext(ci, ti, anchor);
}
@Override
protected int getNewElementInfoIndex (AllocationContext ctx) {
int idx;
int cnt;
IntTable.Entry<AllocationContext> cntEntry = allocCounts.getInc(ctx);
cnt = cntEntry.val;
Allocation alloc = new Allocation(ctx, cnt);
IntTable.Entry<Allocation> sgoidEntry = sgoids.get(alloc);
if (sgoidEntry != null) { // we already had this one
idx = sgoidEntry.val;
} else { // new entry
idx = ++nextSgoid;
sgoids.put(alloc, idx);
}
// sanity check - we do this here (and not in our super class) since we know how elements are stored
// assert get(idx) == null;
return idx;
}
}