tcustomtrace.nim 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. discard """
  2. outputsub: '''1
  3. 2
  4. 3
  5. 4
  6. 5
  7. 6
  8. 89
  9. 90
  10. 90
  11. 0 0 1
  12. 0 1 2
  13. 0 2 3
  14. 1 0 4
  15. 1 1 5
  16. 1 2 6
  17. 1 3 7
  18. after 6 6
  19. MEM 0'''
  20. joinable: false
  21. cmd: "nim c --gc:orc -d:useMalloc $file"
  22. valgrind: "true"
  23. """
  24. import typetraits
  25. type
  26. myseq*[T] = object
  27. len, cap: int
  28. data: ptr UncheckedArray[T]
  29. # XXX make code memory safe for overflows in '*'
  30. var
  31. allocCount, deallocCount: int
  32. proc `=destroy`*[T](x: var myseq[T]) =
  33. if x.data != nil:
  34. when not supportsCopyMem(T):
  35. for i in 0..<x.len: `=destroy`(x[i])
  36. dealloc(x.data)
  37. inc deallocCount
  38. x.data = nil
  39. x.len = 0
  40. x.cap = 0
  41. proc `=copy`*[T](a: var myseq[T]; b: myseq[T]) =
  42. if a.data == b.data: return
  43. if a.data != nil:
  44. `=destroy`(a)
  45. #dealloc(a.data)
  46. #inc deallocCount
  47. #a.data = nil
  48. a.len = b.len
  49. a.cap = b.cap
  50. if b.data != nil:
  51. a.data = cast[type(a.data)](alloc(a.cap * sizeof(T)))
  52. inc allocCount
  53. when supportsCopyMem(T):
  54. copyMem(a.data, b.data, a.cap * sizeof(T))
  55. else:
  56. for i in 0..<a.len:
  57. a.data[i] = b.data[i]
  58. proc `=sink`*[T](a: var myseq[T]; b: myseq[T]) =
  59. if a.data != nil and a.data != b.data:
  60. dealloc(a.data)
  61. inc deallocCount
  62. a.len = b.len
  63. a.cap = b.cap
  64. a.data = b.data
  65. proc `=trace`*[T](x: var myseq[T]; env: pointer) =
  66. if x.data != nil:
  67. for i in 0..<x.len: `=trace`(x[i], env)
  68. proc resize[T](s: var myseq[T]) =
  69. let oldCap = s.cap
  70. if oldCap == 0: s.cap = 8
  71. else: s.cap = (s.cap * 3) shr 1
  72. if s.data == nil: inc allocCount
  73. s.data = cast[typeof(s.data)](realloc0(s.data, oldCap * sizeof(T), s.cap * sizeof(T)))
  74. proc reserveSlot[T](x: var myseq[T]): ptr T =
  75. if x.len >= x.cap: resize(x)
  76. result = addr(x.data[x.len])
  77. inc x.len
  78. template add*[T](x: var myseq[T]; y: T) =
  79. reserveSlot(x)[] = y
  80. proc shrink*[T](x: var myseq[T]; newLen: int) =
  81. assert newLen <= x.len
  82. assert newLen >= 0
  83. when not supportsCopyMem(T):
  84. for i in countdown(x.len - 1, newLen - 1):
  85. `=destroy`(x.data[i])
  86. x.len = newLen
  87. proc grow*[T](x: var myseq[T]; newLen: int; value: T) =
  88. if newLen <= x.len: return
  89. assert newLen >= 0
  90. let oldCap = x.cap
  91. if oldCap == 0: x.cap = newLen
  92. else: x.cap = max(newLen, (oldCap * 3) shr 1)
  93. if x.data == nil: inc allocCount
  94. x.data = cast[type(x.data)](realloc0(x.data, oldCap * sizeof(T), x.cap * sizeof(T)))
  95. for i in x.len..<newLen:
  96. x.data[i] = value
  97. x.len = newLen
  98. template default[T](t: typedesc[T]): T =
  99. var v: T
  100. v
  101. proc setLen*[T](x: var myseq[T]; newLen: int) {.deprecated.} =
  102. if newlen < x.len: shrink(x, newLen)
  103. else: grow(x, newLen, default(T))
  104. template `[]`*[T](x: myseq[T]; i: Natural): T =
  105. assert i < x.len
  106. x.data[i]
  107. template `[]=`*[T](x: myseq[T]; i: Natural; y: T) =
  108. assert i < x.len
  109. x.data[i] = y
  110. proc createSeq*[T](elems: varargs[T]): myseq[T] =
  111. result = myseq[T](
  112. cap: max(elems.len, 2),
  113. len: elems.len)
  114. result.data = cast[type(result.data)](alloc0(result.cap * sizeof(T)))
  115. inc allocCount
  116. when supportsCopyMem(T):
  117. copyMem(result.data, addr(elems[0]), result.cap * sizeof(T))
  118. else:
  119. for i in 0..<result.len:
  120. result.data[i] = elems[i]
  121. proc len*[T](x: myseq[T]): int {.inline.} = x.len
  122. proc main =
  123. var s = createSeq(1, 2, 3, 4, 5, 6)
  124. s.add 89
  125. s.grow s.len + 2, 90
  126. for i in 0 ..< s.len:
  127. echo s[i]
  128. var nested = createSeq(createSeq(1, 2, 3), createSeq(4, 5, 6, 7))
  129. for i in 0 ..< nested.len:
  130. for j in 0 ..< nested[i].len:
  131. echo i, " ", j, " ", nested[i][j]
  132. main()
  133. echo "after ", allocCount, " ", deallocCount
  134. type
  135. Node = ref object
  136. name: char
  137. sccId: int
  138. kids: myseq[Node]
  139. rc: int
  140. proc edge(a, b: Node) =
  141. inc b.rc
  142. a.kids.add b
  143. proc createNode(name: char): Node =
  144. new result
  145. result.name = name
  146. result.kids = createSeq[Node]()
  147. proc use(x: Node) = discard
  148. proc buildComplexGraph: Node =
  149. # see https://en.wikipedia.org/wiki/Strongly_connected_component for the
  150. # graph:
  151. let a = createNode('a')
  152. let b = createNode('b')
  153. let c = createNode('c')
  154. let d = createNode('d')
  155. let e = createNode('e')
  156. a.edge c
  157. c.edge b
  158. c.edge e
  159. b.edge a
  160. d.edge c
  161. e.edge d
  162. let f = createNode('f')
  163. b.edge f
  164. e.edge f
  165. let g = createNode('g')
  166. let h = createNode('h')
  167. let i = createNode('i')
  168. f.edge g
  169. f.edge i
  170. g.edge h
  171. h.edge i
  172. i.edge g
  173. let j = createNode('j')
  174. h.edge j
  175. i.edge j
  176. let k = createNode('k')
  177. let l = createNode('l')
  178. f.edge k
  179. k.edge l
  180. l.edge k
  181. k.edge j
  182. let m = createNode('m')
  183. let n = createNode('n')
  184. let p = createNode('p')
  185. let q = createNode('q')
  186. m.edge n
  187. n.edge p
  188. n.edge q
  189. q.edge p
  190. p.edge m
  191. q.edge k
  192. d.edge m
  193. e.edge n
  194. result = a
  195. proc main2 =
  196. let g = buildComplexGraph()
  197. main2()
  198. GC_fullCollect()
  199. echo "MEM ", getOccupiedMem()