<commit_before>#
#
#            Nim's Runtime Library
#        (c) Copyright 2015 <NAME>
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

type
  ForeignCell* = object
    data*: pointer
    owner: ptr GcHeap

proc protect*(x: pointer): ForeignCell =
  nimGCref(x)
  result.data = x
  result.owner = addr(gch)

when defined(nimTypeNames):
  type InstancesInfo = array[400, (cstring, int, int)]
  proc sortInstances(a: var InstancesInfo; n: int) =
    # we use shellsort here; fast and simple
    var h = 1
    while true:
      h = 3 * h + 1
      if h > n: break
    while true:
      h = h div 3
      for i in countup(h, n - 1):
        var v = a[i]
        var j = i
        while a[j - h][2] < v[2]:
          a[j] = a[j - h]
          j = j - h
          if j < h: break
        a[j] = v
      if h == 1: break

  proc dumpNumberOfInstances* =
    # also add the allocated strings to the list of known types:
    if strDesc.nextType == nil:
      strDesc.nextType = nimTypeRoot
      strDesc.name = "string"
      nimTypeRoot = addr strDesc
    var a: InstancesInfo
    var n = 0
    var it = nimTypeRoot
    while it != nil:
      if it.instances > 0 and n < a.len:
        a[n] = (it.name, it.instances, it.sizes)
        inc n
      it = it.nextType
    sortInstances(a, n)
    for i in 0 .. n-1:
      c_fprintf(stdout, "[Heap] %s: #%ld; bytes: %ld\n", a[i][0], a[i][1], a[i][2])


  when defined(nimGcRefLeak):
    proc oomhandler() =
      c_fprintf(stdout, "[Heap] ROOTS: #%ld\n", gch.additionalRoots.len)
      writeLeaks()

    outOfMemHook = oomhandler

template decTypeSize(cell, t) =
  # XXX this needs to use atomics for multithreaded apps!
  when defined(nimTypeNames):
    if t.kind in {tyString, tySequence}:
      let len = cast[PGenericSeq](cellToUsr(cell)).len
      let base = if t.kind == tyString: 1 else: t.base.size
      let size = addInt(mulInt(len, base), GenericSeqSize)
      dec t.sizes, size+sizeof(Cell)
    else:
      dec t.sizes, t.base.size+sizeof(Cell)
    dec t.instances

template incTypeSize(typ, size) =
  when defined(nimTypeNames):
    inc typ.instances
    inc typ.sizes, size+sizeof(Cell)

proc dispose*(x: ForeignCell) =
  when hasThreadSupport:
    # if we own it we can free it directly:<commit_msg>GC: fixes size computation for leak detection<commit_after>#
#
#            Nim's Runtime Library
#        (c) Copyright 2015 <NAME>
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

type
  ForeignCell* = object
    data*: pointer
    owner: ptr GcHeap

proc protect*(x: pointer): ForeignCell =
  nimGCref(x)
  result.data = x
  result.owner = addr(gch)

when defined(nimTypeNames):
  type InstancesInfo = array[400, (cstring, int, int)]
  proc sortInstances(a: var InstancesInfo; n: int) =
    # we use shellsort here; fast and simple
    var h = 1
    while true:
      h = 3 * h + 1
      if h > n: break
    while true:
      h = h div 3
      for i in countup(h, n - 1):
        var v = a[i]
        var j = i
        while a[j - h][2] < v[2]:
          a[j] = a[j - h]
          j = j - h
          if j < h: break
        a[j] = v
      if h == 1: break

  proc dumpNumberOfInstances* =
    # also add the allocated strings to the list of known types:
    if strDesc.nextType == nil:
      strDesc.nextType = nimTypeRoot
      strDesc.name = "string"
      nimTypeRoot = addr strDesc
    var a: InstancesInfo
    var n = 0
    var it = nimTypeRoot
    while it != nil:
      if (it.instances > 0 or it.sizes != 0) and n < a.len:
        a[n] = (it.name, it.instances, it.sizes)
        inc n
      it = it.nextType
    sortInstances(a, n)
    for i in 0 .. n-1:
      c_fprintf(stdout, "[Heap] %s: #%ld; bytes: %ld\n", a[i][0], a[i][1], a[i][2])


  when defined(nimGcRefLeak):
    proc oomhandler() =
      c_fprintf(stdout, "[Heap] ROOTS: #%ld\n", gch.additionalRoots.len)
      writeLeaks()

    outOfMemHook = oomhandler

template decTypeSize(cell, t) =
  # XXX this needs to use atomics for multithreaded apps!
  when defined(nimTypeNames):
    if t.kind in {tyString, tySequence}:
      let cap = cast[PGenericSeq](cellToUsr(cell)).space
      let size = if t.kind == tyString: cap+1+GenericSeqSize
                 else: addInt(mulInt(cap, t.base.size), GenericSeqSize)
      dec t.sizes, size+sizeof(Cell)
    else:
      dec t.sizes, t.base.size+sizeof(Cell)
    dec t.instances

template incTypeSize(typ, size) =
  when defined(nimTypeNames):
    inc typ.instances
    inc typ.sizes, size+sizeof(Cell)

proc dispose*(x: ForeignCell) =
  when hasThreadSupport:
    # if we own it we can free it directly:
{'fraction_non_alphanumeric': 0.11798591849797312, 'fraction_numerical': 0.010027736291871132, 'mean_word_length': 2.4045025417574437, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6404002', 'n_tokens_mistral': 1696, 'n_tokens_neox': 1662, 'n_words': 515}