// // Copyright (C) 2006 United States Government as represented by the // Administrator of the National Aeronautics and Space Administration // (NASA). All Rights Reserved. // // This software is distributed under the NASA Open Source Agreement // (NOSA), version 1.3. The NOSA has been approved by the Open Source // Initiative. See the file NOSA-1.3-JPF at the top of the distribution // directory tree for the complete NOSA document. // // THE SUBJECT SOFTWARE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY OF ANY // KIND, EITHER EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT // LIMITED TO, ANY WARRANTY THAT THE SUBJECT SOFTWARE WILL CONFORM TO // SPECIFICATIONS, ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR // A PARTICULAR PURPOSE, OR FREEDOM FROM INFRINGEMENT, ANY WARRANTY THAT // THE SUBJECT SOFTWARE WILL BE ERROR FREE, OR ANY WARRANTY THAT // DOCUMENTATION, IF PROVIDED, WILL CONFORM TO THE SUBJECT SOFTWARE. // package gov.nasa.jpf.vm; import gov.nasa.jpf.Config; import gov.nasa.jpf.util.StringSetMatcher; /** * default Attributor implementation to set method and fiel attributes * at class load time. Note this is critical functionality, esp. * with respect to threading */ public class DefaultAttributor implements Attributor { static StringSetMatcher atomicMethods; static StringSetMatcher neverBreak; static StringSetMatcher breakShared; public DefaultAttributor (Config conf) { String[] val; val = conf.getStringArray("vm.por.field_boundaries.never"); if (val != null) { neverBreak = new StringSetMatcher(val); } if (conf.getBoolean("vm.por.field_boundaries")) { val = conf.getStringArray("vm.por.field_boundaries.break"); if (val != null) { breakShared = new StringSetMatcher(val); } } val = conf.getStringArray("vm.por.atomic_methods"); if (val != null) { atomicMethods = new StringSetMatcher(val); } } // <2do> we should turn atomicity and scheduling relevance into general // MethodInfo attributes, to keep it consistent with object and field attrs public void setMethodInfoAttributes (MethodInfo mi) { ClassInfo ci = mi.getClassInfo(); String clsName = ci.getName(); String uniqueName = mi.getUniqueName(); if (atomicMethods != null && atomicMethods.matchesAny(uniqueName)){ // but exclude the known blocking methods (Object.wait()/notify(), Thread.join()) // <2do> this should be configurable too if (clsName.equals("java.lang.Object")) { if (uniqueName.startsWith("wait(") || uniqueName.equals("notify()V")) { return; } } else if (clsName.equals("java.lang.Thread")) { if (uniqueName.equals("join()V")) { return; } } // <2do> this is not used - either we have to or this is removed mi.setAtomic(true); } } /** * answer the type based object attributes for this class. See * ElementInfo for valid choices */ public void setElementInfoAttributes (ClassInfo ci) { String clsName = ci.getName(); // very very simplistic for now if (clsName.equals("java.lang.String") || clsName.equals("java.lang.Integer") || clsName.equals("java.lang.Long") || clsName.equals("java.lang.Class") /* ..and a lot more.. */ ) { ci.setElementInfoAttrs(ElementInfo.ATTR_IMMUTABLE); } } public void setFieldInfoAttributes (FieldInfo fi) { int attr = 0; String fid = fi.getFullName(); if (fi.isFinal()) { // <2do> Hmm, finals are not really immutable, they only can be set once // <2do> same here - FieldInfo does not even have a isImmutable() attr |= ElementInfo.ATTR_IMMUTABLE; } // <2do> what about other immutable fields? don't say there are none - try to set one // of the compiler generated magics (like 'this$xx' in inner classes) //--- por field boundary attributes if (neverBreak != null) { if (neverBreak.matchesAny(fid)) { attr |= FieldInfo.NEVER_BREAK; } } if (breakShared != null) { if (breakShared.matchesAny(fid)) { attr |= FieldInfo.BREAK_SHARED; } } fi.setAttributes(attr); } }