FTL should support NewTypedArray
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Feb 2016 04:25:57 +0000 (04:25 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 17 Feb 2016 04:25:57 +0000 (04:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=154268

Reviewed by Saam Barati.

3% speed-up on pdfjs. This was already covered by many different tests.

Rolling this back in after fixing the butterfly argument.

* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileNode):
(JSC::FTL::DFG::LowerDFGToLLVM::compileNewArrayWithSize):
(JSC::FTL::DFG::LowerDFGToLLVM::compileNewTypedArray):
(JSC::FTL::DFG::LowerDFGToLLVM::compileAllocatePropertyStorage):
(JSC::FTL::DFG::LowerDFGToLLVM::allocateBasicStorageAndGetEnd):
(JSC::FTL::DFG::LowerDFGToLLVM::allocateBasicStorage):
(JSC::FTL::DFG::LowerDFGToLLVM::allocateObject):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196684 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/ftl/FTLCapabilities.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

index de5ee2f..dbd72c5 100644 (file)
@@ -1,3 +1,25 @@
+2016-02-16  Filip Pizlo  <fpizlo@apple.com>
+
+        FTL should support NewTypedArray
+        https://bugs.webkit.org/show_bug.cgi?id=154268
+
+        Reviewed by Saam Barati.
+
+        3% speed-up on pdfjs. This was already covered by many different tests.
+
+        Rolling this back in after fixing the butterfly argument.
+
+        * ftl/FTLCapabilities.cpp:
+        (JSC::FTL::canCompile):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileNode):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileNewArrayWithSize):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileNewTypedArray):
+        (JSC::FTL::DFG::LowerDFGToLLVM::compileAllocatePropertyStorage):
+        (JSC::FTL::DFG::LowerDFGToLLVM::allocateBasicStorageAndGetEnd):
+        (JSC::FTL::DFG::LowerDFGToLLVM::allocateBasicStorage):
+        (JSC::FTL::DFG::LowerDFGToLLVM::allocateObject):
+
 2016-02-16  Gavin Barraclough  <barraclough@apple.com>
 
         JSDOMWindow::getOwnPropertySlot should just call getStaticPropertySlot
index 796240a..c62bbe8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -72,6 +72,7 @@ inline CapabilityLevel canCompile(Node* node)
     case NewObject:
     case NewArray:
     case NewArrayBuffer:
+    case NewTypedArray:
     case GetByOffset:
     case GetGetterSetterByOffset:
     case GetGetter:
index 62bdbf1..5d98f68 100644 (file)
@@ -845,6 +845,9 @@ private:
         case NewArrayWithSize:
             compileNewArrayWithSize();
             break;
+        case NewTypedArray:
+            compileNewTypedArray();
+            break;
         case GetTypedArrayByteOffset:
             compileGetTypedArrayByteOffset();
             break;
@@ -4090,8 +4093,7 @@ private:
             
             LValue butterfly = m_out.sub(endOfStorage, payloadSize);
             
-            LValue object = allocateObject<JSArray>(
-                structure, butterfly, failCase);
+            LValue object = allocateObject<JSArray>(structure, butterfly, failCase);
             
             m_out.store32(publicLength, butterfly, m_heaps.Butterfly_publicLength);
             m_out.store32(vectorLength, butterfly, m_heaps.Butterfly_vectorLength);
@@ -4159,6 +4161,86 @@ private:
             m_out.constIntPtr(structure));
         setJSValue(vmCall(m_out.int64, m_out.operation(operationNewArrayWithSize), m_callFrame, structureValue, publicLength));
     }
+
+    void compileNewTypedArray()
+    {
+        TypedArrayType type = m_node->typedArrayType();
+        JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
+        
+        switch (m_node->child1().useKind()) {
+        case Int32Use: {
+            Structure* structure = globalObject->typedArrayStructure(type);
+
+            LValue size = lowInt32(m_node->child1());
+
+            LBasicBlock smallEnoughCase = FTL_NEW_BLOCK(m_out, ("NewTypedArray small enough case"));
+            LBasicBlock nonZeroCase = FTL_NEW_BLOCK(m_out, ("NewTypedArray non-zero case"));
+            LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("NewTypedArray slow case"));
+            LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("NewTypedArray continuation"));
+
+            m_out.branch(
+                m_out.above(size, m_out.constInt32(JSArrayBufferView::fastSizeLimit)),
+                rarely(slowCase), usually(smallEnoughCase));
+
+            LBasicBlock lastNext = m_out.appendTo(smallEnoughCase, nonZeroCase);
+
+            m_out.branch(m_out.notZero32(size), usually(nonZeroCase), rarely(slowCase));
+
+            m_out.appendTo(nonZeroCase, slowCase);
+
+            LValue byteSize =
+                m_out.shl(m_out.zeroExtPtr(size), m_out.constInt32(logElementSize(type)));
+            if (elementSize(type) < 8) {
+                byteSize = m_out.bitAnd(
+                    m_out.add(byteSize, m_out.constIntPtr(7)),
+                    m_out.constIntPtr(~static_cast<intptr_t>(7)));
+            }
+        
+            LValue storage = allocateBasicStorage(byteSize, slowCase);
+
+            LValue fastResultValue =
+                allocateObject<JSArrayBufferView>(structure, m_out.intPtrZero, slowCase);
+
+            m_out.storePtr(storage, fastResultValue, m_heaps.JSArrayBufferView_vector);
+            m_out.store32(size, fastResultValue, m_heaps.JSArrayBufferView_length);
+            m_out.store32(m_out.constInt32(FastTypedArray), fastResultValue, m_heaps.JSArrayBufferView_mode);
+
+            ValueFromBlock fastResult = m_out.anchor(fastResultValue);
+            m_out.jump(continuation);
+
+            m_out.appendTo(slowCase, continuation);
+
+            LValue slowResultValue = lazySlowPath(
+                [=] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> {
+                    return createLazyCallGenerator(
+                        operationNewTypedArrayWithSizeForType(type), locations[0].directGPR(),
+                        CCallHelpers::TrustedImmPtr(structure), locations[1].directGPR());
+                },
+                size);
+            ValueFromBlock slowResult = m_out.anchor(slowResultValue);
+            m_out.jump(continuation);
+
+            m_out.appendTo(continuation, lastNext);
+            setJSValue(m_out.phi(m_out.intPtr, fastResult, slowResult));
+            return;
+        }
+
+        case UntypedUse: {
+            LValue argument = lowJSValue(m_node->child1());
+
+            LValue result = vmCall(
+                m_out.intPtr, m_out.operation(operationNewTypedArrayWithOneArgumentForType(type)),
+                m_callFrame, weakPointer(globalObject->typedArrayStructure(type)), argument);
+
+            setJSValue(result);
+            return;
+        }
+
+        default:
+            DFG_CRASH(m_graph, m_node, "Bad use kind");
+            return;
+        }
+    }
     
     void compileAllocatePropertyStorage()
     {
@@ -7932,6 +8014,11 @@ private:
         return m_out.sub(
             m_out.loadPtr(m_out.absolute(&allocator.m_currentPayloadEnd)), newRemaining);
     }
+
+    LValue allocateBasicStorage(LValue size, LBasicBlock slowPath)
+    {
+        return m_out.sub(allocateBasicStorageAndGetEnd(size, slowPath), size);
+    }
     
     LValue allocateObject(Structure* structure)
     {