001: //
002: // Copyright (C) 2005 United States Government as represented by the
003: // Administrator of the National Aeronautics and Space Administration
004: // (NASA). All Rights Reserved.
005: //
006: // This software is distributed under the NASA Open Source Agreement
007: // (NOSA), version 1.3. The NOSA has been approved by the Open Source
008: // Initiative. See the file NOSA-1.3-JPF at the top of the distribution
009: // directory tree for the complete NOSA document.
010: //
011: // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY
012: // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT
013: // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO
014: // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR
015: // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT
016: // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT
017: // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE.
018: //
019: package gov.nasa.jpf.jvm;
020:
021: import gov.nasa.jpf.Config;
022: import gov.nasa.jpf.JPFException;
023: import gov.nasa.jpf.util.Debug;
024:
025: /**
026: * memory area for static fields
027: */
028: public class StaticArea extends Area {
029:
030: public static void init(Config config) {
031: StaticMap.init();
032: }
033:
034: /**
035: * Creates a new empty static area.
036: */
037: public StaticArea(Config config, KernelState ks) {
038: super (ks, StaticElementInfo.storingDataLength);
039: }
040:
041: public StaticArea(StaticArea sa) {
042: super (sa);
043: }
044:
045: public boolean isStatic() {
046: return true;
047: }
048:
049: public Object clone() {
050: return new StaticArea(this );
051: }
052:
053: public boolean containsClass(String cname) {
054: return indexOf(cname) != -1;
055: }
056:
057: public StaticElementInfo get(String cname) {
058: int index = indexOf(cname);
059:
060: if (index == -1) {
061: newClass(ClassInfo.getClassInfo(cname));
062: }
063:
064: return (StaticElementInfo) get(indexOf(cname));
065: }
066:
067: /**
068: * Returns the index of a given class.
069: */
070: public int indexOf(String cname) {
071: synchronized (StaticMap.class) {
072: if (!StaticMap.hasEntry(cname)) {
073: return -1;
074: }
075:
076: int index = StaticMap.getEntry(cname);
077:
078: if ((index >= 0) && (index < elements.length)
079: && (elements[index] != null)) {
080: return index;
081: } else {
082: return -1;
083: }
084: }
085: }
086:
087: public void initializeClasses() {
088: int length = elements.length;
089: ThreadInfo th = ks.ss.getRunningThread();
090:
091: for (int i = 0; i < length; i++) {
092: if (elements[i] != null) {
093: StaticElementInfo ei = (StaticElementInfo) elements[i];
094: ClassInfo ci = ei.getClassInfo();
095:
096: if (ei.classObjectRef == -1) {
097: // must have been a startup class
098: ei.classObjectRef = ci.createClassObject(th, i);
099: }
100:
101: ci.initializeClass(th);
102: }
103: }
104: }
105:
106: public void log() {
107: Debug.println(Debug.MESSAGE, "SA");
108:
109: for (int i = 0; i < elements.length; i++) {
110: if (elements[i] != null) {
111: elements[i].log();
112: }
113: }
114: }
115:
116: public void markRoots() {
117: int length = elements.length;
118:
119: for (int i = 0; i < length; i++) {
120: StaticElementInfo ei = (StaticElementInfo) elements[i];
121: if (ei != null) {
122: ei.markStaticRoot();
123: }
124: }
125: }
126:
127: /**
128: * to deal with recursive loads/inits, we don't throw exceptions when encountering
129: * a class that's aleady in. Inclusion is checked by the caller, we just make
130: * sure here it doesn't get initialized twice. However, we cannot add early, silently
131: * step over recursive requests, and initialize when we get out of recursion - the
132: * recursive calls might rely on proper initialization being done, i.e. we
133: * have to initermost
134: *
135: * watch out - we can't use this for startup classes (would
136: * end up in infinite recursion)
137: */
138: public int newClass(ClassInfo ci) {
139: int index = indexOf(ci.getName());
140:
141: if (index == -1) {
142: // make sure the superclass is loaded and initialized
143: ClassInfo sci = ci.getSuperClass();
144:
145: if ((sci != null) && !containsClass(sci.getName())) {
146: newClass(sci); // might get recursive here
147: }
148:
149: index = indexOf(ci.getName());
150: if (index == -1) {
151: index = getNewIndexFor(ci.getName());
152:
153: ThreadInfo th = ks.ss.getRunningThread();
154: int cref = ci.createClassObject(th, index);
155: StaticElementInfo ei = createElementInfo(ci, cref);
156:
157: add(index, ei);
158:
159: ci.initializeClass(th); // or here
160: }
161: }
162:
163: return index;
164: }
165:
166: ElementInfo createElementInfo() {
167: return new StaticElementInfo();
168: }
169:
170: int newUninitializedClass(ClassInfo ci) {
171: int index = getNewIndexFor(ci.getName());
172:
173: ThreadInfo th = ks.ss.getRunningThread();
174: int cref = ci.createClassObject(th, index);
175: StaticElementInfo ei = createElementInfo(ci, cref);
176:
177: add(index, ei);
178:
179: return index;
180: }
181:
182: StaticElementInfo createElementInfo(ClassInfo ci, int classObjRef) {
183: Fields f = ci.createStaticFields(this );
184: Monitor m = new Monitor();
185:
186: StaticElementInfo ei = new StaticElementInfo(f, m, classObjRef);
187:
188: return ei;
189: }
190:
191: /**
192: * this is for the VM bootstrapping, i.e. we can't do clinit or
193: * create class objects yet, but we need to get elements entries
194: */
195: int newStartupClass(ClassInfo ci) {
196: StaticElementInfo ei = createElementInfo(ci, -1);
197: int index = getNewIndexFor(ci.getName());
198:
199: add(index, ei);
200:
201: return index;
202: }
203:
204: private static int getNewIndexFor(String cname) {
205: return StaticMap.addEntry(cname);
206: }
207: }
|