diff src/main/gov/nasa/jpf/vm/SystemClassLoaderInfo.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/SystemClassLoaderInfo.java	Fri Jan 23 10:14:01 2015 -0800
@@ -0,0 +1,268 @@
+/*
+ * 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.Config;
+import gov.nasa.jpf.JPF;
+import gov.nasa.jpf.util.JPFLogger;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Nastaran Shafiei <nastaran.shafiei@gmail.com>
+ * 
+ * Represents the JPF system classloader which models the following hierarchy.
+ * 
+ *            ----------------
+ *            | Bootstrap CL |
+ *            ----------------
+ *                   |
+ *            ----------------
+ *            | Extension CL |
+ *            ----------------
+ *                   |
+ *           ------------------
+ *           | Application CL |
+ *           ------------------
+ *           
+ * Since in the standard VM user does not have any control over the built-in 
+ * classloaders hierarchy, in JPF, we model all three by an instance of 
+ * SystemClassLoader which is responsible to load classes from Java API, 
+ * standard extensions packages, and the local file system.     
+ */
+public abstract class SystemClassLoaderInfo extends ClassLoaderInfo {
+
+  static JPFLogger log = JPF.getLogger("class");
+  
+  // we need to keep track of this in case something needs the current SystemClassLoaderInfo before we have a main thread
+  static SystemClassLoaderInfo lastInstance;  
+  
+  // note that initialization requires these to be startup classes
+  protected ClassInfo classLoaderClassInfo;
+  protected ClassInfo objectClassInfo;
+  protected ClassInfo classClassInfo;
+  protected ClassInfo stringClassInfo;
+  protected ClassInfo weakRefClassInfo;
+  protected ClassInfo refClassInfo;
+  protected ClassInfo enumClassInfo;
+  protected ClassInfo threadClassInfo;
+  protected ClassInfo threadGroupClassInfo;
+  protected ClassInfo charArrayClassInfo;
+
+  protected int unCachedClasses = 10;
+  
+  /**
+   * list of configurable Attributors for ClassInfos, MethodInfos and FieldInfos
+   * that are consulted after creating the ClassInfo but before notifying classLoaded() listeners
+   */
+  protected List<Attributor> attributors;
+  
+  
+  public SystemClassLoaderInfo (VM vm, int appId){
+     super(vm);
+
+     lastInstance = this;
+
+    // this is a hack - for user ClassLoaderInfos, we compute the id from the corresponding
+    // objRef of the JPF ClassLoader object. For SystemClassLoaderInfos we can't do that because
+    // they are created before we can create JPF objects. However, this is safe if we know
+    // the provided id is never going to be the objRef of a future ClassLoader object, which is
+    // a safe bet since the first objects created are all system Class objects that are never going to
+    // be recycled.
+    this.id = computeId(appId);
+    
+    initializeSystemClassPath( vm, appId);
+    initializeAttributors( vm, appId);
+  }
+  
+  protected abstract void initializeSystemClassPath (VM vm, int appId);
+  
+  protected void initializeAttributors (VM vm, int appId){
+    attributors = new ArrayList<Attributor>();
+    
+    Config conf = vm.getConfig();
+    String key = conf.getIndexableKey("vm.attributors", appId);
+    if (key != null){
+      for (Attributor a : conf.getInstances(key, Attributor.class)){
+        attributors.add(a);
+      }
+    }
+  }
+
+  public void addAttributor (Attributor a){
+    attributors.add(a);
+  }
+  
+  /**
+   * to be called on each ClassInfo created in the realm of this SystemClassLoader
+   */
+  @Override
+  protected void setAttributes (ClassInfo ci){
+    for (Attributor a: attributors){
+      a.setAttributes(ci);
+    }
+  }
+  
+  //--- these can be used to build the app specific system CP
+  protected File[] getPathElements (Config conf, String keyBase, int appId) {
+    File[] pathElements = null;
+
+    // try appId indexed key first
+    String key = keyBase + '.' + appId;
+    if (conf.containsKey(key)) {
+      pathElements = conf.getPathArray(key);
+
+    } else { // fall back to keyBase
+      pathElements = conf.getPathArray(keyBase);
+    }
+
+    return pathElements;
+  }
+  
+  @Override
+  public SystemClassLoaderInfo getSystemClassLoader() {
+    return this;
+  }
+
+  
+  @Override
+  public ClassInfo getResolvedClassInfo (String clsName){
+    ClassInfo ci = super.getResolvedClassInfo(clsName);
+    
+    if (unCachedClasses > 0){
+      updateCachedClassInfos(ci);
+    }
+    
+    return ci;
+  }
+
+  @Override
+  public boolean isSystemClassLoader() {
+    return true;
+  }
+
+  static boolean checkClassName (String clsName) {
+    if ( !clsName.matches("[a-zA-Z_$][a-zA-Z_$0-9.]*")) {
+      return false;
+    }
+
+    // well, those two could be part of valid class names, but
+    // in all likeliness somebody specified a filename instead of
+    // a classname
+    if (clsName.endsWith(".java")) {
+      return false;
+    }
+    if (clsName.endsWith(".class")) {
+      return false;
+    }
+
+    return true;
+  }
+  
+
+  @Override
+  public ClassInfo loadClass(String cname) {
+    return getResolvedClassInfo(cname);
+  }
+
+  @Override
+  protected ClassInfo loadSystemClass (String typeName){
+    return new ClassInfo( typeName, this);
+  }
+
+  protected void setClassLoaderObject (ElementInfo ei){
+    objRef = ei.getObjectRef();
+    //id = computeId(objRef);
+    
+    // cross link
+    ei.setIntField(ID_FIELD, id);
+  }
+  
+
+  //-- ClassInfos cache management --
+
+  protected void updateCachedClassInfos (ClassInfo ci) {
+    String name = ci.name;
+
+    if ((objectClassInfo == null) && name.equals("java.lang.Object")) {
+      objectClassInfo = ci; unCachedClasses--;
+    } else if ((classClassInfo == null) && name.equals("java.lang.Class")) {
+      classClassInfo = ci; unCachedClasses--;
+    } else if ((classLoaderClassInfo == null) && name.equals("java.lang.ClassLoader")) {
+      classInfo = ci;
+      classLoaderClassInfo = ci;  unCachedClasses--;
+    } else if ((stringClassInfo == null) && name.equals("java.lang.String")) {
+      stringClassInfo = ci; unCachedClasses--;
+    } else if ((charArrayClassInfo == null) && name.equals("[C")) {
+      charArrayClassInfo = ci; unCachedClasses--;
+    } else if ((weakRefClassInfo == null) && name.equals("java.lang.ref.WeakReference")) {
+      weakRefClassInfo = ci; unCachedClasses--;
+    } else if ((refClassInfo == null) && name.equals("java.lang.ref.Reference")) {
+      refClassInfo = ci; unCachedClasses--;
+    } else if ((enumClassInfo == null) && name.equals("java.lang.Enum")) {
+      enumClassInfo = ci; unCachedClasses--;
+    } else if ((threadClassInfo == null) && name.equals("java.lang.Thread")) {
+      threadClassInfo = ci; unCachedClasses--;
+    } else if ((threadGroupClassInfo == null) && name.equals("java.lang.ThreadGroup")) {
+      threadGroupClassInfo = ci; unCachedClasses--;
+    }
+  }
+  
+  protected ClassInfo getObjectClassInfo() {
+    return objectClassInfo;
+  }
+
+  protected ClassInfo getClassClassInfo() {
+    return classClassInfo;
+  }
+
+  protected ClassInfo getClassLoaderClassInfo() {
+    return classLoaderClassInfo;
+  }
+
+  protected ClassInfo getStringClassInfo() {
+    return stringClassInfo;
+  }
+  
+  protected ClassInfo getCharArrayClassInfo() {
+    return charArrayClassInfo;
+  }
+
+  protected ClassInfo getEnumClassInfo() {
+    return enumClassInfo;
+  }
+
+  protected ClassInfo getThreadClassInfo() {
+    return threadClassInfo;
+  }
+
+  protected ClassInfo getThreadGroupClassInfo() {
+    return threadGroupClassInfo;
+  }
+
+  protected ClassInfo getReferenceClassInfo() {
+    return refClassInfo;
+  }
+
+  protected ClassInfo getWeakReferenceClassInfo() {
+    return weakRefClassInfo;
+  }
+
+}