RESOLVED FIXED Bug 178390
Support recursive tail call optimization for polymorphic calls
https://bugs.webkit.org/show_bug.cgi?id=178390
Summary Support recursive tail call optimization for polymorphic calls
Robin Morisset
Reported 2017-10-17 09:01:59 PDT
There is currently code in DFGByteCodeParser.cpp::handleInlining(...) that turns a polymorphic call into a switch on the value of the callee, with fast paths for each frequently called callee. This enables the calls to be inlined, but currently if one is a recursive tail call it cannot be optimized as in https://bugs.webkit.org/show_bug.cgi?id=176601. This is an unnecessary restriction.
Attachments
WIP, preliminary refactoring (28.33 KB, patch)
2017-10-19 10:48 PDT, Robin Morisset
no flags
WIP (36.98 KB, patch)
2017-10-19 12:15 PDT, Robin Morisset
no flags
Patch (39.19 KB, patch)
2017-10-20 08:09 PDT, Robin Morisset
no flags
Patch (39.17 KB, patch)
2017-10-20 10:20 PDT, Robin Morisset
no flags
Patch for landing (39.03 KB, patch)
2017-11-28 02:38 PST, Robin Morisset
no flags
Robin Morisset
Comment 1 2017-10-19 10:48:33 PDT
Created attachment 324250 [details] WIP, preliminary refactoring
Robin Morisset
Comment 2 2017-10-19 12:15:59 PDT
Build Bot
Comment 3 2017-10-19 12:19:17 PDT
Attachment 324262 [details] did not pass style-queue: ERROR: Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:1346: Multi line control clauses should use braces. [whitespace/braces] [4] Total errors found: 1 in 2 files If any of these errors are false positives, please file a bug against check-webkit-style.
Robin Morisset
Comment 4 2017-10-20 08:09:58 PDT
Build Bot
Comment 5 2017-10-20 08:11:27 PDT
Attachment 324401 [details] did not pass style-queue: ERROR: Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:1346: Multi line control clauses should use braces. [whitespace/braces] [4] Total errors found: 1 in 2 files If any of these errors are false positives, please file a bug against check-webkit-style.
Robin Morisset
Comment 6 2017-10-20 08:51:17 PDT
SunSpider: 3d-cube 4.7406+-0.1604 4.4135+-0.3265 might be 1.0741x faster 3d-morph 5.0439+-0.3045 4.9617+-0.1804 might be 1.0166x faster 3d-raytrace 4.6364+-0.4214 ? 4.8838+-0.4810 ? might be 1.0534x slower access-binary-trees 2.0920+-0.1220 2.0292+-0.1858 might be 1.0309x faster access-fannkuch 5.4307+-0.3572 ? 5.8002+-0.9780 ? might be 1.0680x slower access-nbody 2.7929+-0.4545 2.6152+-0.1226 might be 1.0680x faster access-nsieve 2.3547+-0.2029 ? 2.4300+-0.0707 ? might be 1.0320x slower bitops-3bit-bits-in-byte 1.3878+-0.2629 1.3156+-0.1408 might be 1.0548x faster bitops-bits-in-byte 2.7015+-0.3859 2.4362+-0.0911 might be 1.1089x faster bitops-bitwise-and 2.3112+-0.3250 ? 2.4361+-0.1834 ? might be 1.0541x slower bitops-nsieve-bits 3.6935+-0.1521 ? 3.7345+-0.4356 ? might be 1.0111x slower controlflow-recursive 2.2219+-0.2514 2.1355+-0.0903 might be 1.0405x faster crypto-aes 4.4188+-0.3999 4.2502+-0.1615 might be 1.0396x faster crypto-md5 2.4542+-0.1932 ? 2.5405+-0.2197 ? might be 1.0352x slower crypto-sha1 2.6261+-0.2223 2.6048+-0.1838 date-format-tofte 7.7025+-1.5669 7.2689+-0.4865 might be 1.0596x faster date-format-xparb 4.9261+-0.2274 4.8682+-0.3388 might be 1.0119x faster math-cordic 3.0046+-0.1125 ? 3.1100+-0.1763 ? might be 1.0351x slower math-partial-sums 4.2559+-1.4706 4.1099+-0.2877 might be 1.0355x faster math-spectral-norm 2.0585+-0.1687 1.8915+-0.1553 might be 1.0883x faster regexp-dna 7.1373+-0.1023 ? 7.2188+-0.3546 ? might be 1.0114x slower string-base64 4.6766+-0.2453 ? 4.9480+-0.3373 ? might be 1.0580x slower string-fasta 5.8613+-0.3304 ? 6.2903+-0.2644 ? might be 1.0732x slower string-tagcloud 8.3543+-0.2227 8.2750+-0.7080 string-unpack-code 19.1577+-0.5076 18.7568+-0.4761 might be 1.0214x faster string-validate-input 5.1353+-0.2066 ? 5.2360+-0.3733 ? might be 1.0196x slower <arithmetic> 4.6606+-0.1086 4.6369+-0.0824 might be 1.0051x faster Conf#1 Conf#2 LongSpider: 3d-cube 743.3364+-16.9881 ? 747.2447+-9.8873 ? 3d-morph 498.9675+-3.8510 497.3754+-15.8592 3d-raytrace 423.5014+-9.3655 ? 424.0785+-12.1830 ? access-binary-trees 920.3850+-13.2572 ? 921.9882+-20.2226 ? access-fannkuch 260.3717+-14.9256 233.9330+-19.1393 might be 1.1130x faster access-nbody 426.2677+-5.8794 424.7436+-4.6168 access-nsieve 352.6670+-8.5627 348.6665+-12.1425 might be 1.0115x faster bitops-3bit-bits-in-byte 30.4611+-1.0262 ? 31.1438+-3.1502 ? might be 1.0224x slower bitops-bits-in-byte 90.2295+-7.8619 ? 128.0945+-38.3815 ? might be 1.4197x slower bitops-nsieve-bits 342.3952+-15.5238 338.1292+-4.3887 might be 1.0126x faster controlflow-recursive 386.2708+-10.7607 383.4576+-5.0927 crypto-aes 499.9988+-11.4259 499.0734+-8.7046 crypto-md5 449.5331+-2.9971 447.3342+-14.8998 crypto-sha1 550.8433+-8.4904 ? 553.6381+-7.5920 ? date-format-tofte 290.1520+-4.7459 ? 290.8591+-3.5872 ? date-format-xparb 560.8743+-27.6412 ? 561.1144+-36.1531 ? hash-map 133.8291+-7.9164 133.4437+-5.0202 math-cordic 429.9993+-4.1395 ? 431.6057+-3.6335 ? math-partial-sums 228.7563+-0.4379 ? 231.6970+-6.4385 ? might be 1.0129x slower math-spectral-norm 352.9766+-13.2632 352.9424+-10.3477 string-base64 415.9871+-7.7441 ? 419.5347+-10.5945 ? string-fasta 306.8175+-12.3722 ? 312.1820+-12.4545 ? might be 1.0175x slower string-tagcloud 140.2115+-7.0250 ? 142.0247+-4.2935 ? might be 1.0129x slower <geometric> 317.3551+-2.6633 ? 321.1596+-5.4219 ? might be 1.0120x slower Conf#1 Conf#2 V8Spider: crypto 35.8758+-12.8537 31.7330+-0.2946 might be 1.1306x faster deltablue 47.1593+-4.3159 ? 49.9207+-1.8247 ? might be 1.0586x slower earley-boyer 29.5943+-0.5200 ? 32.2305+-7.7521 ? might be 1.0891x slower raytrace 22.2935+-8.1827 20.8257+-4.6855 might be 1.0705x faster regexp 51.1688+-0.7887 50.8893+-1.0603 richards 38.1844+-1.2516 ? 39.6586+-1.8072 ? might be 1.0386x slower splay 27.4482+-0.5682 ? 27.7344+-1.4826 ? might be 1.0104x slower <geometric> 34.4776+-1.9037 ? 34.5392+-1.0912 ? might be 1.0018x slower Conf#1 Conf#2 Octane: encrypt 0.12581+-0.00117 ? 0.12736+-0.00764 ? might be 1.0123x slower decrypt 2.21757+-0.05768 2.20827+-0.05826 deltablue x2 0.12267+-0.00554 0.11535+-0.00982 might be 1.0634x faster earley 0.24258+-0.01153 0.23582+-0.00294 might be 1.0287x faster boyer 4.13986+-0.08825 4.10189+-0.04924 navier-stokes x2 4.58489+-0.05029 ? 4.59649+-0.08957 ? raytrace x2 0.64152+-0.00559 0.63789+-0.00357 richards x2 0.07414+-0.00034 ? 0.07489+-0.00158 ? might be 1.0101x slower splay x2 0.29472+-0.00558 ? 0.29841+-0.00253 ? might be 1.0125x slower regexp x2 14.53782+-0.10715 ? 14.91860+-0.74437 ? might be 1.0262x slower pdfjs x2 37.37914+-0.87305 37.04115+-0.45810 mandreel x2 36.02615+-0.65060 ? 36.26710+-0.99095 ? gbemu x2 27.56974+-0.78518 27.36446+-0.15044 closure 0.42942+-0.00699 0.42707+-0.00263 jquery 5.75672+-0.44038 5.71423+-0.24476 box2d x2 7.09826+-0.09215 7.06418+-0.04907 zlib x2 286.85677+-12.49188 285.61918+-3.65758 typescript x2 591.74445+-18.29531 582.29529+-8.25199 might be 1.0162x faster <geometric> 4.38487+-0.01278 4.36354+-0.01492 might be 1.0049x faster Conf#1 Conf#2 Kraken: ai-astar 75.915+-17.011 75.856+-6.498 audio-beat-detection 32.694+-0.277 ? 33.059+-2.005 ? might be 1.0111x slower audio-dft 79.203+-4.342 ? 87.989+-12.475 ? might be 1.1109x slower audio-fft 23.271+-0.570 ? 23.696+-0.593 ? might be 1.0183x slower audio-oscillator 49.369+-11.196 47.109+-4.762 might be 1.0480x faster imaging-darkroom 50.765+-2.444 ? 51.694+-3.910 ? might be 1.0183x slower imaging-desaturate 41.760+-0.562 ? 41.845+-0.242 ? imaging-gaussian-blur 58.071+-2.915 ? 60.742+-8.093 ? might be 1.0460x slower json-parse-financial 29.507+-1.588 ? 30.736+-1.599 ? might be 1.0416x slower json-stringify-tinderbox 19.445+-2.045 ? 20.548+-3.123 ? might be 1.0567x slower stanford-crypto-aes 32.713+-0.930 ? 33.319+-0.868 ? might be 1.0185x slower stanford-crypto-ccm 30.323+-3.695 29.608+-4.368 might be 1.0242x faster stanford-crypto-pbkdf2 52.881+-2.682 ? 53.582+-4.336 ? might be 1.0133x slower stanford-crypto-sha256-iterative 17.963+-0.484 ? 18.101+-0.305 ? <arithmetic> 42.420+-0.824 ? 43.420+-1.711 ? might be 1.0236x slower So there does not appear to be any significant regression or progression. I still have to check TailBench, and maybe re-run some of these with higher number of runs.
Robin Morisset
Comment 7 2017-10-20 08:55:13 PDT
Some more (skipping the microbenchmarks, none of which show any progression or regression either): Conf#1 Conf#2 AsmBench: bigfib.cpp 412.6786+-7.5506 ? 421.4230+-12.0319 ? might be 1.0212x slower cray.c 294.3629+-5.4464 293.3703+-3.4236 dry.c 361.2978+-4.7491 358.9027+-0.6614 FloatMM.c 529.3777+-4.2541 ? 535.6852+-13.1560 ? might be 1.0119x slower gcc-loops.cpp 3547.4122+-216.3958 3497.5497+-91.0798 might be 1.0143x faster n-body.c 611.6992+-23.4641 606.6401+-9.4231 Quicksort.c 367.9689+-5.2186 ? 370.1124+-21.5112 ? stepanov_container.cpp 2860.0131+-308.2569 2795.7637+-84.5963 might be 1.0230x faster Towers.c 203.7318+-11.1605 201.1208+-2.4274 might be 1.0130x faster <geometric> 604.4949+-4.3115 602.6509+-3.8450 might be 1.0031x faster Conf#1 Conf#2 CompressionBench: huffman 25.6085+-3.3878 24.6127+-0.1713 might be 1.0405x faster arithmetic-simple 235.5256+-1.7086 234.8749+-1.8039 arithmetic-precise 216.5422+-5.0899 ? 220.9287+-16.2782 ? might be 1.0203x slower arithmetic-complex-precise 221.9506+-14.5923 221.3373+-6.8423 arithmetic-precise-order-0 245.5509+-1.2054 ? 245.7853+-0.8679 ? arithmetic-precise-order-1 268.0273+-3.0704 ? 270.1372+-17.6204 ? arithmetic-precise-order-2 306.6118+-3.5147 ? 314.2617+-23.8548 ? might be 1.0249x slower arithmetic-simple-order-1 276.6948+-4.3248 ? 277.3080+-5.2175 ? arithmetic-simple-order-2 321.3170+-6.3690 ? 333.1250+-25.9720 ? might be 1.0367x slower lz-string 225.4969+-1.8691 ? 237.4882+-16.2229 ? might be 1.0532x slower <geometric> 202.6671+-2.1359 ? 204.6571+-2.0159 ? might be 1.0098x slower Conf#1 Conf#2 SixSpeed: template_string.es5 4883.6143+-54.9447 4856.8132+-37.4012 template_string.es6 4138.3417+-65.1480 ? 4146.9897+-57.8470 ? defaults.es5 322.4486+-3.2821 ? 328.2272+-20.7757 ? might be 1.0179x slower defaults.es6 320.8857+-0.8631 ? 325.4340+-4.3139 ? might be 1.0142x slower map-set-lookup.es5 63.3699+-18.0542 ? 69.1140+-20.9033 ? might be 1.0906x slower map-set-lookup.es6 0.9250+-0.1929 ? 1.4653+-1.8007 ? might be 1.5841x slower spread.es5 12.2799+-0.8453 ? 12.3222+-0.1461 ? spread.es6 38.2454+-4.8489 37.7236+-2.1692 might be 1.0138x faster object-assign.es5 203.3602+-3.6944 203.1307+-5.5323 object-assign.es6 205.2889+-7.2714 203.4252+-4.6228 spread-literal.es5 15.4348+-0.4644 15.0320+-0.3064 might be 1.0268x faster spread-literal.es6 22.3255+-0.2088 22.1947+-0.5524 map-set.es5 21.0168+-3.8319 ? 21.4493+-2.1669 ? might be 1.0206x slower map-set.es6 153.0753+-19.3095 149.4788+-6.4879 might be 1.0241x faster destructuring-simple.es5 64.5383+-0.5496 ? 64.9165+-0.8554 ? destructuring-simple.es6 64.5018+-0.4070 ? 64.6168+-0.3211 ? super.es5 10.7960+-1.6672 ? 12.2737+-1.5451 ? might be 1.1369x slower super.es6 21.0604+-0.6828 ? 21.7510+-2.6521 ? might be 1.0328x slower for-of-object.es5 44.8350+-2.4941 43.3120+-4.6808 might be 1.0352x faster for-of-object.es6 141.0807+-2.2138 140.5900+-5.1682 rest.es5 30.1490+-0.9708 30.1376+-0.4853 rest.es6 2.0336+-0.0679 1.9902+-0.0933 might be 1.0218x faster regex-u.es5 33.9125+-0.4769 ? 34.2583+-0.6404 ? might be 1.0102x slower regex-u.es6 65.9092+-8.5911 63.2293+-0.6174 might be 1.0424x faster arrow.es5 64.8582+-0.5937 ? 65.3704+-2.6912 ? arrow.es6 67.2280+-4.6573 64.2952+-0.3072 might be 1.0456x faster bindings-compound.es5 64.7179+-0.3352 54.0939+-11.8612 might be 1.1964x faster bindings-compound.es6 64.4318+-0.2751 ? 68.9605+-13.9606 ? might be 1.0703x slower classes.es5 56.5108+-1.2590 ? 57.2444+-1.8317 ? might be 1.0130x slower classes.es6 56.7508+-1.3581 56.1429+-1.2649 might be 1.0108x faster template_string_tag.es5 60.2440+-0.8336 58.5812+-4.3304 might be 1.0284x faster template_string_tag.es6 171.7587+-5.6791 ? 174.6210+-9.3965 ? might be 1.0167x slower map-string.es5 83.5129+-5.6925 83.1068+-3.7639 map-string.es6 351.3727+-2.2468 ? 352.2203+-4.1178 ? arrow-declare.es5 101.5883+-13.0381 96.7725+-0.6436 might be 1.0498x faster arrow-declare.es6 99.1322+-5.7563 96.7269+-1.3041 might be 1.0249x faster spread-generator.es5 77.7860+-23.2422 70.5928+-1.3365 might be 1.1019x faster spread-generator.es6 174.2321+-10.9408 169.6866+-3.7196 might be 1.0268x faster object-literal-ext.es5 16.6722+-0.5216 16.3120+-0.2331 might be 1.0221x faster object-literal-ext.es6 19.4162+-1.4462 ? 19.9951+-2.3405 ? might be 1.0298x slower generator.es5 98.9652+-0.7480 ? 102.9295+-10.7550 ? might be 1.0401x slower generator.es6 152.0974+-1.7712 ? 154.8335+-9.9898 ? might be 1.0180x slower arrow-args.es5 65.8676+-3.5179 ? 65.9514+-5.2790 ? arrow-args.es6 65.7977+-2.0867 ? 68.2464+-5.2469 ? might be 1.0372x slower for-of-array.es5 172.9953+-14.9916 170.7838+-14.0335 might be 1.0129x faster for-of-array.es6 190.1968+-19.8151 ? 202.8972+-33.4669 ? might be 1.0668x slower bindings.es5 61.2527+-11.9562 ? 64.6559+-0.3929 ? might be 1.0556x slower bindings.es6 64.6057+-0.3761 ? 64.8993+-0.2570 ? destructuring.es5 58.4807+-7.1957 56.6716+-5.8298 might be 1.0319x faster destructuring.es6 60.9296+-3.7189 ? 63.3567+-3.8806 ? might be 1.0398x slower map-set-object.es5 29.8170+-0.1195 29.8151+-0.6593 map-set-object.es6 150.7845+-2.6843 ? 152.5730+-4.1060 ? might be 1.0119x slower <geometric> 68.1462+-0.7738 ? 68.5582+-1.4546 ? might be 1.0060x slower Conf#1 Conf#2 Geomean of preferred means: <scaled-result> 44.1172+-0.2000 ? 44.3246+-0.2259 ? might be 1.0047x slower Conf#1 is ToT, Conf#2 is ToT with this patch.
Saam Barati
Comment 8 2017-10-20 09:49:50 PDT
What about tail bench?
Saam Barati
Comment 9 2017-10-20 10:05:48 PDT
Comment on attachment 324401 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=324401&action=review r=me > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:1739 > + if (InlineCallFrame::isTail(kind) && ByteCodeParser::handleRecursiveTailCall(callee, registerOffset, argumentCountIncludingThis, insertChecksWithAccounting)) { I think you should check the kind == InlineCallFrame::TailCall here and not InlineCallFrame::isTail since that returns true for varargs. Even if this is never called with varargs, I think being explicit is more intuitive. > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:1797 > + (void) c; Why name this parameter if it's unused?
Robin Morisset
Comment 10 2017-10-20 10:20:47 PDT
Build Bot
Comment 11 2017-10-20 10:21:40 PDT
Attachment 324413 [details] did not pass style-queue: ERROR: Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:1346: Multi line control clauses should use braces. [whitespace/braces] [4] Total errors found: 1 in 2 files If any of these errors are false positives, please file a bug against check-webkit-style.
Robin Morisset
Comment 12 2017-10-20 10:22:21 PDT
(In reply to Saam Barati from comment #9) > Comment on attachment 324401 [details] > Patch > > View in context: > https://bugs.webkit.org/attachment.cgi?id=324401&action=review > > r=me > > > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:1739 > > + if (InlineCallFrame::isTail(kind) && ByteCodeParser::handleRecursiveTailCall(callee, registerOffset, argumentCountIncludingThis, insertChecksWithAccounting)) { > > I think you should check the kind == InlineCallFrame::TailCall here and not > InlineCallFrame::isTail since that returns true for varargs. Even if this is > never called with varargs, I think being explicit is more intuitive. Done > > Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:1797 > > + (void) c; > > Why name this parameter if it's unused? I didn't know that parameter names are optional for C++ lambdas. Fixed.
Ryosuke Niwa
Comment 13 2017-10-25 15:16:10 PDT
Comment on attachment 324413 [details] Patch You mean r?
Robin Morisset
Comment 14 2017-11-10 07:23:19 PST
I benchmarked this change on TailBench, and it does not seem to have any significant performance change, probably because all calls are monomorphic. I will try to test it on ARES/Speedometer to see if there is anything that benefits from it, but I am not very optimistic. sbarati: do you think it is worth landing nonetheless for the refactoring (making it a lot clearer which code is used for varargs and for non-varargs calls)?
Saam Barati
Comment 15 2017-11-10 08:40:02 PST
Comment on attachment 324413 [details] Patch r=me It’d be nice to both add this with tests and micro benchmarks. An interesting test would be having all of the polymorphic calllees on the in-line stack, so you jump to different places depending on callee. It’d also be interesting to have tests where one of the polymorphic callees is on the stack, and we go down normal in lining for the others.
Saam Barati
Comment 16 2017-11-10 08:41:40 PST
(In reply to Robin Morisset from comment #14) > I benchmarked this change on TailBench, and it does not seem to have any > significant performance change, probably because all calls are monomorphic. > I will try to test it on ARES/Speedometer to see if there is anything that > benefits from it, but I am not very optimistic. > > sbarati: do you think it is worth landing nonetheless for the refactoring > (making it a lot clearer which code is used for varargs and for non-varargs > calls)? I think it’s worth landing just for quality of tail call loop optimization implementation. Just because it’s not used by TailBench doesn’t mean it won’t be used by programs that use tail calls heavily.
Robin Morisset
Comment 17 2017-11-10 09:56:43 PST
You were right to insist on specific tests and benchmarks, the first benchmark I tested that should trigger this optimisation (a variant of merge-sort.js in CPS) hangs in one in 5 runs approximately (and sadly works fine with useConcurrentJIT=false, and works fine in debug mode, and works fine when restricting the functions being dfg compiled). I am investigating, will keep you informed. (In reply to Saam Barati from comment #15) > Comment on attachment 324413 [details] > Patch > > r=me > It’d be nice to both add this with tests and micro benchmarks. An > interesting test would be having all of the polymorphic calllees on the > in-line stack, so you jump to different places depending on callee. It’d > also be interesting to have tests where one of the polymorphic callees is on > the stack, and we go down normal in lining for the others.
Robin Morisset
Comment 18 2017-11-27 02:59:33 PST
The bug was unrelated to this patch. I made a separate bug for it: https://bugs.webkit.org/show_bug.cgi?id=179835
WebKit Commit Bot
Comment 19 2017-11-27 10:42:26 PST
Comment on attachment 324413 [details] Patch Rejecting attachment 324413 [details] from commit-queue. Failed to run "['/Volumes/Data/EWS/WebKit/Tools/Scripts/webkit-patch', '--status-host=webkit-queues.webkit.org', '--bot-id=webkit-cq-03', 'apply-attachment', '--no-update', '--non-interactive', 324413, '--port=mac']" exit_code: 2 cwd: /Volumes/Data/EWS/WebKit Last 500 characters of output: (offset 6 lines). Hunk #9 succeeded at 1973 (offset 6 lines). Hunk #10 succeeded at 1996 (offset 6 lines). Hunk #11 succeeded at 2038 (offset 6 lines). Hunk #12 succeeded at 2064 (offset 6 lines). Hunk #13 succeeded at 2105 (offset 6 lines). 2 out of 13 hunks FAILED -- saving rejects to file Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp.rej Failed to run "[u'/Volumes/Data/EWS/WebKit/Tools/Scripts/svn-apply', '--force', '--reviewer', u'Saam Barati']" exit_code: 1 cwd: /Volumes/Data/EWS/WebKit Full output: http://webkit-queues.webkit.org/results/5376411
Robin Morisset
Comment 20 2017-11-28 02:38:16 PST
Created attachment 327738 [details] Patch for landing
WebKit Commit Bot
Comment 21 2017-11-28 05:11:36 PST
Comment on attachment 327738 [details] Patch for landing Clearing flags on attachment: 327738 Committed r225212: <https://trac.webkit.org/changeset/225212>
WebKit Commit Bot
Comment 22 2017-11-28 05:11:38 PST
All reviewed patches have been landed. Closing bug.
Radar WebKit Bug Importer
Comment 23 2017-11-28 05:12:34 PST
Note You need to log in before you can comment on or make changes to this bug.