FileDocCategorySizeDatePackage
ClassInfo.javaAPI DocphoneME MR2 API (J2ME)28672Wed May 02 17:59:48 BST 2007components

ClassInfo

public class ClassInfo extends Object

Fields Summary
public String
className
public int
access
public ClassConstant
thisClass
public ClassConstant
superClass
public ClassInfo
superClassInfo
public FieldInfo[]
fields
public MethodInfo[]
methods
public ConstantObject[]
constants
private ConstantObject[]
oldConstants
public ConstantObject[]
symbols
public ClassConstant[]
interfaces
public FieldConstant[]
refFieldtable
public MethodConstant[]
refMethodtable
public FieldInfo[]
fieldtable
public MethodInfo[]
methodtable
public UnicodeConstant
fieldtableName
public UnicodeConstant
methodtableName
public Attribute[]
classAttributes
public SourceFileAttribute
sourceFileAttr
public vm.ClassClass
vmClass
public Vector
allInterfaces
protected boolean
verbose
protected PrintStream
log
public ConstantPool
externalPool
public static boolean
classDebug
public int
flags
public static final int
INCLUDE_ALL
private String
genericNativeName
public static Hashtable
classtable
We keep track of classes by hashing them by name when we read them. They can be looked up using lookupClass, which will take a classname string as parameter.
Constructors Summary
public ClassInfo(boolean v)


         
	verbose = v;
	flags = INCLUDE_ALL; // by default, we want all members.
	// what else should be here?
    
Methods Summary
public static java.util.EnumerationallClasses()

	return classtable.elements();
    
public voidallocateFieldsFromFieldtable()

	if ( refFieldtable == null ) return; // no can do.

	int n = refFieldtable.length;
	int nsuper;
	int fieldoff = 0;
	nsuper = ( superClassInfo == null ) ? 0 : superClassInfo.refFieldtable.length;
	if ( nsuper == 0 ){
	    fieldoff = 0;
	} else {
	    FieldInfo f =  refFieldtable[ nsuper-1 ].find();
	    if ( f.instanceOffset < 0 ){
		superClassInfo.allocateFieldsFromFieldtable();
	    }
	    fieldoff = f.instanceOffset + f.nSlots;
	}
	for ( int i = nsuper ; i < n; i++ ){
	    FieldInfo f = refFieldtable[ i ].find();
	    if ( f == null ){
		// this is not supposed to happen.
		System.out.println( Localizer.getString("classinfo.cannot_find_field", refFieldtable[i]));
		continue;
	    }
	    f.instanceOffset = fieldoff;
	    fieldoff += f.nSlots;
	}
	//
	// and while we're here, do methodtable as well.
	//
	n = refMethodtable.length;
	int methodoff = 0; // 1=>0 EJVM

	for ( int i = 0; i < n ; i++ ){
	    MethodInfo m = refMethodtable[ i ].find();

	    if ( m == null ){
		// this is not supposed to happen.
		System.out.println( Localizer.getString("classinfo.cannot_find_field", refMethodtable[i]));
		continue;
	    } else if ( m.methodTableIndex != methodoff ){
		if ( m.parent != this ){
		    // this method is in a superclass.
		    // which apparently hasn't set up its methodtable yet.
		    // so go do it.
		    superClassInfo.allocateFieldsFromFieldtable();
		} else {
		    // we do it here.?
		    System.out.println("Inconsistent refMethodtable in class "+this.toString());
		    m.methodTableIndex = methodoff;
		}
	    }
	    methodoff += 1;
	}
    
