Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/ikvm-fork.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjfrijters <jfrijters>2011-12-09 19:59:35 +0400
committerjfrijters <jfrijters>2011-12-09 19:59:35 +0400
commit140b448b5c67356e8dbb8358fedfe9e8113ee10f (patch)
tree1c663ca9a9f10e9c837310936fbff1d8ce803788
parenta86ccf30d5e7f9deebb40f9f9e5a09ab163380ca (diff)
Moved AtomicReferenceFieldUpdater creation into FinishContext, to be able to better keep track of the types and avoid the global dictionary.
-rw-r--r--runtime/DynamicTypeWrapper.cs31
-rw-r--r--runtime/atomic.cs51
2 files changed, 40 insertions, 42 deletions
diff --git a/runtime/DynamicTypeWrapper.cs b/runtime/DynamicTypeWrapper.cs
index ebbc8716..9401dd55 100644
--- a/runtime/DynamicTypeWrapper.cs
+++ b/runtime/DynamicTypeWrapper.cs
@@ -3545,6 +3545,7 @@ namespace IKVM.Internal
private List<System.Threading.ThreadStart> postFinishProcs;
private List<Item> items;
private int uniqueId;
+ private Dictionary<FieldWrapper, ConstructorBuilder> arfuMap;
private struct Item
{
@@ -5380,6 +5381,36 @@ namespace IKVM.Internal
});
return cb;
}
+
+ internal ConstructorBuilder GetAtomicReferenceFieldUpdater(FieldWrapper field)
+ {
+ if (arfuMap == null)
+ {
+ arfuMap = new Dictionary<FieldWrapper, ConstructorBuilder>();
+ }
+ ConstructorBuilder cb;
+ if (!arfuMap.TryGetValue(field, out cb))
+ {
+ TypeWrapper arfuTypeWrapper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater");
+ TypeBuilder tb = typeBuilder.DefineNestedType("__<ARFU>_" + (uniqueId++), TypeAttributes.NestedPrivate | TypeAttributes.Sealed, arfuTypeWrapper.TypeAsBaseType);
+ AtomicReferenceFieldUpdaterEmitter.EmitImpl(tb, field.GetField());
+ cb = tb.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, Type.EmptyTypes);
+ arfuMap.Add(field, cb);
+ CodeEmitter ctorilgen = CodeEmitter.Create(cb);
+ ctorilgen.Emit(OpCodes.Ldarg_0);
+ MethodWrapper basector = arfuTypeWrapper.GetMethodWrapper("<init>", "()V", false);
+ basector.Link();
+ basector.EmitCall(ctorilgen);
+ ctorilgen.Emit(OpCodes.Ret);
+ ctorilgen.DoEmit();
+ RegisterPostFinishProc(delegate
+ {
+ arfuTypeWrapper.Finish();
+ tb.CreateType();
+ });
+ }
+ return cb;
+ }
}
private static bool CheckRequireOverrideStub(MethodWrapper mw1, MethodWrapper mw2)
diff --git a/runtime/atomic.cs b/runtime/atomic.cs
index 91c3b971..b15ef0ca 100644
--- a/runtime/atomic.cs
+++ b/runtime/atomic.cs
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2007 Jeroen Frijters
+ Copyright (C) 2007-2011 Jeroen Frijters
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -37,8 +37,6 @@ using InstructionFlags = IKVM.Internal.ClassFile.Method.InstructionFlags;
static class AtomicReferenceFieldUpdaterEmitter
{
- private static readonly Dictionary<FieldWrapper, ConstructorBuilder> map = new Dictionary<FieldWrapper, ConstructorBuilder>();
-
internal static bool Emit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, ClassFile classFile, int i, ClassFile.Method.Instruction[] code, InstructionFlags[] flags)
{
if (i >= 3
@@ -60,7 +58,10 @@ static class AtomicReferenceFieldUpdaterEmitter
if (field != null && !field.IsStatic && field.IsVolatile && field.DeclaringType == wrapper && field.FieldTypeWrapper == vclass)
{
// everything matches up, now call the actual emitter
- DoEmit(context, wrapper, ilgen, field);
+ ilgen.Emit(OpCodes.Pop);
+ ilgen.Emit(OpCodes.Pop);
+ ilgen.Emit(OpCodes.Pop);
+ ilgen.Emit(OpCodes.Newobj, context.GetAtomicReferenceFieldUpdater(field));
return true;
}
}
@@ -68,45 +69,11 @@ static class AtomicReferenceFieldUpdaterEmitter
return false;
}
- private static void DoEmit(DynamicTypeWrapper.FinishContext context, TypeWrapper wrapper, CodeEmitter ilgen, FieldWrapper field)
+ internal static void EmitImpl(TypeBuilder tb, FieldInfo field)
{
- ConstructorBuilder cb;
- bool exists;
- lock (map)
- {
- exists = map.TryGetValue(field, out cb);
- }
- if (!exists)
- {
- // note that we don't need to lock here, because we're running as part of FinishCore, which is already protected by a lock
- TypeWrapper arfuTypeWrapper = ClassLoaderWrapper.LoadClassCritical("ikvm.internal.IntrinsicAtomicReferenceFieldUpdater");
- TypeBuilder tb = wrapper.TypeAsBuilder.DefineNestedType("__<ARFU>_" + field.Name + field.Signature.Replace('.', '/'), TypeAttributes.NestedPrivate | TypeAttributes.Sealed, arfuTypeWrapper.TypeAsBaseType);
- EmitCompareAndSet("compareAndSet", tb, field.GetField());
- EmitGet(tb, field.GetField());
- EmitSet("set", tb, field.GetField());
-
- cb = tb.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, Type.EmptyTypes);
- lock (map)
- {
- map.Add(field, cb);
- }
- CodeEmitter ctorilgen = CodeEmitter.Create(cb);
- ctorilgen.Emit(OpCodes.Ldarg_0);
- MethodWrapper basector = arfuTypeWrapper.GetMethodWrapper("<init>", "()V", false);
- basector.Link();
- basector.EmitCall(ctorilgen);
- ctorilgen.Emit(OpCodes.Ret);
- ctorilgen.DoEmit();
- context.RegisterPostFinishProc(delegate
- {
- arfuTypeWrapper.Finish();
- tb.CreateType();
- });
- }
- ilgen.Emit(OpCodes.Pop);
- ilgen.Emit(OpCodes.Pop);
- ilgen.Emit(OpCodes.Pop);
- ilgen.Emit(OpCodes.Newobj, cb);
+ EmitCompareAndSet("compareAndSet", tb, field);
+ EmitGet(tb, field);
+ EmitSet("set", tb, field);
}
private static void EmitCompareAndSet(string name, TypeBuilder tb, FieldInfo field)