Closed Bug 1518565 Opened 11 months ago Closed 11 months ago

ARM64 IonMonkey: Assertion failure: hasIonScript(), at js/src/vm/JSScript.h:2223

Categories

(Core :: JavaScript Engine: JIT, defect, P1)

ARM64
Unspecified
defect

Tracking

()

RESOLVED FIXED
mozilla66
Tracking Status
firefox66 --- fixed

People

(Reporter: nbp, Assigned: nbp)

References

(Blocks 1 open bug)

Details

(Whiteboard: [arm64:m2])

Attachments

(1 file)

The following issue appears much more frequently on Softiron ARM64 devices than seen on the ARM64 simulator, and might be intermittent.

Thread 1 "js-bugzil.la-ar" received signal SIGSEGV, Segmentation fault.
0x0000aaaaab5414a8 in AnnotateMozCrashReason (reason=0xaaaaabe9b512 "MOZ_RELEASE_ASSERT(hasIonScript())") at /home/nicolas/mozilla/_build/js/bugzil.la/arm64/wip/arm64/clang/pro/dist/include/mozilla/Assertions.h:38
38        gMozCrashReason = reason;
(gdb) bt
#0  0x0000aaaaab5414a8 in AnnotateMozCrashReason (reason=0xaaaaabe9b512 "MOZ_RELEASE_ASSERT(hasIonScript())") at /home/nicolas/mozilla/_build/js/bugzil.la/arm64/wip/arm64/clang/pro/dist/include/mozilla/Assertions.h:38
#1  js::jit::GetCalleeTokenTag (token=<optimized out>) at /home/nicolas/mozilla/wksp-0/js/src/jit/JitFrames.h:31
#2  js::jit::ScriptFromCalleeToken (token=<optimized out>) at /home/nicolas/mozilla/wksp-0/js/src/jit/JitFrames.h:63
#3  js::jit::BailoutFrameInfo::BailoutFrameInfo (this=<optimized out>, activations=..., bailout=0xfffffffe0aa0) at /home/nicolas/mozilla/wksp-0/js/src/jit/arm64/Bailouts-arm64.cpp:43
#4  0x0000aaaaaba78bcc in js::jit::Bailout (sp=0xfffffffe0aa0, bailoutInfo=0xfffffffe0a98) at /home/nicolas/mozilla/wksp-0/js/src/jit/Bailouts.cpp:41
#5  0x00000e832ffaf494 in ?? ()

The simulator is intended to simulate the ICache... that's really the obvious culprit, but you'd think that Baseline would crash too if that were the problem.

Ok, it took me some time to figure out the issue, and my latest understanding is that we do not trash the instruction cache after patching it during an Invalidation. This causes us to enter a Bailout (or worse) instead of the InvalidationBailout.

The bailout code path expect the IonScript to still be present on the JSScript and to be found from the calleeToken, whereas after an invalidation, we lookup the IonScript differently.

I will work on a patch an attach it here after double checking if it works well on ARM64 hardware.

Priority: -- → P1
This patch add AutoFlushICache::flush call to Assembler::PatchWrite_NearCall,
and also adds extra release assertions for the encoding of the 26 bits
immediate.
Attachment #9035921 - Flags: review?(sstangl)
Whiteboard: [arm64:m3]
Whiteboard: [arm64:m3] → [arm64:m2]
Comment on attachment 9035921 [details] [diff] [review]
Flush the instruction cache when patching OSIPoints.

Review of attachment 9035921 [details] [diff] [review]:
-----------------------------------------------------------------

Awesome.

MacroAssembler::patchCall() also looks like it's missing ICache flushing after patching a BL instruction; might as well fix that here too.

::: js/src/jit/arm64/Assembler-arm64.cpp
@@ +387,5 @@
> +                                    CodeLocationLabel toCall) {
> +  Instruction* dest = (Instruction*)start.raw();
> +  ptrdiff_t relTarget = (Instruction*)toCall.raw() - dest;
> +  ptrdiff_t relTarget00 = relTarget >> 2;
> +  MOZ_RELEASE_ASSERT((relTarget & 0x3) == 0);

Why is this true? We `>>2` for every BL, but I don't know why.

@@ +389,5 @@
> +  ptrdiff_t relTarget = (Instruction*)toCall.raw() - dest;
> +  ptrdiff_t relTarget00 = relTarget >> 2;
> +  MOZ_RELEASE_ASSERT((relTarget & 0x3) == 0);
> +  ImmNTest test;
> +  test.imm26 = relTarget00;

VIXL Utils (js/src/jit/arm64/vixl/Utils.h) has a helper function `is_int26(int64_t)` that could be used instead of using the struct. That's the same function that `bl()` uses internally (via `ImmUncondBranch`).
Attachment #9035921 - Flags: review?(sstangl) → review+

(In reply to Sean Stangl [:sstangl] from comment #4)

::: js/src/jit/arm64/Assembler-arm64.cpp
@@ +387,5 @@

  •                                CodeLocationLabel toCall) {
    
  • Instruction* dest = (Instruction*)start.raw();
  • ptrdiff_t relTarget = (Instruction*)toCall.raw() - dest;
  • ptrdiff_t relTarget00 = relTarget >> 2;
  • MOZ_RELEASE_ASSERT((relTarget & 0x3) == 0);

Why is this true? We >>2 for every BL, but I don't know why.

The ARM64 documentation explicit that the branch target is the imm26 immediate to which it appends '00' bits. (see C5.6.20 in the Aarch64 reference manual)

Pushed by npierron@mozilla.com:
https://hg.mozilla.org/integration/mozilla-inbound/rev/68c3af3df20e
Flush the instruction cache when patching OSIPoints. r=sstangl
Status: ASSIGNED → RESOLVED
Closed: 11 months ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla66
You need to log in before you can comment on or make changes to this bug.