MemoryLimitConstraint.cs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. using Jint.Runtime;
  2. namespace Jint.Constraints;
  3. public sealed class MemoryLimitConstraint : Constraint
  4. {
  5. private static readonly Func<long>? GetAllocatedBytesForCurrentThread;
  6. private readonly long _memoryLimit;
  7. private long _initialMemoryUsage;
  8. static MemoryLimitConstraint()
  9. {
  10. var methodInfo = typeof(GC).GetMethod("GetAllocatedBytesForCurrentThread");
  11. if (methodInfo != null)
  12. {
  13. GetAllocatedBytesForCurrentThread = (Func<long>)Delegate.CreateDelegate(typeof(Func<long>), null, methodInfo);
  14. }
  15. }
  16. internal MemoryLimitConstraint(long memoryLimit)
  17. {
  18. _memoryLimit = memoryLimit;
  19. }
  20. public override void Check()
  21. {
  22. if (_memoryLimit > 0)
  23. {
  24. if (GetAllocatedBytesForCurrentThread != null)
  25. {
  26. var memoryUsage = GetAllocatedBytesForCurrentThread() - _initialMemoryUsage;
  27. if (memoryUsage > _memoryLimit)
  28. {
  29. ExceptionHelper.ThrowMemoryLimitExceededException($"Script has allocated {memoryUsage} but is limited to {_memoryLimit}");
  30. }
  31. }
  32. else
  33. {
  34. ExceptionHelper.ThrowPlatformNotSupportedException("The current platform doesn't support MemoryLimit.");
  35. }
  36. }
  37. }
  38. public override void Reset()
  39. {
  40. if (GetAllocatedBytesForCurrentThread != null)
  41. {
  42. _initialMemoryUsage = GetAllocatedBytesForCurrentThread();
  43. }
  44. }
  45. }