Diff
Modified: branches/dfgFourthTier/LayoutTests/ChangeLog (151873 => 151874)
--- branches/dfgFourthTier/LayoutTests/ChangeLog 2013-06-22 01:10:24 UTC (rev 151873)
+++ branches/dfgFourthTier/LayoutTests/ChangeLog 2013-06-22 02:27:16 UTC (rev 151874)
@@ -1,5 +1,19 @@
2013-06-21 Filip Pizlo <[email protected]>
+ fourthTier: DFG should't exit just because it GetByVal'd a big character
+ https://bugs.webkit.org/show_bug.cgi?id=117899
+
+ Reviewed by Mark Hahnenberg.
+
+ This benchmark speeds up by 3x.
+
+ * fast/js/regress/script-tests/string-get-by-val-big-char.js: Added.
+ (foo):
+ * fast/js/regress/string-get-by-val-big-char-expected.txt: Added.
+ * fast/js/regress/string-get-by-val-big-char.html: Added.
+
+2013-06-21 Filip Pizlo <[email protected]>
+
fourthTier: Small strings shouldn't get GC'd
https://bugs.webkit.org/show_bug.cgi?id=117897
Added: branches/dfgFourthTier/LayoutTests/fast/js/regress/script-tests/string-get-by-val-big-char.js (0 => 151874)
--- branches/dfgFourthTier/LayoutTests/fast/js/regress/script-tests/string-get-by-val-big-char.js (rev 0)
+++ branches/dfgFourthTier/LayoutTests/fast/js/regress/script-tests/string-get-by-val-big-char.js 2013-06-22 02:27:16 UTC (rev 151874)
@@ -0,0 +1,22 @@
+function foo(string) {
+ var result1, result2;
+ var m_z = 1;
+ var m_w = 2;
+ for (var i = 0; i < 100000; ++i) {
+ result1 = string[0]; // This will be slow, but we're testing if we stay in the DFG.
+ for (var j = 0; j < 10; ++j) {
+ m_z = (36969 * (m_z & 65535) + (m_z >> 16)) | 0;
+ m_w = (18000 * (m_w & 65535) + (m_w >> 16)) | 0;
+ result2 = ((m_z << 16) + m_w) | 0;
+ }
+ }
+ return [result1, result2];
+}
+
+var lBar = String.fromCharCode(322);
+
+var result = foo(lBar);
+if (result[0] != lBar)
+ throw "Bad result1: " + result[0];
+if (result[1] != 561434430)
+ throw "Bad result2: " + result[1];
Added: branches/dfgFourthTier/LayoutTests/fast/js/regress/string-get-by-val-big-char-expected.txt (0 => 151874)
--- branches/dfgFourthTier/LayoutTests/fast/js/regress/string-get-by-val-big-char-expected.txt (rev 0)
+++ branches/dfgFourthTier/LayoutTests/fast/js/regress/string-get-by-val-big-char-expected.txt 2013-06-22 02:27:16 UTC (rev 151874)
@@ -0,0 +1,10 @@
+JSRegress/string-get-by-val-big-char
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: branches/dfgFourthTier/LayoutTests/fast/js/regress/string-get-by-val-big-char.html (0 => 151874)
--- branches/dfgFourthTier/LayoutTests/fast/js/regress/string-get-by-val-big-char.html (rev 0)
+++ branches/dfgFourthTier/LayoutTests/fast/js/regress/string-get-by-val-big-char.html 2013-06-22 02:27:16 UTC (rev 151874)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>
Modified: branches/dfgFourthTier/Source/_javascript_Core/ChangeLog (151873 => 151874)
--- branches/dfgFourthTier/Source/_javascript_Core/ChangeLog 2013-06-22 01:10:24 UTC (rev 151873)
+++ branches/dfgFourthTier/Source/_javascript_Core/ChangeLog 2013-06-22 02:27:16 UTC (rev 151874)
@@ -1,5 +1,27 @@
2013-06-21 Filip Pizlo <[email protected]>
+ fourthTier: DFG should't exit just because it GetByVal'd a big character
+ https://bugs.webkit.org/show_bug.cgi?id=117899
+
+ Reviewed by Mark Hahnenberg.
+
+ Add a slow path. Also clarify handling of GetByVal in PutStructure elimination.
+ Previously it would fail due to canExit() but now we can also fail because
+ GetByVal(String) can allocate. Just make it so GetByVal is totally poisoned, in
+ a very explicit way.
+
+ * dfg/DFGCSEPhase.cpp:
+ (JSC::DFG::CSEPhase::putStructureStoreElimination):
+ * dfg/DFGOperations.cpp:
+ * dfg/DFGOperations.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compileGetByValOnString):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::callOperation):
+ (SpeculativeJIT):
+
+2013-06-21 Filip Pizlo <[email protected]>
+
fourthTier: Small strings shouldn't get GC'd
https://bugs.webkit.org/show_bug.cgi?id=117897
Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGCSEPhase.cpp (151873 => 151874)
--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGCSEPhase.cpp 2013-06-22 01:10:24 UTC (rev 151873)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGCSEPhase.cpp 2013-06-22 02:27:16 UTC (rev 151874)
@@ -591,6 +591,12 @@
case MakeRope:
return 0;
+ // This either exits, causes a GC (lazy string allocation), or clobbers
+ // the world. The chances of it not doing any of those things are so
+ // slim that we might as well not even try to reason about it.
+ case GetByVal:
+ return 0;
+
case GetIndexedPropertyStorage:
if (node->arrayMode().getIndexedPropertyStorageMayTriggerGC())
return 0;
Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOperations.cpp (151873 => 151874)
--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOperations.cpp 2013-06-22 01:10:24 UTC (rev 151873)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOperations.cpp 2013-06-22 02:27:16 UTC (rev 151874)
@@ -1543,6 +1543,14 @@
return string->value(exec).impl();
}
+JSString* DFG_OPERATION operationSingleCharacterString(ExecState* exec, int32_t character)
+{
+ VM& vm = exec->vm();
+ NativeCallFrameTracer tracer(&vm, exec);
+
+ return jsSingleCharacterString(exec, static_cast<UChar>(character));
+}
+
JSCell* DFG_OPERATION operationNewStringObject(ExecState* exec, JSString* string, Structure* structure)
{
VM& vm = exec->vm();
Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOperations.h (151873 => 151874)
--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOperations.h 2013-06-22 01:10:24 UTC (rev 151873)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGOperations.h 2013-06-22 02:27:16 UTC (rev 151874)
@@ -121,6 +121,7 @@
typedef char* DFG_OPERATION (*P_DFGOperation_EStSS)(ExecState*, Structure*, size_t, size_t);
typedef char* DFG_OPERATION (*P_DFGOperation_EStZ)(ExecState*, Structure*, int32_t);
typedef StringImpl* DFG_OPERATION (*I_DFGOperation_EJss)(ExecState*, JSString*);
+typedef JSString* DFG_OPERATION (*Jss_DFGOperation_EZ)(ExecState*, int32_t);
// These routines are provide callbacks out to C++ implementations of operations too complex to JIT.
JSCell* DFG_OPERATION operationNewObject(ExecState*, Structure*) WTF_INTERNAL;
@@ -209,6 +210,8 @@
char* DFG_OPERATION operationRageEnsureContiguous(ExecState*, JSCell*);
char* DFG_OPERATION operationEnsureArrayStorage(ExecState*, JSCell*);
StringImpl* DFG_OPERATION operationResolveRope(ExecState*, JSString*);
+JSString* DFG_OPERATION operationSingleCharacterString(ExecState*, int32_t);
+
JSCell* DFG_OPERATION operationNewStringObject(ExecState*, JSString*, Structure*);
JSCell* DFG_OPERATION operationToStringOnCell(ExecState*, JSCell*);
JSCell* DFG_OPERATION operationToString(ExecState*, EncodedJSValue);
Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (151873 => 151874)
--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-06-22 01:10:24 UTC (rev 151873)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-06-22 02:27:16 UTC (rev 151874)
@@ -2062,8 +2062,8 @@
m_jit.load16(MacroAssembler::BaseIndex(storageReg, propertyReg, MacroAssembler::TimesTwo, 0), scratchReg);
- // We only support ascii characters
- speculationCheck(Uncountable, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::AboveOrEqual, scratchReg, TrustedImm32(0x100)));
+ JITCompiler::Jump bigCharacter =
+ m_jit.branch32(MacroAssembler::AboveOrEqual, scratchReg, TrustedImm32(0x100));
// 8 bit string values don't need the isASCII check.
cont8Bit.link(&m_jit);
@@ -2072,6 +2072,11 @@
GPRReg smallStringsReg = smallStrings.gpr();
m_jit.move(MacroAssembler::TrustedImmPtr(m_jit.vm()->smallStrings.singleCharacterStrings()), smallStringsReg);
m_jit.loadPtr(MacroAssembler::BaseIndex(smallStringsReg, scratchReg, MacroAssembler::ScalePtr, 0), scratchReg);
+
+ addSlowPathGenerator(
+ slowPathCall(
+ bigCharacter, this, operationSingleCharacterString, scratchReg, scratchReg));
+
cellResult(scratchReg, m_currentNode);
}
Modified: branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (151873 => 151874)
--- branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-06-22 01:10:24 UTC (rev 151873)
+++ branches/dfgFourthTier/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-06-22 02:27:16 UTC (rev 151874)
@@ -1033,6 +1033,12 @@
return appendCallWithExceptionCheckSetResult(operation, result);
}
+ JITCompiler::Call callOperation(Jss_DFGOperation_EZ operation, GPRReg result, GPRReg arg1)
+ {
+ m_jit.setupArgumentsWithExecState(arg1);
+ return appendCallWithExceptionCheckSetResult(operation, result);
+ }
+
JITCompiler::Call callOperation(V_DFGOperation_EC operation, GPRReg arg1)
{
m_jit.setupArgumentsWithExecState(arg1);