public voidbuildFieldtable(ConstantPool cp)

	if (this.fieldtable != null) return; // already done.
	FieldInfo fieldtable[];
	int n;
	int fieldoff;
	int fieldtableLength = 0;
	FieldInfo candidate[] = this.fields;
	for( int i =0; i < candidate.length; i++ ){
	    if ((candidate[i].access & Const.ACC_STATIC) == 0){
		fieldtableLength++;
	    }
	}
	if ( superClassInfo != null ){
	    superClassInfo.buildFieldtable( cp );
	    n = superClassInfo.fieldtable.length;
	    fieldtableLength += n;
	    fieldoff = (n==0)? 0
		    : (superClassInfo.fieldtable[n-1].instanceOffset +
			superClassInfo.fieldtable[n-1].nSlots);
	    fieldtable = new FieldInfo[ fieldtableLength ];
	    System.arraycopy( superClassInfo.fieldtable, 0, fieldtable, 0, n );
	} else {
	    fieldtable = new FieldInfo[ fieldtableLength ];
	    n = 0;
	    fieldoff = 0;
	}
	for( int i =0; i < candidate.length; i++ ){
	    if ((candidate[i].access & Const.ACC_STATIC) == 0){
		fieldtable[n++] = candidate[i];
		candidate[i].instanceOffset = fieldoff;
		fieldoff += candidate[i].nSlots;
	    }
	}
	this.fieldtable = fieldtable;
	//
	// here, we make the gross assumption that
	// if we're building a fieldtable, we're using a shared
	// external Constant Pool
	fieldtableName = (UnicodeConstant)cp.add( new UnicodeConstant(/*NOI18N*/"fieldtable") );
	    
    
public voidbuildMethodtable(ConstantPool cp)

	if ( this.methodtable != null ) return; // already done.
	MethodInfo table[];
	MethodInfo methods[] = this.methods;
	ClassInfo sup = superClassInfo;
	if ((sup != null) && ( (sup.access&Const.ACC_INTERFACE)==(this.access&Const.ACC_INTERFACE) ) ) {
	    sup.buildMethodtable( cp );
	    table = sup.methodtable;
	} else {
	    table = new MethodInfo[0];
	}

	// allocate a temporary table that is certainly large enough.
	MethodInfo newTable[] = new MethodInfo[table.length + methods.length];
	int index = table.length;
	System.arraycopy( table, 0, newTable, 0, index );
	
	if (sup == null) { 
	    // finalize() goes into slot 0 of java.lang.Object
	    // FY: Removed for KVM.  We have no finalize() in slot 0.
		// index++;
	}

    method_loop:
	for (int i = 0; i < methods.length; i++) {
	    if ((methods[i].access & (Const.ACC_STATIC|Const.ACC_PRIVATE)) != 0) {
		continue method_loop;
	    } else if (methods[i].name.string.equals(/*NOI18N*/"<init>")) {
		continue method_loop;
	    } else if (sup == null && methods[i].name.string.equals(/*NOI18N*/"finalize") 
		                   && methods[i].type.string.equals(/*NOI18N*/"()V")) {
	        newTable[0] = methods[i];
		newTable[0].methodTableIndex = 0; // 1=>0 EJVM
		continue method_loop;
	    } 
	    int j;
	    int thisID = methods[i].getID();
	    for ( j = 0; j < table.length; j++) {
		if (thisID == table[j].getID()) {
		    newTable[j] = methods[i];
		    newTable[j].methodTableIndex = j + 0; // 1=>0 EJVM
		    continue method_loop;
		}
	    }
	    // If we're not overriding our parent's method we do add
	    // a new entry to the method table.
	    newTable[index] = methods[i];
	    newTable[index].methodTableIndex = index + 0; // 1=>0 EJVM
	    index++;
	}

	// now allocate a table of the correct size.
	MethodInfo methodTable[] = new MethodInfo[index];
	System.arraycopy( newTable, 0, methodTable, 0, index );

	this.methodtable =  methodTable;
	//
	// here, we make the gross assumption that
	// if we're building a methodtable, we're using a shared
	// external Constant Pool
	methodtableName = (UnicodeConstant)cp.add( new UnicodeConstant(/*NOI18N*/"methodtable") );
    
private FMIrefConstantbuildReference(ClassMemberInfo m, boolean isMethod, ConstantPool cp)

	ClassConstant c = (ClassConstant) cp.dup( m.parent.thisClass );
	FMIrefConstant x;
	NameAndTypeConstant n = (NameAndTypeConstant) cp.add(
	    new NameAndTypeConstant( 
		(UnicodeConstant)cp.add( m.name), 
		(UnicodeConstant)cp.add( m.type )
	    )
	);
	if (isMethod){
	    x = new MethodConstant( c, n );
	}else{
	    x = new FieldConstant( c, n );
	}
	return (FMIrefConstant)cp.add( x );
    
public voidbuildReferenceFieldtable(ConstantPool cp)

	if ( refFieldtable != null ) return; // already done, it says here.
	if ( fieldtableName == null ){
	    fieldtableName = (UnicodeConstant)cp.add( new UnicodeConstant(/*NOI18N*/"fieldtable") );
	}
	buildFieldtable( cp );
	int n = fieldtable.length;
	refFieldtable = new FieldConstant[ n ];
	for ( int i = 0; i < n; i++ ){
	    refFieldtable[i] = (FieldConstant)buildReference( fieldtable[i], false, cp );
	}
    
public voidbuildReferenceMethodtable(ConstantPool cp)

	if ( refMethodtable != null ) return; // already done, it says here.
	if ( methodtableName == null ){
	    methodtableName = (UnicodeConstant)cp.add( new UnicodeConstant(/*NOI18N*/"methodtable") );
	}
	buildMethodtable( cp );
	int n = methodtable.length;
	refMethodtable = new MethodConstant[ n ];
	for ( int i = 0; i < n; i++ ){
	    refMethodtable[i] = (MethodConstant)buildReference( methodtable[i], true, cp );
	}
    
public voidclearMemberFlags(int flagsToClear)

	int mask = ~ flagsToClear;
	int n;
	ClassMemberInfo members[];
	if ( fields != null ){
	    members = fields;
	    n = members.length;
	    for ( int i = 0; i < n; i++ ){
		members[i].flags &= mask;
	    }
	}
	if ( fields != null ){
	    members = methods;
	    n = members.length;
	    for ( int i = 0; i < n; i++ ){
		members[i].flags &= mask;
	    }
	}
    
private static booleanconditionalAdd(java.util.Vector v, java.lang.Object o)

	if ( v.contains( o ) )
	    return false;
	v.addElement( o );
	return true;
    
public booleancountReferences(boolean isRelocatable)

	thisClass.incReference();
	if ( superClass != null ) superClass.incReference();
	// count interface references
	if ( interfaces!=null ){
	    for ( int i = 0; i < interfaces.length ; i++ ){
		interfaces[i].incReference();
	    }
	}
	// then count references from fields.
	if ( fields != null ){
	    for ( int i = 0; i < fields.length; i++ ){
		fields[i].countConstantReferences( isRelocatable );
	    }
	}
	// then count references from code
	if ( methods != null ){
	    for ( int i = 0; i < methods.length; i++ ){
		methods[i].countConstantReferences( constants, isRelocatable );
	    }
	}
	Attribute.countConstantReferences(classAttributes, isRelocatable);
	return true;
    
protected java.lang.StringcreateGenericNativeName()

 
        return Util.convertToClassName(className );
    
private voiddoRead(java.io.DataInput in, boolean readCode, ConstantPool externalSymbols)


	externalPool = externalSymbols; // for convenience, later
	resolveConstants( );

	access = in.readUnsignedShort();
	thisClass = (ClassConstant) symbols[in.readUnsignedShort()];
	int sup = in.readUnsignedShort();
	if ( sup != 0 )
	    superClass = (ClassConstant) symbols[sup];
	className = thisClass.name.string;

	// Read the various parts of the class file
	readInterfaces( in );
	readFields( in );
	readMethods( in, readCode );
	readAttributes( in );
	enterClass( className );
    
public voiddump(java.io.PrintStream o)

	o.print(Util.accessToString(access)+/*NOI18N*/"Class "+thisClass);
	if ( superClass != null )
	    o.print(/*NOI18N*/" extends "+superClass);
	if ( interfaces!=null && interfaces.length != 0 ){
	    o.print(/*NOI18N*/" implements");
	    for( int i = 0; i < interfaces.length ; i++ ){
		o.print(" "+interfaces[i]);
	    }
	}
	o.println();
	dumpComponentTable( o, /*NOI18N*/"Methods", methods );
	dumpComponentTable( o, /*NOI18N*/"Fields",  fields  );
	if ( fieldtable != null )
	    dumpMemberTable( o, /*NOI18N*/"Fieldtable", fieldtable );
	else
	    dumpComponentTable( o, /*NOI18N*/"Fieldtable-by-reference", refFieldtable );
	if ( methodtable != null )
	    dumpMemberTable( o, /*NOI18N*/"Methodtable", methodtable );
	else
	    dumpComponentTable( o, /*NOI18N*/"Methodtable-by-reference", refMethodtable );
	dumpConstantTable( o, /*NOI18N*/"Constants", constants );
    
private static voiddumpComponentTable(java.io.PrintStream o, java.lang.String title, ClassComponent[] t)

	int n;
	if ( (t == null) || ((n=t.length) == 0) ) return;
	o.print( title ); o.println(/*NOI18N*/"["+n+"]:");
	for( int i = 0; i < n; i++ ){
	    if ( t[i] != null )
		o.println(/*NOI18N*/"\t["+i+/*NOI18N*/"]\t"+t[i]);
	}
    
private static voiddumpConstantTable(java.io.PrintStream o, java.lang.String title, ConstantObject[] t)

	int n;
	if ( (t == null) || ((n=t.length) == 0) ) return;
	o.print( title ); o.println(/*NOI18N*/"["+n+/*NOI18N*/"]:");
	o.println(/*NOI18N*/"\tPosition Index\tNrefs");
	for( int i = 0; i < n; i++ ){
	    if ( t[i] != null )
		o.println(/*NOI18N*/"\t["+i+/*NOI18N*/"]\t"+t[i].index+/*NOI18N*/"\t"+t[i].references+/*NOI18N*/"\t"+t[i]);
	}
    
private static voiddumpMemberTable(java.io.PrintStream o, java.lang.String title, ClassMemberInfo[] t)

	int n;
	if ( (t == null) || ((n=t.length) == 0) ) return;
	o.print( title ); o.println(/*NOI18N*/":");
	for( int i = 0; i < n; i++ ){
	    if ( t[i] != null )
		o.println(/*NOI18N*/"\t["+i+/*NOI18N*/"]\t"+t[i].qualifiedName() );
	}
    
protected voidenterClass(java.lang.String key)


         
	// should check to see if a class of this name is already there...
	if ( classtable.containsKey( className ) ){
	    System.err.println(Localizer.getString("classinfo.class_table_already_contains", className));
	    return;
	}
	classtable.put( key, this );
	// if a classvector has been created, we need to add this.
	// at end should be sufficient.
	vm.ClassClass.appendClassElement( this );
    
public voidexternalize(ConstantPool p)

	if (verbose){
	    log.println(Localizer.getString("classinfo.externalizing_class", className));
	}
	externalizeConstants( p );
	thisClass = (ClassConstant)p.dup( thisClass );
	//thisClass.externalize(p);//redundant?
	if ( superClass != null ){
	    superClass = (ClassConstant)p.dup( superClass );
	    //superClass.externalize(p);//redundant?
	}
	//externalizeInterfaces( p ); // interfaces NOT externalized!
	externalizeMethods( p );
	externalizeFields( p );
	externalizeAttributes( p );
    
voidexternalizeAttributes(ConstantPool p)

	Attribute.externalizeAttributes(classAttributes, p);
    
protected voidexternalizeConstants(ConstantPool externalPool)

	if (verbose){
	    log.println(Localizer.getString("classinfo.>>>externalizing_constants"));
	}
	// externalize immediately certain kinds of constants
	// we know to have no direct references.
	for (int i = 1; i < constants.length; i+=constants[i].nSlots) {
	    switch ( constants[i].tag ){
	    case Const.CONSTANT_UTF8:
	    case Const.CONSTANT_NAMEANDTYPE:
		// unquestionably, share these.
		constants[i] = externalPool.add( constants[i] );
		// FALLTHROUGH
	    default:
		constants[i].externalize( externalPool );
		break;
	    }
	}
    
voidexternalizeFields(ConstantPool p)

	int count = fields==null ? 0 : fields.length;
	if(verbose){
	    log.println(Localizer.getString("classinfo.>>>externalizing_field_members"));
	}
	for (int i = 0; i < count; i++) {
	    fields[i].externalize( p );
	}
    
