//
// Copyright (C) 2005 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.jvm.bytecode;
import gov.nasa.jpf.Config;
import gov.nasa.jpf.JPFException;
import gov.nasa.jpf.jvm.ElementInfo;
import gov.nasa.jpf.jvm.ThreadInfo;
import gov.nasa.jpf.jvm.ClassInfo;
import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.Type;
import org.apache.bcel.generic.ReferenceType;
import gov.nasa.jpf.jvm.FieldInfo;
import gov.nasa.jpf.jvm.FieldLockInfo;
/**
* parent class for PUT/GET FIELD/STATIC insns
*
* <2do> there is a inheritance level missing to deal with instance/static
* fields - w/o the instance/static helper methods we would have to duplicate
* code in the getters/setters
*/
public abstract class FieldInstruction extends Instruction implements VariableAccessor
{
static FieldLockInfo prototype; //optimization measure
protected String fname;
protected String className;
protected String varId;
protected FieldInfo fi; // lazy eval, hence not public
protected int size;
protected boolean isReferenceField;
public static void init (Config config) throws Config.Exception {
if (config.getBoolean("vm.por") && config.getBoolean("vm.por.sync_detection")) {
prototype = (FieldLockInfo) config.getEssentialInstance("vm.por.fieldlockinfo.class",
FieldLockInfo.class);
}
}
public void setPeer (org.apache.bcel.generic.Instruction i, ConstantPool cp) {
org.apache.bcel.generic.FieldInstruction fi;
ConstantPoolGen cpg;
fi = (org.apache.bcel.generic.FieldInstruction) i;
cpg = ClassInfo.getConstantPoolGen(cp);
fname = fi.getFieldName(cpg);
className = fi.getClassName(cpg);
Type ft = fi.getFieldType(cpg);
if (ft instanceof ReferenceType) {
isReferenceField = true;
}
size = ft.getSize();
}
public abstract FieldInfo getFieldInfo ();
public boolean isReferenceField () {
return isReferenceField;
}
public String getId(ElementInfo ei) {
// <2do> - OUTCH, should be optimized
return (ei.toString() + '.' + fname);
}
public String getVariableId () {
if (varId == null) {
varId = className + '.' + fname;
}
return varId;
}
/**
* is this field supposed to be protected by a lock?
* this only gets called if on-the-fly POR is in effect
*/
protected boolean isLockProtected (ElementInfo ei, ThreadInfo ti) {
String id = getId(ei);
FieldLockInfo flInfo = ei.getFieldLockInfo( id);
FieldLockInfo flInfoNext;
FieldInfo fi = getFieldInfo(); // so that we make sure it's computed
if (flInfo == null) {
try {
flInfoNext = (FieldLockInfo) prototype.clone();
} catch (Exception x) {
throw new JPFException(x); // pretty lame error handling here
}
} else {
flInfoNext = flInfo.checkProtection(ei,fi,ti);
}
if (flInfoNext != flInfo) {
ei.setFieldLockInfo(id, flInfoNext);
}
return flInfoNext.isProtected();
}
}
|