Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ARC] {.global.} pragma doesn't work when the variable is initialized with non-value types #17552

Open
ghost opened this issue Mar 28, 2021 · 6 comments

Comments

@ghost
Copy link

ghost commented Mar 28, 2021

The title says it all, with ARC {.global.} only seems to work with value types (ints, bools, objects) or when declaration and Initialization of the global variable are separate.
Non-value types (ref objects, strings, and other types that are managed by the runtime) are always initialized each time if they have are declared with an assignment. Found out by investigating memory leak in https://forum.nim-lang.org/t/7709.

Example

proc main = 
  var tc {.global.} = "hi"
  tc &= "hi"
  echo tc

main()
main()
main()

Current Output

ARC/ORC:

hihi
hihi
hihi

refc:

hihi
hihihi
hihihihi

On the contrary, this works just fine:

proc main = 
  var tc {.global.}: string
  tc &= "hi"
  echo tc

main()
main()
main()

I think that the compiler should show a warning when {.global.} pragma is used with ARC/ORC, or at least when it's used with non-value types. Or we can deprecate it altogether

Additional Information

This might be related to #15005.

$ nim -v
Nim Compiler Version 1.5.1 [Linux: amd64]
Compiled at 2021-03-28
Copyright (c) 2006-2021 by Andreas Rumpf

git hash: eb3ed44009fdfea3e67608b68a049c265124d643
active boot switches: -d:release
@ghost
Copy link
Author

ghost commented Mar 28, 2021

Also, what are the alternatives to the {.global.} pragma, to make this code work with ARC like it does with refc for example? So we can document a workaround for people to follow.

@StefanSalewski
Copy link

StefanSalewski commented Mar 28, 2021

I really hope and think this is not true:

$ grep "{.global" ~/.nimble/pkgs/gintro-#head/gintro/*
/home/salewski/.nimble/pkgs/gintro-#head/gintro/gimplglib.nim:  var ch1 {.global.}: glib.IOChannel
/home/salewski/.nimble/pkgs/gintro-#head/gintro/gimplgobj.nim:          r1s.add("  var " & names[i] & "1 {.global.}: " & types[i] & "\n")
/home/salewski/.nimble/pkgs/gintro-#head/gintro/gimplgst.nim:  var bus1 {.global.}: gst.Bus
/home/salewski/.nimble/pkgs/gintro-#head/gintro/gimplgst.nim:  var msg1 {.global.}: gst.Message
/home/salewski/.nimble/pkgs/gintro-#head/gintro/gimplgtk.nim:  var cr1 {.global.}: cairo.Context
/home/salewski/.nimble/pkgs/gintro-#head/gintro/gimplnice.nim:  var ag1 {.global.}: nice.Agent

In the last 12 months I had the feeling that gintro was working fine with ARC. Well minor memory leaks may exists, it is hard to debug leaks with gtk as gtk has itself behaviour which may looks like leaks in valgrind.

I hope I will get my CDT to work with ARC at all :-)

@ghost
Copy link
Author

ghost commented Mar 28, 2021

@StefanSalewski are those "value types" from the Nim perspective? If they're simple raw pointers or ints/bools/etc, they'll work fine.

@StefanSalewski
Copy link

Sorry, forget to mention:

  IOChannel* = ref object
    impl*: ptr IOChannel00
    ignoreFinalizer*: bool
$ grep -A8 "Context\*" ~/.nimble/pkgs/gintro-#head/gintro/cairo.nim 
  Context* = ref object
    impl*: ptr Context00
    ignoreFinalizer*: bool

Most are ref objects. The cairo.Context is used a lot in the draw callback! We get from the cairo lib the low level object only but need the Nim proxy object for the actual drawing code, so we use global pragma to have an instance of the proxy object available for each callback call. New allocation for each call would be not that nice, may work with ARC, but with default GC delayed deallocation can be a problem. It was a problem for Ruby ten years ago.

@ghost ghost changed the title [ARC] {.global.} pragma doesn't work with non-value types [ARC] {.global.} pragma doesn't work when the variable is initialized with non-value types Mar 29, 2021
@ghost
Copy link
Author

ghost commented Mar 29, 2021

Update - global pragma actually works if we separate declaration and initialization

@Araq
Copy link
Member

Araq commented Apr 1, 2021

As much as I dislike .global, we can also just fix the bug.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants