Preparing for tracking the object creation etc.
[jpf-core.git] / src / peers / gov / nasa / jpf / vm / JPF_java_util_concurrent_atomic_AtomicIntegerFieldUpdater.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.annotation.MJI;
22
23
24 /**
25  * a full peer for the AtomicIntegerFieldUpdater
26  */
27 public class JPF_java_util_concurrent_atomic_AtomicIntegerFieldUpdater extends AtomicFieldUpdater {
28
29   @MJI
30   public void $init__Ljava_lang_Class_2Ljava_lang_String_2__V (MJIEnv env, int objRef, int tClsObjRef, int fNameRef) {
31
32     // direct Object subclass, so we don't have to call a super ctor
33
34     ClassInfo ci = env.getReferredClassInfo( tClsObjRef);
35     String fname = env.getStringObject(fNameRef);
36
37     FieldInfo fi = ci.getInstanceField(fname);
38     ClassInfo fci = fi.getTypeClassInfo();
39
40     if (!fci.isPrimitive() || !fci.getName().equals("int")) {
41       // that's also just an approximation, but we need to check
42       env.throwException("java.lang.RuntimeException", "wrong field type");
43     }
44
45     int fidx = fi.getFieldIndex();
46     env.setIntField(objRef, "fieldId", fidx);
47   }
48
49   @MJI
50   public boolean compareAndSet__Ljava_lang_Object_2II__Z (MJIEnv env, int objRef, int tRef, int fExpect, int fUpdate) {    
51     if (tRef == MJIEnv.NULL){
52       env.throwException("java.lang.NullPointerException", "AtomicFieldUpdater called on null object");
53       return false;
54     }
55     
56     ThreadInfo ti = env.getThreadInfo();
57     ElementInfo ei = ti.getModifiableElementInfo(tRef);
58     FieldInfo fi = getFieldInfo( ti.getElementInfo(objRef), ei);
59
60     if (reschedulesAccess(ti, ei, fi)){
61       env.repeatInvocation();
62       return false;
63     }
64         
65     int v = ei.getIntField(fi);
66     if (v == fExpect) {
67       ei = ei.getModifiableInstance();
68       ei.setIntField(fi, fUpdate);
69       return true;
70     } else {
71       return false;
72     }
73   }
74
75   @MJI
76   public boolean weakCompareAndSet__Ljava_lang_Object_2II__Z (MJIEnv env, int objRef, int tRef, int fExpect, int fUpdate) {
77     return (compareAndSet__Ljava_lang_Object_2II__Z(env, objRef, tRef, fExpect, fUpdate));
78   }
79
80   @MJI
81   public void set__Ljava_lang_Object_2I__V (MJIEnv env, int objRef, int tRef, int fNewValue) {
82     if (tRef == MJIEnv.NULL){
83       env.throwException("java.lang.NullPointerException", "AtomicFieldUpdater called on null object");
84       return;
85     }
86     
87     ThreadInfo ti = env.getThreadInfo();
88     ElementInfo ei = ti.getModifiableElementInfo(tRef);
89     FieldInfo fi = getFieldInfo( ti.getElementInfo(objRef), ei);
90
91     if (reschedulesAccess(ti, ei, fi)){
92       env.repeatInvocation();
93       return;
94     }
95
96     ei.setIntField(fi, fNewValue);
97   }
98
99   @MJI
100   public void lazySet__Ljava_lang_Object_2I__V (MJIEnv env, int objRef, int tRef, int fNewValue) {
101     set__Ljava_lang_Object_2I__V(env, objRef, tRef, fNewValue);
102   }
103
104   @MJI
105   public int get__Ljava_lang_Object_2__I(MJIEnv env, int objRef, int tRef) {
106     if (tRef == MJIEnv.NULL){
107       env.throwException("java.lang.NullPointerException", "AtomicFieldUpdater called on null object");
108       return 0;
109     }
110     
111     ThreadInfo ti = env.getThreadInfo();
112     ElementInfo ei = ti.getElementInfo(tRef);
113     FieldInfo fi = getFieldInfo( ti.getElementInfo(objRef), ei);
114
115     if (reschedulesAccess(ti, ei, fi)){
116       env.repeatInvocation();
117       return 0;
118     }
119
120
121     return ei.getIntField(fi);
122   }
123
124   @MJI
125   public int getAndSet__Ljava_lang_Object_2I__I (MJIEnv env, int objRef, int tRef, int fNewValue) {
126     if (tRef == MJIEnv.NULL){
127       env.throwException("java.lang.NullPointerException", "AtomicFieldUpdater called on null object");
128       return 0;
129     }
130     
131     ThreadInfo ti = env.getThreadInfo();
132     ElementInfo ei = ti.getModifiableElementInfo(tRef);
133     FieldInfo fi = getFieldInfo( ti.getElementInfo(objRef), ei);
134
135     if (reschedulesAccess(ti, ei, fi)){
136       env.repeatInvocation();
137       return 0;
138     }
139
140     int result = ei.getIntField(fi);
141     ei.setIntField(fi, fNewValue);
142
143     return result;
144   }
145
146   @MJI
147   public int getAndAdd__Ljava_lang_Object_2I__I (MJIEnv env, int objRef, int tRef, int fDelta) {
148     if (tRef == MJIEnv.NULL){
149       env.throwException("java.lang.NullPointerException", "AtomicFieldUpdater called on null object");
150       return 0;
151     }
152     
153     ThreadInfo ti = env.getThreadInfo();
154     ElementInfo ei = ti.getModifiableElementInfo(tRef);
155     FieldInfo fi = getFieldInfo( ti.getElementInfo(objRef), ei);
156
157     if (reschedulesAccess(ti, ei, fi)){
158       env.repeatInvocation();
159       return 0;
160     }
161
162     int result = ei.getIntField(fi);
163     ei.setIntField(fi, result + fDelta);
164
165     return result;
166   }
167
168 }