+ private final static String GROOVY_CALLSITE_LIB = "org.codehaus.groovy.runtime.callsite";
+ private final static String JAVA_STRING_LIB = "java.lang.String";
+ private final static String JAVA_INTEGER = "int";
+ private final static String DO_CALL_METHOD = "doCall";
+ private final static String GET_PROPERTY_METHOD =
+ "invokeinterface org.codehaus.groovy.runtime.callsite.CallSite.callGetProperty";
+ private final static String[] EXCLUDED_FIELDS_ITERATOR = {"java.util.LinkedHashMap"};
+
+ private ReadWriteSet getReadWriteSet(int currentChoice) {
+ // Do the analysis to get Read and Write accesses to fields
+ ReadWriteSet rwSet;
+ // We already have an entry
+ if (readWriteFieldsMap.containsKey(refChoices[currentChoice])) {
+ rwSet = readWriteFieldsMap.get(refChoices[currentChoice]);
+ } else { // We need to create a new entry
+ rwSet = new ReadWriteSet();
+ readWriteFieldsMap.put(refChoices[currentChoice], rwSet);
+ }
+ return rwSet;
+ }
+
+ private void analyzeReadWriteAccesses(Instruction instruction, ThreadInfo ti, int currentChoice) {
+ // Get method name
+ INVOKEINTERFACE insn = (INVOKEINTERFACE) instruction;
+ if (insn.toString().startsWith(GET_PROPERTY_METHOD) &&
+ insn.getMethodInfo().getName().equals(DO_CALL_METHOD)) {
+ // Extract info from the stack frame
+ StackFrame frame = ti.getTopFrame();
+ int[] frameSlots = frame.getSlots();
+ // Get the Groovy callsite library at index 0
+ ElementInfo eiCallsite = VM.getVM().getHeap().get(frameSlots[0]);
+ if (!eiCallsite.getClassInfo().getName().startsWith(GROOVY_CALLSITE_LIB)) {
+ return;
+ }
+ // Get the iterated object whose property is accessed
+ ElementInfo eiAccessObj = VM.getVM().getHeap().get(frameSlots[1]);
+ // TODO: MIGHT NEED TO EXCLUDE OTHER UNRELATED OBJECTS!
+ for (String excludedField : EXCLUDED_FIELDS_ITERATOR) {
+ if (eiAccessObj.getClassInfo().getName().startsWith(excludedField)) {
+ return;
+ }
+ }
+ // Extract fields from this object and put them into the read write
+ int numOfFields = eiAccessObj.getNumberOfFields();
+ for(int i=0; i<numOfFields; i++) {
+ FieldInfo fieldInfo = eiAccessObj.getFieldInfo(i);
+ if (fieldInfo.getType().equals(JAVA_STRING_LIB) || fieldInfo.getType().equals(JAVA_INTEGER)) {
+ String fieldClass = fieldInfo.getFullName();
+ ReadWriteSet rwSet = getReadWriteSet(currentChoice);
+ int objectId = fieldInfo.getClassInfo().getClassObjectRef();
+ // Record the field in the map
+ rwSet.addReadField(fieldClass, objectId);
+ }
+ }
+
+ }
+ }
+