[Ikvm-commit] ikvm/runtime ClassFile.cs, 1.124, 1.125 DynamicTypeWrapper.cs, 1.240, 1.241
Brought to you by:
jfrijters
|
From: Jeroen F. <jfr...@us...> - 2014-05-27 12:32:28
|
Update of /cvsroot/ikvm/ikvm/runtime In directory sfp-cvs-1.v30.ch3.sourceforge.com:/tmp/cvs-serv27925/runtime Modified Files: ClassFile.cs DynamicTypeWrapper.cs Log Message: Replaced Unsafe cas operations in Class with Interlocked.CompareExchange(). Index: DynamicTypeWrapper.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/DynamicTypeWrapper.cs,v retrieving revision 1.240 retrieving revision 1.241 diff -C2 -d -r1.240 -r1.241 *** DynamicTypeWrapper.cs 21 May 2014 07:21:21 -0000 1.240 --- DynamicTypeWrapper.cs 27 May 2014 12:32:26 -0000 1.241 *************** *** 4098,4101 **** --- 4098,4106 ---- continue; } + if (m.InterlockedCompareAndSetField != null && EmitInterlockedCompareAndSet(methods[i], m.InterlockedCompareAndSetField, ilGenerator)) + { + ilGenerator.DoEmit(); + continue; + } #endif // see if there exists a "managed JNI" class for this type *************** *** 4460,4463 **** --- 4465,4538 ---- } + #if STATIC_COMPILER + private bool EmitInterlockedCompareAndSet(MethodWrapper method, string fieldName, CodeEmitter ilGenerator) + { + TypeWrapper[] parameters = method.GetParameters(); + if (!method.IsStatic || parameters.Length != 3 || method.ReturnType != PrimitiveTypeWrapper.BOOLEAN) + { + return false; + } + if (parameters[0].IsUnloadable || parameters[0].IsPrimitive || parameters[0].IsNonPrimitiveValueType || parameters[0].IsGhost) + { + return false; + } + if (parameters[1] != parameters[2]) + { + return false; + } + if (parameters[1].IsUnloadable || parameters[1].IsPrimitive || parameters[1].IsNonPrimitiveValueType || parameters[1].IsGhost) + { + return false; + } + FieldWrapper casField = null; + foreach (FieldWrapper fw in parameters[0].GetFields()) + { + if (fw.Name == fieldName) + { + if (casField != null) + { + return false; + } + casField = fw; + } + } + if (casField == null) + { + return false; + } + if (casField.IsStatic) + { + return false; + } + if (casField.IsPropertyAccessor) + { + return false; + } + if (casField.DeclaringType.TypeAsBaseType == typeBuilder.DeclaringType) + { + // allow access to fields in outer class + } + else if (!casField.IsAccessibleFrom(casField.DeclaringType, wrapper, casField.DeclaringType)) + { + return false; + } + casField.Link(); + FieldInfo fi = casField.GetField(); + if (fi == null) + { + return false; + } + ilGenerator.EmitLdarg(0); + ilGenerator.Emit(OpCodes.Ldflda, fi); + ilGenerator.EmitLdarg(2); + ilGenerator.EmitLdarg(1); + ilGenerator.Emit(OpCodes.Call, AtomicReferenceFieldUpdaterEmitter.MakeCompareExchange(casField.FieldTypeWrapper.TypeAsSignatureType)); + ilGenerator.EmitLdarg(1); + ilGenerator.Emit(OpCodes.Ceq); + ilGenerator.Emit(OpCodes.Ret); + return true; + } + #endif + private void AddMethodParameterInfo(ClassFile.Method m, MethodWrapper mw, MethodBuilder mb, out string[] parameterNames) { Index: ClassFile.cs =================================================================== RCS file: /cvsroot/ikvm/ikvm/runtime/ClassFile.cs,v retrieving revision 1.124 retrieving revision 1.125 diff -C2 -d -r1.124 -r1.125 *** ClassFile.cs 19 May 2014 09:09:57 -0000 1.124 --- ClassFile.cs 27 May 2014 12:32:26 -0000 1.125 *************** *** 2679,2682 **** --- 2679,2683 ---- internal string DllExportName; internal int DllExportOrdinal; + internal string InterlockedCompareAndSetField; #endif } *************** *** 2888,2891 **** --- 2889,2911 ---- } } + if(annot[1].Equals("Likvm/internal/InterlockedCompareAndSet;")) + { + string field = null; + for (int j = 2; j < annot.Length; j += 2) + { + if (annot[j].Equals("value") && annot[j + 1] is string) + { + field = (string)annot[j + 1]; + } + } + if (field != null) + { + if (low == null) + { + low = new LowFreqData(); + } + low.InterlockedCompareAndSetField = field; + } + } } break; *************** *** 3057,3060 **** --- 3077,3088 ---- } } + + internal string InterlockedCompareAndSetField + { + get + { + return low == null ? null : low.InterlockedCompareAndSetField; + } + } #endif |