internal MemoryMappedStorage(object data, MemoryRegion region, MemoryLayout layout) { Kind = EKind.Data; Data = data; Region = region; Layout = layout; }
internal MemoryMappedStorage(object dataItem, TypeDescriptor dataItemType, MemoryRegion region, MemoryLayout layout) { Kind = EKind.DataItem; DataItem = dataItem; DataItemType = dataItemType; Region = region; Layout = layout; }
internal ArrayMemoryLayout(TypeDescriptor layoutedType, uint wordSize, ulong[] strides, ulong subStride, uint elementsPerWord, uint wordsPerElement, MemoryLayout elementLayout) : base(layoutedType) { Contract.Requires(layoutedType != null); Contract.Requires(wordSize >= 1); Contract.Requires(strides != null); Contract.Requires(strides.Length >= 1); Contract.Requires(strides.Take(strides.Length - 1).All(n => n >= 1)); Contract.Requires(elementLayout != null); WordSize = wordSize; Strides = strides; SubStride = subStride; ElementsPerWord = elementsPerWord; WordsPerElement = wordsPerElement; ElementLayout = elementLayout; }
internal MemoryMappedStorage(IStorable variable, MemoryRegion region, MemoryLayout layout) { Kind = EKind.Variable; Variable = variable; Region = region; Layout = layout; }
/// <summary> /// Constructs an instance. /// </summary> /// <param name="field">layouted field</param> /// <param name="fieldLayout">memory layout of the field</param> /// <param name="offset">start offset inside the superordinate layout</param> public FieldLocation(FieldInfo field, MemoryLayout fieldLayout, ulong offset) { Field = field; FieldLayout = fieldLayout; Offset = offset; }
/// <summary> /// Computes a memory layout for a given type descriptor. /// </summary> /// <param name="td">type descriptor to layout</param> /// <param name="info">marshalling information</param> /// <returns>memory layout</returns> public static MemoryLayout Layout(TypeDescriptor td, IMarshalInfo info) { Type type = td.CILType; ISerializer ser = SLVSerializable.TryGetSerializer(type); if (ser != null) { object sample = td.GetSampleInstance(); return(CreatePrimLayout(ser.Serialize(sample).Size, td, info)); } if (ser == null && td.HasIntrinsicTypeOverride) { throw new InvalidOperationException("Type " + type.Name + " has intrinsic type override but no serializer"); } if (type.IsEnum) { return(new EnumMemoryLayout(td, info)); } if (type.IsArray) { td.AssertStatic(); TypeDescriptor elemTd = td.Element0Type; MemoryLayout elemLayout = Layout(elemTd, info); ulong subStride = elemLayout.SizeInBits; if (subStride == 0) { return(new EmptyMemoryLayout(td) { Size = 0, SizeInBits = 0 }); } ulong[] strides = new ulong[type.GetArrayRank()]; ulong elemsPerWord = (ulong)info.WordSize / elemLayout.SizeInBits; ulong wordsPerElem = elemLayout.Size; if (elemsPerWord > 1) { if (info.UseArraySubWordAlignment) { if (info.UseArrayDimPow2Alignment) { elemsPerWord = MathExt.FloorPow2(elemsPerWord); subStride = info.WordSize / elemsPerWord; } } else { elemsPerWord = 1; } } ulong dimSize = (ulong)(int)td.TypeParams.Last(); ulong dimWords; if (elemsPerWord <= 1) { subStride = 0; if (info.UseArrayDimPow2Alignment) { wordsPerElem = MathExt.CeilPow2(wordsPerElem); } dimWords = wordsPerElem * dimSize; } else { wordsPerElem = 0; dimWords = (dimSize + elemsPerWord - 1) / elemsPerWord; } strides[strides.Length - 1] = wordsPerElem; for (int i = strides.Length - 2; i >= 0; i--) { if (info.UseArrayDimPow2Alignment) { dimWords = MathExt.CeilPow2(dimWords); } strides[i] = dimWords; dimSize = (ulong)(int)td.TypeParams[i]; dimWords *= dimSize; } return(new ArrayMemoryLayout(td, info.WordSize, strides, subStride, (uint)elemsPerWord, (uint)wordsPerElem, elemLayout) { Size = dimWords, SizeInBits = dimWords * info.WordSize }); } if (type.IsValueType && !type.IsPrimitive) { StructMemoryLayout ml = new StructMemoryLayout(td); FieldInfo[] fields = type.GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); ulong offset = 0; foreach (FieldInfo field in fields) { TypeDescriptor fieldTd = td.GetFieldType(field); MemoryLayout fieldLayout = Layout(fieldTd, info); FieldLocation fieldLoc = new FieldLocation(field, fieldLayout, offset); ml.AddLocation(fieldLoc); offset += fieldLayout.Size; } ml.Size = offset; ml.SizeInBits = offset * info.WordSize; return(ml); } throw new InvalidOperationException("Unable to create data layout for type " + type.Name); }