[bazel] Frozen Cache exception with MEMORY64=1
wrangelvid opened this issue · 13 comments
I am trying to bind a library that uses 64bits for it's hashing algorithm. In the process I ran into several bugs where I set the architecture to 64 bits with --copt=-m64
and used both -s MEMORY64=1
and -s WASM_BIGINT=1
in the linker options.
Then I got this strange error with Exception: FROZEN_CACHE is set, but cache file is missing
, where I hit my debugging limits. I was told that #971 and #1405 may/should've have resolved these issues but again, I am not deep enough into bazel and embind yet to understand the caching issue.
However, to make this process easier, I created a minimum example to reproduce this problem.
You don't need -sMEMORY64
just to use 64-bit values. -sMEMORY64
is only really needed if you need to address more than 32-bits of memory.
However, if you did want to use -sMEMORY64
then I think the solution in #1405 would be the way to go.
Ah good catch. For now I only need 64 bit values. What is the recommended approach for that?
Without sMEMORY64
I would get:
wasm-ld: error: bazel-out/wasm-opt-ST-***/bin/module/_objs/hello_embind/hello_js.o: must specify -mwasm64 to process wasm64 object files
However, it wasn't clear to me where mwasm64
would come into the game. I tried the linker options, but then digged through the feature flags and documentation until I found this, which inspired me to "try" sMEMORY64
.
However, if you did want to use
-sMEMORY64
then I think the solution in #1405 would be the way to go.
Given the hint that sMEMORY64
injects -mwasm64
, I sat down and tried to understand what the frozen cache actually wants. I added the targets one by one:
register_emscripten_toolchains(cache = {
"configuration": ["--wasm64"],
"targets": [
"libprintf_long_double",
"libembind-rtti",
"libGL-getprocaddr",
"libal",
"libhtml5",
"libstubs",
"libnoexit",
"libc",
"libemmalloc",
"libcompiler_rt",
"libc++-noexcept",
"libc++abi-noexcept",
"libsockets"
]
})
It compiled! In chrome I had to enable a few experimental flags:
chrome://flags/#experimental-wasm-memory64
chrome://flags/#enable-experimental-webassembly-features
My test function verified that was indeed getting 64bit values 🎉 🎉
Now the question is: How can we do this without 64bit memory and only 64 bit values to avoid the feature flag hassle?
Ah good catch. For now I only need 64 bit values. What is the recommended approach for that?
Without
sMEMORY64
I would get:
wasm-ld: error: bazel-out/wasm-opt-ST-***/bin/module/_objs/hello_embind/hello_js.o: must specify -mwasm64 to process wasm64 object files
However, it wasn't clear to me where
mwasm64
would come into the game. I tried the linker options, but then digged through the feature flags and documentation until I found this, which inspired me to "try"sMEMORY64
.
This means that somehow hello_js.o
was built with -sMEMORY64
. You need to figure out who added that flag and remove it. You almost certainly don't actually want memory64 in this case.
This means that somehow
hello_js.o
was built with-sMEMORY64
. You need to figure out who added that flag and remove it. You almost certainly don't actually want memory64 in this case.
I think this happening because I am using -m64
via copt. The library I am trying to bind requires size_t to be 64 bits:
static_assert(sizeof(size_t) == (64 / 8), "We require a 64-bit size_t");
But it looks like m64 is not only making the int and long 64 bit, but also the pointers 64 bit causes the wasm-ld error
when sMEMORY64
is not specified.
Perhaps there is another way to tell Emscripten to use 64 bits in the values? sWASM_BIGINT
would still give yield the static assertion.
If you need size_t
to be 64-bit then yes you do need -sMEMORY64
. The size_t
type is linked to the pointer type so the only way to get 64-bit size_t
is to have 64-bit pointers.
That seems like a rather odd requirement though. Can you link o the We require a 64-bit size_t
in the source code so we can see why its needed?
Remember that wasm64 is still experimental so it would still be better to find a way to remove the requirement if you can.
Update: I wrote a small patch with 32bit hashing. A few things broke, but luckily nothing that I care about. In the long term, I anticipate wasm64 to be a more stable solution. Is there timeline for wasm64 graduating out of the experimental state?
It should be fairly soon now. I would hope in the next month.
I see. They are using FNV1a 64 bit hashing implemented here. I think 32bit would do it too, although I need to check in how close we get to collisions.
Do you have any idea why they chose to use size_t
here? Surely the algorithm should work fine with the more explicit int64_t
which will work regardless of the pointer size.
Do you have any idea why they chose to use
size_t
here? Surely the algorithm should work fine with the more explicitint64_t
which will work regardless of the pointer size.
I think that comes from std::hash, which has size_t as the return type.
It should be fairly soon now. I would hope in the next month.
That's exciting! Does that encompass the experimental state here or also the experimental support for other browsers?
Once a proposal reaches stage4 that means at least 2 browser support it. In this case that will be chrome and firefox. Once stage4 is reached the next release of those browser will support wasm64 without a flag.
Great thank you!