voidexternalizeInterfaces(ConstantPool p)

	int count = interfaces==null ? 0 : interfaces.length;
	if(verbose){
	    log.println(Localizer.getString("classinfo.>>>externalizing_interfaces_implemented"));
	}
	for (int i = 0; i < count; i++) {
	    interfaces[i] = (ClassConstant)p.dup( interfaces[i] );
	}
    
voidexternalizeMethods(ConstantPool p)

	int count = methods==null ? 0 : methods.length;
	if(verbose){
	    log.println(Localizer.getString("classinfo.>>>externalizing_methods"));
	}
	for (int i = 0; i < count; i++) {
	    methods[i].externalize( p );
	}
    
public voidfindAllInterfaces()

	/*
	 * This works recursively, by computing parent's interface
	 * set first. THIS ASSUMES NON-CIRCULARITY, as does the rest
	 * of the Java system. This assumption will fail loudly, if
	 * at all.
	 */
	if ( superClassInfo == null ){
	    // we must be java.lang.Object!
	    allInterfaces = new Vector(5); // a generous size.
	} else {
	    if ( superClassInfo.allInterfaces == null )
		superClassInfo.findAllInterfaces();
	    allInterfaces = (Vector)(superClassInfo.allInterfaces.clone());
	}
	if ( interfaces == null ) return; // all done!
	for( int i = 0; i < interfaces.length; i++ ){
	    ClassInfo interf = interfaces[i].find();
	    if ( ( interf == null ) || ( (interf.access&Const.ACC_INTERFACE) == 0 ) ){
		System.err.println(Localizer.getString("classinfo.class_which_should_be_an_interface_but_is_not", className, interfaces[i]));
		continue;
	    }
	    if ( interf.allInterfaces == null )
		interf.findAllInterfaces();
	    if ( ! conditionalAdd( allInterfaces, interf ) ){
		// if this interface was already in the set,
		// then all the interfaces that it extend/implement
		// will be, too.
		continue;
	    }
	    Enumeration interfInterf = interf.allInterfaces.elements();
	    while( interfInterf.hasMoreElements() ){
		conditionalAdd( allInterfaces, interfInterf.nextElement() );
	    }
	}
    
public booleanfindReferences()

	try {
	    for ( int i = 0; i < methods.length; i++ ){
		methods[i].findConstantReferences();
	    }
	} catch ( DataFormatException e ){
	    return false;
	}
	return true;
    
public final java.lang.StringgetGenericNativeName()

 
        if (genericNativeName == null) 
	    genericNativeName = createGenericNativeName();
        return genericNativeName;
    
public static components.ClassInfolookupClass(java.lang.String key)

	return (ClassInfo)classtable.get( key );
    
public static intnClasses()

	return classtable.size();
    
public voidread(java.io.DataInput in, boolean readCode, ConstantPool externalSymbols)

	readConstantPool( in );
	symbols = constants;	// symbol table == constant pool
	doRead( in, readCode, externalSymbols );
    
voidreadAttributes(java.io.DataInput in)

	int count = in.readUnsignedShort();
	Vector clssAttr = new Vector();
	
	if(verbose){
	    log.println(Localizer.getString("classinfo.reading_attributes", Integer.toString(count)));
	}

	for (int i = 0; i < count; i++) {
	    int nameIndex = in.readUnsignedShort();
	    int bytes = in.readInt();
	    UnicodeConstant name = (UnicodeConstant)symbols[nameIndex];
	    if (name.string.equals(/*NOI18N*/"fieldtable")){
		fieldtableName = name;
		if (verbose){
		    log.println(Localizer.getString("classinfo.reading_name",name));
		}
		int n = bytes / 2;
		refFieldtable = new FieldConstant[ n ];
		for( int j = 0; j < n; j++ ){
		    refFieldtable[j] = (FieldConstant)symbols[ in.readUnsignedShort() ];
		}
	    } else if  (name.string.equals(/*NOI18N*/"methodtable")){
		methodtableName = name;
		if (verbose){
		    log.println(Localizer.getString("classinfo.reading_name", name));
		}
		int n = bytes / 2;
		refMethodtable = new MethodConstant[ n ];
		for( int j = 0; j < n; j++ ){
		    refMethodtable[j] = (MethodConstant)symbols[ in.readUnsignedShort() ];
		}
	    } else if  (name.string.equals(/*NOI18N*/"SourceFile")) {
		if (ClassInfo.classDebug) {
		    UnicodeConstant srcName =
			(UnicodeConstant)symbols[in.readUnsignedShort()];
		    sourceFileAttr =
			new SourceFileAttribute(name, bytes, srcName);
		    clssAttr.addElement(sourceFileAttr);
		} else {
		    byte[] b = new byte[bytes];
		    in.readFully(b);
		    clssAttr.addElement
			(new UninterpretedAttribute(name, bytes, b));
		}
	    } else {
		byte[] b = new byte[bytes];
		in.readFully(b);
		clssAttr.addElement
		    (new UninterpretedAttribute(name, bytes, b));
	    }
	}
	int nattr = clssAttr.size();
	if (nattr > 0) {
	    this.classAttributes = new Attribute[nattr];
	    clssAttr.copyInto(classAttributes);
	}
    
