private void PerformStaticAllocationOf(Context allocation, Context assignment)
        {
            MosaType  allocatedType   = (allocation.InvokeMethod != null) ? allocation.InvokeMethod.DeclaringType : allocation.Result.Type;
            MosaField assignmentField = (assignment.Instruction is DupInstruction) ? FindStsfldForDup(assignment).MosaField : assignment.MosaField;

            // Get size of type
            int typeSize = TypeLayout.GetTypeSize(allocatedType);

            // If instruction is newarr then get the size of the element, multiply it by array size, and add array header size
            // Also need to align to a 4-byte boundry
            if (allocation.Instruction is NewarrInstruction)
            {
                typeSize = (TypeLayout.GetTypeSize(allocatedType.ElementType) * (int)allocation.Previous.Operand1.ConstantSignedLongInteger) + (TypeLayout.NativePointerSize * 3);
            }

            // Allocate a linker symbol to refer to this allocation. Use the destination field name as the linker symbol name.
            var symbolName = MethodCompiler.Linker.CreateSymbol(assignmentField.FullName + @"<<$cctor", SectionKind.ROData, Architecture.NativeAlignment, typeSize);

            // Try to get typeDefinitionSymbol if allocatedType isn't a value type
            string typeDefinitionSymbol = GetTypeDefinition(allocatedType);

            if (typeDefinitionSymbol != null)
            {
                MethodCompiler.Linker.Link(LinkType.AbsoluteAddress, BuiltInPatch.I4, symbolName, 0, 0, typeDefinitionSymbol, SectionKind.ROData, 0);
            }

            // Issue a load request before the newobj and before the assignment.
            Operand symbol1 = InsertLoadBeforeInstruction(assignment, symbolName.Name, assignmentField.FieldType);

            assignment.Operand1 = symbol1;

            // If the instruction is a newarr and the assignment instruction is a dup then we want to remove it
            if (allocation.Instruction is NewarrInstruction && assignment.Instruction is DupInstruction)
            {
                assignment.SetInstruction(CILInstruction.Get(OpCode.Ldc_i4), assignment.Result, assignment.Operand1);
            }

            // Change the newobj to a call and increase the operand count to include the this ptr.
            // If the instruction is a newarr, then just replace with a nop instead
            allocation.ResultCount = 0;
            if (allocation.Instruction is NewarrInstruction)
            {
                allocation.OperandCount = 0;
                allocation.SetInstruction(CILInstruction.Get(OpCode.Nop));
            }
            else
            {
                Operand symbol2           = InsertLoadBeforeInstruction(allocation, symbolName.Name, assignmentField.FieldType);
                IEnumerable <Operand> ops = allocation.Operands;
                allocation.OperandCount++;
                allocation.Operand1 = symbol2;
                int i = 0;
                foreach (Operand op in ops)
                {
                    i++;
                    allocation.SetOperand(i, op);
                }
                allocation.ReplaceInstructionOnly(CILInstruction.Get(OpCode.Call));
            }
        }
예제 #2
0
        private static void PatchConstructor(BaseMethodCompiler methodCompiler)
        {
            Operand thisOperand          = methodCompiler.Parameters[0];
            Operand instanceOperand      = methodCompiler.Parameters[1];
            Operand methodPointerOperand = methodCompiler.Parameters[2];

            var size = methodCompiler.Architecture.NativeInstructionSize;

            MosaField methodPointerField         = GetField(methodCompiler.Method.DeclaringType, "methodPointer");
            int       methodPointerOffset        = methodCompiler.TypeLayout.GetFieldOffset(methodPointerField);
            Operand   methodPointerOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, methodPointerOffset);

            MosaField instanceField         = GetField(methodCompiler.Method.DeclaringType, "instance");
            int       instanceOffset        = methodCompiler.TypeLayout.GetFieldOffset(instanceField);
            Operand   instanceOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, instanceOffset);

            var context = new Context(CreateMethodStructure(methodCompiler, true));

            Operand v1 = methodCompiler.CreateVirtualRegister(thisOperand.Type);

            context.AppendInstruction(IRInstruction.Move, v1, thisOperand);
            context.AppendInstruction(IRInstruction.Store, size, null, v1, methodPointerOffsetOperand, methodPointerOperand);
            context.MosaType = methodPointerOperand.Type;
            context.AppendInstruction(IRInstruction.Store, size, null, v1, instanceOffsetOperand, instanceOperand);
            context.MosaType = instanceOperand.Type;
            context.AppendInstruction(IRInstruction.Return, methodCompiler.BasicBlocks.EpilogueBlock);
        }
