Log Message
REGRESSION: Sometimes, operations on proven strings ignore changes to the string prototype https://bugs.webkit.org/show_bug.cgi?id=113353 <rdar://problem/13510778>
Source/_javascript_Core: Reviewed by Mark Hahnenberg and Geoffrey Garen. ToString should call speculateStringObject() even if you know that it's a string object, since it calls it to also get the watchpoint. Note that even with this change, if you do Phantom(Check:StringObject:@a), it might get eliminated just because we proved that @a is a string object (thereby eliminating the prototype watchpoint); that's fine since ToString is MustGenerate and never decays to Phantom. * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileToStringOnCell): (JSC::DFG::SpeculativeJIT::speculateStringObject): (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject): * dfg/DFGSpeculativeJIT.h: (SpeculativeJIT): (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure): LayoutTests: Reviewed by Mark Hahnenberg and Geoffrey Garen. * fast/js/jsc-test-list: * fast/js/dfg-phantom-base-expected.txt: Added. * fast/js/dfg-phantom-base.html: Added. * fast/js/dfg-to-string-toString-becomes-bad-with-check-structure-expected.txt: Added. * fast/js/dfg-to-string-toString-becomes-bad-with-check-structure.html: Added.
Modified Paths
- trunk/LayoutTests/ChangeLog
- trunk/LayoutTests/fast/js/jsc-test-list
- trunk/Source/_javascript_Core/ChangeLog
- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp
- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h
Added Paths
- trunk/LayoutTests/fast/js/dfg-phantom-base-expected.txt
- trunk/LayoutTests/fast/js/dfg-phantom-base.html
- trunk/LayoutTests/fast/js/dfg-to-string-toString-becomes-bad-with-check-structure-expected.txt
- trunk/LayoutTests/fast/js/dfg-to-string-toString-becomes-bad-with-check-structure.html
- trunk/LayoutTests/fast/js/script-tests/dfg-phantom-base.js
- trunk/LayoutTests/fast/js/script-tests/dfg-to-string-toString-becomes-bad-with-check-structure.js
Diff
Modified: trunk/LayoutTests/ChangeLog (146946 => 146947)
--- trunk/LayoutTests/ChangeLog 2013-03-26 23:52:31 UTC (rev 146946)
+++ trunk/LayoutTests/ChangeLog 2013-03-27 00:03:41 UTC (rev 146947)
@@ -1,3 +1,17 @@
+2013-03-26 Filip Pizlo <fpi...@apple.com>
+
+ REGRESSION: Sometimes, operations on proven strings ignore changes to the string prototype
+ https://bugs.webkit.org/show_bug.cgi?id=113353
+ <rdar://problem/13510778>
+
+ Reviewed by Mark Hahnenberg and Geoffrey Garen.
+
+ * fast/js/jsc-test-list:
+ * fast/js/dfg-phantom-base-expected.txt: Added.
+ * fast/js/dfg-phantom-base.html: Added.
+ * fast/js/dfg-to-string-toString-becomes-bad-with-check-structure-expected.txt: Added.
+ * fast/js/dfg-to-string-toString-becomes-bad-with-check-structure.html: Added.
+
2013-03-26 Dean Jackson <d...@apple.com>
When a primary plugin is restarted, also start similar plugins
Added: trunk/LayoutTests/fast/js/dfg-phantom-base-expected.txt (0 => 146947)
--- trunk/LayoutTests/fast/js/dfg-phantom-base-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-phantom-base-expected.txt 2013-03-27 00:03:41 UTC (rev 146947)
@@ -0,0 +1,209 @@
+Tests that we use Phantom on the base of put_by_base correctly.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}}) is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/dfg-phantom-base.html (0 => 146947)
--- trunk/LayoutTests/fast/js/dfg-phantom-base.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-phantom-base.html 2013-03-27 00:03:41 UTC (rev 146947)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/js/dfg-to-string-toString-becomes-bad-with-check-structure-expected.txt (0 => 146947)
--- trunk/LayoutTests/fast/js/dfg-to-string-toString-becomes-bad-with-check-structure-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-to-string-toString-becomes-bad-with-check-structure-expected.txt 2013-03-27 00:03:41 UTC (rev 146947)
@@ -0,0 +1,109 @@
+Tests that the DFG checks that the toString method didn't become bad even if the StringObject already had a CheckStructure.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "foo"
+PASS foo.call(new String("foo")) is "42"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/dfg-to-string-toString-becomes-bad-with-check-structure.html (0 => 146947)
--- trunk/LayoutTests/fast/js/dfg-to-string-toString-becomes-bad-with-check-structure.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-to-string-toString-becomes-bad-with-check-structure.html 2013-03-27 00:03:41 UTC (rev 146947)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/fast/js/jsc-test-list (146946 => 146947)
--- trunk/LayoutTests/fast/js/jsc-test-list 2013-03-26 23:52:31 UTC (rev 146946)
+++ trunk/LayoutTests/fast/js/jsc-test-list 2013-03-27 00:03:41 UTC (rev 146947)
@@ -184,6 +184,7 @@
fast/js/dfg-obvious-constant-cfa
fast/js/dfg-osr-entry-hoisted-clobbered-structure-check
fast/js/dfg-other-branch
+fast/js/dfg-phantom-base
fast/js/dfg-phantom-get-local
fast/js/dfg-post-inc-then-exit
fast/js/dfg-proto-access-inline-osr-exit
@@ -204,6 +205,7 @@
fast/js/dfg-to-string-on-value
fast/js/dfg-to-string-side-effect
fast/js/dfg-to-string-side-effect-clobbers-toString
+fast/js/dfg-to-string-toString-becomes-bad-with-check-structure
fast/js/dfg-to-string-toString-becomes-bad-with-dictionary-string-prototype
fast/js/dfg-to-string-toString-becomes-bad
fast/js/dfg-to-string-toString-in-string
Added: trunk/LayoutTests/fast/js/script-tests/dfg-phantom-base.js (0 => 146947)
--- trunk/LayoutTests/fast/js/script-tests/dfg-phantom-base.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-phantom-base.js 2013-03-27 00:03:41 UTC (rev 146947)
@@ -0,0 +1,19 @@
+description(
+"Tests that we use Phantom on the base of put_by_base correctly."
+);
+
+function foo(o) {
+ var x = o;
+ var y = o.f;
+ if (y) {
+ o.g.h;
+ return !x;
+ }
+
+ // Do things to ensure that the structure check on o is not hoisted.
+ return o + o + o + o + o;
+}
+
+for (var i = 0; i < 200; ++i)
+ shouldBe("foo(i < 190 ? {f:42, g:{h:3}} : {f:42, g:{}})", "false");
+
Added: trunk/LayoutTests/fast/js/script-tests/dfg-to-string-toString-becomes-bad-with-check-structure.js (0 => 146947)
--- trunk/LayoutTests/fast/js/script-tests/dfg-to-string-toString-becomes-bad-with-check-structure.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-to-string-toString-becomes-bad-with-check-structure.js 2013-03-27 00:03:41 UTC (rev 146947)
@@ -0,0 +1,14 @@
+description(
+"Tests that the DFG checks that the toString method didn't become bad even if the StringObject already had a CheckStructure."
+);
+
+function foo() {
+ return String(this);
+}
+
+for (var i = 0; i < 100; ++i) {
+ if (i == 99)
+ String.prototype.toString = function() { return 42; }
+ shouldBe("foo.call(new String(\"foo\"))", i >= 99 ? "\"42\"" : "\"foo\"");
+}
+
Modified: trunk/Source/_javascript_Core/ChangeLog (146946 => 146947)
--- trunk/Source/_javascript_Core/ChangeLog 2013-03-26 23:52:31 UTC (rev 146946)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-03-27 00:03:41 UTC (rev 146947)
@@ -1,3 +1,25 @@
+2013-03-26 Filip Pizlo <fpi...@apple.com>
+
+ REGRESSION: Sometimes, operations on proven strings ignore changes to the string prototype
+ https://bugs.webkit.org/show_bug.cgi?id=113353
+ <rdar://problem/13510778>
+
+ Reviewed by Mark Hahnenberg and Geoffrey Garen.
+
+ ToString should call speculateStringObject() even if you know that it's a string object, since
+ it calls it to also get the watchpoint. Note that even with this change, if you do
+ Phantom(Check:StringObject:@a), it might get eliminated just because we proved that @a is a
+ string object (thereby eliminating the prototype watchpoint); that's fine since ToString is
+ MustGenerate and never decays to Phantom.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileToStringOnCell):
+ (JSC::DFG::SpeculativeJIT::speculateStringObject):
+ (JSC::DFG::SpeculativeJIT::speculateStringOrStringObject):
+ * dfg/DFGSpeculativeJIT.h:
+ (SpeculativeJIT):
+ (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
+
2013-03-26 Mark Hahnenberg <mhahnenb...@apple.com>
REGRESSION(r144131): It made fast/js/regress/string-repeat-arith.html assert on 32 bit
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (146946 => 146947)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-03-26 23:52:31 UTC (rev 146946)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-03-27 00:03:41 UTC (rev 146947)
@@ -3981,10 +3981,8 @@
GPRTemporary result(this);
GPRReg resultGPR = result.gpr();
- if (!m_state.forNode(node->child1()).m_currentKnownStructure.isSubsetOf(StructureSet(m_jit.globalObjectFor(node->codeOrigin)->stringObjectStructure()))) {
- speculateStringObject(op1GPR);
- m_state.forNode(node->child1()).filter(SpecStringObject);
- }
+ speculateStringObject(node->child1(), op1GPR);
+ m_state.forNode(node->child1()).filter(SpecStringObject);
m_jit.loadPtr(JITCompiler::Address(op1GPR, JSWrapperObject::internalValueCellOffset()), resultGPR);
cellResult(resultGPR, node);
break;
@@ -3998,7 +3996,7 @@
JITCompiler::Jump isString = m_jit.branchPtr(
JITCompiler::Equal, resultGPR, TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
- speculateStringObjectForStructure(resultGPR);
+ speculateStringObjectForStructure(node->child1(), resultGPR);
m_jit.loadPtr(JITCompiler::Address(op1GPR, JSWrapperObject::internalValueCellOffset()), resultGPR);
@@ -4212,9 +4210,9 @@
MacroAssembler::TrustedImmPtr(m_jit.globalData()->stringStructure.get())));
}
-void SpeculativeJIT::speculateStringObject(GPRReg gpr)
+void SpeculativeJIT::speculateStringObject(Edge edge, GPRReg gpr)
{
- speculateStringObjectForStructure(JITCompiler::Address(gpr, JSCell::structureOffset()));
+ speculateStringObjectForStructure(edge, JITCompiler::Address(gpr, JSCell::structureOffset()));
}
void SpeculativeJIT::speculateStringObject(Edge edge)
@@ -4227,7 +4225,7 @@
if (!needsTypeCheck(edge, SpecStringObject))
return;
- speculateStringObject(gpr);
+ speculateStringObject(edge, gpr);
m_state.forNode(edge).filter(SpecStringObject);
}
@@ -4249,7 +4247,7 @@
JITCompiler::Jump isString = m_jit.branchPtr(
JITCompiler::Equal, structureGPR, TrustedImmPtr(m_jit.globalData()->stringStructure.get()));
- speculateStringObjectForStructure(structureGPR);
+ speculateStringObjectForStructure(edge, structureGPR);
isString.link(&m_jit);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (146946 => 146947)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-03-26 23:52:31 UTC (rev 146946)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-03-27 00:03:41 UTC (rev 146947)
@@ -2260,8 +2260,8 @@
void speculateObjectOrOther(Edge);
void speculateString(Edge);
template<typename StructureLocationType>
- void speculateStringObjectForStructure(StructureLocationType);
- void speculateStringObject(GPRReg);
+ void speculateStringObjectForStructure(Edge, StructureLocationType);
+ void speculateStringObject(Edge, GPRReg);
void speculateStringObject(Edge);
void speculateStringOrStringObject(Edge);
void speculateNotCell(Edge);
@@ -2991,17 +2991,19 @@
};
template<typename StructureLocationType>
-void SpeculativeJIT::speculateStringObjectForStructure(StructureLocationType structureLocation)
+void SpeculativeJIT::speculateStringObjectForStructure(Edge edge, StructureLocationType structureLocation)
{
Structure* stringObjectStructure =
m_jit.globalObjectFor(m_currentNode->codeOrigin)->stringObjectStructure();
Structure* stringPrototypeStructure = stringObjectStructure->storedPrototype().asCell()->structure();
ASSERT(stringPrototypeStructure->transitionWatchpointSetIsStillValid());
- speculationCheck(
- NotStringObject, JSValueRegs(), 0,
- m_jit.branchPtr(
- JITCompiler::NotEqual, structureLocation, TrustedImmPtr(stringObjectStructure)));
+ if (!m_state.forNode(edge).m_currentKnownStructure.isSubsetOf(StructureSet(m_jit.globalObjectFor(m_currentNode->codeOrigin)->stringObjectStructure()))) {
+ speculationCheck(
+ NotStringObject, JSValueRegs(), 0,
+ m_jit.branchPtr(
+ JITCompiler::NotEqual, structureLocation, TrustedImmPtr(stringObjectStructure)));
+ }
stringPrototypeStructure->addTransitionWatchpoint(speculationWatchpoint(NotStringObject));
}
_______________________________________________ webkit-changes mailing list webkit-changes@lists.webkit.org https://lists.webkit.org/mailman/listinfo/webkit-changes