2929import pascal .taie .ir .exp .InstanceFieldAccess ;
3030import pascal .taie .ir .exp .Var ;
3131import pascal .taie .ir .stmt .Invoke ;
32+ import pascal .taie .ir .stmt .LoadArray ;
33+ import pascal .taie .ir .stmt .LoadField ;
3234import pascal .taie .ir .stmt .Stmt ;
3335import pascal .taie .ir .stmt .StoreArray ;
3436import pascal .taie .ir .stmt .StoreField ;
@@ -50,7 +52,10 @@ public class UnsafeModel extends IRModelPlugin {
5052 super (solver );
5153 }
5254
53- @ InvokeHandler (signature = "<sun.misc.Unsafe: boolean compareAndSwapObject(java.lang.Object,long,java.lang.Object,java.lang.Object)>" )
55+ @ InvokeHandler (signature = {
56+ "<sun.misc.Unsafe: boolean compareAndSwapObject(java.lang.Object,long,java.lang.Object,java.lang.Object)>" ,
57+ "<jdk.internal.misc.Unsafe: boolean compareAndSetReference(java.lang.Object,long,java.lang.Object,java.lang.Object)>"
58+ })
5459 public List <Stmt > compareAndSwapObject (Invoke invoke ) {
5560 // unsafe.compareAndSwapObject(o, offset, expected, x);
5661 List <Var > args = invoke .getInvokeExp ().getArgs ();
@@ -77,4 +82,59 @@ public List<Stmt> compareAndSwapObject(Invoke invoke) {
7782 }
7883 return stmts ;
7984 }
85+
86+ @ InvokeHandler (signature = "<jdk.internal.misc.Unsafe: java.lang.Object getReferenceAcquire(java.lang.Object,long)>" )
87+ public List <Stmt > getReferenceAcquire (Invoke invoke ) {
88+ // r = unsafe.getReferenceAcquire(o, offset);
89+ List <Var > args = invoke .getInvokeExp ().getArgs ();
90+ List <Stmt > stmts = new ArrayList <>();
91+ Var o = args .get (0 );
92+ Var r = invoke .getResult ();
93+ if (r == null ) {
94+ return List .of ();
95+ }
96+ if (o .getType () instanceof ArrayType ) { // if o is of ArrayType
97+ // generate r = o[i];
98+ Var i = new Var (invoke .getContainer (),
99+ "%unsafe-index" + counter ++, IntType .INT , -1 );
100+ stmts .add (new LoadArray (r , new ArrayAccess (o , i )));
101+ } else { // otherwise, o is of ClassType
102+ // generate r = o.f; for every field f.
103+ JClass clazz = ((ClassType ) o .getType ()).getJClass ();
104+ Type rType = r .getType ();
105+ clazz .getDeclaredFields ()
106+ .stream ()
107+ .filter (field -> !field .isStatic ())
108+ .filter (f -> f .getType ().equals (rType ))
109+ .forEach (f -> stmts .add (new LoadField (
110+ r , new InstanceFieldAccess (f .getRef (), o ))));
111+ }
112+ return stmts ;
113+ }
114+
115+ @ InvokeHandler (signature = "<jdk.internal.misc.Unsafe: void putReferenceRelease(java.lang.Object,long,java.lang.Object)>" )
116+ public List <Stmt > putReferenceRelease (Invoke invoke ) {
117+ // unsafe.putReferenceRelease(o, offset, x);
118+ List <Var > args = invoke .getInvokeExp ().getArgs ();
119+ List <Stmt > stmts = new ArrayList <>();
120+ Var o = args .get (0 );
121+ Var x = args .get (2 );
122+ if (o .getType () instanceof ArrayType ) { // if o is of ArrayType
123+ // generate o[i] = x;
124+ Var i = new Var (invoke .getContainer (),
125+ "%unsafe-index" + counter ++, IntType .INT , -1 );
126+ stmts .add (new StoreArray (new ArrayAccess (o , i ), x ));
127+ } else { // otherwise, o is of ClassType
128+ // generate o.f = x; for field f that has the same type of x.
129+ JClass clazz = ((ClassType ) o .getType ()).getJClass ();
130+ Type xType = x .getType ();
131+ clazz .getDeclaredFields ()
132+ .stream ()
133+ .filter (field -> !field .isStatic ())
134+ .filter (f -> f .getType ().equals (xType ))
135+ .forEach (f -> stmts .add (new StoreField (
136+ new InstanceFieldAccess (f .getRef (), o ), x )));
137+ }
138+ return stmts ;
139+ }
80140}
0 commit comments