[Ikvm-commit] ikvm/runtime intrinsics.cs,1.45,1.46
Brought to you by:
jfrijters
|
From: Jeroen F. <jfr...@us...> - 2014-11-14 15:28:36
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv10249 Modified Files: intrinsics.cs Log Message: Added intrinsic for array version of Unsafe.getAndSetObject(). Index: intrinsics.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/intrinsics.cs,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** intrinsics.cs 19 May 2014 12:43:43 -0000 1.45 --- intrinsics.cs 14 Nov 2014 15:28:34 -0000 1.46 *************** *** 210,213 **** --- 210,214 ---- intrinsics.Add(new IntrinsicKey("sun.misc.Unsafe", "getObject", "(Ljava.lang.Object;J)Ljava.lang.Object;"), Unsafe_getObjectVolatile); intrinsics.Add(new IntrinsicKey("sun.misc.Unsafe", "compareAndSwapObject", "(Ljava.lang.Object;JLjava.lang.Object;Ljava.lang.Object;)Z"), Unsafe_compareAndSwapObject); + intrinsics.Add(new IntrinsicKey("sun.misc.Unsafe", "getAndSetObject", "(Ljava.lang.Object;JLjava.lang.Object;)Ljava.lang.Object;"), Unsafe_getAndSetObject); return intrinsics; } *************** *** 867,870 **** --- 868,914 ---- } + private static bool Unsafe_getAndSetObject(EmitIntrinsicContext eic) + { + TypeWrapper tw = eic.GetStackTypeWrapper(0, 2); + if (IsSupportedArrayTypeForUnsafeOperation(tw) + && eic.GetStackTypeWrapper(0, 0).IsAssignableTo(tw.ElementTypeWrapper)) + { + Type type = tw.TypeAsLocalOrStackType.GetElementType(); + CodeEmitterLocal newValue = eic.Emitter.AllocTempLocal(type); + CodeEmitterLocal index = eic.Emitter.AllocTempLocal(Types.Int32); + CodeEmitterLocal obj = eic.Emitter.AllocTempLocal(tw.TypeAsLocalOrStackType); + eic.Emitter.Emit(OpCodes.Stloc, newValue); + eic.Emitter.Emit(OpCodes.Conv_Ovf_I4); + eic.Emitter.Emit(OpCodes.Stloc, index); + eic.Emitter.Emit(OpCodes.Stloc, obj); + EmitConsumeUnsafe(eic); + eic.Emitter.Emit(OpCodes.Ldloc, obj); + eic.Emitter.Emit(OpCodes.Ldloc, index); + eic.Emitter.Emit(OpCodes.Ldelema, type); + eic.Emitter.Emit(OpCodes.Ldloc, newValue); + eic.Emitter.Emit(OpCodes.Call, MakeExchange(type)); + eic.Emitter.ReleaseTempLocal(obj); + eic.Emitter.ReleaseTempLocal(index); + eic.Emitter.ReleaseTempLocal(newValue); + eic.NonLeaf = false; + return true; + } + return false; + } + + internal static MethodInfo MakeExchange(Type type) + { + MethodInfo interlockedExchange = null; + foreach (MethodInfo m in JVM.Import(typeof(System.Threading.Interlocked)).GetMethods()) + { + if (m.Name == "Exchange" && m.IsGenericMethodDefinition) + { + interlockedExchange = m; + break; + } + } + return interlockedExchange.MakeGenericMethod(type); + } + private static void EmitConsumeUnsafe(EmitIntrinsicContext eic) { |