Mercurial > hg > Members > kono > jpf-core
view 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 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.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; } }