Bug 19217 - REGRESSION: Assertion failure in JSImmediate::toString when loading GMail
Summary: REGRESSION: Assertion failure in JSImmediate::toString when loading GMail
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: All All
: P2 Normal
Assignee: Nobody
URL:
Keywords: HasReduction, InRadar
Depends on:
Blocks:
 
Reported: 2008-05-23 10:56 PDT by Adam Roben (:aroben)
Modified: 2008-05-23 16:45 PDT (History)
1 user (show)

See Also:


Attachments
reduction (124 bytes, text/html)
2008-05-23 13:40 PDT, Adam Roben (:aroben)
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Adam Roben (:aroben) 2008-05-23 10:56:05 PDT
I'm seeing an assertion failure in JSImmediate::toString when loading GMail

To repro:
1. Log in to GMail

>	WebKit_debug.dll!KJS::JSImmediate::toString(const KJS::JSValue * v=0xdddddddd)  Line 62 + 0x2c bytes	C++
 	WebKit_debug.dll!KJS::JSValue::toString(KJS::ExecState * exec=0x0012eeec)  Line 518 + 0x20 bytes	C++
 	WebKit_debug.dll!WebCore::JSXMLHttpRequest::open(KJS::ExecState * exec=0x0012eeec, const KJS::List & args={...})  Line 134 + 0x1c bytes	C++
 	WebKit_debug.dll!WebCore::jsXMLHttpRequestPrototypeFunctionOpen(KJS::ExecState * exec=0x0012eeec, KJS::JSObject * thisObj=0x09038c80, const KJS::List & args={...})  Line 186	C++
 	WebKit_debug.dll!KJS::PrototypeFunction::callAsFunction(KJS::ExecState * exec=0x0012eeec, KJS::JSObject * thisObj=0x09038c80, const KJS::List & args={...})  Line 733 + 0x16 bytes	C++
 	WebKit_debug.dll!KJS::Machine::privateExecute(KJS::Machine::ExecutionFlag flag=Normal, KJS::ExecState * exec=0x0012eeec, KJS::RegisterFile * registerFile=0x08c2d720, KJS::Register * r=0x0a6f2cbc, KJS::ScopeChainNode * scopeChain=0x0a25b548, KJS::CodeBlock * codeBlock=0x06b1ba30, KJS::JSValue * * exception=0x0012ef88)  Line 1945 + 0x27 bytes	C++
 	WebKit_debug.dll!KJS::Machine::execute(KJS::FunctionBodyNode * functionBodyNode=0x0a243aa8, KJS::ExecState * exec=0x0012f68c, KJS::FunctionImp * function=0x09033440, KJS::JSObject * thisObj=0x09080600, const KJS::List & args={...}, KJS::RegisterFileStack * registerFileStack=0x06acfef8, KJS::ScopeChainNode * scopeChain=0x09fa7120, KJS::JSValue * * exception=0x0012ef88)  Line 739 + 0x22 bytes	C++
 	WebKit_debug.dll!KJS::FunctionImp::callAsFunction(KJS::ExecState * exec=0x0012f68c, KJS::JSObject * thisObj=0x09080600, const KJS::List & args={...})  Line 95 + 0x3c bytes	C++
 	WebKit_debug.dll!KJS::JSObject::call(KJS::ExecState * exec=0x0012f68c, KJS::JSObject * thisObj=0x09080600, const KJS::List & args={...})  Line 99 + 0x1b bytes	C++
 	WebKit_debug.dll!KJS::functionProtoFuncApply(KJS::ExecState * exec=0x0012f68c, KJS::JSObject * thisObj=0x09033440, const KJS::List & args={...})  Line 107 + 0x14 bytes	C++
 	WebKit_debug.dll!KJS::PrototypeFunction::callAsFunction(KJS::ExecState * exec=0x0012f68c, KJS::JSObject * thisObj=0x09033440, const KJS::List & args={...})  Line 733 + 0x16 bytes	C++
 	WebKit_debug.dll!KJS::Machine::privateExecute(KJS::Machine::ExecutionFlag flag=Normal, KJS::ExecState * exec=0x0012f68c, KJS::RegisterFile * registerFile=0x08c2d720, KJS::Register * r=0x0a741e14, KJS::ScopeChainNode * scopeChain=0x06376230, KJS::CodeBlock * codeBlock=0x06d12248, KJS::JSValue * * exception=0x0012f728)  Line 1945 + 0x27 bytes	C++
 	WebKit_debug.dll!KJS::Machine::execute(KJS::FunctionBodyNode * functionBodyNode=0x0a205aa8, KJS::ExecState * exec=0x06ad0108, KJS::FunctionImp * function=0x091377e0, KJS::JSObject * thisObj=0x091377c0, const KJS::List & args={...}, KJS::RegisterFileStack * registerFileStack=0x06acfef8, KJS::ScopeChainNode * scopeChain=0x0a40f0e0, KJS::JSValue * * exception=0x0012f728)  Line 739 + 0x22 bytes	C++
 	WebKit_debug.dll!KJS::FunctionImp::callAsFunction(KJS::ExecState * exec=0x06ad0108, KJS::JSObject * thisObj=0x091377c0, const KJS::List & args={...})  Line 90 + 0x3c bytes	C++
 	WebKit_debug.dll!KJS::JSObject::call(KJS::ExecState * exec=0x06ad0108, KJS::JSObject * thisObj=0x091377c0, const KJS::List & args={...})  Line 99 + 0x1b bytes	C++
 	WebKit_debug.dll!WebCore::JSAbstractEventListener::handleEvent(WebCore::Event * ele=0x0a76fa70, bool isWindowEvent=false)  Line 100 + 0x14 bytes	C++
 	WebKit_debug.dll!WebCore::EventTarget::handleLocalEvents(WebCore::EventTargetNode * referenceNode=0x0a0ad808, WebCore::Event * evt=0x0a76fa70, bool useCapture=false)  Line 314 + 0x2e bytes	C++
 	WebKit_debug.dll!WebCore::EventTargetNode::handleLocalEvents(WebCore::Event * evt=0x0a76fa70, bool useCapture=false)  Line 106	C++
 	WebKit_debug.dll!WebCore::EventTarget::dispatchGenericEvent(WebCore::EventTargetNode * referenceNode=0x0a0ad808, WTF::PassRefPtr<WebCore::Event> e={...}, int & __formal=0, bool tempEvent=true)  Line 212 + 0x1d bytes	C++
 	WebKit_debug.dll!WebCore::EventTargetNode::dispatchEvent(WTF::PassRefPtr<WebCore::Event> e={...}, int & ec=0, bool tempEvent=true)  Line 121 + 0x1e bytes	C++
 	WebKit_debug.dll!WebCore::EventTargetNode::dispatchHTMLEvent(const WebCore::AtomicString & eventType={...}, bool canBubbleArg=false, bool cancelableArg=false)  Line 358	C++
 	WebKit_debug.dll!WebCore::HTMLImageLoader::dispatchLoadEvent()  Line 131	C++
 	WebKit_debug.dll!WebCore::Document::dispatchImageLoadEventsNow()  Line 2769 + 0xf bytes	C++
 	WebKit_debug.dll!WebCore::Document::imageLoadEventTimerFired(WebCore::Timer<WebCore::Document> * __formal=0x069e7fb8)  Line 2777	C++
Comment 1 Adam Roben (:aroben) 2008-05-23 10:58:49 PDT
Calling dumpCallFrame(codeBlock, scopeChain, registerFile, r) in the top Machine::privateExecute frame gives this:

21 instructions; 92 bytes at 06D12248; 1 locals (1 parameters); 15 temporaries

[   0] get_scoped_var            tr0, -6, 0
[   4] get_by_id         tr1, tr0, apply(@id0)
[   8] get_scoped_var            tr13, -4, 0
[  12] resolve           tr14, arguments(@id1)
[  15] call              tr0, tr1, tr0, 12, 3
[  21] ret               tr0

Identifiers:
  id0 = apply
  id1 = arguments

Register frame:

----------------------------------------
     use      |   address  |    value
----------------------------------------
[call frame]  |   0A741DE8 |   DDDDDDDD
[call frame]  |   0A741DEC |   DDDDDDDD
[call frame]  |   0A741DF0 |   DDDDDDDD
[call frame]  |   0A741DF4 |   DDDDDDDD
[call frame]  |   0A741DF8 |   DDDDDDDD
[call frame]  |   0A741DFC |   DDDDDDDD
[call frame]  |   0A741E00 |   DDDDDDDD
[call frame]  |   0A741E04 |   DDDDDDDD
[call frame]  |   0A741E08 |   DDDDDDDD
[call frame]  |   0A741E0C |   DDDDDDDD
----------------------------------------
[param]       |   0A741E10 |   DDDDDDDD
----------------------------------------
[temp]        |   0A741E14 |   DDDDDDDD
[temp]        |   0A741E18 |   DDDDDDDD
[temp]        |   0A741E1C |   DDDDDDDD
[temp]        |   0A741E20 |   DDDDDDDD
[temp]        |   0A741E24 |   DDDDDDDD
[temp]        |   0A741E28 |   DDDDDDDD
[temp]        |   0A741E2C |   DDDDDDDD
[temp]        |   0A741E30 |   DDDDDDDD
[temp]        |   0A741E34 |   DDDDDDDD
[temp]        |   0A741E38 |   DDDDDDDD
[temp]        |   0A741E3C |   DDDDDDDD
[temp]        |   0A741E40 |   DDDDDDDD
[temp]        |   0A741E44 |   DDDDDDDD
[temp]        |   0A741E48 |   DDDDDDDD
[temp]        |   0A741E4C |   DDDDDDDD
Comment 2 Adam Roben (:aroben) 2008-05-23 11:00:04 PDT
(In reply to comment #1)
> Calling dumpCallFrame(codeBlock, scopeChain, registerFile, r) in the top
> Machine::privateExecute frame gives this:

Where by "the top Machine::privateExecute frame" I meant "the Machine::privateExecute frame that is closest to the WebCore::JSAbstractEventListener::handleEvent frame"
Comment 3 Adam Roben (:aroben) 2008-05-23 11:02:24 PDT
dumpCallFrame in the Machine::privateExecute frame that is closest to JSImmediate::toString gives:

450 instructions; 2128 bytes at 06C38900; 8 locals (5 parameters); 30 temporaries

[   0] load              lr1, undefined(@k0)
[   3] load              lr2, undefined(@k0)
[   6] load              lr3, undefined(@k0)
[   9] get_by_id         tr0, lr8, vd(@id0)
[  13] jfalse            tr0, 17(->32)
[  16] get_scoped_var            tr0, -83, 0
[  20] get_scoped_var            tr12, -914, 0
[  24] call              tr0, tr0, tr2147483647, 11, 2
[  30] throw             tr0
[  32] mov               tr0, lr6
[  35] jtrue             tr0, 5(->42)
[  38] get_scoped_var            tr0, -915, 0
[  42] mov               lr1, tr0
[  45] mov               tr0, lr8
[  48] put_by_id         tr0, jS(@id1), lr7
[  52] mov               tr0, lr8
[  55] get_scoped_var            tr1, -298, 0
[  59] put_by_id         tr0, oh(@id2), tr1
[  63] mov               tr2, lr8
[  66] load              tr3, 0(@k1)
[  69] put_by_id         tr2, Dg(@id3), tr3
[  73] mov               tr4, lr8
[  76] put_by_id         tr4, eBb(@id4), lr1
[  80] mov               tr0, lr8
[  83] load              tr1, true(@k2)
[  86] put_by_id         tr0, vd(@id0), tr1
[  90] mov               tr2, lr8
[  93] get_scoped_var            tr3, -893, 0
[  97] construct         tr4, tr3, 14, 1
[ 102] put_by_id         tr2, va(@id5), tr4
[ 106] mov               tr5, lr8
[ 109] get_scoped_var            tr6, -896, 0
[ 113] jtrue             tr6, 15(->130)
[ 116] get_scoped_var            tr7, -895, 0
[ 120] call              tr6, tr7, tr2147483647, 18, 1
[ 126] put_scoped_var            -896, 0, tr6
[ 130] put_by_id         tr5, O9(@id6), tr6
[ 134] get_scoped_var            tr7, -892, 0
[ 138] get_by_id         tr8, tr7, vCb(@id7)
[ 142] get_by_id         tr20, lr8, va(@id5)
[ 146] call              tr7, tr8, tr7, 19, 2
[ 152] get_by_id         tr8, lr8, va(@id5)
[ 156] get_scoped_var            tr9, -274, 0
[ 160] get_by_id         tr21, lr8, gTa(@id8)
[ 164] mov               tr22, lr8
[ 167] call              tr9, tr9, tr2147483647, 20, 3
[ 173] put_by_id         tr8, onreadystatechange(@id9), tr9
[ 177] get_by_id         tr10, lr8, va(@id5)
[ 181] get_by_id         tr11, tr10, open(@id10)
[ 185] mov               tr23, lr1
[ 188] mov               tr24, lr7
[ 191] load              tr25, true(@k2)
[ 194] call              tr10, tr11, tr10, 22, 4
[ 200] jmp               36(->237)
[ 202] catch             tr10
[ 204] new_object        tr11
[ 206] put_by_id         tr11, f(@id11), tr10
[ 210] push_scope        tr11
[ 212] get_by_id         tr12, lr8, Xt(@id12)
[ 216] load              tr24, 5(@k3)
[ 219] resolve           tr25, f(@id11)
[ 222] call              tr12, tr12, lr8, 23, 3
[ 228] load              tr13, undefined(@k0)
[ 231] jmp_scopes       ^1, 1(->234)
[ 234] ret               tr13
[ 236] pop_scope
[ 237] jfalse            lr5, 16(->255)
[ 240] get_scoped_var            tr10, -90, 0
[ 244] mov               tr22, lr5
[ 247] call              lr2, tr10, tr2147483647, 21, 2
[ 253] jmp               5(->259)
[ 255] get_scoped_var            lr2, -298, 0
[ 259] get_by_id         tr10, lr8, headers(@id13)
[ 263] get_by_id         tr11, tr10, Mb(@id14)
[ 267] call              lr3, tr11, tr10, 22, 1
[ 273] jfalse            lr4, 17(->292)
[ 276] get_scoped_var            tr0, -360, 0
[ 280] mov               tr12, lr4
[ 283] new_func_exp      tr13, f0
[ 286] call              tr0, tr0, tr2147483647, 11, 3
[ 292] get_scoped_var            tr1, -916, 0
[ 296] eq                tr0, lr1, tr1
[ 300] jfalse            tr0, 18(->320)
[ 303] get_by_id         tr1, lr3, Nb(@id15)
[ 307] get_scoped_var            tr13, -909, 0
[ 311] call              tr1, tr1, lr3, 12, 2
[ 317] not               tr0, tr1
[ 320] jfalse            tr0, 19(->341)
[ 323] get_by_id         tr0, lr3, R(@id16)
[ 327] get_scoped_var            tr12, -909, 0
[ 331] get_scoped_var            tr13, -917, 0
[ 335] call              tr0, tr0, lr3, 11, 3
[ 341] get_scoped_var            tr0, -360, 0
[ 345] mov               tr12, lr3
[ 348] new_func_exp      tr13, f1
[ 351] mov               tr14, lr8
[ 354] call              tr0, tr0, tr2147483647, 11, 4
[ 360] get_by_id         tr1, lr8, bC(@id17)
[ 364] jfalse            tr1, 29(->395)
[ 367] get_scoped_var            tr1, -796, 0
[ 371] get_by_id         tr2, tr1, clearTimeout(@id18)
[ 375] get_by_id         tr14, lr8, bC(@id17)
[ 379] call              tr1, tr2, tr1, 13, 2
[ 385] mov               tr2, lr8
[ 388] load              tr3, null(@k4)
[ 391] put_by_id         tr2, bC(@id17), tr3
[ 395] load              tr1, 0(@k1)
[ 398] get_by_id         tr2, lr8, xy(@id19)
[ 402] less              tr1, tr1, tr2
[ 406] jfalse            tr1, 43(->451)
[ 409] mov               tr1, lr8
[ 412] get_scoped_var            tr2, -796, 0
[ 416] get_by_id         tr3, tr2, setTimeout(@id20)
[ 420] get_scoped_var            tr16, -274, 0
[ 424] get_by_id         tr28, lr8, wv(@id21)
[ 428] mov               tr29, lr8
[ 431] call              tr15, tr16, tr2147483647, 27, 3
[ 437] get_by_id         tr16, lr8, xy(@id19)
[ 441] call              tr2, tr3, tr2, 14, 3
[ 447] put_by_id         tr1, bC(@id17), tr2
[ 451] mov               tr1, lr8
[ 454] load              tr2, false(@k5)
[ 457] put_by_id         tr1, sea(@id22), tr2
[ 461] mov               tr3, lr8
[ 464] load              tr4, true(@k2)
[ 467] put_by_id         tr3, Aia(@id23), tr4
[ 471] get_by_id         tr5, lr8, va(@id5)
[ 475] get_by_id         tr6, tr5, send(@id24)
[ 479] mov               tr18, lr2
[ 482] call              tr5, tr6, tr5, 17, 2
[ 488] mov               tr6, lr8
[ 491] load              tr7, false(@k5)
[ 494] put_by_id         tr6, Aia(@id23), tr7
[ 498] jmp               28(->527)
[ 500] catch             tr1
[ 502] new_object        tr2
[ 504] put_by_id         tr2, f(@id11), tr1
[ 508] push_scope        tr2
[ 510] get_by_id         tr3, lr8, Xt(@id12)
[ 514] load              tr15, 5(@k3)
[ 517] resolve           tr16, f(@id11)
[ 520] call              tr3, tr3, lr8, 14, 3
[ 526] pop_scope
[ 527] load              tr0, undefined(@k0)
[ 530] ret               tr0

Identifiers:
  id0 = vd
  id1 = jS
  id2 = oh
  id3 = Dg
  id4 = eBb
  id5 = va
  id6 = O9
  id7 = vCb
  id8 = gTa
  id9 = onreadystatechange
  id10 = open
  id11 = f
  id12 = Xt
  id13 = headers
  id14 = Mb
  id15 = Nb
  id16 = R
  id17 = bC
  id18 = clearTimeout
  id19 = xy
  id20 = setTimeout
  id21 = wv
  id22 = sea
  id23 = Aia
  id24 = send

Constants:
  k0 = undefined
  k1 = 0
  k2 = true
  k3 = 5
  k4 = null
  k5 = false

Exception Handlers:
         1: { start: [ 177] end: [ 200] target: [ 202] }
         2: { start: [ 360] end: [ 498] target: [ 500] }

Register frame:

----------------------------------------
     use      |   address  |    value
----------------------------------------
[call frame]  |   0477B10C |   00710070
[call frame]  |   0477B110 |   0030006A
[call frame]  |   0477B114 |   00650061
[call frame]  |   0477B118 |   007A0038
[call frame]  |   0477B11C |   00730033
[call frame]  |   0477B120 |   00350039
[call frame]  |   0477B124 |   00790039
[call frame]  |   0477B128 |   006E0069
[call frame]  |   0477B12C |   00730031
[call frame]  |   0477B130 |   00640078
----------------------------------------
[param]       |   0477B134 |   00340074
[param]       |   0477B138 |   006C0075
[param]       |   0477B13C |   00560026
[param]       |   0477B140 |   00520045
[param]       |   0477B144 |   0036003D
----------------------------------------
[var]         |   0477B148 |   00690026
[var]         |   0477B14C |   003D0074
[var]         |   0477B150 |   00380036
----------------------------------------
[temp]        |   0477B154 |   00380032
[temp]        |   0477B158 |   00540026
[temp]        |   0477B15C |   00500059
[temp]        |   0477B160 |   003D0045
[temp]        |   0477B164 |   006D0078
[temp]        |   0477B168 |   0068006C
[temp]        |   0477B16C |   00740074
[temp]        |   0477B170 |   00260070
[temp]        |   0477B174 |   0078007A
[temp]        |   0477B178 |   0069003D
[temp]        |   0477B17C |   00610070
[temp]        |   0477B180 |   0064007A
[temp]        |   0477B184 |   00650032
[temp]        |   0477B188 |   00610062
[temp]        |   0477B18C |   00660065
[temp]        |   0477B190 |   00260066
[temp]        |   0477B194 |   003D0074
[temp]        |   0477B198 |   FDFD0031
[temp]        |   0477B19C |   DDDDFDFD
[temp]        |   0477B1A0 |   00240027
[temp]        |   0477B1A4 |   020E01EF
[temp]        |   0477B1A8 |   0A38E9D0
[temp]        |   0477B1AC |   086AC8D0
[temp]        |   0477B1B0 |   00000000
[temp]        |   0477B1B4 |   00000000
[temp]        |   0477B1B8 |   00000106
[temp]        |   0477B1BC |   00000001
[temp]        |   0477B1C0 |   001354B0
[temp]        |   0477B1C4 |   FDFDFDFD
[temp]        |   0477B1C8 |   70747468


Comment 4 Anders Carlsson 2008-05-23 11:38:30 PDT
<rdar://problem/5959886>
Comment 5 Adam Roben (:aroben) 2008-05-23 11:41:11 PDT
So far we've only been able to reproduce this on a Windows debug build. MallocScribble with a Mac debug build hasn't yet turned up the crash.
Comment 6 Anders Carlsson 2008-05-23 12:10:29 PDT
I was able to reproduce this on Mac as well with MallocScribble turned on.
Comment 7 Adam Roben (:aroben) 2008-05-23 12:13:10 PDT
It looks like all the register have been deleted (they're showing up as 0xdddddddd on Windows and 0x55555555 on Mac).
Comment 8 Adam Roben (:aroben) 2008-05-23 13:40:29 PDT
Created attachment 21321 [details]
reduction

Reduced testcase
Comment 9 Adam Roben (:aroben) 2008-05-23 14:19:26 PDT
We have a fix ready, but we need to performance test it.
Comment 10 Adam Roben (:aroben) 2008-05-23 14:19:41 PDT
Our initial fix (removing calls to setSafeForReentry around native function and constructor calls) is a 12% regression on SunSpider.

Geoff suspects we may be able to mitigate this by "caching one level of register file".
Comment 11 Anders Carlsson 2008-05-23 16:45:54 PDT
Committed revision 34095.