Title: [160246] trunk
Revision
160246
Author
[email protected]
Date
2013-12-06 14:05:10 -0800 (Fri, 06 Dec 2013)

Log Message

FTL should support hole/OOB array accesses
https://bugs.webkit.org/show_bug.cgi?id=118077

Reviewed by Oliver Hunt and Mark Hahnenberg.

Source/_javascript_Core: 

* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLIntrinsicRepository.h:
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileGetByVal):
(JSC::FTL::LowerDFGToLLVM::baseIndex):

LayoutTests: 

* js/regress/double-get-by-val-out-of-bounds-expected.txt: Added.
* js/regress/double-get-by-val-out-of-bounds.html: Added.
* js/regress/get-by-val-out-of-bounds-expected.txt: Added.
* js/regress/get-by-val-out-of-bounds.html: Added.
* js/regress/script-tests/double-get-by-val-out-of-bounds.js: Added.
(foo):
* js/regress/script-tests/get-by-val-out-of-bounds.js: Added.
(foo):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (160245 => 160246)


--- trunk/LayoutTests/ChangeLog	2013-12-06 21:40:34 UTC (rev 160245)
+++ trunk/LayoutTests/ChangeLog	2013-12-06 22:05:10 UTC (rev 160246)
@@ -1,3 +1,19 @@
+2013-12-06  Filip Pizlo  <[email protected]>
+
+        FTL should support hole/OOB array accesses
+        https://bugs.webkit.org/show_bug.cgi?id=118077
+
+        Reviewed by Oliver Hunt and Mark Hahnenberg.
+
+        * js/regress/double-get-by-val-out-of-bounds-expected.txt: Added.
+        * js/regress/double-get-by-val-out-of-bounds.html: Added.
+        * js/regress/get-by-val-out-of-bounds-expected.txt: Added.
+        * js/regress/get-by-val-out-of-bounds.html: Added.
+        * js/regress/script-tests/double-get-by-val-out-of-bounds.js: Added.
+        (foo):
+        * js/regress/script-tests/get-by-val-out-of-bounds.js: Added.
+        (foo):
+
 2013-12-06  Rob Buis  <[email protected]>
 
         [CSS Shapes] ShapeOutsideInfo needs to use the parent's writing mode when calculating offsets

Added: trunk/LayoutTests/js/regress/double-get-by-val-out-of-bounds-expected.txt (0 => 160246)


--- trunk/LayoutTests/js/regress/double-get-by-val-out-of-bounds-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/regress/double-get-by-val-out-of-bounds-expected.txt	2013-12-06 22:05:10 UTC (rev 160246)
@@ -0,0 +1,10 @@
+JSRegress/double-get-by-val-out-of-bounds
+
+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: trunk/LayoutTests/js/regress/double-get-by-val-out-of-bounds.html (0 => 160246)


--- trunk/LayoutTests/js/regress/double-get-by-val-out-of-bounds.html	                        (rev 0)
+++ trunk/LayoutTests/js/regress/double-get-by-val-out-of-bounds.html	2013-12-06 22:05:10 UTC (rev 160246)
@@ -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>

Added: trunk/LayoutTests/js/regress/get-by-val-out-of-bounds-expected.txt (0 => 160246)


--- trunk/LayoutTests/js/regress/get-by-val-out-of-bounds-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/regress/get-by-val-out-of-bounds-expected.txt	2013-12-06 22:05:10 UTC (rev 160246)
@@ -0,0 +1,10 @@
+JSRegress/get-by-val-out-of-bounds
+
+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: trunk/LayoutTests/js/regress/get-by-val-out-of-bounds.html (0 => 160246)


--- trunk/LayoutTests/js/regress/get-by-val-out-of-bounds.html	                        (rev 0)
+++ trunk/LayoutTests/js/regress/get-by-val-out-of-bounds.html	2013-12-06 22:05:10 UTC (rev 160246)
@@ -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>

Added: trunk/LayoutTests/js/regress/script-tests/double-get-by-val-out-of-bounds.js (0 => 160246)


--- trunk/LayoutTests/js/regress/script-tests/double-get-by-val-out-of-bounds.js	                        (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/double-get-by-val-out-of-bounds.js	2013-12-06 22:05:10 UTC (rev 160246)
@@ -0,0 +1,11 @@
+function foo(a) {
+    return a[1];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = foo([42.5]);
+    if (result !== void 0)
+        throw "Error: bad value: " + result;
+}

Added: trunk/LayoutTests/js/regress/script-tests/get-by-val-out-of-bounds.js (0 => 160246)


--- trunk/LayoutTests/js/regress/script-tests/get-by-val-out-of-bounds.js	                        (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/get-by-val-out-of-bounds.js	2013-12-06 22:05:10 UTC (rev 160246)
@@ -0,0 +1,11 @@
+function foo(a) {
+    return a[1];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 100000; ++i) {
+    var result = foo([42]);
+    if (result !== void 0)
+        throw "Error: bad value: " + result;
+}

Modified: trunk/Source/_javascript_Core/ChangeLog (160245 => 160246)


--- trunk/Source/_javascript_Core/ChangeLog	2013-12-06 21:40:34 UTC (rev 160245)
+++ trunk/Source/_javascript_Core/ChangeLog	2013-12-06 22:05:10 UTC (rev 160246)
@@ -1,3 +1,17 @@
+2013-12-06  Filip Pizlo  <[email protected]>
+
+        FTL should support hole/OOB array accesses
+        https://bugs.webkit.org/show_bug.cgi?id=118077
+
+        Reviewed by Oliver Hunt and Mark Hahnenberg.
+
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLIntrinsicRepository.h:
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileGetByVal):
+        (JSC::FTL::LowerDFGToLLVM::baseIndex):
+
 2013-12-06  Michael Saboff  <[email protected]>
 
         Split sizing of VarArgs frames from loading arguments for the frame

Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (160245 => 160246)


--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2013-12-06 21:40:34 UTC (rev 160245)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp	2013-12-06 22:05:10 UTC (rev 160246)
@@ -158,13 +158,6 @@
                 return CanCompileAndOSREnter;
             return CannotCompile;
         }
-        switch (node->arrayMode().speculation()) {
-        case Array::SaneChain:
-        case Array::InBounds:
-            break;
-        default:
-            return CannotCompile;
-        }
         break;
     case PutByVal:
     case PutByValAlias:

Modified: trunk/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h (160245 => 160246)


--- trunk/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h	2013-12-06 21:40:34 UTC (rev 160245)
+++ trunk/Source/_javascript_Core/ftl/FTLIntrinsicRepository.h	2013-12-06 22:05:10 UTC (rev 160246)
@@ -54,6 +54,7 @@
     macro(C_JITOperation_ESt, functionType(intPtr, intPtr, intPtr)) \
     macro(I_JITOperation_EJss, functionType(intPtr, intPtr, intPtr)) \
     macro(J_JITOperation_E, functionType(int64, intPtr)) \
+    macro(J_JITOperation_EAZ, functionType(int64, intPtr, intPtr, int32)) \
     macro(J_JITOperation_EJssZ, functionType(int64, intPtr, intPtr, int32)) \
     macro(J_JITOperation_ESsiJI, functionType(int64, intPtr, intPtr, int64, intPtr)) \
     macro(Jss_JITOperation_EZ, functionType(intPtr, intPtr, int32)) \

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (160245 => 160246)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2013-12-06 21:40:34 UTC (rev 160245)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2013-12-06 22:05:10 UTC (rev 160246)
@@ -1482,25 +1482,45 @@
             LValue index = lowInt32(m_node->child2());
             LValue storage = lowStorage(m_node->child3());
             
+            IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
+                m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
+            
             if (m_node->arrayMode().isInBounds()) {
                 speculate(
                     OutOfBounds, noValue(), 0,
                     m_out.aboveOrEqual(
                         index, m_out.load32(storage, m_heaps.Butterfly_publicLength)));
                 
-                LValue result = m_out.load64(m_out.baseIndex(
-                    m_node->arrayMode().type() == Array::Int32 ?
-                        m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
-                    storage, m_out.zeroExt(index, m_out.intPtr),
-                    m_state.forNode(m_node->child2()).m_value));
+                LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
                 speculate(LoadFromHole, noValue(), 0, m_out.isZero64(result));
                 setJSValue(result);
                 return;
             }
             