예제 #3
0
        /// <summary>
        /// Gets the size of the field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <returns></returns>
        public int GetFieldSize(MosaField field)
        {
            var size = 0;

            //FIXME: This is not thread safe!
            if (fieldSizes.TryGetValue(field, out size))
            {
                return(size);
            }
            else
            {
                ResolveType(field.DeclaringType);
            }

            // If the field is another struct, we have to dig down and compute its size too.
            if (field.FieldType.IsValueType)
            {
                size = GetTypeSize(field.FieldType);
            }
            else
            {
                size = GetMemorySize(field.FieldType);
            }

            fieldSizes.Add(field, size);

            return(size);
        }
예제 #4
0
 /// <summary>
 /// Gets the size of the field.
 /// </summary>
 /// <param name="field">The field.</param>
 /// <returns></returns>
 public int GetFieldSize(MosaField field)
 {
     lock (_lock)
     {
         return(ComputeFieldSize(field));
     }
 }
예제 #5
0
        private int ComputeFieldSize(MosaField field)
        {
            if (fieldSizes.TryGetValue(field, out int size))
            {
                return(size);
            }
            else
            {
                ResolveType(field.DeclaringType);
            }

            // If the field is another struct, we have to dig down and compute its size too.
            if (field.FieldType.IsValueType)
            {
                size = GetTypeSize(field.FieldType);
            }
            else
            {
                size = NativePointerSize;
            }

            fieldSizes.Add(field, size);

            return(size);
        }
예제 #6
0
 public bool IsFieldAccessed(MosaField field)
 {
     if (!IsEnabled)
     {
         return(true);                // always
     }
     return(accessedFields.Contains(field));
 }
예제 #7
0
        /// <summary>
        /// Gets the size of the field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <returns></returns>
        public int GetFieldOffset(MosaField field)
        {
            ResolveType(field.DeclaringType);

            var offset = 0;

            fieldOffsets.TryGetValue(field, out offset);

            return(offset);
        }
예제 #8
0
        /// <summary>
        /// Creates a new runtime member <see cref="Operand"/>.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <returns></returns>
        public static Operand CreateField(MosaField field)
        {
            var operand = new Operand(field.FieldType);

            operand.IsMemoryAddress = true;
            operand.IsField         = true;
            operand.Displacement    = 0;
            operand.Field           = field;
            return(operand);
        }
예제 #9
0
        /// <summary>
        /// Gets the size of the field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <returns></returns>
        public int GetFieldOffset(MosaField field)
        {
            lock (_lock)
            {
                ResolveType(field.DeclaringType);

                fieldOffsets.TryGetValue(field, out int offset);

                return(offset);
            }
        }
예제 #10
0
 private void AllocateSpace(MosaField field, SectionKind section, int size, int alignment)
 {
     using (var stream = Compiler.Linker.Allocate(field.FullName, section, size, alignment))
     {
         if (field.Data != null)
         {
             stream.Write(field.Data, 0, size);
         }
         else
         {
             stream.WriteZeroBytes(size);
         }
     }
 }
예제 #11
0
        /// <summary>
        /// Creates a new runtime member <see cref="Operand"/>.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <returns></returns>
        public static Operand CreateField(MosaField field)
        {
            Debug.Assert(field.IsStatic);

            var operand = new Operand(field.FieldType);

            operand.IsStaticField = true;
            operand.Offset        = 0;
            operand.Field         = field;

            //operand.IsResolved = true;
            operand.IsConstant = true;
            return(operand);
        }
예제 #12
0
        /// <summary>
        /// Creates a new runtime member <see cref="Operand" />.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="typeSystem">The type system.</param>
        /// <returns></returns>
        public static Operand CreateStaticField(MosaField field, TypeSystem typeSystem)
        {
            Debug.Assert(field.IsStatic);

            var type = field.FieldType.IsReferenceType ? typeSystem.BuiltIn.Object : field.FieldType.ToManagedPointer();

            return(new Operand(type)
            {
                IsStaticField = true,                 // field.IsStatic
                Offset = 0,
                Field = field,
                IsConstant = true
            });
        }
예제 #13
0
        public void AccessedField(MosaField field)
        {
            if (!IsEnabled)
            {
                return;
            }

            if (!field.IsStatic)
            {
                return;
            }

            lock (accessedFields)
            {
                accessedFields.AddIfNew(field);
            }
        }
예제 #14
0
        private void ResolveField(MosaField field)
        {
            var resolver = new GenericArgumentResolver();

            if (field.DeclaringType.GenericArguments.Count > 0)
            {
                resolver.PushTypeGenericArguments(field.DeclaringType.GenericArguments.GetGenericArguments());
            }

            using (var mosaField = metadata.Controller.MutateField(field))
            {
                mosaField.FieldType = metadata.Loader.GetType(resolver.Resolve(field.GetFieldSig().Type));

                mosaField.HasOpenGenericParams = field.DeclaringType.HasOpenGenericParams ||
                                                 field.FieldType.GetTypeSig().HasOpenGenericParameter();

                ResolveCustomAttributes(mosaField, field.GetUnderlyingObject <UnitDesc <FieldDef, FieldSig> >().Definition);
            }
        }
예제 #15
0
        private static void PatchInvoke(BaseMethodCompiler methodCompiler, bool withReturn)
        {
            // check if instance is null (if so, it's a static call to the methodPointer)

            MosaField methodPointerField         = GetField(methodCompiler.Method.DeclaringType, "methodPointer");
            int       methodPointerOffset        = methodCompiler.TypeLayout.GetFieldOffset(methodPointerField);
            Operand   methodPointerOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, methodPointerOffset);

            MosaField instanceField         = GetField(methodCompiler.Method.DeclaringType, "instance");
            int       instanceOffset        = methodCompiler.TypeLayout.GetFieldOffset(instanceField);
            Operand   instanceOffsetOperand = Operand.CreateConstant(methodCompiler.TypeSystem, instanceOffset);

            var size = methodCompiler.Architecture.NativeInstructionSize;

            Context b0 = new Context(CreateMethodStructure(methodCompiler, false));
            Context b1 = new Context(methodCompiler.BasicBlocks.CreateBlock());
            Context b2 = new Context(methodCompiler.BasicBlocks.CreateBlock());
            Context b3 = new Context(methodCompiler.BasicBlocks.CreateBlock());

            Operand[] vrs = new Operand[methodCompiler.Parameters.Length];

            for (int i = 0; i < methodCompiler.Parameters.Length; i++)
            {
                vrs[i] = methodCompiler.VirtualRegisters.Allocate(methodCompiler.Parameters[i].Type);

                if (methodCompiler.TypeLayout.IsCompoundType(methodCompiler.Parameters[i].Type))
                {
                    b0.AppendInstruction(IRInstruction.CompoundMove, vrs[i], methodCompiler.Parameters[i]);
                }
                else
                {
                    b0.AppendInstruction(IRInstruction.Move, vrs[i], methodCompiler.Parameters[i]);
                }
            }

            Operand thisOperand = vrs[0];

            Operand opMethod   = methodCompiler.VirtualRegisters.Allocate(methodCompiler.TypeSystem.BuiltIn.U4);
            Operand opInstance = methodCompiler.VirtualRegisters.Allocate(thisOperand.Type);
            Operand opCompare  = methodCompiler.VirtualRegisters.Allocate(methodCompiler.TypeSystem.BuiltIn.I4);

            Operand opReturn = withReturn ? methodCompiler.VirtualRegisters.Allocate(methodCompiler.TypeSystem.BuiltIn.Object) : null;
            Operand c0       = Operand.CreateConstant(methodCompiler.TypeSystem, 0);

            b0.AppendInstruction(IRInstruction.Load, size, opMethod, thisOperand, methodPointerOffsetOperand);
            b0.AppendInstruction(IRInstruction.Load, size, opInstance, thisOperand, instanceOffsetOperand);
            b0.AppendInstruction(IRInstruction.IntegerCompare, ConditionCode.Equal, opCompare, opInstance, c0);
            b0.AppendInstruction(IRInstruction.IntegerCompareBranch, ConditionCode.Equal, null, opCompare, c0);
            b0.AddBranchTarget(b2.Block);
            b0.AppendInstruction(IRInstruction.Jmp, b1.Block);

            // no instance
            b1.AppendInstruction(IRInstruction.Call, opReturn, opMethod);
            b1.InvokeMethod = methodCompiler.Method;
            for (int i = 1; i < methodCompiler.Parameters.Length; i++)
            {
                b1.AddOperand(vrs[i]);
            }
            b1.AppendInstruction(IRInstruction.Jmp, b3.Block);

            // instance
            b2.AppendInstruction(IRInstruction.Call, opReturn, opMethod);
            b2.InvokeMethod = methodCompiler.Method;
            b2.AddOperand(opInstance);
            for (int i = 1; i < methodCompiler.Parameters.Length; i++)
            {
                b2.AddOperand(vrs[i]);
            }
            b2.AppendInstruction(IRInstruction.Jmp, b3.Block);

            // return
            b3.AppendInstruction(IRInstruction.Return, methodCompiler.BasicBlocks.EpilogueBlock);
            if (withReturn)
            {
                b3.SetOperand(0, opReturn);
            }
        }
