comparison src/main/gov/nasa/jpf/vm/PreciseAllocationContext.java @ 0:61d41facf527

initial v8 import (history reset)
author Peter Mehlitz <Peter.C.Mehlitz@nasa.gov>
date Fri, 23 Jan 2015 10:14:01 -0800
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:61d41facf527
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.vm;
19
20 import gov.nasa.jpf.Config;
21 import gov.nasa.jpf.util.OATHash;
22
23 import java.util.Arrays;
24 import java.util.HashMap;
25
26 /**
27 * class that captures execution context consisting of executing thread and
28 * pc's of ti's current StackFrames
29 *
30 * note that we pool (i.e. use static factory methods) in order to avoid
31 * creating a myriad of redundant objects
32 */
33 public class PreciseAllocationContext implements AllocationContext {
34
35 // this is search global, i.e. does not have to be backtracked, but has to be
36 // re-initialized between JPF runs (everything that changes hashCode)
37 static private HashMap<PreciseAllocationContext,PreciseAllocationContext> ccCache = new HashMap<PreciseAllocationContext,PreciseAllocationContext>();
38
39 protected ThreadInfo ti;
40 protected Instruction[] cc;
41 protected int hashCode; // computed once during construction (from LookupContext)
42
43 // a mutable ExecutionContext that is only used internally to avoid creating superfluous new instances to
44 // find out if we already have seen a similar one
45 private static class LookupContext extends PreciseAllocationContext {
46 int stackDepth;
47
48 LookupContext (){
49 cc = new Instruction[64];
50 }
51
52 @Override
53 public int getStackDepth(){
54 return stackDepth;
55 }
56 }
57
58 private static LookupContext lookupContext = new LookupContext();
59
60 static boolean init (Config config) {
61 ccCache = new HashMap<PreciseAllocationContext,PreciseAllocationContext>();
62 return true;
63 }
64
65 public static synchronized PreciseAllocationContext getSUTExecutionContext (ClassInfo ci, ThreadInfo ti){
66 int stackDepth = ti.getStackDepth();
67 int h = 0;
68
69 lookupContext.ti = ti;
70 lookupContext.stackDepth = stackDepth;
71
72 h = OATHash.hashMixin(h, ti.getId());
73
74 Instruction[] cc = lookupContext.cc;
75 if (cc.length < stackDepth){
76 cc = new Instruction[stackDepth];
77 lookupContext.cc = cc;
78 }
79
80 int i=0;
81 for (StackFrame f = ti.getTopFrame(); f != null; f = f.getPrevious()){
82 Instruction insn = f.getPC();
83 cc[i++] = insn;
84 h = OATHash.hashMixin(h, insn.hashCode());
85 }
86 h = OATHash.hashFinalize(h);
87 lookupContext.hashCode = h;
88
89 PreciseAllocationContext ec = ccCache.get(lookupContext);
90 if (ec == null){
91 ec = new PreciseAllocationContext(ti, Arrays.copyOf(cc, stackDepth), h);
92 ccCache.put(ec, ec);
93 }
94
95 return ec;
96 }
97
98 protected PreciseAllocationContext(){
99 // for subclassing
100 }
101
102 // we only construct this from a LookupContext, which already has all the data
103 private PreciseAllocationContext (ThreadInfo ti, Instruction[] cc, int hashCode){
104 this.ti = ti;
105 this.cc = cc;
106 this.hashCode = hashCode;
107 }
108
109 @Override
110 public int hashCode(){
111 return hashCode;
112 }
113
114 public int getStackDepth(){
115 return cc.length;
116 }
117
118 @Override
119 public boolean equals (Object o){
120 if (o == this){ // identity shortcut
121 return true;
122
123 } else {
124 if (o instanceof PreciseAllocationContext){
125 PreciseAllocationContext other = (PreciseAllocationContext)o;
126 if (hashCode == other.hashCode){ // we might get here because of bin masking
127 if (ti.getId() == other.ti.getId()) {
128 Instruction[] ccOther = other.cc;
129 if (cc.length == other.getStackDepth()) {
130 for (int i = 0; i < cc.length; i++) {
131 if (cc[i] != ccOther[i]) {
132 return false;
133 }
134 }
135 return true;
136 }
137 }
138 }
139 }
140
141 return false;
142 }
143 }
144
145 // for automatic field init allocations
146 @Override
147 public AllocationContext extend (ClassInfo ci, int anchor) {
148 return new PreciseAllocationContext(ti, cc, OATHash.hash(hashCode, ci.hashCode()));
149 }
150
151 /** mostly for debugging purposes */
152 @Override
153 public String toString(){
154 StringBuffer sb = new StringBuffer();
155 sb.append("(tid=");
156 sb.append(ti.getId());
157 sb.append(",stack=[");
158 for (int i=0; i<cc.length; i++){
159 if (i>0){
160 sb.append(',');
161 }
162 sb.append(cc[i]);
163 }
164 sb.append("])");
165 return sb.toString();
166 }
167 }