diff --git a/src/hx/cppia/Cppia.cpp b/src/hx/cppia/Cppia.cpp index ba68a29fa..ea5d1f43c 100644 --- a/src/hx/cppia/Cppia.cpp +++ b/src/hx/cppia/Cppia.cpp @@ -1619,6 +1619,12 @@ struct NewExpr : public CppiaDynamicExpr // sJitReturnReg = alloc->spaceFirst - will be the result if all goes well compiler->move(sJitReturnReg, sJitCtx.star(jtPointer, offsetof(hx::StackContext,spaceFirst) ) ); + #ifdef HXCPP_ALIGN_ALLOC + // As ImmixAllocator::alloc: skip 4 bytes to align the object, which the nursery scan expects + compiler->bitOp(bitOpAnd, sJitTemp1.as(jtInt), sJitReturnReg.as(jtInt), (int)4 ); + compiler->add(sJitReturnReg.as(jtPointer), sJitReturnReg.as(jtPointer), sJitTemp1.as(jtPointer) ); + #endif + // sJitTemp1 = end = spaceFirst + size + sizeof(int) compiler->add(sJitTemp1.as(jtPointer), sJitReturnReg.as(jtPointer), (int)(size + sizeof(int) ) ); diff --git a/test/cppia/Client.hx b/test/cppia/Client.hx index 710373f4b..36e73f776 100644 --- a/test/cppia/Client.hx +++ b/test/cppia/Client.hx @@ -14,6 +14,19 @@ class ClientFoo implements IFoo { } } +class ClientNursery { + + public var value:Dynamic; + + public function new() {} + + // With -jit, the jitted code allocates these in the nursery itself. + public static function allocate() { + new ClientNursery(); + new ClientNursery(); + } +} + class Client { public static var clientBool0 = true; diff --git a/test/cppia/cases/TestCommon.hx b/test/cppia/cases/TestCommon.hx index eaacb5a76..b317566aa 100644 --- a/test/cppia/cases/TestCommon.hx +++ b/test/cppia/cases/TestCommon.hx @@ -1,6 +1,7 @@ package cases; import cpp.cppia.Host; +import cpp.vm.Gc; import utest.Test; import utest.Assert; @@ -59,6 +60,19 @@ class TestCommon extends Test { Assert.equals(2, Common.callbackSet, 'Bad cppia closure'); } + @:depends(testStatus) + function testStackObjectAfterScriptAllocations() { + final nursery = Type.resolveClass('ClientNursery'); + Reflect.callMethod(nursery, Reflect.field(nursery, 'allocate'), []); + // Only the stack references it, so only the nursery scan finds it. + final kept = [42]; + + Gc.run(false); + final junk = [for (i in 0...100000) [i]]; + + Assert.equals(42, kept[0]); + } + @:depends(testStatus) function testInterfaceCalling() { final obj : IFoo = Type.createInstance(Type.resolveClass('ClientFoo'), []); diff --git a/test/cppia/compile-host.hxml b/test/cppia/compile-host.hxml index 76bf2d790..051e26186 100644 --- a/test/cppia/compile-host.hxml +++ b/test/cppia/compile-host.hxml @@ -1,6 +1,7 @@ -m CppiaHost HostExtendedRoot -D scriptable +-D HXCPP_GC_GENERATIONAL -D dll_export=host_classes.info -L utest --dce no