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

[bazel] Frozen Cache exception with MEMORY64=1 #1432

Closed
wrangelvid opened this issue Jul 31, 2024 · 13 comments
Closed

[bazel] Frozen Cache exception with MEMORY64=1 #1432

wrangelvid opened this issue Jul 31, 2024 · 13 comments

Comments

@wrangelvid
Copy link

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.

@sbc100
Copy link
Collaborator

sbc100 commented Aug 1, 2024

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.

@wrangelvid
Copy link
Author

wrangelvid commented Aug 1, 2024

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.

@wrangelvid
Copy link
Author

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?

@sbc100
Copy link
Collaborator

sbc100 commented Aug 1, 2024

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.

@wrangelvid
Copy link
Author

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.

@sbc100
Copy link
Collaborator

sbc100 commented Aug 1, 2024

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.

@wrangelvid
Copy link
Author

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.

@wrangelvid
Copy link
Author

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?

@sbc100
Copy link
Collaborator

sbc100 commented Aug 1, 2024

It should be fairly soon now. I would hope in the next month.

@sbc100
Copy link
Collaborator

sbc100 commented Aug 1, 2024

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.

@wrangelvid
Copy link
Author

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.

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?

@sbc100
Copy link
Collaborator

sbc100 commented Aug 2, 2024

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.

@wrangelvid
Copy link
Author

Great thank you!

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

No branches or pull requests

2 participants