-
Notifications
You must be signed in to change notification settings - Fork 229
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
GC disabled during native function execution #387
Comments
Hi @adamschackart, can you please paste here some sample code? |
I've created this contrived example that leaks 1.5gb on my system before finishing: static bool NativeFunction(gravity_vm *vm, gravity_value_t *args,
uint16_t nargs, uint32_t rindex)
{
gravity_closure_t* closure = (
gravity_closure_t*)gravity_vm_getvalue(vm, "GravityFunction", strlen("GravityFunction")).p;
gravity_vm_runclosure(vm, closure, VALUE_FROM_NULL, NULL, 0);
RETURN_VALUE(VALUE_FROM_NULL, rindex);
}
int main(int argc, char** argv)
{
gravity_delegate_t delegate = {};
gravity_compiler_t* compiler = gravity_compiler_create(&delegate);
const char* source_code =
"extern var NativeClass\n"
"\n"
"func GravityFunction()\n"
"{\n"
" for (var i in 0..<100000)\n"
" {\n"
" var s = []\n"
"\n"
" for (var j in 0..<1000)\n"
" {\n"
" s.push(j)\n"
" }\n"
" }\n"
"}\n"
"\n"
"func main()\n"
"{\n"
" NativeClass()\n"
"}\n";
gravity_closure_t* closure = gravity_compiler_run(compiler, source_code,
strlen(source_code), 0, true, true);
gravity_vm* vm = gravity_vm_new(&delegate);
gravity_compiler_transfer(compiler, vm);
gravity_compiler_free(compiler);
gravity_class_t* klass = gravity_class_new_pair(NULL, "NativeClass", NULL, 0, 0);
gravity_class_bind(klass, "init", NEW_CLOSURE_VALUE(NativeFunction));
gravity_vm_setvalue(vm, "NativeClass", gravity_value_from_object(klass));
gravity_vm_runmain(vm, closure);
gravity_vm_free(vm);
gravity_core_free();
return EXIT_SUCCESS;
} |
Hi @adamschackart, thanks for the example. The design choice was to trust external user code (for performance reason) and to disable GC during external user C code execution. You can see the actual VM code here: // gravity_vm_exec:1244
BEGIN_TRUST_USERCODE(vm);
bool result = closure->f->internal(vm, &stackstart[rwin], r3, r1);
END_TRUST_USERCODE(vm);
// BEGIN/END_TRUST_USERCODE are macros that disable/enable GC You can change this behavior by adding the line: System.gcEnabled = true" before the first If you need a more aggressive GC you can modify the System values:
See Hope this helps. |
That works for my example, but still segfaults on my (much more complicated) game state machine. However, I can do a little restructuring so the state "manager" emits one frame at a time, and the outer loop is run in Gravity. |
@adamschackart, if you give me a way to reproduce the crash, I would be more than willing to fix it. |
Reopening - I've written the whole event loop in gravity, and it still crashes. It appears that when the GC kicks in, the entire program is being grayed before it's finished running - the root fiber, the names of all classes and methods, closures, everything. My repro involves a large (400k SLOC) proprietary codebase, so I'm unsure of how to proceed on that. Maybe I could make a super cut-down version and email it to you or something. EDIT debug output and GDB stack trace:
|
If you are able to send me a code that is able to reproduce the crash that would be perfect. |
I believe I've found the bug. It appears that passing a valid (non-NULL) VM pointer into |
I'm calling
gravity_vm_runclosure
from inside a long-running C callback function, but every gravity object allocated inside that closure is leaked until the C function returns. Manually callinggravity_gc_start
directly or indirectly causes weird issues likely related to memory corruption - is there any other way to call arbitrary gravity code from inside C without ballooning memory use?The text was updated successfully, but these errors were encountered: