Last Comment Bug 779841 - IonMonkey: Assertion failure: script->hasIonScript(), at ion/Ion.cpp:1392 or Crash [@ js::ion::Invalidate]
: IonMonkey: Assertion failure: script->hasIonScript(), at ion/Ion.cpp:1392 or ...
: assertion, testcase
Product: Core
Classification: Components
Component: JavaScript Engine (show other bugs)
: Other Branch
: x86 Linux
-- major (vote)
: ---
Assigned To: Nicolas B. Pierron [:nbp]
: general
: Jason Orendorff [:jorendorff]
Depends on:
Blocks: langfuzz IonFuzz
  Show dependency treegraph
Reported: 2012-08-02 07:05 PDT by Christian Holler (:decoder)
Modified: 2013-01-14 08:09 PST (History)
7 users (show)
choller: in‑testsuite+
See Also:
Crash Signature:
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---

Escape inline cache if invalidated by the lookup. (2.13 KB, patch)
2012-08-03 15:05 PDT, Nicolas B. Pierron [:nbp]
dvander: review+
nicolas.b.pierron: checkin+
Details | Diff | Splinter Review

Description User image Christian Holler (:decoder) 2012-08-02 07:05:52 PDT
The following testcase asserts on ionmonkey revision 2169bca0c9a5 (run with --ion -n -m --ion-eager -a):

function outer2() {
    "use strict";
    return new (function () {}).arguments
outer2().toString(this, true);
Comment 1 User image Christian Holler (:decoder) 2012-08-02 07:07:30 PDT
The crash probably just a null-deref due to the IonScript pointer being NULL:

==27569== Invalid read of size 8
==27569==    at 0x6C5874: js::ion::Invalidate(js::FreeOp*, js::Vector<js::types::CompilerOutput, 0ul, js::TempAllocPolicy> const&, bool) (IonCode.h:372)
==27569==    by 0x6C5BCE: js::ion::Invalidate(JSContext*, JSScript*, bool) (Ion.cpp:1399)
==27569==    by 0x6ECBBC: js::ion::GetPropertyCache(JSContext*, unsigned long, JS::Handle<JSObject*>, JS::MutableHandle<JS::Value>) (IonCaches.cpp:332)
==27569==    by 0x4032CA3: ???
==27569==    by 0x6C32E6: EnterIon(JSContext*, js::StackFrame*, void*) (Ion.cpp:1155)
==27569==    by 0x4A9D19: js::Interpret(JSContext*, js::StackFrame*, js::InterpMode) (jsinterp.cpp:2499)
==27569==    by 0x623C84: js::mjit::EnterMethodJIT(JSContext*, js::StackFrame*, void*, JS::Value*, bool) (MethodJIT.cpp:1063)
==27569==    by 0x6251DE: js::mjit::JaegerShot(JSContext*, bool) (MethodJIT.cpp:1094)
==27569==    by 0x4AAC61: js::RunScript(JSContext*, JSScript*, js::StackFrame*) (jsinterp.cpp:318)
==27569==    by 0x4AB9C9: js::Execute(JSContext*, JSScript*, JSObject&, JS::Value*) (jsinterp.cpp:507)
==27569==    by 0x41D5A9: JS_ExecuteScript (jsapi.cpp:5626)
==27569==    by 0x408EFF: Process(JSContext*, JSObject*, char const*, bool) (js.cpp:435)
==27569==  Address 0x70 is not stack'd, malloc'd or (recently) free'd
Comment 2 User image Nicolas B. Pierron [:nbp] 2012-08-03 12:01:09 PDT
When we eagerly compile this script, we compile the « .arguments » as a getPropertyCache.  This property cache is then looking up in the Function for the arguments property which is a native and cause the invalidation of the script, which then try to be invalidated a second time.

The weird seems to be the first cause of the invalidation:

(gdb) bt
#0  js::types::TypeCompartment::addPendingRecompile (this=0xe43728, cx=0xe42bc0, script=0x7fffef107190)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsinfer.cpp:2197
#1  0x00000000004fcf55 in js::analyze::ScriptAnalysis::addTypeBarrier (this=0x7ffff7f9ac70, cx=0xe42bc0, pc=0xe4cef5 "5", 
    target=0xe4e4e0, type=...) at /home/nicolas/mozilla/ionmonkey/js/src/jsinfer.cpp:2328
#2  0x00000000004f8b5f in TypeConstraintSubsetBarrier::newType (this=0x7ffff7f9b0f8, cx=0xe42bc0, source=0x7ffff7f9b020, type=...)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsinfer.cpp:893
#3  0x0000000000463c1c in js::types::TypeCompartment::resolvePending (this=0xe43728, cx=0xe42bc0)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsinferinlines.h:987
#4  0x00000000004641fe in js::types::TypeSet::addType (this=0x7ffff7f9b020, cx=0xe42bc0, type=...)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsinferinlines.h:1302
#5  0x00000000004ff27c in InlineAddTypeProperty (cx=0xe42bc0, obj=0x7fffef1001f0, id=..., type=...)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsinfer.cpp:2879
#6  0x00000000004ff2c6 in js::types::TypeObject::addPropertyType (this=0x7fffef1001f0, cx=0xe42bc0, id=..., type=...)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsinfer.cpp:2885
#7  0x000000000042baea in js::types::AddTypePropertyId (cx=0xe42bc0, obj=0x7fffef111d00, id=..., type=...)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsinferinlines.h:465
#8  0x0000000000566f99 in js::DefineNativeProperty (cx=0xe42bc0, obj=..., id=..., value=..., getter=0x7fffef1069c0, 
    setter=0x7fffef1069c0, attrs=52, flags=0, shortid=0, defineHow=0) at /home/nicolas/mozilla/ionmonkey/js/src/jsobj.cpp:4122
#9  0x00000000004c7e16 in fun_resolve (cx=0xe42bc0, obj=..., id=..., flags=1, objp=...)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsfun.cpp:350
#10 0x0000000000567712 in CallResolveOp (cx=0xe42bc0, obj=..., id=..., flags=1, objp=..., propp=..., recursedp=0x7fffffff90af)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsobj.cpp:4252
#11 0x0000000000567a85 in LookupPropertyWithFlagsInline (cx=0xe42bc0, obj=..., id=..., flags=65535, objp=..., propp=...)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsobj.cpp:4304
#12 0x0000000000567d06 in js::baseops::LookupProperty (cx=0xe42bc0, obj=..., id=..., objp=..., propp=...)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsobj.cpp:4353
#13 0x000000000040886f in JSObject::lookupGeneric (this=0x7fffef111d00, cx=0xe42bc0, id=..., objp=..., propp=...)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsobjinlines.h:1047
#14 0x000000000051c19f in JSObject::lookupProperty (this=0x7fffef111d00, cx=0xe42bc0, name=0x7fffef2246c0, objp=..., propp=...)
    at /home/nicolas/mozilla/ionmonkey/js/src/jsobjinlines.h:1055
#15 0x000000000086b1de in TryAttachNativeStub (cx=0xe42bc0, cache=..., obj=..., name=..., isCacheableNative=0x7fffffff937f)
    at /home/nicolas/mozilla/ionmonkey/js/src/ion/IonCaches.cpp:275
#16 0x000000000086b429 in js::ion::GetPropertyCache (cx=0xe42bc0, cacheIndex=0, obj=..., vp=...)
    at /home/nicolas/mozilla/ionmonkey/js/src/ion/IonCaches.cpp:317
#17 0x00007ffff7f8a68c in ?? ()

because if we invalidate while adding a new type this means that we are freezing some type sets at one point or another.
Comment 3 User image Nicolas B. Pierron [:nbp] 2012-08-03 15:05:24 PDT
Created attachment 648870 [details] [diff] [review]
Escape inline cache if invalidated by the lookup.
Comment 4 User image David Anderson [:dvander] 2012-08-07 16:59:49 PDT
Comment on attachment 648870 [details] [diff] [review]
Escape inline cache if invalidated by the lookup.

Review of attachment 648870 [details] [diff] [review]:

::: js/src/ion/IonCaches.cpp
@@ +321,5 @@
> +    // effectful such as what is done in fun_resolve where DefineNativePropery
> +    // is called when the native is resolved. This function can modify the type
> +    // object and thus invalidate the script. In such case we just return to the
> +    // fallback path.
> +    if (!topScript->hasIonScript())

r=me with this check moved into the |if| case below. You can probably just shorten the comment to, "Don't re-invalidate if the lookup already caused invalidation."
Comment 5 User image Nicolas B. Pierron [:nbp] 2012-08-07 18:59:29 PDT
Comment on attachment 648870 [details] [diff] [review]
Escape inline cache if invalidated by the lookup.
Comment 6 User image Christian Holler (:decoder) 2013-01-14 08:09:37 PST
A testcase for this bug was automatically identified at js/src/jit-test/tests/ion/bug779841.js.

Note You need to log in before you can comment on or make changes to this bug.