From 17ac6e8a023a8c7a6af0dd8d41f86879e550b5b1 Mon Sep 17 00:00:00 2001 From: Hugh Sanderson Date: Thu, 29 Aug 2024 13:59:45 +0800 Subject: [PATCH] Update emscripten config to match standard installations. Add some emscipten specific GC paths. --- src/hx/gc/Immix.cpp | 147 ++++++++++++++++++++--------- toolchain/emscripten-toolchain.xml | 85 +++++++++++++---- toolchain/haxe-target.xml | 2 +- tools/hxcpp/BuildTool.hx | 6 +- tools/hxcpp/Setup.hx | 28 +++++- 5 files changed, 199 insertions(+), 69 deletions(-) diff --git a/src/hx/gc/Immix.cpp b/src/hx/gc/Immix.cpp index 00d2f2ff5..458e33a4f 100644 --- a/src/hx/gc/Immix.cpp +++ b/src/hx/gc/Immix.cpp @@ -7,6 +7,14 @@ #include "GcRegCapture.h" #include +#ifdef EMSCRIPTEN + #include + #ifdef HXCPP_SINGLE_THREADED_APP + // Use provided tools to measure stack extent + #define HXCPP_EXPLICIT_STACK_EXTENT + #endif +#endif + #include #include @@ -28,7 +36,6 @@ int gSlowPath = 0; using hx::gByteMarkID; using hx::gRememberedByteMarkID; -// #define HXCPP_SINGLE_THREADED_APP namespace hx { @@ -108,10 +115,6 @@ static size_t sgMaximumFreeSpace = 1024*1024*1024; static size_t sgMaximumFreeSpace = 1024*1024*1024; #endif -#ifdef EMSCRIPTEN -// #define HXCPP_STACK_UP -#endif - // #define HXCPP_GC_DEBUG_LEVEL 1 @@ -5762,8 +5765,10 @@ class LocalAllocator : public hx::StackContext bool mMoreHoles; + #ifndef HXCPP_EXPLICIT_STACK_EXTENT int *mTopOfStack; int *mBottomOfStack; + #endif hx::RegisterCaptureBuffer mRegisterBuf; int mRegisterBufSize; @@ -5801,7 +5806,9 @@ class LocalAllocator : public hx::StackContext void AttachThread(int *inTopOfStack) { + #ifndef HXCPP_EXPLICIT_STACK_EXTENT mTopOfStack = mBottomOfStack = inTopOfStack; + #endif mRegisterBufSize = 0; mStackLocks = 0; @@ -5859,7 +5866,9 @@ class LocalAllocator : public hx::StackContext } #endif + #ifndef HXCPP_EXPLICIT_STACK_EXTENT mTopOfStack = mBottomOfStack = 0; + #endif sGlobalAlloc->RemoveLocalLocked(this); @@ -5891,7 +5900,7 @@ class LocalAllocator : public hx::StackContext // Other places may call this to ensure the the current thread is registered // indefinitely (until forcefully revoked) // - // Normally liraries/mains will then let this dangle. + // Normally libraries/mains will then let this dangle. // // However after the main, on android it calls SetTopOfStack(0,true), to unregister the thread, // because it is likely to be the ui thread, and the remaining call will be from @@ -5916,13 +5925,28 @@ class LocalAllocator : public hx::StackContext // SetTopOfStack(top,true) -> add stack lock // SetTopOfStack(0,_) -> pop stack lock. If all gone, clear global stack lock // + + #ifdef HXCPP_EXPLICIT_STACK_EXTENT // { + + void SetTopOfStack(int *inTop,bool inPush) { } + void PushTopOfStack(void *inTop) { } + void PopTopOfStack() { } + void SetBottomOfStack(int *inBottom) { } + void PauseForCollect() { } + void EnterGCFreeZone() { } + bool TryGCFreeZone() { return true; } + bool TryExitGCFreeZone() { return false; } + void ExitGCFreeZoneLocked() { } + + + #else // } !HXCPP_EXPLICIT_STACK_EXTENT { void SetTopOfStack(int *inTop,bool inPush) { if (inTop) { if (!mTopOfStack) mTopOfStack = inTop; - // EMSCRIPTEN the stack grows upwards + // EMSCRIPTEN the stack grows upwards - not wasm. // It could be that the main routine was called from deep with in the stack, // then some callback was called from a higher location on the stack #ifdef HXCPP_STACK_UP @@ -5987,39 +6011,6 @@ class LocalAllocator : public hx::StackContext #endif } - virtual void SetupStackAndCollect(bool inMajor, bool inForceCompact, bool inLocked=false,bool inFreeIsFragged=false) - { - #ifndef HXCPP_SINGLE_THREADED_APP - #if HXCPP_DEBUG - if (mGCFreeZone) - CriticalGCError("Collecting from a GC-free thread"); - #endif - #endif - - volatile int dummy = 1; - mBottomOfStack = (int *)&dummy; - - CAPTURE_REGS; - - if (!mTopOfStack) - mTopOfStack = mBottomOfStack; - // EMSCRIPTEN the stack grows upwards - #ifdef HXCPP_STACK_UP - if (mBottomOfStack < mTopOfStack) - mTopOfStack = mBottomOfStack; - #else - if (mBottomOfStack > mTopOfStack) - mTopOfStack = mBottomOfStack; - #endif - - #ifdef VerifyStackRead - VerifyStackRead(mBottomOfStack, mTopOfStack) - #endif - - - sGlobalAlloc->Collect(inMajor, inForceCompact, inLocked, inFreeIsFragged); - } - void PauseForCollect() { @@ -6145,6 +6136,58 @@ class LocalAllocator : public hx::StackContext #endif } + #endif // } HXCPP_EXPLICIT_STACK_EXTENT + + + void SetupStackAndCollect(bool inMajor, bool inForceCompact, bool inLocked=false,bool inFreeIsFragged=false) + { + #ifndef HXCPP_SINGLE_THREADED_APP + #if HXCPP_DEBUG + if (mGCFreeZone) + CriticalGCError("Collecting from a GC-free thread"); + #endif + #endif + + #ifndef HXCPP_EXPLICIT_STACK_EXTENT + volatile int dummy = 1; + mBottomOfStack = (int *)&dummy; + + CAPTURE_REGS; + + if (!mTopOfStack) + mTopOfStack = mBottomOfStack; + + // EMSCRIPTEN the stack grows upwards + #ifdef HXCPP_STACK_UP + if (mBottomOfStack < mTopOfStack) + mTopOfStack = mBottomOfStack; + #else + if (mBottomOfStack > mTopOfStack) + mTopOfStack = mBottomOfStack; + #endif + + #ifdef VerifyStackRead + VerifyStackRead(mBottomOfStack, mTopOfStack) + #endif + + #endif + + + sGlobalAlloc->Collect(inMajor, inForceCompact, inLocked, inFreeIsFragged); + } + + + + + + + + + + + + + void ExpandAlloc(int &ioSize) { #ifdef HXCPP_GC_NURSERY @@ -6331,11 +6374,13 @@ class LocalAllocator : public hx::StackContext void Mark(hx::MarkContext *__inCtx) { + #ifndef HXCPP_SINGLE_THREADED_APP if (!mTopOfStack) { Reset(); return; } + #endif #ifdef SHOW_MEM_EVENTS //int here = 0; @@ -6345,19 +6390,33 @@ class LocalAllocator : public hx::StackContext #ifdef HXCPP_DEBUG MarkPushClass("Stack",__inCtx); MarkSetMember("Stack",__inCtx); + + #ifdef HXCPP_EXPLICIT_STACK_EXTENT + hx::MarkConservative( (int *)emscripten_stack_get_current(),(int *)emscripten_stack_get_base(), __inCtx); + #else if (mTopOfStack && mBottomOfStack) hx::MarkConservative(mBottomOfStack, mTopOfStack , __inCtx); + #endif + #ifdef HXCPP_SCRIPTABLE MarkSetMember("ScriptStack",__inCtx); hx::MarkConservative((int *)(stack), (int *)(pointer),__inCtx); #endif MarkSetMember("Registers",__inCtx); hx::MarkConservative(CAPTURE_REG_START, CAPTURE_REG_END, __inCtx); + + MarkPopClass(__inCtx); #else - if (mTopOfStack && mBottomOfStack) - hx::MarkConservative(mBottomOfStack, mTopOfStack , __inCtx); - hx::MarkConservative(CAPTURE_REG_START, CAPTURE_REG_END, __inCtx); + + #ifdef HXCPP_EXPLICIT_STACK_EXTENT + hx::MarkConservative( (int *)emscripten_stack_get_current(), (int *) emscripten_stack_get_base(), __inCtx); + #else + if (mTopOfStack && mBottomOfStack) + hx::MarkConservative(mBottomOfStack, mTopOfStack , __inCtx); + hx::MarkConservative(CAPTURE_REG_START, CAPTURE_REG_END, __inCtx); + #endif + #ifdef HXCPP_SCRIPTABLE hx::MarkConservative((int *)(stack), (int *)(pointer),__inCtx); #endif @@ -6390,6 +6449,7 @@ inline LocalAllocator *GetLocalAlloc(bool inAllowEmpty=false) #endif } +#ifndef HXCPP_SINGLE_THREADED_APP void WaitForSafe(LocalAllocator *inAlloc) { inAlloc->WaitForSafe(); @@ -6399,6 +6459,7 @@ void ReleaseFromSafe(LocalAllocator *inAlloc) { inAlloc->ReleaseFromSafe(); } +#endif void MarkLocalAlloc(LocalAllocator *inAlloc,hx::MarkContext *__inCtx) { diff --git a/toolchain/emscripten-toolchain.xml b/toolchain/emscripten-toolchain.xml index f99d3a545..ab5316a57 100644 --- a/toolchain/emscripten-toolchain.xml +++ b/toolchain/emscripten-toolchain.xml @@ -1,17 +1,60 @@ + + - - + + + + + + + + +
- - - + + + +
@@ -41,6 +84,10 @@ +
+ + +
@@ -100,9 +147,12 @@ -
- - + + + +
+ +
@@ -119,18 +169,13 @@ -
- - -
-
-
+
@@ -140,10 +185,13 @@
+ +
@@ -153,9 +201,12 @@
-
- - + + + +
+ +
diff --git a/toolchain/haxe-target.xml b/toolchain/haxe-target.xml index cfff7ceeb..a795596ab 100644 --- a/toolchain/haxe-target.xml +++ b/toolchain/haxe-target.xml @@ -1,7 +1,7 @@ - + diff --git a/tools/hxcpp/BuildTool.hx b/tools/hxcpp/BuildTool.hx index 92be6063c..22f85d898 100644 --- a/tools/hxcpp/BuildTool.hx +++ b/tools/hxcpp/BuildTool.hx @@ -1612,8 +1612,8 @@ class BuildTool { Setup.initHXCPPConfig(defines); Setup.setupEmscripten(defines); - var node = defines.get("EMSCRIPTEN_NODE_JS"); - Log.v( node==null ? "EMSCRIPTEN_NODE_JS undefined, using 'node'" : 'Using $node from EMSCRIPTEN_NODE_JS'); + var node = defines.get("EMSDK_NODE"); + Log.v( node==null ? "EMSDK_NODE undefined, using 'node'" : 'Using $node from EMSDK_NODE'); if (node=="" || node==null) node = "node"; @@ -2347,7 +2347,7 @@ class BuildTool public function checkToolVersion(inVersion:String) { var ver = Std.parseInt(inVersion); - if (ver>5) + if (ver>6) Log.error("Your version of hxcpp.n is out-of-date. Please update by compiling 'haxe compile.hxml' in hxcpp/tools/hxcpp."); } diff --git a/tools/hxcpp/Setup.hx b/tools/hxcpp/Setup.hx index 546fc7efa..1b6eb36ff 100644 --- a/tools/hxcpp/Setup.hx +++ b/tools/hxcpp/Setup.hx @@ -267,11 +267,12 @@ class Setup public static function setupEmscripten(ioDefines:Hash) { - // Setup EMSCRIPTEN_SDK if possible - else assume developer has it in path - if (!ioDefines.exists("EMSCRIPTEN_SDK")) + // Setup EMSDK if possible - else assume developer has it in path + if (!ioDefines.exists("EMSDK") ) { var home = ioDefines.get("HXCPP_HOME"); var file = home + "/.emscripten"; + Log.v('No EMSDK provided, checking $file'); if (FileSystem.exists(file)) { var content = sys.io.File.getContent(file); @@ -285,16 +286,33 @@ class Setup var val= value.matched(2); if (name=="EMSCRIPTEN_ROOT") { - ioDefines.set("EMSCRIPTEN_SDK", val); + ioDefines.set("EMSDK", val); } if (name=="PYTHON") - ioDefines.set("EMSCRIPTEN_PYTHON", val); + ioDefines.set("EMSDK_PYTHON", val); if (name=="NODE_JS") - ioDefines.set("EMSCRIPTEN_NODE_JS", val); + ioDefines.set("EMSDK_NODE", val); } } } } + else + { + Log.v('Using provided EMSDK ${ioDefines.get("EMSDK")}'); + } + + if (!ioDefines.exists("EMSDK_PYTHON")) + { + Log.v("No EMSDK_PYTHON provided, using 'python'"); + } + else + Log.v('Using provided EMSDK_PYTHON ${ioDefines.get("EMSDK_PYTHON")}'); + + if (!ioDefines.exists("EMSDK_NODE")) + { + Log.v("No EMSDK_NODE provided, using 'node'"); + ioDefines.set("EMSDK_NODE", "node"); + } }