voidreadConstantPool(java.io.DataInput in)

	int num = in.readUnsignedShort();

	if(verbose){
	    log.println(Localizer.getString("classinfo.reading_entries_in_constant_pool", Integer.toString(num)));
	}
	constants = new ConstantObject[num];
	for (int i = 1; i < num; i+=constants[i].nSlots) {
	    constants[i] = ConstantObject.readObject( in );
	    constants[i].index = i;
	}
    
voidreadFields(java.io.DataInput in)

	int count = in.readUnsignedShort();
	fields = new FieldInfo[count];
	if(verbose){
	    log.println(Localizer.getString("classinfo.reading_field_members", Integer.toString(count)));
	}

	for (int i = 0; i < count; i++) {
	    fields[i] = FieldInfo.readField(in, this);
	    fields[i].index = i;
	}
    
voidreadInterfaces(java.io.DataInput in)

	int count = in.readUnsignedShort();
	if(verbose){
	    log.println(Localizer.getString("classinfo.reading_interfaces_implemented", Integer.toString(count)));
	}
	interfaces = new ClassConstant[count];
	for (int i = 0; i < count; i++) {
	    //interfaces[i] = (ClassConstant) symbols[in.readUnsignedShort()];
	    // interfaces not external -- they use own constant pool!
	    interfaces[i] = (ClassConstant) constants[in.readUnsignedShort()];
	}
    
voidreadMethods(java.io.DataInput in, boolean readCode)

	int count = in.readUnsignedShort();
	methods = new MethodInfo[count];

	if(verbose){
	    log.println(Localizer.getString(
			"classinfo.reading_methods", Integer.toString(count)));
	}
	for (int i = 0; i < count; i++) {
	    methods[i] = MethodInfo.readMethod( in, this, readCode );
	    methods[i].index = i;
	}
    
public voidrelocateAndPackCode()

        for ( int i = 0; i < methods.length; i++ )
            methods[i].relocateAndPackCode(constants); 
    
public booleanrelocateReferences()

	try {
	    for ( int i = 0; i < methods.length; i++ ){
		methods[i].relocateConstantReferences( oldConstants );
	    }
	} catch ( DataFormatException e ){
	    return false;
	}
	return true;
    
private voidresolveConstants()

	if (verbose){
	    log.println(Localizer.getString("classinfo.>>>resolving_constants"));
	}
	for (int i = 1; i < constants.length; i+=constants[i].nSlots) {
	    constants[i].resolve( symbols );
	}
    
public static booleanresolveSupers()

	Enumeration allclasses = allClasses();
	boolean ok = true;
	while( allclasses.hasMoreElements() ){
	    ClassInfo c = (ClassInfo)allclasses.nextElement();
	    if ( c.superClass==null ){
		// only java.lang.Object can be parentless
		if ( ! c.className.equals( /*NOI18N*/"java/lang/Object" ) ){
		    System.out.println(Localizer.getString("classinfo.class_is_parent-less", c.className));
		    ok = false;
		}
	    } else {
		ClassInfo s = ClassInfo.lookupClass( c.superClass.name.string );
		if ( s == null ){
		    System.out.println(Localizer.getString("classinfo.class_is_missing_parent", c.className, c.superClass.name.string ));
		    ok = false;
		} else {
		    c.superClassInfo = s;
		}
	    }
	}
	return ok;
    
