/// <summary> /// 映射到绝对空间 /// </summary> /// <param name="offset"></param> /// <param name="from"></param> /// <returns></returns> public static uint MapToAbsolute(uint offset, MemoryTag from) { switch (from) { case MemoryTag.NULL: return(NullAddress); case MemoryTag.PRESERVED: if (offset >= Preserved.SizeLimit) { throw new XiVMError("Cannot map to preserved space, exceeds max size"); } return(offset + 1); case MemoryTag.STACK: if (offset >= Stack.SizeLimit) { throw new XiVMError("Cannot map to stack space, exceeds stack max size"); } return((uint)(offset + 1 + Preserved.SizeLimit)); case MemoryTag.HEAP: if (offset >= Heap.SizeLimit) { throw new XiVMError("Cannot map to heap space, exceeds heap max size"); } return((uint)(offset + 1 + Preserved.SizeLimit + Stack.SizeLimit)); case MemoryTag.STATIC: if (offset >= StaticArea.SizeLimit) { throw new XiVMError("Cannot map to static area, exceeds static area max size"); } return((uint)(offset + 1 + Preserved.SizeLimit + Stack.SizeLimit + Heap.SizeLimit)); case MemoryTag.METHOD: if (offset >= MethodArea.SizeLimit) { throw new XiVMError("Cannot map to method area, exceeds method area max size"); } return((uint)(offset + 1 + Preserved.SizeLimit + Stack.SizeLimit + Heap.SizeLimit + StaticArea.SizeLimit)); default: throw new NotImplementedException(); } }
private static void MarkObject(uint addr) { MemoryTag tag = MemoryMap.MapToOffset(addr, out addr); if (tag == MemoryTag.HEAP) { HeapData data = Heap.Singleton.GetData(addr); data.GCInfo |= (uint)GCTag.GCMark; uint typeInfo = data.TypeInfo; if ((data.GCInfo & (uint)GCTag.ArrayMark) != 0) { // 是数组 if (typeInfo == (uint)VariableTypeTag.ADDRESS) { // 是地址数组 int len = BitConverter.ToInt32(data.Data, HeapData.MiscDataSize); for (int i = 0; i < len; i++) { MarkObject(BitConverter.ToUInt32(data.Data, HeapData.ArrayOffsetMap(VariableType.AddressType.Size, i))); } } } else { // 是普通对象 ModuleLoader.Classes.TryGetValue(typeInfo, out VMClass vmClass); foreach (var field in vmClass.Fields) { if (field.Type.Tag == VariableTypeTag.ADDRESS) { // 是地址 MarkObject(BitConverter.ToUInt32(data.Data, field.Offset)); } } } } }