gcleak4.nim 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. discard """
  2. outputsub: "no leak: "
  3. """
  4. when defined(GC_setMaxPause):
  5. GC_setMaxPause 2_000
  6. type
  7. TExpr = object {.inheritable.} ## abstract base class for an expression
  8. PLiteral = ref TLiteral
  9. TLiteral = object of TExpr
  10. x: int
  11. op1: string
  12. TPlusExpr = object of TExpr
  13. a, b: ref TExpr
  14. op2: string
  15. method eval(e: ref TExpr): int =
  16. # override this base method
  17. quit "to override!"
  18. method eval(e: ref TLiteral): int = return e.x
  19. method eval(e: ref TPlusExpr): int =
  20. # watch out: relies on dynamic binding
  21. return eval(e.a) + eval(e.b)
  22. proc newLit(x: int): ref TLiteral =
  23. new(result)
  24. {.watchpoint: result.}
  25. result.x = x
  26. result.op1 = $getOccupiedMem()
  27. proc newPlus(a, b: ref TExpr): ref TPlusExpr =
  28. new(result)
  29. {.watchpoint: result.}
  30. result.a = a
  31. result.b = b
  32. result.op2 = $getOccupiedMem()
  33. const Limit = when compileOption("gc", "markAndSweep") or compileOption("gc", "boehm"): 5*1024*1024 else: 500_000
  34. for i in 0..100_000:
  35. var s: array[0..11, ref TExpr]
  36. for j in 0..high(s):
  37. s[j] = newPlus(newPlus(newLit(j), newLit(2)), newLit(4))
  38. if eval(s[j]) != j+6:
  39. quit "error: wrong result"
  40. if getOccupiedMem() > Limit: quit("still a leak!")
  41. echo "no leak: ", getOccupiedMem()