/* * @(#)ClassClass.java 1.55 06/11/07 * * Copyright 1990-2008 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 only, as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License version 2 for more details (a copy is * included at /legal/license.txt). * * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa * Clara, CA 95054 or visit www.sun.com if you need additional * information or have any questions. * */ package vm; /* * VM-specific internal representation of * a class. Target-machine independent. * There is a references from each instance of components.ClassInfo to * one of these, and a reference back as well. * * See also JDKVM for VM-specific info not associated directly with a class. */ import components.*; import util.*; import consts.Const; import java.util.Enumeration; import java.util.Vector; import java.util.Hashtable; import java.util.StringTokenizer; public abstract class ClassClass { public ClassInfo classInfo; public InterfaceMethodTable inf; public boolean impureConstants = false; public int nGCStatics = 0; public boolean hasStaticInitializer = false; public static void setTypes(){ classFactory.setTypes(); } /* * Make the class list into a vector * ordered s.t. superclasses precede their * subclasses. */ private static ClassClass[]cvector; private static int cindex; private static VMClassFactory classFactory; // this is the recursive part private static void insertClassElement( ClassInfo e ){ if ( e.vmClass != null ) return; // already in place. ClassInfo sup = e.superClassInfo; // make sure our super precedes us. if ( (sup != null) && (sup.vmClass == null) ) insertClassElement( sup ); ClassClass newVmClass = classFactory.newVMClass( e ); cvector[ cindex++ ] = newVmClass; // // If the superclass of class C has a <clinit> method, C must // be marked as having a static initializer too. // if (!newVmClass.hasStaticInitializer && (sup != null) && sup.vmClass.hasStaticInitializer) { newVmClass.hasStaticInitializer = true; } } // this is the entry point for vector building. public static ClassClass[] getClassVector( VMClassFactory ftry ){ if ( cvector != null ) return cvector; // just once, at most. classFactory = ftry; cvector = new ClassClass[ ClassTable.size() ]; cindex = 0; Enumeration classlist = ClassTable.elements(); while( classlist.hasMoreElements() ){ ClassInfo e = (ClassInfo)classlist.nextElement(); if (e.vmClass == null) { insertClassElement( e ); } } // "cindex" is the current class count, as counted // by insertClassElement(). See if a class was not // added for some reason. if (cvector.length != cindex) { throw new InternalError("class vector size " + cindex + " not " + cvector.length); } return cvector; } public static boolean hasClassVector(){ return cvector != null; } public static void destroyClassVector(){ for (int i = 0; i < cvector.length; ++i) { cvector[i].classInfo.vmClass = null; } cvector = null; } /** * Size of an instance in WORDS. */ public int instanceSize(){ // fieldtable must always be in order. FieldInfo ft[] = classInfo.fieldtable; if ( ft == null || ft.length == 0 ) return 0; FieldInfo lastField = ft[ft.length-1]; return (lastField.instanceOffset+lastField.nSlots); } public boolean isInterface() { return (classInfo.access&Const.ACC_INTERFACE) != 0; } public boolean hasMethodtable(){ return ((!isInterface()) && (classInfo.methodtable != null)); } public boolean isArrayClass(){ return (classInfo instanceof ArrayClassInfo); } public boolean isPrimitiveClass() { return (classInfo instanceof PrimitiveClassInfo); } public int nmethods(){ return (classInfo.methods == null) ? 0 : classInfo.methods.length; } public int nfields(){ return (classInfo.fields == null) ? 0 : classInfo.fields.length; } /* * A concrete ClassClass needs to declare what needs to be done * to a constant pool containing unresolved references. * Some need to add UTF string references. Some may not. * Returns: TRUE for pure (nothing symbolic left to resolve) * FALSE otherwise. */ abstract public boolean adjustSymbolicConstants(UnresolvedReferenceList missingObjects); public static boolean isPartiallyResolved( ConstantPool cp ){ int nconst = cp.getLength(); if ( nconst == 0 ) return false; // no const! // first see if we have anything that needs our attention. int nsymbolic = 0; ConstantObject[] consts = cp.getConstants(); for( int i = 1; i < nconst; i += consts[i].nSlots ){ ConstantObject o = consts[i]; if (!o.isResolved()) { return true; } } return false; } /* * The concrete ClassClass can define this to return an inlining for * all its methods */ abstract public void getInlining(); }