BBS: TELESC.NET.BR Assunto: get_all_msg_headers(): cold *_NULL fields read undefined via dot-acces De: Deucе Data: Thu, 21 May 2026 15:13:07 -0700 ----------------------------------------------------------- https://gitlab.synchro.net/main/sbbs/-/issues/1143#note_8988 A few problems with the diagnosis I want to surface before we move on. 1. JIT is off in the build that produced these counts. JAVASCRIPT_OPTIONS in sbbsdefs.h:69 is 0x810 = JSOPTION_JIT | JSOPTION_COMPILE_N_GO, which is what global->js.options defaults to (sbbs_ini.c:317) and what jsexec uses (jsexec.cpp:63). JSOPTION_JIT is bit 11, which is TraceMonkey, not MethodJIT, and js-confdefs.h for this tree compiles in JS_METHODJIT, JS_MONOIC, JS_POLYIC but not JS_TRACER. TraceMonkey is gone entirely. MethodJIT (with its PolyIC/MonoIC inline caches) is compiled in but requires JSOPTION_METHODJIT (bit 14 = 0x4000), which is not in 0x810. The only caching layer that could plausibly produce the reported behavior under defaults is therefore the interpreter PropertyCache in jspropertycache.cpp. 2. The interpreter PropertyCache as written can't mis-serve the way the issue describes. Trace from fill() to test(): - The GET-path fill at jsobj.cpp:5432 (js_GetPropertyHelperWithShapeInline) passes adding=JS_FALSE (default, no third arg). - In fill() (jspropertycache.cpp:51), with adding=FALSE and a default getter, control reaches the if (kshape == 0) block at line 256, which sets kshape = obj->shape() and vshape = pobj->shape(). By this point the resolve hook has already called JS_DefineProperty and the shape has transitioned, so this obj->shape() reads post-transition (call it S_post). - test() at jspropertycacheinlines.h:73 reads kshape = obj->shape() for the receiver currently being looked up (line 78), then rejects unless entry->kshape == kshape (line 84). A fresh header at S_init reading hdr.to_ext therefore has kshape = S_init in test(). Any entry filled by a populated-sibling header is at kshape = S_post. The kshape check fails, control falls through to fullTest, then to js_GetPropertyHelper, which calls the resolve hook. There is no path in the interpreter cache I can find where a same-S_init header gets a hit on an entry filled by an S_post header. 3. Other candidate mechanisms considered and discarded: - Cached miss / negative caching of "this id not on this shape": PCVal (jspropertycache.h:81-119) has four states (Null, FunObj, Slot, Shape), no negative state. fill() requires a real Shape* and bails via JS_NO_PROP_CACHE_FILL if !pobj->nativeContains(*shape). Every fill call site passes a real shape. - Proto-chain contamination (a stray to_ext = undefined defined on the shared msghdr prototype): falsified by the very GETELEM-vs-GETPROP discriminator. If the proto held the entry, GETELEM's proto walk in js_LookupPropertyWithFlagsInline at jsobj.cpp:4985-5009 would find it and return undef too. The reported GETELEM count of 213 (matching true-NULL count) rules this out. - "Shape priming" from ca448cb8b: not a real SpiderMonkey concept. Shapes transition via PropertyTree::getChild (jspropertytree.cpp:204-243) which returns existing nodes for matching transitions, so two headers both adding "number" land on the same destination shape. There's no per-object priming distinct from shape. - JIT PolyIC misprediction (methodjit/PolyIC.cpp): would have been my next candidate, except JIT is off per (1). 4. What this leaves. Either (a) there is a path in fullTest (jspropertycache.cpp:320-410) or the vcapTag()==1 proto-hit branch in test() (jspropertycacheinlines.h:87-90) that I have not traced and that does in fact mis-serve under shared-shape conditions, or (b) the reported counts are not measuring what the writeup says they measure. I can't rule out (a) without sitting in the debugger. But (b) is the more parsimonious read of where this issue's history has been so far: ca448cb8b's commit-message theory did not survive scrutiny, 666ff71ce's did not either, and the experimental writeup cites a mechanism (per-(shape, pc) cache hit on a same-S_init fresh header) that does not reproduce against a read of the source on JIT-off SM 1.8.5. Request: please attach probe_enum.js and probe_to_ext.js, or paste them inline. The numbers (cold to_ext = 7138 undef, GETELEM = 213, sibling-alive = 7140, cold-defined-but-wrong = 0) are load-bearing for the diagnosis, and without seeing how each was counted, I can't tell whether the discriminator was actually exercised, or whether (for example) the GETELEM pass was inadvertently warmed by something that ran earlier in the same script. With the scripts in hand we can re-run them, and either confirm the misprediction is real (in which case the next step is gdb on the interpreter cache to find the path I missed) or identify the script artifact. --- SBBSecho 3.37-Linux * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705) ----------------------------------------------------------- [Voltar]