4 ms·
Brings back memories.. When running SpiderMonkey (interpreter, not JIT) on IA64 it would randomly crash and burn with what looked like GC issues. Values were be
by apaprocki 11y ago
Brings back memories.. When running SpiderMonkey (interpreter, not JIT) on IA64 it would randomly crash and burn with what looked like GC issues. Values were being collected even though they were still in use. It turned out the mark-and-sweep collector that would scan the registers and stack was working properly, but was not aware that IA64 would not write out all of its registers to the buffer provided to `setjmp()`. You would have to send the processor a `flushrs` instruction to tell it to flush all stacked general registers in the "dirty" partition (not yet written to the backing store) of the register stack to the backing store. After that, you'd need to get the exact pointers to the register backing store and then scan those. Fun times.
- peterfirefly 11y agoYou might have had less visible problems on other architectures as well. setjmp()/longjmp() are not guaranteed to work with local variables not marked volatile.
- peterfirefly 11y agodmr explaining what's going on: http://yarchive.net/comp/longjmp.html http://yarchive.net/comp/longjmp.html
- aardvark179 11y agoThe size of the jump buffers on ia64 terrifies me. X64 on windows is bad enough, but ia64 looks horrible. Was it a performance problem?
- apaprocki 11y agoI don't think it amounted to any performance issue because SM was only using the setjmp() buffer in that way as a shortcut to get all of the register values in a buffer to scan linearly. Since there was the RSE backing store, there was an extra block of memory to scan regardless, but you're still talking about a reasonably bounded area only scanned on each GC run, which is not a frequent (to the processor) event.
- nickpsecurity 11y agoThat comes with the RSE it uses for performance enhancement. The flushrs requirement, etc were mentioned here: Microsoft on RSE (2002) https://web.archive.org/web/20021018050724/http://portals.devx.com/Intel/Article/6834/0/page/1 https://web.archive.org/web/20021018050724/http://portals.de... Smotherman's notes (2002) http://people.cs.clemson.edu/~mark/subroutines/itanium.html http://people.cs.clemson.edu/~mark/subroutines/itanium.html USENIX presentation on Itanium (2005) https://www.usenix.org/legacy/events/usenix05/tech/general/gray/gray_html/ https://www.usenix.org/legacy/events/usenix05/tech/general/g... I could see how you wouldn't expect it coming from another ISA and they could be a bit more explicit. It was weird. It was documented, though, by different people building on Itanium. Different workloads use it in a different way for efficiency.
- apaprocki 11y agoSure.. it was straightforward to track down once you see that a value is in a register but is being collected anyway. I seem to remember the other fun bits were the fact that function pointers were not actually function pointers.. they were pointers into a giant lookup table that contained a struct that contained the actual address of the call. Also, unwinding the stack was so complicated that you could not reasonably do it manually like on nearly any other architecture -- you needed to link in an Intel library to do it. None of these things were giant issues -- it just showed how much of a departure from other prevalent systems it was.
- nickpsecurity 11y agoWow, that does sound like a painful learning curve. Curious, were the function pointer problems inherent to the architecture or the tool/lib you used? Might be worth documenting in case a reader stumbles upon this before going through what you did.
- apaprocki 11y agoIf you want all the nasty details, this post covers it all: "This also has a side-effect on function pointers. Since function pointers are generally used at some distance from allocation, they might be used in a module with a different gp value. The compiler gets around this by not compiling a function pointer to a single pointer-sized value; it compiles to a pair of pointer-sized values, one representing the address of the first instruction (bundle on IA64) in the function, the other being the correct gp value to use." http://mikedimmick.blogspot.com/2004/01/ia64s-global-pointer.html?m=1 http://mikedimmick.blogspot.com/2004/01/ia64s-global-pointer...