MemoryLimit.cs 1.6 KB

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