public voidsmashConstantPool()

	int nOld = constants.length;
	int nNew = 1;
	ConstantObject o;
	// first, count and index.
	for ( int i = 1; i < nOld; i += o.nSlots ){
	    o = constants[i];
	    if ( ! o.shared ){
		if ( o.references == 0 ){
		    o.index = -1; // trouble.
		} else {
		    // we're keeping it.
		    o.index = nNew;
		    nNew += o.nSlots;
		}
	    }
	}
	// now reallocate and copy.
	ConstantObject newConstants[] = new ConstantObject[ nNew ];
	int j = 1;
	for ( int i = 1; i < nOld; i += o.nSlots ){
	    o = constants[i];
	    if ( (! o.shared ) && ( o.references != 0 ) ){
		// we're keeping it.
		newConstants[j] = o;
		j += o.nSlots;
	    }
	}
	oldConstants = constants;
	constants = newConstants;
    
public java.lang.StringtoString()

	return /*NOI18N*/"ClassInfo-\""+className+/*NOI18N*/"\"";
    
public voidwrite(java.io.DataOutput o)

	writeConstantPool( o );
	o.writeShort( access );
	o.writeShort( thisClass.index );
	o.writeShort( superClass==null? 0 : superClass.index );
	writeInterfaces( o );
	writeFields( o );
	writeMethods( o );
	writeAttributes( o );
    
voidwriteAttributes(java.io.DataOutput out)

	int count = 0;
	if ( fieldtableName != null )
	    count++;
	if ( methodtableName != null )
	    count++;

	if (classAttributes != null) {
	    count += classAttributes.length;
	}
	out.writeShort(count);

	if ( fieldtableName != null ){
	    writeTableAttribute( out, fieldtableName, refFieldtable );
	}
	if ( methodtableName != null ){
	    writeTableAttribute( out, methodtableName, refMethodtable );
	}
	if (classAttributes != null) {
	    for (int k = 0; k < classAttributes.length; k++) {
		classAttributes[k].write( out );
	    }
	}
    
voidwriteConstantPool(java.io.DataOutput out)

	int num = constants==null ? 0 : constants.length;
	if(verbose){
	    log.println(Localizer.getString("classinfo.writing_constant_pool_entries", Integer.toString(num)));
	}
	out.writeShort( num );
	for (int i = 1; i < num; i+=constants[i].nSlots) {
	    constants[i].write( out );
	}
    
voidwriteFields(java.io.DataOutput out)

	int count = fields==null ? 0 : fields.length;
	if(verbose){
	    log.println(Localizer.getString("classinfo.writing_field_members", Integer.toString(count)));
	}
	out.writeShort( count );
	for (int i = 0; i < count; i++) {
	    fields[i].write( out );
	}
    
voidwriteInterfaces(java.io.DataOutput out)

	int count = interfaces==null ? 0 : interfaces.length;
	if(verbose){
	    log.println(Localizer.getString("classinfo.writing_interfaces_implemented", Integer.toString(count)));
	}
	out.writeShort( count );
	for (int i = 0; i < count; i++) {
	    out.writeShort( interfaces[i].index );
	}
    
voidwriteMethods(java.io.DataOutput out)

	int count = methods==null ? 0 : methods.length;
	if(verbose){
	    log.println(Localizer.getString("classinfo.writing_methods", Integer.toString(count)));
	}
	out.writeShort(count);
	for (int i = 0; i < count; i++) {
	    methods[i].write( out );
	}
    
voidwriteTableAttribute(java.io.DataOutput out, UnicodeConstant name, FMIrefConstant[] table)

	if (verbose){
	    log.println(Localizer.getString("classinfo.writing_name", name.string));
	}
	out.writeShort( name.index );
	int n = table.length;
	out.writeInt( 2*n );
	for ( int i = 0; i < n; i++ ){
	    out.writeShort( table[i].index );
	}