diff src/main/gov/nasa/jpf/vm/BoxObjectCacheManager.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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/gov/nasa/jpf/vm/BoxObjectCacheManager.java	Fri Jan 23 10:14:01 2015 -0800
@@ -0,0 +1,264 @@
+/*
+ * 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;
+
+/**
+ * @author Nastaran Shafiei <nastaran.shafiei@gmail.com>
+ * 
+ *         Cache management implementation for the types Boolean, Byte,
+ *         Character, Short, Integer, Long. The references to the caches are in
+ *         the class classes/gov/nasa/jpf/BoxObjectCaches.
+ * 
+ *         All the caches, except Boolean, are initialized on the first
+ *         invocation of valueOf(), and they all exempt from garbage collection.
+ * 
+ *         NOTE: All classes obtained from getResolvedClassInfo in
+ *         BoxObjectCacheManager are safe, and there is no need to check if they
+ *         are initialized. The wrappers and BoxObjectCaches are initialized in
+ *         VM.intialize(), and there are no clinit for array classes.
+ *         
+ *         NOTE: the initXCache allocations are system allocations, whereas the
+ *         valueOfX() allocations are rooted in SUT code
+ */
+public class BoxObjectCacheManager {
+  private static final String MODEL_CLASS = "gov.nasa.jpf.BoxObjectCaches";
+  private static final int ANCHOR = BoxObjectCacheManager.class.getName().hashCode();  
+  
+  // cache default bounds
+  private static int defLow = -128;
+  private static int defHigh = 127;
+
+  public static int valueOfBoolean (ThreadInfo ti, boolean b) {
+    ClassInfo cls = ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Boolean");
+
+    int boolObj;
+    if (b) {
+      boolObj = cls.getStaticElementInfo().getReferenceField("TRUE");
+    } else {
+      boolObj = cls.getStaticElementInfo().getReferenceField("FALSE");
+    }
+
+    return boolObj;
+  }
+
+  // Byte cache bounds
+  private static byte byteLow;
+  private static byte byteHigh;
+
+  public static int initByteCache (ThreadInfo ti) {
+    byteLow = (byte) ti.getVM().getConfig().getInt("vm.cache.low_byte", defLow);
+    byteHigh = (byte) ti.getVM().getConfig().getInt("vm.cache.high_byte", defHigh);
+    int n = (byteHigh - byteLow) + 1;
+    
+    Heap heap = ti.getHeap();
+    ElementInfo eiArray = heap.newSystemArray("Ljava/lang/Byte", n, ti, ANCHOR);
+    int arrayRef = eiArray.getObjectRef();
+
+    ClassInfo ci = ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Byte");
+    byte val = byteLow;
+    for (int i = 0; i < n; i++) {
+      ElementInfo eiByte = heap.newSystemObject(ci, ti, ANCHOR);
+      eiByte.setByteField("value", val++);
+      eiArray.setReferenceElement(i, eiByte.getObjectRef());
+    }
+
+    ClassInfo cacheClass = ClassLoaderInfo.getSystemResolvedClassInfo(MODEL_CLASS);
+    cacheClass.getModifiableStaticElementInfo().setReferenceField("byteCache", arrayRef);
+    return arrayRef;
+  }
+
+  public static int valueOfByte (ThreadInfo ti, byte b) {
+    ClassInfo cacheClass = ClassLoaderInfo.getSystemResolvedClassInfo(MODEL_CLASS);
+    int byteCache = cacheClass.getStaticElementInfo().getReferenceField("byteCache");
+
+    if (byteCache == MJIEnv.NULL) { // initializing the cache on demand
+      byteCache = initByteCache(ti);
+    }
+
+    if (b >= byteLow && b <= byteHigh) { return ti.getElementInfo(byteCache).getReferenceElement(b - byteLow); }
+
+    ClassInfo ci = ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Byte");
+    ElementInfo eiByte = ti.getHeap().newObject(ci, ti);
+    eiByte.setByteField("value", b);
+    return eiByte.getObjectRef();
+  }
+
+  // Character cache bound
+  private static int charHigh;
+
+  public static int initCharCache (ThreadInfo ti) {
+    charHigh = ti.getVM().getConfig().getInt("vm.cache.high_char", defHigh);
+    int n = charHigh + 1;
+    
+    Heap heap = ti.getHeap();    
+    ElementInfo eiArray = heap.newSystemArray("Ljava/lang/Character", n, ti, ANCHOR);
+    int arrayRef = eiArray.getObjectRef();
+
+    ClassInfo ci = ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Character");
+    for (int i = 0; i < n; i++) {
+      ElementInfo eiChar = heap.newSystemObject(ci, ti, ANCHOR);
+      eiChar.setCharField("value", (char) i);
+      eiArray.setReferenceElement(i, eiChar.getObjectRef());
+    }
+
+    ClassInfo cacheClass = ClassLoaderInfo.getSystemResolvedClassInfo(MODEL_CLASS);
+    cacheClass.getModifiableStaticElementInfo().setReferenceField("charCache", arrayRef);
+    return arrayRef;
+  }
+
+  public static int valueOfCharacter (ThreadInfo ti, char c) {
+    ClassInfo cacheClass = ClassLoaderInfo.getSystemResolvedClassInfo(MODEL_CLASS);
+    int charCache = cacheClass.getStaticElementInfo().getReferenceField("charCache");
+
+    if (charCache == MJIEnv.NULL) { // initializing the cache on demand
+      charCache = initCharCache(ti);
+    }
+
+    if (c >= 0 && c <= charHigh) { return ti.getElementInfo(charCache).getReferenceElement(c); }
+
+    ClassInfo ci = ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Character");
+    ElementInfo eiChar = ti.getHeap().newObject(ci, ti);
+    eiChar.setCharField("value", c);
+    return eiChar.getObjectRef();
+  }
+
+  // Short cache bounds
+  private static short shortLow;
+
+  private static short shortHigh;
+
+  public static int initShortCache (ThreadInfo ti) {
+    shortLow = (short) ti.getVM().getConfig().getInt("vm.cache.low_short", defLow);
+    shortHigh = (short) ti.getVM().getConfig().getInt("vm.cache.high_short", defHigh);
+    int n = (shortHigh - shortLow) + 1;
+    
+    Heap heap = ti.getHeap();    
+    ElementInfo eiArray = heap.newSystemArray("Ljava/lang/Short", n, ti, ANCHOR);
+    int arrayRef = eiArray.getObjectRef();
+
+    ClassInfo ci = ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Short");
+    short val = shortLow;
+    for (int i = 0; i < n; i++) {
+      ElementInfo eiShort = heap.newSystemObject(ci, ti, ANCHOR);
+      eiShort.setShortField("value", val++);
+      eiArray.setReferenceElement(i, eiShort.getObjectRef());
+    }
+
+    ClassInfo cacheClass = ClassLoaderInfo.getSystemResolvedClassInfo(MODEL_CLASS);
+    cacheClass.getModifiableStaticElementInfo().setReferenceField("shortCache", arrayRef);
+    return arrayRef;
+  }
+
+  public static int valueOfShort (ThreadInfo ti, short s) {
+    ClassInfo cacheClass = ClassLoaderInfo.getSystemResolvedClassInfo(MODEL_CLASS);
+    int shortCache = cacheClass.getStaticElementInfo().getReferenceField("shortCache");
+
+    if (shortCache == MJIEnv.NULL) { // initializing the cache on demand
+      shortCache = initShortCache(ti);
+    }
+
+    if (s >= shortLow && s <= shortHigh) { return ti.getElementInfo(shortCache).getReferenceElement(s - shortLow); }
+
+    ClassInfo ci = ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Short");
+    ElementInfo eiShort = ti.getHeap().newObject(ci, ti);
+    eiShort.setShortField("value", s);
+    return eiShort.getObjectRef();
+  }
+
+  // Integer cache bounds
+  private static int intLow;
+  private static int intHigh;
+
+  public static int initIntCache (ThreadInfo ti) {
+    intLow = ti.getVM().getConfig().getInt("vm.cache.low_int", defLow);
+    intHigh = ti.getVM().getConfig().getInt("vm.cache.high_int", defHigh);
+    int n = (intHigh - intLow) + 1;
+    
+    Heap heap = ti.getHeap();    
+    ElementInfo eiArray = heap.newSystemArray("Ljava/lang/Integer", n, ti, ANCHOR);
+    int arrayRef = eiArray.getObjectRef();
+
+    ClassInfo ci = ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Integer");
+    for (int i = 0; i < n; i++) {
+      ElementInfo eiInteger = heap.newSystemObject(ci, ti, ANCHOR);
+      eiInteger.setIntField("value", i + intLow);
+      eiArray.setReferenceElement(i, eiInteger.getObjectRef());
+    }
+
+    ClassInfo cacheClass = ClassLoaderInfo.getSystemResolvedClassInfo(MODEL_CLASS);
+    cacheClass.getModifiableStaticElementInfo().setReferenceField("intCache", arrayRef);
+    return arrayRef;
+  }
+
+  public static int valueOfInteger (ThreadInfo ti, int i) {
+    ClassInfo cacheClass = ClassLoaderInfo.getSystemResolvedClassInfo(MODEL_CLASS);
+    int intCache = cacheClass.getStaticElementInfo().getReferenceField("intCache");
+
+    if (intCache == MJIEnv.NULL) { // initializing the cache on demand
+      intCache = initIntCache(ti);
+    }
+
+    if (i >= intLow && i <= intHigh) { return ti.getElementInfo(intCache).getReferenceElement(i - intLow); }
+
+    ClassInfo ci = ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Integer");
+    ElementInfo eiInteger = ti.getHeap().newObject(ci, ti);
+    eiInteger.setIntField("value", i);
+    return eiInteger.getObjectRef();
+  }
+
+  // Long cache bounds
+  private static int longLow;
+  private static int longHigh;
+
+  public static int initLongCache (ThreadInfo ti) {
+    longLow = ti.getVM().getConfig().getInt("vm.cache.low_long", defLow);
+    longHigh = ti.getVM().getConfig().getInt("vm.cache.high_long", defHigh);
+    int n = (longHigh - longLow) + 1;
+    
+    Heap heap = ti.getHeap();    
+    ElementInfo eiArray = heap.newSystemArray("Ljava/lang/Long", n, ti, ANCHOR);
+    int arrayRef = eiArray.getObjectRef();
+
+    ClassInfo ci = ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Long");
+    for (int i = 0; i < n; i++) {
+      ElementInfo eiLong = heap.newSystemObject(ci, ti, ANCHOR);
+      eiLong.setLongField("value", i + longLow);
+      eiArray.setReferenceElement(i, eiLong.getObjectRef());
+    }
+
+    ClassInfo cacheClass = ClassLoaderInfo.getSystemResolvedClassInfo(MODEL_CLASS);
+    cacheClass.getModifiableStaticElementInfo().setReferenceField("longCache", arrayRef);
+    return arrayRef;
+  }
+
+  public static int valueOfLong (ThreadInfo ti, long l) {
+    ClassInfo cacheClass = ClassLoaderInfo.getSystemResolvedClassInfo(MODEL_CLASS);
+    int longCache = cacheClass.getStaticElementInfo().getReferenceField("longCache");
+
+    if (longCache == MJIEnv.NULL) { // initializing the cache on demand
+      longCache = initLongCache(ti);
+    }
+
+    if (l >= longLow && l <= longHigh) { return ti.getElementInfo(longCache).getReferenceElement((int) l - longLow); }
+
+    ClassInfo ci = ClassLoaderInfo.getSystemResolvedClassInfo("java.lang.Long");
+    ElementInfo eiLong = ti.getHeap().newObject(ci, ti);
+    eiLong.setLongField("value", l);
+    return eiLong.getObjectRef();
+  }
+}