Mercurial > hg > Members > kono > jpf-core
view src/main/gov/nasa/jpf/vm/LockSetThresholdFli.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; /** * a threshold FieldLockInfo with a set of lock candidates * * this is the destructive update version. Override singleLockThresholdFli() and lockSetthresholdFli() for * a persistent version */ public class LockSetThresholdFli extends ThresholdFieldLockInfo { protected int[] lockRefSet; // this is only used once during prototype generation public LockSetThresholdFli(ThreadInfo ti, int[] currentLockRefs, int checkThreshold) { super(checkThreshold); tiLastCheck = ti; lockRefSet = currentLockRefs; } @Override protected int[] getCandidateLockSet() { return lockRefSet; } /** * override this for search global FieldLockInfos */ protected SingleLockThresholdFli singleLockThresholdFli (ThreadInfo ti, int lockRef, int remainingChecks) { return new SingleLockThresholdFli(ti, lockRef, remainingChecks); } protected LockSetThresholdFli lockSetThresholdFli (ThreadInfo ti, int[] lockRefs, int remainingChecks){ this.lockRefSet = lockRefs; this.tiLastCheck = ti; this.remainingChecks = remainingChecks; return this; } @Override public FieldLockInfo checkProtection(ThreadInfo ti, ElementInfo ei, FieldInfo fi) { int[] currentLockRefs = ti.getLockedObjectReferences(); int nLocks = currentLockRefs.length; int nRemaining = Math.max(0, remainingChecks--); if (nLocks == 0) { // no current locks, so intersection is empty checkFailedLockAssumption(ti, ei, fi); return empty; } else { // we had a lock set, and there currently is at least one lock held int l = 0; int[] newLset = new int[lockRefSet.length]; for (int i = 0; i < nLocks; i++) { // get the set intersection int leidx = currentLockRefs[i]; for (int j = 0; j < lockRefSet.length; j++) { if (lockRefSet[j] == leidx) { newLset[l++] = leidx; break; // sets don't contain duplicates } } } if (l == 0) { // intersection empty checkFailedLockAssumption(ti, ei, fi); return empty; } else if (l == 1) { // only one candidate left return singleLockThresholdFli(ti, newLset[0], nRemaining); } else if (l < newLset.length) { // candidate set did shrink int[] newLockRefSet = new int[l]; System.arraycopy(newLset, 0, newLockRefSet, 0, l); return lockSetThresholdFli(ti, newLockRefSet, nRemaining); } else { return lockSetThresholdFli(ti, lockRefSet, nRemaining); } } } /** * only called at the end of the gc on all live objects. The recycled ones are * either already nulled in the heap, or are not marked as live */ @Override public FieldLockInfo cleanUp(Heap heap) { int[] newSet = null; int l = 0; if (lockRefSet != null) { for (int i = 0; i < lockRefSet.length; i++) { ElementInfo ei = heap.get(lockRefSet[i]); if (!heap.isAlive(ei)) { // we got a stale one, so we have to change us if (newSet == null) { // first one, copy everything up to it newSet = new int[lockRefSet.length - 1]; if (i > 0) { System.arraycopy(lockRefSet, 0, newSet, 0, i); l = i; } } } else { if (newSet != null) { // we already had a dangling ref, now copy the live ones newSet[l++] = lockRefSet[i]; } } } } if (l == 1) { assert (newSet != null); return new SingleLockThresholdFli(tiLastCheck, newSet[0], remainingChecks); } else { if (newSet != null) { if (l == newSet.length) { // we just had one stale ref lockRefSet = newSet; } else { // several stales - make a new copy if (l == 0) { return empty; } else { lockRefSet = new int[l]; System.arraycopy(newSet, 0, lockRefSet, 0, l); } } } return this; } } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("LockSetThresholdFli {"); sb.append("remainingChecks="); sb.append(remainingChecks); sb.append(",lset=["); if (lockRefSet != null) { for (int i = 0; i < lockRefSet.length; i++) { if (i > 0) { sb.append(','); } sb.append(lockRefSet[i]); } } sb.append("]}"); return sb.toString(); } }