Diff
Modified: trunk/LayoutTests/ChangeLog (153285 => 153286)
--- trunk/LayoutTests/ChangeLog 2013-07-25 04:05:08 UTC (rev 153285)
+++ trunk/LayoutTests/ChangeLog 2013-07-25 04:05:12 UTC (rev 153286)
@@ -1,3 +1,29 @@
+2013-07-19 Filip Pizlo <[email protected]>
+
+ fourthTier: String GetByVal out-of-bounds handling is so wrong
+ https://bugs.webkit.org/show_bug.cgi?id=118935
+
+ Reviewed by Geoffrey Garen.
+
+ * fast/js/dfg-string-out-of-bounds-check-structure-expected.txt: Added.
+ * fast/js/dfg-string-out-of-bounds-check-structure.html: Added.
+ * fast/js/dfg-string-out-of-bounds-cse-expected.txt: Added.
+ * fast/js/dfg-string-out-of-bounds-cse.html: Added.
+ * fast/js/dfg-string-out-of-bounds-negative-check-structure-expected.txt: Added.
+ * fast/js/dfg-string-out-of-bounds-negative-check-structure.html: Added.
+ * fast/js/dfg-string-out-of-bounds-negative-proto-value-expected.txt: Added.
+ * fast/js/dfg-string-out-of-bounds-negative-proto-value.html: Added.
+ * fast/js/jsc-test-list:
+ * fast/js/script-tests/dfg-string-out-of-bounds-check-structure.js: Added.
+ (foo):
+ * fast/js/script-tests/dfg-string-out-of-bounds-cse.js: Added.
+ (foo):
+ * fast/js/script-tests/dfg-string-out-of-bounds-negative-check-structure.js: Added.
+ (foo):
+ (while):
+ * fast/js/script-tests/dfg-string-out-of-bounds-negative-proto-value.js: Added.
+ (foo):
+
2013-06-25 Filip Pizlo <[email protected]>
fourthTier: DFG should support switch_string
Added: trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-check-structure-expected.txt (0 => 153286)
--- trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-check-structure-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-check-structure-expected.txt 2013-07-25 04:05:12 UTC (rev 153286)
@@ -0,0 +1,9 @@
+Tests what happens when you do a out-of-bounds access on a string and use that to install a getter that clobbers a structure.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Passed some tests silently.
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-check-structure.html (0 => 153286)
--- trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-check-structure.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-check-structure.html 2013-07-25 04:05:12 UTC (rev 153286)
@@ -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-string-out-of-bounds-cse-expected.txt (0 => 153286)
--- trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-cse-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-cse-expected.txt 2013-07-25 04:05:12 UTC (rev 153286)
@@ -0,0 +1,9 @@
+Tests what happens when you present a CSE opportunity across an out-of-bounds string access.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Passed some tests silently.
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-cse.html (0 => 153286)
--- trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-cse.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-cse.html 2013-07-25 04:05:12 UTC (rev 153286)
@@ -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-string-out-of-bounds-negative-check-structure-expected.txt (0 => 153286)
--- trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-negative-check-structure-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-negative-check-structure-expected.txt 2013-07-25 04:05:12 UTC (rev 153286)
@@ -0,0 +1,9 @@
+Tests what happens when you do a negative out-of-bounds access on a string and use that to install a getter that clobbers a structure.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Passed some tests silently.
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-negative-check-structure.html (0 => 153286)
--- trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-negative-check-structure.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-negative-check-structure.html 2013-07-25 04:05:12 UTC (rev 153286)
@@ -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-string-out-of-bounds-negative-proto-value-expected.txt (0 => 153286)
--- trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-negative-proto-value-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-negative-proto-value-expected.txt 2013-07-25 04:05:12 UTC (rev 153286)
@@ -0,0 +1,9 @@
+Tests what happens when you do a negative out-of-bounds access on a string while the prototype has a negative indexed property.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Passed some tests silently.
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-negative-proto-value.html (0 => 153286)
--- trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-negative-proto-value.html (rev 0)
+++ trunk/LayoutTests/fast/js/dfg-string-out-of-bounds-negative-proto-value.html 2013-07-25 04:05:12 UTC (rev 153286)
@@ -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 (153285 => 153286)
--- trunk/LayoutTests/fast/js/jsc-test-list 2013-07-25 04:05:08 UTC (rev 153285)
+++ trunk/LayoutTests/fast/js/jsc-test-list 2013-07-25 04:05:12 UTC (rev 153286)
@@ -212,6 +212,10 @@
fast/js/dfg-resolve-global-specific-dictionary
fast/js/dfg-side-effect-assignment-osr-exit
fast/js/dfg-sqrt-backwards-propagation
+fast/js/dfg-string-out-of-bounds-check-structure
+fast/js/dfg-string-out-of-bounds-cse
+fast/js/dfg-string-out-of-bounds-negative-check-structure
+fast/js/dfg-string-out-of-bounds-negative-proto-value
fast/js/dfg-string-stricteq
fast/js/dfg-tear-off-arguments-not-activation
fast/js/dfg-tear-off-function-dot-arguments
Added: trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-check-structure.js (0 => 153286)
--- trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-check-structure.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-check-structure.js 2013-07-25 04:05:12 UTC (rev 153286)
@@ -0,0 +1,29 @@
+description(
+"Tests what happens when you do a out-of-bounds access on a string and use that to install a getter that clobbers a structure."
+);
+
+function foo(s, o) {
+ var x = o.f;
+ s[42];
+ var y = o.g;
+ return x + y;
+}
+
+noInline(foo);
+silentTestPass = true;
+
+var theObject = {};
+
+var didGetCalled = false;
+String.prototype.__defineGetter__("42", function() { didGetCalled = true; delete theObject.g; theObject.h = 42 });
+
+while (testRunner.numberOfDFGCompiles(foo) < 1) {
+ didGetCalled = false;
+ shouldBe("foo(\"hello\", {f:1, g:2})", "3");
+ shouldBe("didGetCalled", "true");
+}
+
+theObject = {f:1, g:2};
+didGetCalled = false;
+shouldBe("foo(\"hello\", theObject)", "0/0");
+shouldBe("didGetCalled", "true");
Added: trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-cse.js (0 => 153286)
--- trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-cse.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-cse.js 2013-07-25 04:05:12 UTC (rev 153286)
@@ -0,0 +1,23 @@
+description(
+"Tests what happens when you present a CSE opportunity across an out-of-bounds string access."
+);
+
+function foo(s, o) {
+ var x = o.f;
+ s[0];
+ var y = o.f;
+ return x + y;
+}
+
+noInline(foo);
+silentTestPass = true;
+
+var theObject = {};
+
+String.prototype.__defineGetter__("0", function() { theObject.f = 42; });
+
+while (!dfgCompiled({f:foo}))
+ shouldBe("foo(\"\", {f:1})", "2");
+
+theObject = {f:1};
+shouldBe("foo(\"\", theObject)", "43");
Added: trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-negative-check-structure.js (0 => 153286)
--- trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-negative-check-structure.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-negative-check-structure.js 2013-07-25 04:05:12 UTC (rev 153286)
@@ -0,0 +1,23 @@
+description(
+"Tests what happens when you do a negative out-of-bounds access on a string and use that to install a getter that clobbers a structure."
+);
+
+function foo(s, o) {
+ var x = o.f;
+ s[-1];
+ var y = o.g;
+ return x + y;
+}
+
+noInline(foo);
+silentTestPass = true;
+
+var theObject = {};
+
+String.prototype.__defineGetter__("-1", function() { delete theObject.g; });
+
+while (testRunner.numberOfDFGCompiles(foo) < 1)
+ shouldBe("foo(\"hello\", {f:1, g:2})", "3");
+
+theObject = {f:1, g:2};
+shouldBe("foo(\"hello\", theObject)", "0/0");
Added: trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-negative-proto-value.js (0 => 153286)
--- trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-negative-proto-value.js (rev 0)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-string-out-of-bounds-negative-proto-value.js 2013-07-25 04:05:12 UTC (rev 153286)
@@ -0,0 +1,16 @@
+description(
+"Tests what happens when you do a negative out-of-bounds access on a string while the prototype has a negative indexed property."
+);
+
+function foo(s) {
+ return s[-1];
+}
+
+noInline(foo);
+silentTestPass = true;
+
+String.prototype[-1] = "hello";
+
+for (var i = 0; i < 2; i = dfgIncrement({f:foo, i:i + 1, n:1, compiles:2}))
+ shouldBe("foo(\"hello\")", "\"hello\"");
+
Modified: trunk/Source/_javascript_Core/API/JSCTestRunnerUtils.cpp (153285 => 153286)
--- trunk/Source/_javascript_Core/API/JSCTestRunnerUtils.cpp 2013-07-25 04:05:08 UTC (rev 153285)
+++ trunk/Source/_javascript_Core/API/JSCTestRunnerUtils.cpp 2013-07-25 04:05:12 UTC (rev 153286)
@@ -48,17 +48,23 @@
JSValueRef numberOfDFGCompiles(JSContextRef context, JSValueRef theFunctionValueRef)
{
+ bool pretendToHaveManyCompiles = false;
+#if ENABLE(DFG_JIT)
+ if (!Options::useJIT() || !Options::useDFGJIT())
+ pretendToHaveManyCompiles = true;
+#else
+ pretendToHaveManyCompiles = true;
+#endif
+
if (FunctionExecutable* executable = getExecutable(context, theFunctionValueRef)) {
CodeBlock* baselineCodeBlock = executable->baselineCodeBlockFor(CodeForCall);
if (!baselineCodeBlock)
return JSValueMakeNumber(context, 0);
-#if ENABLE(DFG_JIT)
+ if (pretendToHaveManyCompiles)
+ return JSValueMakeNumber(context, 1000000.0);
return JSValueMakeNumber(context, baselineCodeBlock->numberOfDFGCompiles());
-#else
- return JSValueMakeNumber(context, 1000000.0);
-#endif
}
return JSValueMakeUndefined(context);
Modified: trunk/Source/_javascript_Core/ChangeLog (153285 => 153286)
--- trunk/Source/_javascript_Core/ChangeLog 2013-07-25 04:05:08 UTC (rev 153285)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-07-25 04:05:12 UTC (rev 153286)
@@ -1,5 +1,51 @@
2013-07-19 Filip Pizlo <[email protected]>
+ fourthTier: String GetByVal out-of-bounds handling is so wrong
+ https://bugs.webkit.org/show_bug.cgi?id=118935
+
+ Reviewed by Geoffrey Garen.
+
+ Bunch of String GetByVal out-of-bounds fixes:
+
+ - Even if the string proto chain is sane, we need to watch out for negative
+ indices. They may get values or call getters in the prototypes, since proto
+ sanity doesn't check for negative indexed properties, as they are not
+ technically indexed properties.
+
+ - GetByVal String out-of-bounds does in fact clobberWorld(). CSE should be
+ given this information.
+
+ - GetByVal String out-of-bounds does in fact clobberWorld(). CFA should be
+ given this information.
+
+ Also fixed some other things:
+
+ - If the DFG is disabled, the testRunner should pretend that we've done a
+ bunch of DFG compiles. That's necessary to prevent the tests from timing
+ out.
+
+ - Disassembler shouldn't try to dump source code since it's not safe in the
+ concurrent JIT.
+
+ * API/JSCTestRunnerUtils.cpp:
+ (JSC::numberOfDFGCompiles):
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::::executeEffects):
+ * dfg/DFGDisassembler.cpp:
+ (JSC::DFG::Disassembler::dumpHeader):
+ * dfg/DFGGraph.h:
+ (JSC::DFG::Graph::byValIsPure):
+ * dfg/DFGSaneStringGetByValSlowPathGenerator.h: Added.
+ (DFG):
+ (SaneStringGetByValSlowPathGenerator):
+ (JSC::DFG::SaneStringGetByValSlowPathGenerator::SaneStringGetByValSlowPathGenerator):
+ (JSC::DFG::SaneStringGetByValSlowPathGenerator::generateInternal):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
+
+2013-07-19 Filip Pizlo <[email protected]>
+
fourthTier: Structure::isValidOffset() should be able to tell you if you're loading a valid JSValue, and not just not crashing
https://bugs.webkit.org/show_bug.cgi?id=118911
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (153285 => 153286)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2013-07-25 04:05:08 UTC (rev 153285)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2013-07-25 04:05:12 UTC (rev 153286)
@@ -767,6 +767,7 @@
A73A535B1799CD5D00170C19 /* DFGLazyJSValue.h in Headers */ = {isa = PBXBuildFile; fileRef = A73A53591799CD5D00170C19 /* DFGLazyJSValue.h */; settings = {ATTRIBUTES = (Private, ); }; };
A73E1330179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */; };
A73E1331179624CD00E4DEA8 /* DFGDesiredStructureChains.h in Headers */ = {isa = PBXBuildFile; fileRef = A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ A741017F179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h in Headers */ = {isa = PBXBuildFile; fileRef = A741017E179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
A7482B9411671147003B0712 /* JSWeakObjectMapRefPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */; };
A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1831,6 +1832,7 @@
A73A53591799CD5D00170C19 /* DFGLazyJSValue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLazyJSValue.h; path = dfg/DFGLazyJSValue.h; sourceTree = "<group>"; };
A73E132C179624CD00E4DEA8 /* DFGDesiredStructureChains.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGDesiredStructureChains.cpp; path = dfg/DFGDesiredStructureChains.cpp; sourceTree = "<group>"; };
A73E132D179624CD00E4DEA8 /* DFGDesiredStructureChains.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGDesiredStructureChains.h; path = dfg/DFGDesiredStructureChains.h; sourceTree = "<group>"; };
+ A741017E179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSaneStringGetByValSlowPathGenerator.h; path = dfg/DFGSaneStringGetByValSlowPathGenerator.h; sourceTree = "<group>"; };
A7482B791166CDEA003B0712 /* JSWeakObjectMapRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectMapRefPrivate.h; sourceTree = "<group>"; };
A7482B7A1166CDEA003B0712 /* JSWeakObjectMapRefPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSWeakObjectMapRefPrivate.cpp; sourceTree = "<group>"; };
A7482E37116A697B003B0712 /* JSWeakObjectMapRefInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSWeakObjectMapRefInternal.h; sourceTree = "<group>"; };
@@ -2165,9 +2167,9 @@
034768DFFF38A50411DB9C8B /* Products */ = {
isa = PBXGroup;
children = (
+ 0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
932F5BD90822A1C700736975 /* _javascript_Core.framework */,
932F5BE10822A1C700736975 /* jsc */,
- 0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
141211200A48793C00480255 /* minidom */,
14BD59BF0A3E8F9000BAF59C /* testapi */,
6511230514046A4C002B101D /* testRegExp */,
@@ -3181,6 +3183,7 @@
0F766D4215B2A3BD008F363E /* DFGRegisterSet.h */,
86BB09BE138E381B0056702F /* DFGRepatch.cpp */,
86BB09BF138E381B0056702F /* DFGRepatch.h */,
+ A741017E179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h */,
86ECA3F9132DF25A002B2AD7 /* DFGScoreBoard.h */,
0F766D4515B3701D008F363E /* DFGScratchRegisterAllocator.h */,
0F1E3A65153A21DF000F9456 /* DFGSilentRegisterSavePlan.h */,
@@ -3568,6 +3571,7 @@
86EC9DD11328DF82002B2AD7 /* DFGRegisterBank.h in Headers */,
0F766D4415B2A3C0008F363E /* DFGRegisterSet.h in Headers */,
86BB09C1138E381B0056702F /* DFGRepatch.h in Headers */,
+ A741017F179DAF80002EB8BA /* DFGSaneStringGetByValSlowPathGenerator.h in Headers */,
86ECA3FA132DF25A002B2AD7 /* DFGScoreBoard.h in Headers */,
0F766D4615B3701F008F363E /* DFGScratchRegisterAllocator.h in Headers */,
0F1E3A67153A21E2000F9456 /* DFGSilentRegisterSavePlan.h in Headers */,
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (153285 => 153286)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2013-07-25 04:05:08 UTC (rev 153285)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2013-07-25 04:05:12 UTC (rev 153286)
@@ -785,7 +785,9 @@
// GetByVal operation the fact that we're using a watchpoint, using
// something like Array::SaneChain (except not quite, because that
// implies an in-bounds access). None of this feels like it's worth it,
- // so we're going with TOP for now.
+ // so we're going with TOP for now. The same thing applies to
+ // clobbering the world.
+ clobberWorld(node->codeOrigin, indexInBlock);
forNode(node).makeTop();
} else
forNode(node).set(m_graph, m_graph.m_vm.stringStructure.get());
Modified: trunk/Source/_javascript_Core/dfg/DFGDisassembler.cpp (153285 => 153286)
--- trunk/Source/_javascript_Core/dfg/DFGDisassembler.cpp 2013-07-25 04:05:08 UTC (rev 153285)
+++ trunk/Source/_javascript_Core/dfg/DFGDisassembler.cpp 2013-07-25 04:05:12 UTC (rev 153286)
@@ -69,7 +69,6 @@
{
out.print("Generated DFG JIT code for ", CodeBlockWithJITType(m_graph.m_codeBlock, JITCode::DFGJIT), ", instruction count = ", m_graph.m_codeBlock->instructionCount(), ":\n");
out.print(" Optimized with execution counter = ", m_graph.m_profiledBlock->jitExecuteCounter(), "\n");
- out.print(" Source: ", m_graph.m_codeBlock->sourceCodeOnOneLine(), "\n");
out.print(" Code at [", RawPointer(linkBuffer.debugAddress()), ", ", RawPointer(static_cast<char*>(linkBuffer.debugAddress()) + linkBuffer.debugSize()), "):\n");
}
Modified: trunk/Source/_javascript_Core/dfg/DFGGraph.h (153285 => 153286)
--- trunk/Source/_javascript_Core/dfg/DFGGraph.h 2013-07-25 04:05:08 UTC (rev 153285)
+++ trunk/Source/_javascript_Core/dfg/DFGGraph.h 2013-07-25 04:05:12 UTC (rev 153286)
@@ -497,7 +497,7 @@
case Array::SlowPutArrayStorage:
return !node->arrayMode().mayStoreToHole();
case Array::String:
- return node->op() == GetByVal;
+ return node->op() == GetByVal && node->arrayMode().isInBounds();
#if USE(JSVALUE32_64)
case Array::Arguments:
if (node->op() == GetByVal)
Added: trunk/Source/_javascript_Core/dfg/DFGSaneStringGetByValSlowPathGenerator.h (0 => 153286)
--- trunk/Source/_javascript_Core/dfg/DFGSaneStringGetByValSlowPathGenerator.h (rev 0)
+++ trunk/Source/_javascript_Core/dfg/DFGSaneStringGetByValSlowPathGenerator.h 2013-07-25 04:05:12 UTC (rev 153286)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DFGSaneStringGetByValSlowPathGenerator_h
+#define DFGSaneStringGetByValSlowPathGenerator_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(DFG_JIT)
+
+#include "DFGCommon.h"
+#include "DFGOperations.h"
+#include "DFGSlowPathGenerator.h"
+#include "DFGSpeculativeJIT.h"
+#include <wtf/Vector.h>
+
+namespace JSC { namespace DFG {
+
+class SaneStringGetByValSlowPathGenerator : public JumpingSlowPathGenerator<MacroAssembler::Jump> {
+public:
+ SaneStringGetByValSlowPathGenerator(
+ const MacroAssembler::Jump& from, SpeculativeJIT* jit, JSValueRegs resultRegs,
+ GPRReg baseReg, GPRReg propertyReg)
+ : JumpingSlowPathGenerator<MacroAssembler::Jump>(from, jit)
+ , m_resultRegs(resultRegs)
+ , m_baseReg(baseReg)
+ , m_propertyReg(propertyReg)
+ {
+ jit->silentSpillAllRegistersImpl(false, m_plans, extractResult(resultRegs));
+ }
+
+protected:
+ void generateInternal(SpeculativeJIT* jit)
+ {
+ linkFrom(jit);
+
+ MacroAssembler::Jump isNeg = jit->m_jit.branch32(
+ MacroAssembler::LessThan, m_propertyReg, MacroAssembler::TrustedImm32(0));
+
+#if USE(JSVALUE64)
+ jit->m_jit.move(
+ MacroAssembler::TrustedImm64(JSValue::encode(jsUndefined())), m_resultRegs.gpr());
+#else
+ jit->m_jit.move(
+ MacroAssembler::TrustedImm32(JSValue::UndefinedTag), m_resultRegs.tagGPR());
+ jit->m_jit.move(
+ MacroAssembler::TrustedImm32(0), m_resultRegs.payloadGPR());
+#endif
+ jumpTo(jit);
+
+ isNeg.link(&jit->m_jit);
+
+ for (unsigned i = 0; i < m_plans.size(); ++i)
+ jit->silentSpill(m_plans[i]);
+ jit->callOperation(operationGetByValStringInt, extractResult(m_resultRegs), m_baseReg, m_propertyReg);
+ GPRReg canTrample = SpeculativeJIT::pickCanTrample(extractResult(m_resultRegs));
+ for (unsigned i = m_plans.size(); i--;)
+ jit->silentFill(m_plans[i], canTrample);
+
+ jumpTo(jit);
+ }
+
+private:
+ JSValueRegs m_resultRegs;
+ GPRReg m_baseReg;
+ GPRReg m_propertyReg;
+ Vector<SilentRegisterSavePlan, 2> m_plans;
+};
+
+} } // namespace JSC::DFG
+
+#endif // ENABLE(DFG_JIT)
+
+#endif // DFGSaneStringGetByValSlowPathGenerator_h
+
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (153285 => 153286)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-07-25 04:05:08 UTC (rev 153285)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-07-25 04:05:12 UTC (rev 153286)
@@ -33,6 +33,7 @@
#include "DFGArrayifySlowPathGenerator.h"
#include "DFGBinarySwitch.h"
#include "DFGCallArrayAllocatorSlowPathGenerator.h"
+#include "DFGSaneStringGetByValSlowPathGenerator.h"
#include "DFGSlowPathGenerator.h"
#include "JSCJSValueInlines.h"
#include "LinkBuffer.h"
@@ -2147,16 +2148,12 @@
JSGlobalObject* globalObject = m_jit.globalObjectFor(node->codeOrigin);
if (globalObject->stringPrototypeChainIsSane()) {
#if USE(JSVALUE64)
- addSlowPathGenerator(
- slowPathMove(
- outOfBounds, this, TrustedImm64(JSValue::encode(jsUndefined())),
- scratchReg));
+ addSlowPathGenerator(adoptPtr(new SaneStringGetByValSlowPathGenerator(
+ outOfBounds, this, JSValueRegs(scratchReg), baseReg, propertyReg)));
#else
- addSlowPathGenerator(
- slowPathMove(
- outOfBounds, this,
- TrustedImm32(JSValue::UndefinedTag), resultTagReg,
- TrustedImm32(0), scratchReg));
+ addSlowPathGenerator(adoptPtr(new SaneStringGetByValSlowPathGenerator(
+ outOfBounds, this, JSValueRegs(resultTagReg, scratchReg),
+ baseReg, propertyReg)));
#endif
} else {
#if USE(JSVALUE64)