예제 #16
0
 public void AddField(MosaField field)
 {
     fieldLookup.Add(field.GetUnderlyingObject<UnitDesc<FieldDef, FieldSig>>().Token, field);
 }
예제 #17
0
        /// <summary>
        /// Gets the size of the field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <returns></returns>
        public int GetFieldSize(MosaField field)
        {
            var size = 0;

            if (fieldSizes.TryGetValue(field, out size))
            {
                return size;
            }
            else
            {
                ResolveType(field.DeclaringType);
            }

            // If the field is another struct, we have to dig down and compute its size too.
            if (field.FieldType.IsValueType)
            {
                size = GetTypeSize(field.FieldType);
            }
            else
            {
                size = GetMemorySize(field.FieldType);
            }

            fieldSizes.Add(field, size);

            return size;
        }
예제 #18
0
        /// <summary>
        /// Creates a new runtime member <see cref="Operand"/>.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <returns></returns>
        public static Operand CreateField(MosaField field)
        {
            Debug.Assert(field.IsStatic);

            var operand = new Operand(field.FieldType);
            operand.IsStaticField = true;
            operand.Offset = 0;
            operand.Field = field;

            //operand.IsResolved = true;
            operand.IsConstant = true;
            return operand;
        }
예제 #19
0
 public void AddField(MosaField field)
 {
     fieldLookup.Add(field.GetUnderlyingObject <UnitDesc <FieldDef, FieldSig> >().Token, field);
 }
예제 #20
0
        private void ResolveField(MosaField field)
        {
            GenericArgumentResolver resolver = new GenericArgumentResolver();

            if (field.DeclaringType.GenericArguments.Count > 0)
                resolver.PushTypeGenericArguments(field.DeclaringType.GenericArguments.GetGenericArguments());

            using (var mosaField = metadata.Controller.MutateField(field))
            {
                mosaField.FieldType = metadata.Loader.GetType(resolver.Resolve(field.GetFieldSig().Type));

                mosaField.HasOpenGenericParams =
                    field.DeclaringType.HasOpenGenericParams ||
                    field.FieldType.GetTypeSig().HasOpenGenericParameter();

                ResolveCustomAttributes(mosaField, field.GetUnderlyingObject<UnitDesc<FieldDef, FieldSig>>().Definition);
            }
        }
예제 #21
0
 /// <summary>
 /// Creates a new runtime member <see cref="Operand"/>.
 /// </summary>
 /// <param name="field">The field.</param>
 /// <returns></returns>
 public static Operand CreateField(MosaField field)
 {
     var operand = new Operand(field.FieldType);
     operand.IsMemoryAddress = true;
     operand.IsField = true;
     operand.Displacement = 0;
     operand.Field = field;
     return operand;
 }
