Initial import
[jpf-core.git] / src / peers / gov / nasa / jpf / vm / JPF_gov_nasa_jpf_test_MemoryGoal.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
19 package gov.nasa.jpf.vm;
20
21 import gov.nasa.jpf.ListenerAdapter;
22 import gov.nasa.jpf.annotation.MJI;
23 import gov.nasa.jpf.jvm.bytecode.JVMReturnInstruction;
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.MJIEnv;
28 import gov.nasa.jpf.vm.MethodInfo;
29 import gov.nasa.jpf.vm.NativePeer;
30
31 /**
32  * native peer for MemoryGoal tests
33  */
34 public class JPF_gov_nasa_jpf_test_MemoryGoal extends NativePeer {
35
36   Listener listener;
37   
38   // <2do> that's too simple, because we should only measure what is
39   // allocated from the invoked method, not the MethodTester. Needs a listener
40   
41   static class Listener extends ListenerAdapter {
42     
43     MethodInfo mi;
44     boolean active;
45     
46     long nAllocBytes;
47     long nFreeBytes;
48     long nAlloc;
49     long nFree;
50     
51     Listener (MethodInfo mi){
52       this.mi = mi;
53     }
54     
55     @Override
56     public void objectCreated (VM vm, ThreadInfo ti, ElementInfo ei){
57       if (active){        
58         nAlloc++;
59         nAllocBytes += ei.getHeapSize(); // just an approximation
60       }
61     }
62     
63     @Override
64     public void objectReleased (VM vm, ThreadInfo ti, ElementInfo ei){
65       if (active){
66         nFree++;
67         nFreeBytes += ei.getHeapSize(); // just an approximation
68       }      
69     }
70
71     @Override
72     public void instructionExecuted (VM vm, ThreadInfo ti, Instruction nextInsn, Instruction executedInsn){
73       if (!active) {
74         if (executedInsn.getMethodInfo() == mi){
75           active = true;
76         }
77       } else {
78         if ((executedInsn instanceof JVMReturnInstruction) && (executedInsn.getMethodInfo() == mi)){
79           active = false;
80         }
81       }
82     }
83     
84     long totalAllocBytes() {
85       return nAllocBytes - nFreeBytes;
86     }
87   }
88   
89   @MJI
90   public boolean preCheck__Lgov_nasa_jpf_test_TestContext_2Ljava_lang_reflect_Method_2__Z
91                       (MJIEnv env, int objRef, int testContextRef, int methodRef){
92     MethodInfo mi = JPF_java_lang_reflect_Method.getMethodInfo(env, methodRef);
93     
94     listener = new Listener(mi);
95     env.addListener(listener);
96     return true;
97   }
98   
99   // what a terrible name!
100   @MJI
101   public boolean postCheck__Lgov_nasa_jpf_test_TestContext_2Ljava_lang_reflect_Method_2Ljava_lang_Object_2Ljava_lang_Throwable_2__Z 
102            (MJIEnv env, int objRef, int testContextRef, int methdRef, int resultRef, int exRef){
103
104     long nMax = env.getLongField(objRef, "maxGrowth");
105
106     Listener l = listener;
107     env.removeListener(l);
108     listener = null;
109     
110     return (l.totalAllocBytes() <= nMax);
111   }
112 }