Bug 154542

Summary: Debug assertion failure while loading http://kangax.github.io/compat-table/es6/.
Product: WebKit Reporter: Mark Lam <mark.lam>
Component: JavaScriptCoreAssignee: Mark Lam <mark.lam>
Status: RESOLVED FIXED    
Severity: Normal CC: benjamin, buildbot, fpizlo, ggaren, keith_miller, msaboff, rniwa, sbarati, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: WebKit Local Build   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
proposed patch.
ggaren: review+
proposed patch 2: a more comprehensive and correct fix.
mark.lam: review-
proposed patch 3: resolved test failures.
mark.lam: review-, buildbot: commit-queue-
Archive of layout-test-results from ews106 for mac-yosemite-wk2
none
Archive of layout-test-results from ews101 for mac-yosemite
none
proposed patch 4: rebased remaining tests sbarati: review+

Description Mark Lam 2016-02-22 10:05:39 PST
Just loading the kangax ES6 compatibility tests site triggers the following assertion failure on a debug build:

    Structure* InternalFunction::createSubclassStructure(ExecState* exec, JSValue newTarget, Structure* baseClass)
    {

        VM& vm = exec->vm();
        // We allow newTarget == JSValue() because the API needs to be able to create classes without having a real JS frame.
        // Since we don't allow subclassing in the API we just treat newTarget == JSValue() as newTarget == exec->callee()
        ASSERT(!newTarget || newTarget.isFunction());   // <============ Failed this assert.

        if (newTarget && newTarget != exec->callee()) {
        ...

(lldb) bt
* thread #1: tid = 0x671b, 0x00000001064aa0a7 JavaScriptCore`::WTFCrash() + 39 at Assertions.cpp:322, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xbbadbeef)
  * frame #0: 0x00000001064aa0a7 JavaScriptCore`::WTFCrash() + 39 at Assertions.cpp:322
    frame #1: 0x0000000105ea106f JavaScriptCore`JSC::InternalFunction::createSubclassStructure(exec=0x00007fff5dd208d0, newTarget=JSValue @ 0x00007fff5dd20480, baseClass=0x000000011d658c00) + 111 at InternalFunction.cpp:87
    frame #2: 0x0000000105f50993 JavaScriptCore`JSC::constructArrayBuffer(exec=0x00007fff5dd208d0) + 339 at JSArrayBufferConstructor.cpp:99
    frame #3: 0x00000001060e82b6 JavaScriptCore`JSC::LLInt::handleHostCall(execCallee=0x00007fff5dd208d0, pc=0x000000011ed14280, callee=JSValue @ 0x00007fff5dd206a8, kind=CodeForCall) + 262 at LLIntSlowPaths.cpp:1108
    frame #4: 0x00000001060e8fda JavaScriptCore`JSC::LLInt::setUpCall(execCallee=0x00007fff5dd208d0, pc=0x000000011ed14280, kind=CodeForCall, calleeAsValue=JSValue @ 0x00007fff5dd20808, callLinkInfo=0x0000000120fa34b8) + 106 at LLIntSlowPaths.cpp:1154
    frame #5: 0x00000001060e8f56 JavaScriptCore`JSC::LLInt::genericCall(exec=0x00007fff5dd20960, pc=0x000000011ed14280, kind=CodeForCall) + 230 at LLIntSlowPaths.cpp:1238
    frame #6: 0x00000001060e5ffc JavaScriptCore`::llint_slow_path_call(exec=0x00007fff5dd20960, pc=0x000000011ed14280) + 60 at LLIntSlowPaths.cpp:1244
    frame #7: 0x00000001060f10c9 JavaScriptCore`llint_entry + 26821
    frame #8: 0x00000001060f10db JavaScriptCore`llint_entry + 26839
    frame #9: 0x00000001060f10db JavaScriptCore`llint_entry + 26839
    frame #10: 0x00000001060f10db JavaScriptCore`llint_entry + 26839
    frame #11: 0x00000001060f10db JavaScriptCore`llint_entry + 26839
    frame #12: 0x00000001060ea5ee JavaScriptCore`llintPCRangeStart + 334
    frame #13: 0x0000000105f0b58a JavaScriptCore`JSC::JITCode::execute(this=0x0000000120d86c30, vm=0x0000000117803380, protoCallFrame=0x00007fff5dd20e98) + 218 at JITCode.cpp:80
    frame #14: 0x0000000105ea5716 JavaScriptCore`JSC::Interpreter::execute(this=0x00000001179ec138, program=0x000000011c43b900, callFrame=0x000000011ce59140, thisObj=0x0000000117853f70) + 4518 at Interpreter.cpp:972
    frame #15: 0x000000010588ee20 JavaScriptCore`JSC::evaluate(exec=0x000000011ce59140, source=0x00007fff5dd22608, thisValue=JSValue @ 0x00007fff5dd222f0, returnedException=0x00007fff5dd22450) + 480 at Completion.cpp:106
    frame #16: 0x000000010588ef5e JavaScriptCore`JSC::profiledEvaluate(exec=0x000000011ce59140, reason=Other, source=0x00007fff5dd22608, thisValue=JSValue @ 0x00007fff5dd22348, returnedException=0x00007fff5dd22450) + 94 at Completion.cpp:121
    frame #17: 0x000000010a4d8c8b WebCore`WebCore::JSMainThreadExecState::profiledEvaluate(exec=0x000000011ce59140, reason=Other, source=0x00007fff5dd22608, thisValue=JSValue @ 0x00007fff5dd223d0, returnedException=0x00007fff5dd22450) + 75 at JSMainThreadExecState.h:80
    frame #18: 0x000000010a4d6806 WebCore`WebCore::ScriptController::evaluateInWorld(this=0x00000001179f5770, sourceCode=0x00007fff5dd22600, world=0x00000001179fb090, exceptionDetails=0x0000000000000000) + 326 at ScriptController.cpp:164
    frame #19: 0x000000010a4d696c WebCore`WebCore::ScriptController::evaluate(this=0x00000001179f5770, sourceCode=0x00007fff5dd22600, exceptionDetails=0x0000000000000000) + 76 at ScriptController.cpp:180
    frame #20: 0x000000010a4e5d6b WebCore`WebCore::ScriptElement::executeScript(this=0x00000001219f9e40, sourceCode=0x00007fff5dd22600) + 491 at ScriptElement.cpp:314
    frame #21: 0x000000010a4e4c53 WebCore`WebCore::ScriptElement::prepareScript(this=0x00000001219f9e40, scriptStartPosition=0x00007fff5dd228b8, supportLegacyTypes=DisallowLegacyTypeInTypeAttribute) + 1731 at ScriptElement.cpp:245
    frame #22: 0x000000010921ecbc WebCore`WebCore::HTMLScriptRunner::runScript(this=0x000000011c51e3a8, script=0x00000001219f9e40, scriptStartPosition=0x00007fff5dd228b8) + 364 at HTMLScriptRunner.cpp:302
    frame #23: 0x000000010921eaca WebCore`WebCore::HTMLScriptRunner::execute(this=0x000000011c51e3a8, scriptElement=PassRefPtr<WebCore::Element> @ 0x00007fff5dd228a8, scriptStartPosition=0x00007fff5dd228b8) + 138 at HTMLScriptRunner.cpp:175
    frame #24: 0x0000000109142bb1 WebCore`WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder(this=0x000000011d671e40) + 289 at HTMLDocumentParser.cpp:195
    frame #25: 0x0000000109142cc1 WebCore`WebCore::HTMLDocumentParser::canTakeNextToken(this=0x000000011d671e40, mode=AllowYield, session=0x00007fff5dd22a98) + 177 at HTMLDocumentParser.cpp:213
    frame #26: 0x000000010914202f WebCore`WebCore::HTMLDocumentParser::pumpTokenizer(this=0x000000011d671e40, mode=AllowYield) + 399 at HTMLDocumentParser.cpp:252
    frame #27: 0x00000001091429ef WebCore`WebCore::HTMLDocumentParser::resumeParsingAfterYield(this=0x000000011d671e40) + 47 at HTMLDocumentParser.cpp:183
    frame #28: 0x00000001092050a8 WebCore`WebCore::HTMLParserScheduler::continueNextChunkTimerFired(this=0x00000001179c7c80) + 152 at HTMLParserScheduler.cpp:114
    frame #29: 0x0000000109206998 WebCore`void std::__1::__invoke_void_return_wrapper<void>::__call<std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>&>(std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>&&&) [inlined] decltype(__f=0x00000001179c7ce8, __a0=0x00000001179c7cf8)).*fp(std::__1::forward<>(fp1))) std::__1::__invoke<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*&, void>(void (WebCore::HTMLParserScheduler::*&&&)(), WebCore::HTMLParserScheduler*&&&) + 248 at __functional_base:382
    frame #30: 0x0000000109206912 WebCore`void std::__1::__invoke_void_return_wrapper<void>::__call<std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>&>(std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>&&&) [inlined] std::__1::__bind_return<void (WebCore::HTMLParserScheduler::*)(), std::__1::tuple<WebCore::HTMLParserScheduler*>, std::__1::tuple<>, _is_valid_bind_return<void (WebCore::HTMLParserScheduler::*)(), std::__1::tuple<WebCore::HTMLParserScheduler*>, std::__1::tuple<> >::value>::type std::__1::__apply_functor<void (__f=0x00000001179c7ce8, __bound_args=0x00000001179c7cf8, (null)=__tuple_indices<0> @ 0x00007fff5dd22df0, __args=0x00007fff5dd22db0)(), std::__1::tuple<WebCore::HTMLParserScheduler*>, 0ul, std::__1::tuple<> >(void (WebCore::HTMLParserScheduler::*&)(), std::__1::tuple<WebCore::HTMLParserScheduler*>&, std::__1::__tuple_indices<0ul>, std::__1::tuple<>&&) + 40 at functional:2060
    frame #31: 0x00000001092068ea WebCore`void std::__1::__invoke_void_return_wrapper<void>::__call<std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>&>(std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>&&&) [inlined] std::__1::__bind_return<void (WebCore::HTMLParserScheduler::*)(), std::__1::tuple<WebCore::HTMLParserScheduler*>, std::__1::tuple<>, _is_valid_bind_return<void (WebCore::HTMLParserScheduler::*)(), std::__1::tuple<WebCore::HTMLParserScheduler*>, std::__1::tuple<> >::value>::type std::__1::__bind<void (this=0x00000001179c7ce8)(), WebCore::HTMLParserScheduler*>::operator()<>() + 31 at functional:2123
    frame #32: 0x00000001092068cb WebCore`void std::__1::__invoke_void_return_wrapper<void>::__call<std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>&>(std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>&&&) [inlined] decltype(__f=0x00000001179c7ce8)(), WebCore::HTMLParserScheduler*>&>(fp)(std::__1::forward<>(fp0))) std::__1::__invoke<std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>&>(std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>&&&) + 11 at __functional_base:415
    frame #33: 0x00000001092068c0 WebCore`void std::__1::__invoke_void_return_wrapper<void>::__call<std::__1::__bind<void (__args=0x00000001179c7ce8)(), WebCore::HTMLParserScheduler*>&>(std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>&&&) + 32 at __functional_base:440
    frame #34: 0x000000010920686c WebCore`std::__1::__function::__func<std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*>, std::__1::allocator<std::__1::__bind<void (WebCore::HTMLParserScheduler::*&)(), WebCore::HTMLParserScheduler*> >, void ()>::operator(this=0x00000001179c7ce0)() + 44 at functional:1407
    frame #35: 0x00000001085a9c3a WebCore`std::__1::function<void ()>::operator(this=0x00000001179c7ce0)() const + 26 at functional:1793
    frame #36: 0x00000001085a9b5c WebCore`WebCore::Timer::fired(this=0x00000001179c7ca0) + 28 at Timer.h:133
    frame #37: 0x000000010a9c528a WebCore`WebCore::ThreadTimers::sharedTimerFiredInternal(this=0x00000001179b1618) + 394 at ThreadTimers.cpp:121
    frame #38: 0x000000010a9c64d1 WebCore`WebCore::ThreadTimers::setSharedTimer(this=0x000000010bb456f8)::$_0::operator()() const + 33 at ThreadTimers.cpp:73
    frame #39: 0x000000010a9c649d WebCore`void std::__1::__invoke_void_return_wrapper<void>::__call<WebCore::ThreadTimers::setSharedTimer(WebCore::SharedTimer*)::$_0&>(WebCore::ThreadTimers::setSharedTimer(WebCore::SharedTimer*)::$_0&&&) [inlined] decltype(__f=0x000000010bb456f8)::$_0&>(fp)(std::__1::forward<>(fp0))) std::__1::__invoke<WebCore::ThreadTimers::setSharedTimer(WebCore::SharedTimer*)::$_0&>(WebCore::ThreadTimers::setSharedTimer(WebCore::SharedTimer*)::$_0&&&) + 45 at __functional_base:415
    frame #40: 0x000000010a9c648c WebCore`void std::__1::__invoke_void_return_wrapper<void>::__call<WebCore::ThreadTimers::setSharedTimer(__args=0x000000010bb456f8)::$_0&>(WebCore::ThreadTimers::setSharedTimer(WebCore::SharedTimer*)::$_0&&&) + 28 at __functional_base:440
    frame #41: 0x000000010a9c643c WebCore`std::__1::__function::__func<WebCore::ThreadTimers::setSharedTimer(WebCore::SharedTimer*)::$_0, std::__1::allocator<WebCore::ThreadTimers::setSharedTimer(WebCore::SharedTimer*)::$_0>, void ()>::operator(this=0x000000010bb456f0)() + 44 at functional:1407
    frame #42: 0x00000001085a9c3a WebCore`std::__1::function<void ()>::operator(this=0x000000010bb456f0)() const + 26 at functional:1793
    frame #43: 0x0000000109d2dd2f WebCore`WebCore::MainThreadSharedTimer::fired(this=0x000000010bb456e0) + 111 at MainThreadSharedTimer.cpp:52
    frame #44: 0x0000000109d2e229 WebCore`WebCore::timerFired((null)=0x00007f9632d38930, (null)=0x0000000000000000) + 41 at MainThreadSharedTimerCF.cpp:74
    ...
Comment 1 Radar WebKit Bug Importer 2016-02-22 10:07:19 PST
<rdar://problem/24771127>
Comment 2 Radar WebKit Bug Importer 2016-02-22 10:08:33 PST
<rdar://problem/24771133>
Comment 3 Mark Lam 2016-02-22 10:16:06 PST
The JS stack at the point of the assertion failure:

(lldb) p JSDollarVMPrototype::printStack((JSC::ExecState*)0x00007fff5dd208d0)

      frame 0x7fff5dd208d0 {
         name: ArrayBuffer
         sourceURL: [native code]
         isInlinedFrame: false
         callee: 0x11d64cc00
         returnPC: 0x0
         callerFrame: 0x7fff5dd20960
         rawLocationBits: 0 0x0
         codeBlock: 0x0 
      }
      frame 0x7fff5dd20960 {
         name: 
         sourceURL: 
         isInlinedFrame: false
         callee: 0x11c43c610
         returnPC: 0x1060f10db
         callerFrame: 0x7fff5dd20a30
         rawLocationBits: 79 0x4f
         codeBlock: 0x11ced3840 #ADXjvF:[0x11ced3840->0x11c47fbc0, LLIntFunctionCall, 105]
            bytecodeOffset: 79 of 105
            line: 20
            column: 26
      }
      frame 0x7fff5dd20a30 {
         name: every
         sourceURL: 
         isInlinedFrame: false
         callee: 0x11d634760
         returnPC: 0x1060f10db
         callerFrame: 0x7fff5dd20ac0
         rawLocationBits: 251 0xfb
         codeBlock: 0x11c45d860 every#CkOerD:[0x11c45d860->0x11d649dc0, LLIntFunctionCall, 273 (StrictMode)]
            bytecodeOffset: 251 of 273
            line: 1
            column: 11
      }
      frame 0x7fff5dd20ac0 {
         name: anonymous
         sourceURL: 
         isInlinedFrame: false
         callee: 0x11c43c670
         returnPC: 0x1060f10db
         callerFrame: 0x7fff5dd20b40
         rawLocationBits: 72 0x48
         codeBlock: 0x11c45da80 anonymous#C4snY3:[0x11c45da80->0x11c47fe40, LLIntFunctionCall, 83]
            bytecodeOffset: 72 of 83
            line: 17
            column: 26
      }
      frame 0x7fff5dd20b40 {
         name: 
         sourceURL: http://kangax.github.io/compat-table/es6/
         isInlinedFrame: false
         callee: 0x11c43c700
         returnPC: 0x1060f10db
         callerFrame: 0x7fff5dd20bd0
         rawLocationBits: 99 0x63
         codeBlock: 0x11c45dca0 #Ecw5Kd:[0x11c45dca0->0x11c454240, LLIntFunctionCall, 248]
            bytecodeOffset: 99 of 248
            line: 20163
            column: 645
      }
      frame 0x7fff5dd20bd0 {
         name: global code
         sourceURL: http://kangax.github.io/compat-table/es6/
         isInlinedFrame: false
         callee: 0x11c487d60
         returnPC: 0x1060ea5ee
         callerFrame: 0x0
         rawLocationBits: 31 0x1f
         codeBlock: 0x11c45dec0 <global>#EBP81e:[0x11c45dec0->0x11c43b900, LLIntGlobal, 51]
            bytecodeOffset: 31 of 51
            line: 20163
            column: 1361
      }
Comment 4 Keith Miller 2016-02-22 10:29:53 PST
The problem is that constructArrayBuffer is used for both call and construct. This causes try to use the this value as the new.target, which is not a function and triggers the assert. Fortunately, there is a really simple solution since ArrayBuffer is supposed to throw if called as a function per ES6 (https://tc39.github.io/ecma262/#sec-arraybuffer-constructor). All we need to do is make ArrayBuffer have CallTypeNone
Comment 5 Mark Lam 2016-02-22 11:09:38 PST
<rdar://problem/24750971>
Comment 6 Mark Lam 2016-02-22 11:19:41 PST
Created attachment 271935 [details]
proposed patch.
Comment 7 Keith Miller 2016-02-22 11:22:31 PST
Comment on attachment 271935 [details]
proposed patch.

Looks good to me.
Comment 8 Geoffrey Garen 2016-02-22 11:23:02 PST
Comment on attachment 271935 [details]
proposed patch.

r=me
Comment 9 Saam Barati 2016-02-22 11:25:02 PST
r=me too
Maybe some tests in es6.yaml need to be changed.
Comment 10 Mark Lam 2016-02-22 11:26:52 PST
This broke the following tests:
es6.yaml/es6/typed_arrays_ArrayBuffer[Symbol.species].js.default: ERROR: Unexpected exit code: 3
es6.yaml/es6/Proxy_internal_get_calls_CreateDynamicFunction.js.default: ERROR: Unexpected exit code: 139

Will investigate first.
Comment 11 Mark Lam 2016-02-22 11:46:23 PST
(In reply to comment #10)
> This broke the following tests:
> es6.yaml/es6/typed_arrays_ArrayBuffer[Symbol.species].js.default: ERROR:
> Unexpected exit code: 3
> es6.yaml/es6/Proxy_internal_get_calls_CreateDynamicFunction.js.default:
> ERROR: Unexpected exit code: 139
> 
> Will investigate first.

The Proxy_internal_get_calls_CreateDynamicFunction.js was a pre-existing failure unrelated to this patch.
Comment 12 Mark Lam 2016-02-22 14:39:06 PST
Created attachment 271957 [details]
proposed patch 2: a more comprehensive and correct fix.

Still running tests.
Comment 13 Mark Lam 2016-02-22 15:29:51 PST
Comment on attachment 271957 [details]
proposed patch 2: a more comprehensive and correct fix.

This patch causes lots of failures when running the JSC tests.  Taking another look.
Comment 14 Mark Lam 2016-02-23 10:05:00 PST
Created attachment 272028 [details]
proposed patch 3: resolved test failures.

The test failures were simply because the test results needed to be rebased due to the new TypeError message.

Also, the es6/typed_arrays_%TypedArray%[Symbol.species].js test now passes.  However, the run-jsc-stress-test harness does not like the use of % in the test name.  When the test changed from failing to passing, the harness choked when it tried to report the change.  This was obscuring the fact that the test is now passing.  Once I updated the expected result, all is well again.
Comment 15 Build Bot 2016-02-23 10:57:32 PST
Comment on attachment 272028 [details]
proposed patch 3: resolved test failures.

Attachment 272028 [details] did not pass mac-wk2-ews (mac-wk2):
Output: http://webkit-queues.webkit.org/results/872891

New failing tests:
js/dom/basic-weakset.html
js/dom/basic-weakmap.html
Comment 16 Build Bot 2016-02-23 10:57:37 PST
Created attachment 272032 [details]
Archive of layout-test-results from ews106 for mac-yosemite-wk2

The attached test failures were seen while running run-webkit-tests on the mac-wk2-ews.
Bot: ews106  Port: mac-yosemite-wk2  Platform: Mac OS X 10.10.5
Comment 17 Build Bot 2016-02-23 11:02:02 PST
Comment on attachment 272028 [details]
proposed patch 3: resolved test failures.

Attachment 272028 [details] did not pass mac-ews (mac):
Output: http://webkit-queues.webkit.org/results/872899

New failing tests:
js/dom/basic-weakset.html
js/dom/basic-weakmap.html
Comment 18 Build Bot 2016-02-23 11:02:07 PST
Created attachment 272035 [details]
Archive of layout-test-results from ews101 for mac-yosemite

The attached test failures were seen while running run-webkit-tests on the mac-ews.
Bot: ews101  Port: mac-yosemite  Platform: Mac OS X 10.10.5
Comment 19 Mark Lam 2016-02-23 11:03:13 PST
Comment on attachment 272028 [details]
proposed patch 3: resolved test failures.

2 more tests to rebase.
Comment 20 Mark Lam 2016-02-23 11:11:50 PST
Created attachment 272037 [details]
proposed patch 4: rebased remaining tests
Comment 21 Mark Lam 2016-02-23 11:42:59 PST
Thanks for the review.  Landed in r196986: <http://trac.webkit.org/r196986>.