예제 #22
0
 public MosaField.Mutator MutateField(MosaField field)
 {
     return new MosaField.Mutator(field);
 }
예제 #23
0
 public MosaField CreateField(MosaField source = null)
 {
     if (source == null)
     {
         return new MosaField()
         {
             ID = id++,
             TypeSystem = typeSystem
         };
     }
     else
     {
         MosaField result = source.Clone();
         result.ID = id++;
         return result;
     }
 }
예제 #24
0
 protected string FormatRuntimeMember(MosaField field)
 {
     return(field.Name);
 }
예제 #25
0
        /// <summary>
        /// Allocates memory for the static field and initializes it.
        /// </summary>
        /// <param name="field">The field.</param>
        private void CreateStaticField(MosaField field)
        {
            // Determine the size of the type & alignment requirements
            int size, alignment;
            Architecture.GetTypeRequirements(TypeLayout, field.FieldType, out size, out alignment);

            size = (int)TypeLayout.GetFieldSize(field);

            // The linker section to move this field into
            SectionKind section = field.Data != null ? section = SectionKind.Data : section = SectionKind.BSS;

            AllocateSpace(field, section, size, alignment);
        }
예제 #26
0
 public static FieldSig GetFieldSig(this MosaField field)
 {
     return(field.GetUnderlyingObject <UnitDesc <FieldDef, FieldSig> >().Signature);
 }
예제 #27
0
        private MosaType LoadGenericTypeInstanceSig(GenericInstSig typeSig)
        {
            //Debug.Assert(false, typeSig.FullName);
            MosaType origin = GetType(typeSig.GenericType);
            MosaType result = metadata.Controller.CreateType(origin);
            var      desc   = result.GetUnderlyingObject <UnitDesc <TypeDef, TypeSig> >();

            using (var resultType = metadata.Controller.MutateType(result))
            {
                resultType.UnderlyingObject = desc.Clone(typeSig);
                resultType.ElementType      = origin;

                foreach (var genericArg in typeSig.GenericArguments)
                {
                    resultType.GenericArguments.Add(GetType(genericArg));
                }

                metadata.Resolver.EnqueueForResolve(result);

                GenericArgumentResolver resolver = new GenericArgumentResolver();
                resolver.PushTypeGenericArguments(typeSig.GenericArguments);

                for (int i = 0; i < result.Methods.Count; i++)
                {
                    MosaMethod method = metadata.Controller.CreateMethod(result.Methods[i]);

                    using (var mosaMethod = metadata.Controller.MutateMethod(method))
                    {
                        mosaMethod.DeclaringType    = result;
                        mosaMethod.UnderlyingObject = method.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >();
                    }

                    resultType.Methods[i] = method;
                    metadata.Resolver.EnqueueForResolve(method);
                }

                for (int i = 0; i < result.Fields.Count; i++)
                {
                    MosaField field = metadata.Controller.CreateField(result.Fields[i]);

                    using (var mosaField = metadata.Controller.MutateField(field))
                    {
                        mosaField.DeclaringType    = result;
                        mosaField.UnderlyingObject = field.GetUnderlyingObject <UnitDesc <FieldDef, FieldSig> >();
                    }

                    resultType.Fields[i] = field;
                    metadata.Resolver.EnqueueForResolve(field);
                }

                for (int i = 0; i < result.Properties.Count; i++)
                {
                    MosaProperty property = metadata.Controller.CreateProperty(result.Properties[i]);

                    PropertySig newSig = property.GetPropertySig().Clone();
                    newSig.RetType = resolver.Resolve(newSig.RetType);
                    using (var mosaProperty = metadata.Controller.MutateProperty(property))
                    {
                        mosaProperty.DeclaringType    = result;
                        mosaProperty.UnderlyingObject = property.GetUnderlyingObject <UnitDesc <PropertyDef, PropertySig> >();
                    }

                    resultType.Properties[i] = property;
                    metadata.Resolver.EnqueueForResolve(property);
                }

                resultType.HasOpenGenericParams = typeSig.HasOpenGenericParameter();
            }

            metadata.Controller.AddType(result);

            return(result);
        }
예제 #28
0
        private void Load(MosaModule module, TypeDef typeDef)
        {
            TypeSig typeSig = typeDef.ToTypeSig();

            // Check to see if its one of our classes we need for SZ Arrays
            if (typeDef.Name.Contains("SZArrayHelper`1"))
            {
                szHelperSig = typeSig as ClassOrValueTypeSig;
            }
            else if (typeDef.Name.Contains("IList`1"))
            {
                iListSig = typeSig as ClassOrValueTypeSig;
            }

            MosaType mosaType = metadata.Controller.CreateType();

            using (var type = metadata.Controller.MutateType(mosaType))
            {
                type.Module           = module;
                type.UnderlyingObject = new UnitDesc <TypeDef, TypeSig>(typeDef.Module, typeDef, typeSig);

                type.Namespace = typeDef.Namespace;
                type.Name      = typeDef.Name;

                type.IsInterface = typeDef.IsInterface;
                type.IsEnum      = typeDef.IsEnum;
                type.IsDelegate  =
                    typeDef.BaseType != null && typeDef.BaseType.DefinitionAssembly.IsCorLib() &&
                    (typeDef.BaseType.FullName == "System.Delegate" || typeDef.BaseType.FullName == "System.MulticastDelegate");
                type.IsModule = typeDef.IsGlobalModuleType;

                type.IsExplicitLayout = typeDef.IsExplicitLayout;
                if (typeDef.IsExplicitLayout)
                {
                    type.ClassSize   = (int)typeDef.ClassSize;
                    type.PackingSize = typeDef.PackingSize;
                }
                type.TypeAttributes = (MosaTypeAttributes)typeDef.Attributes;
                type.TypeCode       = (MosaTypeCode)typeSig.ElementType;

                // Load members

                foreach (var fieldDef in typeDef.Fields)
                {
                    MosaField mosaField = metadata.Controller.CreateField();

                    using (var field = metadata.Controller.MutateField(mosaField))
                        LoadField(mosaType, field, fieldDef);

                    type.Fields.Add(mosaField);
                    metadata.Cache.AddField(mosaField);
                    LoadedUnits.Add(mosaField);
                }

                foreach (var methodDef in typeDef.Methods)
                {
                    MosaMethod mosaMethod = metadata.Controller.CreateMethod();

                    using (var method = metadata.Controller.MutateMethod(mosaMethod))
                        LoadMethod(mosaType, method, methodDef);

                    type.Methods.Add(mosaMethod);
                    metadata.Cache.AddMethod(mosaMethod);
                    LoadedUnits.Add(mosaMethod);
                }

                foreach (var propertyDef in typeDef.Properties)
                {
                    MosaProperty mosaProperty = metadata.Controller.CreateProperty();

                    using (var property = metadata.Controller.MutateProperty(mosaProperty))
                        LoadProperty(mosaType, property, propertyDef);

                    type.Properties.Add(mosaProperty);
                    metadata.Cache.AddProperty(mosaProperty);
                    LoadedUnits.Add(mosaProperty);
                }
            }
            typeCache[typeSig] = mosaType;
            metadata.Controller.AddType(mosaType);
            metadata.Cache.AddType(mosaType);
            LoadedUnits.Add(mosaType);
        }
예제 #29
0
        /// <summary>
        /// Gets the size of the field.
        /// </summary>
        /// <param name="field">The field.</param>
        /// <returns></returns>
        public int GetFieldOffset(MosaField field)
        {
            ResolveType(field.DeclaringType);

            var offset = 0;

            fieldOffsets.TryGetValue(field, out offset);

            return offset;
        }
예제 #30
0
 protected string FormatRuntimeMember(MosaField field)
 {
     return field.Name;
 }
예제 #31
0
 public void TrackFieldReferenced(MosaField field)
 {
     // TODO
 }
예제 #32
0
 public void TrackFieldReferenced(MosaField field)
 {
     // TODO
 }
예제 #33
0
        void ICompilationScheduler.TrackFieldReferenced(MosaField field)
        {
            Debug.Assert(!field.FieldType.HasOpenGenericParams);

            (this as ICompilationScheduler).TrackTypeAllocated(field.DeclaringType);
        }