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