Fixing bugs and cleaning up: Continuing sub-graph executions when there is no matched...
[jpf-core.git] / src / main / gov / nasa / jpf / listener / ReferenceLocator.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package gov.nasa.jpf.listener;
19
20 import gov.nasa.jpf.Config;
21 import gov.nasa.jpf.ListenerAdapter;
22 import gov.nasa.jpf.jvm.bytecode.JVMInstanceFieldInstruction;
23 import gov.nasa.jpf.jvm.bytecode.InstanceInvocation;
24 import gov.nasa.jpf.vm.ElementInfo;
25 import gov.nasa.jpf.vm.Instruction;
26 import gov.nasa.jpf.vm.VM;
27 import gov.nasa.jpf.vm.StackFrame;
28 import gov.nasa.jpf.vm.ThreadInfo;
29
30 import java.io.PrintWriter;
31 import java.util.Arrays;
32
33 /**
34  * tiny utility listener that can be used to find out where a certain
35  * object (specified by reference) gets allocated or accessed (call or field),
36  * and when it gets gc'ed
37  */
38 public class ReferenceLocator extends ListenerAdapter {
39   
40   PrintWriter pw;
41   int[] createRefs;
42   int[] releaseRefs;
43   int[] useRefs;
44   
45   public ReferenceLocator (Config conf){
46     createRefs = sort( conf.getIntArray("refloc.create"));
47     releaseRefs = sort( conf.getIntArray("refloc.release"));
48     useRefs = sort( conf.getIntArray("refloc.use"));
49     
50     // <2do> we might want to configure output destination
51     pw = new PrintWriter(System.out, true);
52   }
53   
54   protected int[] sort(int[] a){
55     if (a != null){
56       Arrays.sort(a);
57     }
58     return a;
59   }
60   
61   protected void printLocation(String msg, ThreadInfo ti){
62     pw.println(msg);
63     for (StackFrame frame : ti) {
64       pw.print("\tat ");
65       pw.println(frame.getStackTraceInfo());
66     }
67
68     pw.println();
69   }
70   
71   @Override
72   public void objectCreated (VM vm, ThreadInfo ti, ElementInfo ei){
73     int ref = ei.getObjectRef();
74     
75     if (createRefs != null && Arrays.binarySearch(createRefs, ref) >= 0){    
76       printLocation("[ReferenceLocator] object " + ei + " created at:", ti);
77     } 
78   }
79   
80   @Override
81   public void objectReleased (VM vm, ThreadInfo ti, ElementInfo ei){
82     int ref = ei.getObjectRef();
83     
84     if (releaseRefs != null && Arrays.binarySearch(releaseRefs, ref) >= 0){
85       pw.println("[ReferenceLocator] object " + ei + " released");
86     }
87   }
88   
89   @Override
90   public void instructionExecuted (VM vm, ThreadInfo ti, Instruction nextInsn, Instruction executedInsn){
91     
92     if (useRefs != null){
93       if (executedInsn instanceof InstanceInvocation) {
94         int ref = ((InstanceInvocation)executedInsn).getCalleeThis(ti);
95         if (Arrays.binarySearch(useRefs, ref) >= 0){
96           printLocation("[ReferenceLocator] call on object " + ti.getElementInfo(ref) + " at:", ti);
97         }
98       } else if (executedInsn instanceof JVMInstanceFieldInstruction){
99         int ref = ((JVMInstanceFieldInstruction)executedInsn).getLastThis();
100         if (Arrays.binarySearch(useRefs, ref) >= 0){
101           printLocation("[ReferenceLocator] field access of " + ti.getElementInfo(ref) + " at:", ti);          
102         }
103       }
104     }
105   }
106 }