-            // FIXME: Implement hole/OOB loads in the FTL.
-            // https://bugs.webkit.org/show_bug.cgi?id=118077
-            RELEASE_ASSERT_NOT_REACHED();
+            LValue base = lowCell(m_node->child1());
+            
+            LBasicBlock fastCase = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous fast case"));
+            LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous slow case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous continuation"));
+            
+            m_out.branch(
+                m_out.aboveOrEqual(
+                    index, m_out.load32(storage, m_heaps.Butterfly_publicLength)),
+                slowCase, fastCase);
+            
+            LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
+            
+            ValueFromBlock fastResult = m_out.anchor(
+                m_out.load64(baseIndex(heap, storage, index, m_node->child2())));
+            m_out.branch(m_out.isZero64(fastResult.value()), slowCase, continuation);
+            
+            m_out.appendTo(slowCase, continuation);
+            ValueFromBlock slowResult = m_out.anchor(
+                vmCall(m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(continuation, lastNext);
+            setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
             return;
         }
             
@@ -1508,16 +1528,16 @@
             LValue index = lowInt32(m_node->child2());
             LValue storage = lowStorage(m_node->child3());
             
+            IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
+            
             if (m_node->arrayMode().isInBounds()) {
                 speculate(
                     OutOfBounds, noValue(), 0,
                     m_out.aboveOrEqual(
                         index, m_out.load32(storage, m_heaps.Butterfly_publicLength)));
                 
-                LValue result = m_out.loadDouble(m_out.baseIndex(
-                    m_heaps.indexedDoubleProperties,
-                    storage, m_out.zeroExt(index, m_out.intPtr),
-                    m_state.forNode(m_node->child2()).m_value));
+                LValue result = m_out.loadDouble(
+                    baseIndex(heap, storage, index, m_node->child2()));
                 
                 if (!m_node->arrayMode().isSaneChain()) {
                     speculate(
@@ -1528,9 +1548,35 @@
                 break;
             }
             
-            // FIXME: Implement hole/OOB loads in the FTL.
-            // https://bugs.webkit.org/show_bug.cgi?id=118077
-            RELEASE_ASSERT_NOT_REACHED();
+            LValue base = lowCell(m_node->child1());
+            
+            LBasicBlock inBounds = FTL_NEW_BLOCK(m_out, ("GetByVal double in bounds"));
+            LBasicBlock boxPath = FTL_NEW_BLOCK(m_out, ("GetByVal double boxing"));
+            LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetByVal double slow case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal double continuation"));
+            
+            m_out.branch(
+                m_out.aboveOrEqual(
+                    index, m_out.load32(storage, m_heaps.Butterfly_publicLength)),
+                slowCase, inBounds);
+            
+            LBasicBlock lastNext = m_out.appendTo(inBounds, boxPath);
+            LValue doubleValue = m_out.loadDouble(
+                baseIndex(heap, storage, index, m_node->child2()));
+            m_out.branch(
+                m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue), slowCase, boxPath);
+            
+            m_out.appendTo(boxPath, slowCase);
+            ValueFromBlock fastResult = m_out.anchor(boxDouble(doubleValue));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(slowCase, continuation);
+            ValueFromBlock slowResult = m_out.anchor(
+                vmCall(m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(continuation, lastNext);
+            setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
             return;
         }
             
@@ -2715,6 +2761,13 @@
         info.m_isInvalidationPoint = true;
     }
     
+    TypedPointer baseIndex(IndexedAbstractHeap& heap, LValue storage, LValue index, Edge edge)
+    {
+        return m_out.baseIndex(
+            heap, storage, m_out.zeroExt(index, m_out.intPtr),
+            m_state.forNode(edge).m_value);
+    }
+    
     LValue allocateCell(LValue allocator, LValue structure, LBasicBlock slowPath)
     {
         LBasicBlock success = FTL_NEW_BLOCK(m_out, ("object allocation success"));
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to