/// <summary> /// Allocates a new class of the given type /// </summary> /// <param name="classType">The type of the class</param> public IntPtr NewClass(ClassType classType) { var classPointer = this.AllocateObject(this.youngGeneration, classType, classType.Metadata.Size); if (this.virtualMachine.Config.EnableDebug && this.virtualMachine.Config.PrintAllocation) { RuntimeInterface.DebugLog($"Allocated class of type '{classType}' at 0x{classPointer.ToString("x8")}."); } return(classPointer); }
/// <summary> /// Allocates a new array of the given type and length /// </summary> /// <param name="arrayType">The type of the array</param> /// <param name="length">The length</param> public IntPtr NewArray(ArrayType arrayType, int length) { var elementType = arrayType.ElementType; var elementSize = TypeSystem.SizeOf(elementType); var objectSize = Constants.ArrayLengthSize + (length * elementSize); var arrayPointer = this.AllocateObject(this.youngGeneration, arrayType, objectSize); //Set the length of the array NativeHelpers.SetInt(arrayPointer, 0, length); if (this.virtualMachine.Config.EnableDebug && this.virtualMachine.Config.PrintAllocation) { RuntimeInterface.DebugLog($"Allocated array (length: {length}) with element type '{elementType}' at 0x{arrayPointer.ToString("x8")}."); } return(arrayPointer); }
/// <summary> /// Starts a garbage collection at the given stack frame /// </summary> /// <param name="stackFrame">The current stack frame</param> public void Collect(StackFrame stackFrame) { if (this.virtualMachine.Config.EnableDebug && this.virtualMachine.Config.PrintAliveObjectsWhenGC) { RuntimeInterface.DebugLog("Alive objects:"); youngGeneration.Heap.VisitObjects(objectReference => { RuntimeInterface.DebugLog(objectReference.ToString()); }); RuntimeInterface.DebugLog(""); } if (this.virtualMachine.Config.LogDeallocation) { this.Deallocations.Add(new List <IntPtr>()); } this.MarkAllObjects(this.youngGeneration, stackFrame); this.SweepObjects(this.youngGeneration); }
/// <summary> /// Sweeps the objects in the given generation /// </summary> /// <param name="generation">The generation</param> private void SweepObjects(CollectorGeneration generation) { generation.Heap.VisitObjects(objectReference => { if (objectReference.IsMarked) { objectReference.Unmark(); objectReference.IncreaseSurvivalCount(); } else { if (this.virtualMachine.Config.EnableDebug && this.virtualMachine.Config.PrintDeallocation) { RuntimeInterface.DebugLog($"Deleted object {objectReference}"); } this.DeleteObject(objectReference); } }); }
/// <summary> /// Marks all the objects starting at the given frame /// </summary> /// <param name="generation">The generation</param> /// <param name="stackFrame">The stack frame</param> private void MarkAllObjects(CollectorGeneration generation, StackFrame stackFrame) { var stalkWalker = new StackWalker(this.virtualMachine.CallStack); stalkWalker.VisitObjectReferences( stackFrame, frameEntry => { var objectPointer = new IntPtr(frameEntry.Value); this.MarkObject(generation, this.GetObjectReference(objectPointer)); }, frame => { if (this.virtualMachine.Config.EnableDebug && this.virtualMachine.Config.PrintStackFrameWhenGC) { RuntimeInterface.DebugLog($"{frame.Function.Definition.Name} ({frame.InstructionIndex})"); RuntimeInterface.PrintStackFrame(frame, false); } }); }