Closed Bug 1245160 Opened 8 years ago Closed 8 years ago

Assertion failure: result ([OOM] Is it really infallible?), at js/src/ds/LifoAlloc.h:281 involving js::jit::IonBuilder::jsop_getelem

Categories

(Core :: JavaScript Engine, defect)

x86_64
Linux
defect
Not set
critical

Tracking

()

RESOLVED INCOMPLETE
Tracking Status
firefox47 --- wontfix

People

(Reporter: gkw, Assigned: nbp)

References

Details

(Keywords: assertion, regression, Whiteboard: [jsbugmon:ignore])

Attachments

(1 file)

+++ This bug was initially created as a clone of Bug #1244828 +++

Nicolas requests that each stack should have it's own bug, blocking meta bug 1244824. Assigning to him by default.

Line numbers from m-c rev b2a3dc4b161f:

#0  js::LifoAlloc::allocInfallibleOrAssert (this=<optimized out>, n=<optimized out>) at /home/ubuntu/trees/mozilla-central/js/src/ds/LifoAlloc.h:281
#1  js::jit::TempAllocator::allocateInfallible (this=<optimized out>, bytes=<optimized out>) at /home/ubuntu/trees/mozilla-central/js/src/jit/JitAllocPolicy.h:40
#2  0x00000000005a67e3 in js::jit::TempObject::operator new (nbytes=184, alloc=...) at /home/ubuntu/trees/mozilla-central/js/src/jit/JitAllocPolicy.h:174
#3  js::jit::MBoundsCheck::New (alloc=..., index=<optimized out>, length=<optimized out>) at /home/ubuntu/trees/mozilla-central/js/src/jit/MIR.h:8697
#4  js::jit::IonBuilder::addBoundsCheck (this=<optimized out>, index=<optimized out>, length=<optimized out>) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:13539
#5  js::jit::IonBuilder::jsop_getelem_dense (this=0x7ffeaa139ab8, obj=<optimized out>, index=<optimized out>, unboxedType=<optimized out>) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:9423
#6  0x00000000005a36dc in js::jit::IonBuilder::getElemTryDense (this=0x7ffeaa139ab8, emitted=0x7ffeaa1398c7, obj=0x6210c88, index=0x620fe40) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:9000
#7  0x0000000000591be8 in js::jit::IonBuilder::jsop_getelem (this=0x7ffeaa139ab8) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:8550
#8  0x000000000058880a in js::jit::IonBuilder::inspectOpcode (this=0x7ffeaa139ab8, op=JSOP_GETELEM) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:1984
#9  0x0000000000586a0f in js::jit::IonBuilder::traverseBytecode (this=0x7ffeaa139ab8) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:1522
#10 0x0000000000587260 in js::jit::IonBuilder::buildInline (this=0x7ffeaa139ab8, callerBuilder=<optimized out>, callerResumePoint=<optimized out>, callInfo=...) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:1089
#11 0x000000000059ab32 in js::jit::IonBuilder::inlineScriptedCall (this=0x2a482a0, callInfo=..., target=<optimized out>) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:5080
#12 0x000000000059bd3a in js::jit::IonBuilder::inlineSingleCall (this=0x2a482a0, callInfo=..., targetArg=0x7f8e97af1600) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:5588
#13 0x000000000059bfcc in js::jit::IonBuilder::inlineCallsite (this=0x2a482a0, targets=..., callInfo=...) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:5644
#14 0x000000000058fc7e in js::jit::IonBuilder::jsop_call (this=0x2a482a0, argc=<optimized out>, constructing=<optimized out>) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:6581
#15 0x00000000005885d2 in js::jit::IonBuilder::inspectOpcode (this=0x2a482a0, op=<optimized out>) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:1888
#16 0x0000000000586a0f in js::jit::IonBuilder::traverseBytecode (this=0x2a482a0) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:1522
#17 0x00000000005834df in js::jit::IonBuilder::build (this=0x2a482a0) at /home/ubuntu/trees/mozilla-central/js/src/jit/IonBuilder.cpp:918
#18 0x0000000000577d58 in js::jit::IonCompile (script=<optimized out>, baselineFrame=<optimized out>, osrPc=<optimized out>, optimizationLevel=<optimized out>, cx=<optimized out>, constructing=<optimized out>, recompile=<optimized out>) at /home/ubuntu/trees/mozilla-central/js/src/jit/Ion.cpp:2210
#19 js::jit::Compile (cx=0x18e49c0, script=..., osrFrame=<optimized out>, osrPc=<optimized out>, constructing=<optimized out>, forceRecompile=<optimized out>) at /home/ubuntu/trees/mozilla-central/js/src/jit/Ion.cpp:2448
#20 0x000000000057869a in BaselineCanEnterAtEntry (cx=0x18e49c0, frame=0x7ffeaa13a8a8, script=...) at /home/ubuntu/trees/mozilla-central/js/src/jit/Ion.cpp:2573
#21 js::jit::IonCompileScriptForBaseline (cx=0x18e49c0, frame=0x7ffeaa13a8a8, pc=<optimized out>) at /home/ubuntu/trees/mozilla-central/js/src/jit/Ion.cpp:2697
#22 0x00007f8e9d91cf00 in ?? ()
#23 0x0000000000000000 in ?? ()
Gary, was this a debug build?

If this is a debug build, then I wonder if we should not increase our ballast space, as the temporary vector which are before are likely to check for the ballast space.

Otherwise, I think the unbounded allocation might be in one of the earlier functions, likely snoopControlFlow, in which case I would be interested if you have signatures with snoopControlFlow on the stack.
Flags: needinfo?(gary)
Ok, I think I found one potential source for this issue.

Currently the TemporaryTypeSet::addType function which takes the LifoAlloc of the compilation and uses it to allocate arrays of size O(~n) in a O(n²) loop under  jit::PropertyReadNeedsTypeBarrier.

The first issue which surprises me, is that addType handle allocations failures by reporting an unknowObject [1].  The second thing, is that the the PropertyReadNeedsTypeBarrier does not have error cases, and it still use the GetJitContext [2] to get the LifoAlloc.

A naive approach would be to consider the TemporaryTypeSet as bounded, and just check that we have enough ballast space after any call to PropertyReadNeedsTypeBarrier.

[1] https://dxr.mozilla.org/mozilla-central/source/js/src/vm/TypeInference.cpp#560-561
[2] https://dxr.mozilla.org/mozilla-central/source/js/src/jit/MIR.cpp#5211,5237
It sounds that Bug 923614 deliberately removed the OOM check because the returned value was mixed-up with the state of the function.

Also note that the enumerateTypes function can also fail.
Flags: needinfo?(gary)
Summary: Assertion failure: result ([OOM] Is it really infallible?), at js/src/ds/LifoAlloc.h:281 involving js::jit::MBoundsCheck::New → Assertion failure: result ([OOM] Is it really infallible?), at js/src/ds/LifoAlloc.h:281 involving js::jit::IonBuilder::getElemTryDense
This patch can be used to find the most of exercised issues without help
from the OOMTest function nor any fuzzing mechanism.

This patch print on the fd number 3 all the allocations made with the
TempAllocator used in the JitAllocPolicy.  Thus one can track the stats of
the LifoAlloc by running the following command:

  ./js foo.js 3> ./jitalloc.log

The same can be done with the test suite, but the test suite should be
executed with -j1 to prevent lines from being mixed up between different
program executions.

The generated file will contain way too many useless information, but the
following command can be used to filter the most dramatic allocations which
are often relevant of issues.

  sort -t, -g -k2 <(awk -F, ' $2 < 10000 && $2 > 5000 ' ./js/src/tempalloc.log)

If you decide to uncomment the rest of the allocations, then you might have
to filter by frame addresses, as follow:

  sort -t, -g -k2 <(
     awk -F, ' $2 < 10000 && $2 > 5000 &&  /, 0x4e8d41 0x4e8e58/ '
        ./js/src/tempalloc.log)

To briefly explain the command:
  sort -t, -g -k2  :  sort by maximal continuous free space available for an
    allocations.  To highlight the most dramatic one exercised by the test suite.

  awk -F, ' $2 < 10000 && $2 > 5000 ' :  filter by allocations made under
    the context where the maximal free space is between ~5k and ~10k.
    Knowing that the first allocation is made in a block which has only 4k,
    and that the ballast space ensure that there is at least 16k.

These filters implies that we have allocated at between ~6k / ~11k bytes
before the last time we execute the ensureBallast function.  Which usually
indicate an unbounded ensureBallast call.
And I forgot to mention, that the stack trace can be obtained by running the following command with the pointers which are at the end of each line of the log file:

   addr2line -fiC -e ./js 0xaddr 0xaddr 0xaddr
Summary: Assertion failure: result ([OOM] Is it really infallible?), at js/src/ds/LifoAlloc.h:281 involving js::jit::IonBuilder::getElemTryDense → Assertion failure: result ([OOM] Is it really infallible?), at js/src/ds/LifoAlloc.h:281 involving js::jit::IonBuilder::jsop_getelem
Gary, this issue seems to have a lot of aliases, would it be possible to reproduce (or record with rr) any of these one to a signature within IonBuilder?
Flags: needinfo?(gary)
Resolving INCOMPLETE for now. Testing clang-compiled non-Asan builds is not applicable for the moment, since it isn't even on treeherder, and I do not have more information to provide.
Status: ASSIGNED → RESOLVED
Closed: 8 years ago
Flags: needinfo?(gary)
Resolution: --- → INCOMPLETE
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: