Mercurial > hg > Members > kono > jpf-core
view src/main/gov/nasa/jpf/vm/FieldLockInfo.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.JPF; import java.util.logging.Logger; /** * class encapsulating the lock protection status for field access * instructions. Used by on-the-fly partial order reduction in FieldInstruction * to determine if a GET/PUT_FIELD/STATIC insn has to be treated as a * boundary step (terminates a transition). If the field access is always * protected by a lock, only the corresponding sync (INVOKExx or MONITORENTER) * are boundary steps, thus the number of states can be significantly reduced. * * FieldLockInfos are only used if vm.por.sync_detection is set * * NOTE this might involve assumptions that can be violated in subsequent * paths, and might cause potential races to go undetected */ public abstract class FieldLockInfo implements Cloneable { static Logger log = JPF.getLogger("gov.nasa.jpf.vm.FieldLockInfo"); static protected final FieldLockInfo empty = new EmptyFieldLockInfo(); protected ThreadInfo tiLastCheck; // the thread this FieldLockInfo was last checked for public static FieldLockInfo getEmptyFieldLockInfo(){ return empty; } public abstract FieldLockInfo checkProtection (ThreadInfo ti, ElementInfo ei, FieldInfo fi); public abstract boolean isProtected (); public abstract FieldLockInfo cleanUp (Heap heap); protected abstract int[] getCandidateLockSet(); public boolean isFinal() { return isProtected(); } public boolean needsPindown (ElementInfo ei) { return false; } /* * we need this for faster instantiation. Make sure it gets overridden in * case there is a need for per-instance parameterization */ @Override public Object clone () throws CloneNotSupportedException { return super.clone(); } void lockAssumptionFailed (ThreadInfo ti, ElementInfo ei, FieldInfo fi) { String src = ti.getTopFrameMethodInfo().getClassInfo().getSourceFileName(); int line = ti.getLine(); StringBuilder sb = new StringBuilder( "unprotected field access of: "); sb.append(ei); sb.append('.'); sb.append(fi.getName()); sb.append( " in thread: "); sb.append( ti.getName()); sb.append( " ("); sb.append( src); sb.append(':'); sb.append(line); sb.append(")\n[SEVERE].. last lock candidates: "); appendLockSet(sb, getCandidateLockSet()); if (tiLastCheck != null) { sb.append(" set by "); sb.append(tiLastCheck); } sb.append( "\n[SEVERE].. current locks: "); appendLockSet(sb, ti.getLockedObjectReferences()); sb.append("\n[SEVERE].. if this is not a race, re-run with 'vm.shared.sync_detection=false' or exclude field from checks"); log.severe(sb.toString()); } void appendLockSet (StringBuilder sb, int[] lockSet) { Heap heap = VM.getVM().getHeap(); if ((lockSet == null) || (lockSet.length == 0)) { sb.append( "{}"); } else { sb.append('{'); for (int i=0; i<lockSet.length;) { int ref = lockSet[i]; if (ref != MJIEnv.NULL) { ElementInfo ei = heap.get(ref); if (ei != null) { sb.append(ei); } else { sb.append("?@"); sb.append(lockSet[i]); } } i++; if (i<lockSet.length) sb.append(','); } sb.append('}'); } } } /** * FieldLockSet implementation for fields that are terminally considered to be unprotected */ class EmptyFieldLockInfo extends FieldLockInfo { @Override public FieldLockInfo checkProtection (ThreadInfo ti, ElementInfo ei, FieldInfo fi) { return this; } @Override public FieldLockInfo cleanUp (Heap heap) { return this; } @Override public boolean isProtected () { return false; } @Override public boolean isFinal() { return true; } @Override protected int[] getCandidateLockSet() { return new int[0]; } @Override public String toString() { return "EmptyFieldLockInfo"; } }