Typed arrays should use MarkedSpace instead of CopiedSpace
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Sep 2016 18:18:10 +0000 (18:18 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 6 Sep 2016 18:18:10 +0000 (18:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=161100

Reviewed by Geoffrey Garen.

This moves typed array backing stores out of CopiedSpace and into Auxiliary MarkedSpace.

This is a purely mechanical change since Auxiliary MarkedSpace already knows how to do
everything that typed arrays want.

* dfg/DFGOperations.cpp:
(JSC::DFG::newTypedArrayWithSize):
* dfg/DFGOperations.h:
(JSC::DFG::operationNewTypedArrayWithSizeForType):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileNewTypedArray):
* dfg/DFGSpeculativeJIT.h:
(JSC::DFG::SpeculativeJIT::callOperation):
(JSC::DFG::SpeculativeJIT::emitAllocateBasicStorage): Deleted.
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray):
(JSC::FTL::DFG::LowerDFGToB3::initializeArrayElements):
(JSC::FTL::DFG::LowerDFGToB3::splatWords):
(JSC::FTL::DFG::LowerDFGToB3::allocateBasicStorageAndGetEnd): Deleted.
(JSC::FTL::DFG::LowerDFGToB3::allocateBasicStorage): Deleted.
* heap/CopyToken.h:
* heap/SlotVisitor.cpp:
(JSC::SlotVisitor::markAuxiliary):
* jit/JITOperations.h:
* runtime/JSArrayBufferView.cpp:
(JSC::JSArrayBufferView::ConstructionContext::ConstructionContext):
(JSC::JSArrayBufferView::JSArrayBufferView):
* runtime/JSArrayBufferView.h:
* runtime/JSGenericTypedArrayView.h:
* runtime/JSGenericTypedArrayViewInlines.h:
(JSC::JSGenericTypedArrayView<Adaptor>::createWithFastVector):
(JSC::JSGenericTypedArrayView<Adaptor>::visitChildren):
(JSC::JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory):
(JSC::JSGenericTypedArrayView<Adaptor>::copyBackingStore): Deleted.

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

13 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/dfg/DFGOperations.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/heap/CopyToken.h
Source/JavaScriptCore/heap/SlotVisitor.cpp
Source/JavaScriptCore/jit/JITOperations.h
Source/JavaScriptCore/runtime/JSArrayBufferView.cpp
Source/JavaScriptCore/runtime/JSArrayBufferView.h
Source/JavaScriptCore/runtime/JSGenericTypedArrayView.h
Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h

index 02f68e9..29c85ce 100644 (file)
@@ -1,3 +1,45 @@
+2016-09-06  Filip Pizlo  <fpizlo@apple.com>
+
+        Typed arrays should use MarkedSpace instead of CopiedSpace
+        https://bugs.webkit.org/show_bug.cgi?id=161100
+
+        Reviewed by Geoffrey Garen.
+        
+        This moves typed array backing stores out of CopiedSpace and into Auxiliary MarkedSpace.
+        
+        This is a purely mechanical change since Auxiliary MarkedSpace already knows how to do
+        everything that typed arrays want.
+
+        * dfg/DFGOperations.cpp:
+        (JSC::DFG::newTypedArrayWithSize):
+        * dfg/DFGOperations.h:
+        (JSC::DFG::operationNewTypedArrayWithSizeForType):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileNewTypedArray):
+        * dfg/DFGSpeculativeJIT.h:
+        (JSC::DFG::SpeculativeJIT::callOperation):
+        (JSC::DFG::SpeculativeJIT::emitAllocateBasicStorage): Deleted.
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray):
+        (JSC::FTL::DFG::LowerDFGToB3::initializeArrayElements):
+        (JSC::FTL::DFG::LowerDFGToB3::splatWords):
+        (JSC::FTL::DFG::LowerDFGToB3::allocateBasicStorageAndGetEnd): Deleted.
+        (JSC::FTL::DFG::LowerDFGToB3::allocateBasicStorage): Deleted.
+        * heap/CopyToken.h:
+        * heap/SlotVisitor.cpp:
+        (JSC::SlotVisitor::markAuxiliary):
+        * jit/JITOperations.h:
+        * runtime/JSArrayBufferView.cpp:
+        (JSC::JSArrayBufferView::ConstructionContext::ConstructionContext):
+        (JSC::JSArrayBufferView::JSArrayBufferView):
+        * runtime/JSArrayBufferView.h:
+        * runtime/JSGenericTypedArrayView.h:
+        * runtime/JSGenericTypedArrayViewInlines.h:
+        (JSC::JSGenericTypedArrayView<Adaptor>::createWithFastVector):
+        (JSC::JSGenericTypedArrayView<Adaptor>::visitChildren):
+        (JSC::JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory):
+        (JSC::JSGenericTypedArrayView<Adaptor>::copyBackingStore): Deleted.
+
 2016-09-06  Michael Catanzaro  <mcatanzaro@igalia.com>
 
         Silence GCC warning spam introduced in r205462
index b387aa6..20ae52b 100644 (file)
@@ -134,7 +134,7 @@ ALWAYS_INLINE static void JIT_OPERATION operationPutByValInternal(ExecState* exe
 }
 
 template<typename ViewClass>
-char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size)
+char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size, char* vector)
 {
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
@@ -144,6 +144,10 @@ char* newTypedArrayWithSize(ExecState* exec, Structure* structure, int32_t size)
         throwException(exec, scope, createRangeError(exec, ASCIILiteral("Requested length is negative")));
         return 0;
     }
+    
+    if (vector)
+        return bitwise_cast<char*>(ViewClass::createWithFastVector(exec, structure, size, vector));
+    
     return bitwise_cast<char*>(ViewClass::create(exec, structure, size));
 }
 
@@ -958,9 +962,9 @@ char* JIT_OPERATION operationNewArrayBuffer(ExecState* exec, Structure* arrayStr
 }
 
 char* JIT_OPERATION operationNewInt8ArrayWithSize(
-    ExecState* exec, Structure* structure, int32_t length)
+    ExecState* exec, Structure* structure, int32_t length, char* vector)
 {
-    return newTypedArrayWithSize<JSInt8Array>(exec, structure, length);
+    return newTypedArrayWithSize<JSInt8Array>(exec, structure, length, vector);
 }
 
 char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(
@@ -972,9 +976,9 @@ char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(
 }
 
 char* JIT_OPERATION operationNewInt16ArrayWithSize(
-    ExecState* exec, Structure* structure, int32_t length)
+    ExecState* exec, Structure* structure, int32_t length, char* vector)
 {
-    return newTypedArrayWithSize<JSInt16Array>(exec, structure, length);
+    return newTypedArrayWithSize<JSInt16Array>(exec, structure, length, vector);
 }
 
 char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(
@@ -986,9 +990,9 @@ char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(
 }
 
 char* JIT_OPERATION operationNewInt32ArrayWithSize(
-    ExecState* exec, Structure* structure, int32_t length)
+    ExecState* exec, Structure* structure, int32_t length, char* vector)
 {
-    return newTypedArrayWithSize<JSInt32Array>(exec, structure, length);
+    return newTypedArrayWithSize<JSInt32Array>(exec, structure, length, vector);
 }
 
 char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(
@@ -1000,9 +1004,9 @@ char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(
 }
 
 char* JIT_OPERATION operationNewUint8ArrayWithSize(
-    ExecState* exec, Structure* structure, int32_t length)
+    ExecState* exec, Structure* structure, int32_t length, char* vector)
 {
-    return newTypedArrayWithSize<JSUint8Array>(exec, structure, length);
+    return newTypedArrayWithSize<JSUint8Array>(exec, structure, length, vector);
 }
 
 char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(
@@ -1014,9 +1018,9 @@ char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(
 }
 
 char* JIT_OPERATION operationNewUint8ClampedArrayWithSize(
-    ExecState* exec, Structure* structure, int32_t length)
+    ExecState* exec, Structure* structure, int32_t length, char* vector)
 {
-    return newTypedArrayWithSize<JSUint8ClampedArray>(exec, structure, length);
+    return newTypedArrayWithSize<JSUint8ClampedArray>(exec, structure, length, vector);
 }
 
 char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(
@@ -1028,9 +1032,9 @@ char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(
 }
 
 char* JIT_OPERATION operationNewUint16ArrayWithSize(
-    ExecState* exec, Structure* structure, int32_t length)
+    ExecState* exec, Structure* structure, int32_t length, char* vector)
 {
-    return newTypedArrayWithSize<JSUint16Array>(exec, structure, length);
+    return newTypedArrayWithSize<JSUint16Array>(exec, structure, length, vector);
 }
 
 char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(
@@ -1042,9 +1046,9 @@ char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(
 }
 
 char* JIT_OPERATION operationNewUint32ArrayWithSize(
-    ExecState* exec, Structure* structure, int32_t length)
+    ExecState* exec, Structure* structure, int32_t length, char* vector)
 {
-    return newTypedArrayWithSize<JSUint32Array>(exec, structure, length);
+    return newTypedArrayWithSize<JSUint32Array>(exec, structure, length, vector);
 }
 
 char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(
@@ -1056,9 +1060,9 @@ char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(
 }
 
 char* JIT_OPERATION operationNewFloat32ArrayWithSize(
-    ExecState* exec, Structure* structure, int32_t length)
+    ExecState* exec, Structure* structure, int32_t length, char* vector)
 {
-    return newTypedArrayWithSize<JSFloat32Array>(exec, structure, length);
+    return newTypedArrayWithSize<JSFloat32Array>(exec, structure, length, vector);
 }
 
 char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(
@@ -1070,9 +1074,9 @@ char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(
 }
 
 char* JIT_OPERATION operationNewFloat64ArrayWithSize(
-    ExecState* exec, Structure* structure, int32_t length)
+    ExecState* exec, Structure* structure, int32_t length, char* vector)
 {
-    return newTypedArrayWithSize<JSFloat64Array>(exec, structure, length);
+    return newTypedArrayWithSize<JSFloat64Array>(exec, structure, length, vector);
 }
 
 char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(
index 2c392c5..65ebd9d 100644 (file)
@@ -71,23 +71,23 @@ char* JIT_OPERATION operationNewArray(ExecState*, Structure*, void*, size_t) WTF
 char* JIT_OPERATION operationNewArrayBuffer(ExecState*, Structure*, size_t, size_t) WTF_INTERNAL;
 char* JIT_OPERATION operationNewEmptyArray(ExecState*, Structure*) WTF_INTERNAL;
 char* JIT_OPERATION operationNewArrayWithSize(ExecState*, Structure*, int32_t, Butterfly*) WTF_INTERNAL;
-char* JIT_OPERATION operationNewInt8ArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL;
+char* JIT_OPERATION operationNewInt8ArrayWithSize(ExecState*, Structure*, int32_t, char*) WTF_INTERNAL;
 char* JIT_OPERATION operationNewInt8ArrayWithOneArgument(ExecState*, Structure*, EncodedJSValue) WTF_INTERNAL;
-char* JIT_OPERATION operationNewInt16ArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL;
+char* JIT_OPERATION operationNewInt16ArrayWithSize(ExecState*, Structure*, int32_t, char*) WTF_INTERNAL;
 char* JIT_OPERATION operationNewInt16ArrayWithOneArgument(ExecState*, Structure*, EncodedJSValue) WTF_INTERNAL;
-char* JIT_OPERATION operationNewInt32ArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL;
+char* JIT_OPERATION operationNewInt32ArrayWithSize(ExecState*, Structure*, int32_t, char*) WTF_INTERNAL;
 char* JIT_OPERATION operationNewInt32ArrayWithOneArgument(ExecState*, Structure*, EncodedJSValue) WTF_INTERNAL;
-char* JIT_OPERATION operationNewUint8ArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL;
+char* JIT_OPERATION operationNewUint8ArrayWithSize(ExecState*, Structure*, int32_t, char*) WTF_INTERNAL;
 char* JIT_OPERATION operationNewUint8ArrayWithOneArgument(ExecState*, Structure*, EncodedJSValue) WTF_INTERNAL;
-char* JIT_OPERATION operationNewUint8ClampedArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL;
+char* JIT_OPERATION operationNewUint8ClampedArrayWithSize(ExecState*, Structure*, int32_t, char*) WTF_INTERNAL;
 char* JIT_OPERATION operationNewUint8ClampedArrayWithOneArgument(ExecState*, Structure*, EncodedJSValue) WTF_INTERNAL;
-char* JIT_OPERATION operationNewUint16ArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL;
+char* JIT_OPERATION operationNewUint16ArrayWithSize(ExecState*, Structure*, int32_t, char*) WTF_INTERNAL;
 char* JIT_OPERATION operationNewUint16ArrayWithOneArgument(ExecState*, Structure*, EncodedJSValue) WTF_INTERNAL;
-char* JIT_OPERATION operationNewUint32ArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL;
+char* JIT_OPERATION operationNewUint32ArrayWithSize(ExecState*, Structure*, int32_t, char*) WTF_INTERNAL;
 char* JIT_OPERATION operationNewUint32ArrayWithOneArgument(ExecState*, Structure*, EncodedJSValue) WTF_INTERNAL;
-char* JIT_OPERATION operationNewFloat32ArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL;
+char* JIT_OPERATION operationNewFloat32ArrayWithSize(ExecState*, Structure*, int32_t, char*) WTF_INTERNAL;
 char* JIT_OPERATION operationNewFloat32ArrayWithOneArgument(ExecState*, Structure*, EncodedJSValue) WTF_INTERNAL;
-char* JIT_OPERATION operationNewFloat64ArrayWithSize(ExecState*, Structure*, int32_t) WTF_INTERNAL;
+char* JIT_OPERATION operationNewFloat64ArrayWithSize(ExecState*, Structure*, int32_t, char*) WTF_INTERNAL;
 char* JIT_OPERATION operationNewFloat64ArrayWithOneArgument(ExecState*, Structure*, EncodedJSValue) WTF_INTERNAL;
 void JIT_OPERATION operationPutByValStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL;
 void JIT_OPERATION operationPutByValNonStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue) WTF_INTERNAL;
@@ -198,7 +198,7 @@ char* JIT_OPERATION triggerOSREntryNow(ExecState*, unsigned bytecodeIndex) WTF_I
 
 } // extern "C"
 
-inline P_JITOperation_EStZ operationNewTypedArrayWithSizeForType(TypedArrayType type)
+inline P_JITOperation_EStZP operationNewTypedArrayWithSizeForType(TypedArrayType type)
 {
     switch (type) {
     case TypeInt8:
index 87fe277..6c1c8ed 100644 (file)
@@ -7180,6 +7180,8 @@ void SpeculativeJIT::compileNewTypedArray(Node* node)
     GPRReg scratchGPR2 = scratch2.gpr();
     
     JITCompiler::JumpList slowCases;
+    
+    m_jit.move(TrustedImmPtr(0), storageGPR);
 
     slowCases.append(m_jit.branch32(
         MacroAssembler::Above, sizeGPR, TrustedImm32(JSArrayBufferView::fastSizeLimit)));
@@ -7191,26 +7193,10 @@ void SpeculativeJIT::compileNewTypedArray(Node* node)
         m_jit.add32(TrustedImm32(7), scratchGPR);
         m_jit.and32(TrustedImm32(~7), scratchGPR);
     }
-    slowCases.append(
-        emitAllocateBasicStorage(scratchGPR, storageGPR));
-    
-    m_jit.subPtr(scratchGPR, storageGPR);
-    
-    emitAllocateJSObject<JSArrayBufferView>(
-        resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR, scratchGPR2,
-        slowCases);
-    
-    m_jit.storePtr(
-        storageGPR,
-        MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfVector()));
-    m_jit.store32(
-        sizeGPR,
-        MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfLength()));
-    m_jit.store32(
-        TrustedImm32(FastTypedArray),
-        MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfMode()));
+    m_jit.emitAllocateVariableSized(
+        storageGPR, m_jit.vm()->heap.subspaceForAuxiliaryData(), scratchGPR, scratchGPR,
+        scratchGPR2, slowCases);
     
-#if USE(JSVALUE32_64)
     MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, sizeGPR);
     m_jit.move(sizeGPR, scratchGPR);
     if (elementSize(type) != 4) {
@@ -7230,11 +7216,24 @@ void SpeculativeJIT::compileNewTypedArray(Node* node)
         MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesFour));
     m_jit.branchTest32(MacroAssembler::NonZero, scratchGPR).linkTo(loop, &m_jit);
     done.link(&m_jit);
-#endif // USE(JSVALUE32_64)
+    
+    emitAllocateJSObject<JSArrayBufferView>(
+        resultGPR, TrustedImmPtr(structure), TrustedImmPtr(0), scratchGPR, scratchGPR2,
+        slowCases);
+    
+    m_jit.storePtr(
+        storageGPR,
+        MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfVector()));
+    m_jit.store32(
+        sizeGPR,
+        MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfLength()));
+    m_jit.store32(
+        TrustedImm32(FastTypedArray),
+        MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfMode()));
     
     addSlowPathGenerator(slowPathCall(
         slowCases, this, operationNewTypedArrayWithSizeForType(type),
-        resultGPR, structure, sizeGPR));
+        resultGPR, structure, sizeGPR, storageGPR));
     
     cellResult(resultGPR, node);
 }
index 5be01c9..7a849c7 100644 (file)
@@ -988,19 +988,19 @@ public:
         m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure));
         return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, GPRReg arg2)
+    JITCompiler::Call callOperation(P_JITOperation_EStZP operation, GPRReg result, Structure* structure, GPRReg arg2, GPRReg arg3)
     {
-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2);
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), arg2, arg3);
         return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, Structure* structure, size_t arg2)
+    JITCompiler::Call callOperation(P_JITOperation_EStZP operation, GPRReg result, Structure* structure, size_t arg2, GPRReg arg3)
     {
-        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2));
+        m_jit.setupArgumentsWithExecState(TrustedImmPtr(structure), TrustedImm32(arg2), arg3);
         return appendCallSetResult(operation, result);
     }
-    JITCompiler::Call callOperation(P_JITOperation_EStZ operation, GPRReg result, GPRReg arg1, GPRReg arg2)
+    JITCompiler::Call callOperation(P_JITOperation_EStZP operation, GPRReg result, GPRReg arg1, GPRReg arg2, GPRReg arg3)
     {
-        m_jit.setupArgumentsWithExecState(arg1, arg2);
+        m_jit.setupArgumentsWithExecState(arg1, arg2, arg3);
         return appendCallSetResult(operation, result);
     }
     JITCompiler::Call callOperation(P_JITOperation_EStZB operation, GPRReg result, Structure* structure, GPRReg arg2, GPRReg butterfly)
@@ -2550,31 +2550,6 @@ public:
     void moveFalseTo(GPRReg);
     void blessBoolean(GPRReg);
     
-    // size can be an immediate or a register, and must be in bytes. If size is a register,
-    // it must be a different register than resultGPR. Emits code that place a pointer to
-    // the end of the allocation. The returned jump is the jump to the slow path.
-    template<typename SizeType>
-    MacroAssembler::Jump emitAllocateBasicStorage(SizeType size, GPRReg resultGPR)
-    {
-        CopiedAllocator* copiedAllocator = &m_jit.vm()->heap.storageAllocator();
-
-        // It's invalid to allocate zero bytes in CopiedSpace. 
-#ifndef NDEBUG
-        m_jit.move(size, resultGPR);
-        MacroAssembler::Jump nonZeroSize = m_jit.branchTest32(MacroAssembler::NonZero, resultGPR);
-        m_jit.abortWithReason(DFGBasicStorageAllocatorZeroSize);
-        nonZeroSize.link(&m_jit);
-#endif
-
-        m_jit.loadPtr(&copiedAllocator->m_currentRemaining, resultGPR);
-        MacroAssembler::Jump slowPath = m_jit.branchSubPtr(JITCompiler::Signed, size, resultGPR);
-        m_jit.storePtr(resultGPR, &copiedAllocator->m_currentRemaining);
-        m_jit.negPtr(resultGPR);
-        m_jit.addPtr(JITCompiler::AbsoluteAddress(&copiedAllocator->m_currentPayloadEnd), resultGPR);
-        
-        return slowPath;
-    }
-
     // Allocator for a cell of a specific size.
     template <typename StructureType> // StructureType can be GPR or ImmPtr.
     void emitAllocateJSCell(
index e4a6f14..5b2e20c 100644 (file)
@@ -4132,6 +4132,8 @@ private:
             LBasicBlock nonZeroCase = m_out.newBlock();
             LBasicBlock slowCase = m_out.newBlock();
             LBasicBlock continuation = m_out.newBlock();
+            
+            ValueFromBlock noStorage = m_out.anchor(m_out.intPtrZero);
 
             m_out.branch(
                 m_out.above(size, m_out.constInt32(JSArrayBufferView::fastSizeLimit)),
@@ -4151,7 +4153,18 @@ private:
                     m_out.constIntPtr(~static_cast<intptr_t>(7)));
             }
         
-            LValue storage = allocateBasicStorage(byteSize, slowCase);
+            LValue allocator = allocatorForSize(
+                vm().heap.subspaceForAuxiliaryData(), byteSize, slowCase);
+            LValue storage = allocateHeapCell(allocator, slowCase);
+            
+            splatWords(
+                storage,
+                m_out.int32Zero,
+                m_out.castToInt32(m_out.lShr(byteSize, m_out.constIntPtr(3))),
+                m_out.int64Zero,
+                m_heaps.typedArrayProperties);
+
+            ValueFromBlock haveStorage = m_out.anchor(storage);
 
             LValue fastResultValue =
                 allocateObject<JSArrayBufferView>(structure, m_out.intPtrZero, slowCase);
@@ -4159,19 +4172,21 @@ private:
             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 storageValue = m_out.phi(pointerType(), noStorage, haveStorage);
 
             LValue slowResultValue = lazySlowPath(
                 [=] (const Vector<Location>& locations) -> RefPtr<LazySlowPath::Generator> {
                     return createLazyCallGenerator(
                         operationNewTypedArrayWithSizeForType(type), locations[0].directGPR(),
-                        CCallHelpers::TrustedImmPtr(structure), locations[1].directGPR());
+                        CCallHelpers::TrustedImmPtr(structure), locations[1].directGPR(),
+                        locations[2].directGPR());
                 },
-                size);
+                size, storageValue);
             ValueFromBlock slowResult = m_out.anchor(slowResultValue);
             m_out.jump(continuation);
 
@@ -7785,31 +7800,39 @@ private:
         else
             hole = m_out.constInt64(JSValue::encode(JSValue()));
         
+        splatWords(butterfly, begin, end, hole, heap->atAnyIndex());
+    }
+    
+    void splatWords(LValue base, LValue begin, LValue end, LValue value, const AbstractHeap& heap)
+    {
         const uint64_t unrollingLimit = 10;
         if (begin->hasInt() && end->hasInt()) {
             uint64_t beginConst = static_cast<uint64_t>(begin->asInt());
             uint64_t endConst = static_cast<uint64_t>(end->asInt());
             
             if (endConst - beginConst <= unrollingLimit) {
-                for (uint64_t i = beginConst; i < endConst; ++i)
-                    m_out.store64(hole, butterfly, heap->at(i));
+                for (uint64_t i = beginConst; i < endConst; ++i) {
+                    LValue pointer = m_out.add(base, m_out.constIntPtr(i * sizeof(uint64_t)));
+                    m_out.store64(value, TypedPointer(heap, pointer));
+                }
                 return;
             }
         }
 
-        // Doubles must be initialized to PNaN.
         LBasicBlock initLoop = m_out.newBlock();
         LBasicBlock initDone = m_out.newBlock();
         
+        LBasicBlock lastNext = m_out.insertNewBlocksBefore(initLoop);
+        
         ValueFromBlock originalIndex = m_out.anchor(end);
-        ValueFromBlock originalPointer = m_out.anchor(butterfly);
+        ValueFromBlock originalPointer = m_out.anchor(base);
         m_out.branch(m_out.notEqual(end, begin), unsure(initLoop), unsure(initDone));
         
-        LBasicBlock initLastNext = m_out.appendTo(initLoop, initDone);
+        m_out.appendTo(initLoop, initDone);
         LValue index = m_out.phi(Int32, originalIndex);
         LValue pointer = m_out.phi(pointerType(), originalPointer);
         
-        m_out.store64(hole, TypedPointer(heap->atAnyIndex(), pointer));
+        m_out.store64(value, TypedPointer(heap, pointer));
         
         LValue nextIndex = m_out.sub(index, m_out.int32One);
         m_out.addIncomingToPhi(index, m_out.anchor(nextIndex));
@@ -7817,7 +7840,7 @@ private:
         m_out.branch(
             m_out.notEqual(nextIndex, begin), unsure(initLoop), unsure(initDone));
         
-        m_out.appendTo(initDone, initLastNext);
+        m_out.appendTo(initDone, lastNext);
     }
     
     LValue allocatePropertyStorage(LValue object, Structure* previousStructure)
@@ -8595,32 +8618,6 @@ private:
         return allocateObject(allocator, structure, butterfly, slowPath);
     }
     
-    // Returns a pointer to the end of the allocation.
-    LValue allocateBasicStorageAndGetEnd(LValue size, LBasicBlock slowPath)
-    {
-        CopiedAllocator& allocator = vm().heap.storageAllocator();
-        
-        LBasicBlock success = m_out.newBlock();
-        
-        LValue remaining = m_out.loadPtr(m_out.absolute(&allocator.m_currentRemaining));
-        LValue newRemaining = m_out.sub(remaining, size);
-        
-        m_out.branch(
-            m_out.lessThan(newRemaining, m_out.intPtrZero),
-            rarely(slowPath), usually(success));
-        
-        m_out.appendTo(success);
-        
-        m_out.storePtr(newRemaining, m_out.absolute(&allocator.m_currentRemaining));
-        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)
     {
         size_t allocationSize = JSFinalObject::allocationSize(structure->inlineCapacity());
index 927b24a..e1d6824 100644 (file)
@@ -29,7 +29,6 @@
 namespace JSC {
 
 enum CopyToken {
-    TypedArrayVectorCopyToken,
     MapBackingStoreCopyToken,
     DirectArgumentsOverridesCopyToken
 };
index 45d886e..9d0d9fd 100644 (file)
@@ -247,6 +247,8 @@ void SlotVisitor::markAuxiliary(const void* base)
 {
     HeapCell* cell = bitwise_cast<HeapCell*>(base);
     
+    ASSERT(cell->heap() == heap());
+    
     if (Heap::testAndSetMarked(m_version, cell)) {
         RELEASE_ASSERT(Heap::isMarked(cell));
         return;
index 16a81d7..216adf5 100644 (file)
@@ -291,6 +291,7 @@ typedef char* (JIT_OPERATION *P_JITOperation_EStPS)(ExecState*, Structure*, void
 typedef char* (JIT_OPERATION *P_JITOperation_EStSS)(ExecState*, Structure*, size_t, size_t);
 typedef char* (JIT_OPERATION *P_JITOperation_EStZ)(ExecState*, Structure*, int32_t);
 typedef char* (JIT_OPERATION *P_JITOperation_EStZB)(ExecState*, Structure*, int32_t, Butterfly*);
+typedef char* (JIT_OPERATION *P_JITOperation_EStZP)(ExecState*, Structure*, int32_t, char*);
 typedef char* (JIT_OPERATION *P_JITOperation_EZZ)(ExecState*, int32_t, int32_t);
 typedef SlowPathReturnType (JIT_OPERATION *Sprt_JITOperation_ECli)(ExecState*, CallLinkInfo*);
 typedef StringImpl* (JIT_OPERATION *T_JITOperation_EJss)(ExecState*, JSString*);
index 6280d25..b0120f4 100644 (file)
@@ -42,6 +42,17 @@ String JSArrayBufferView::toStringName(const JSObject*, ExecState*)
 }
 
 JSArrayBufferView::ConstructionContext::ConstructionContext(
+    Structure* structure, uint32_t length, void* vector)
+    : m_structure(structure)
+    , m_vector(vector)
+    , m_length(length)
+    , m_mode(FastTypedArray)
+    , m_butterfly(nullptr)
+{
+    RELEASE_ASSERT(length <= fastSizeLimit);
+}
+
+JSArrayBufferView::ConstructionContext::ConstructionContext(
     VM& vm, Structure* structure, uint32_t length, uint32_t elementSize,
     InitializationMode mode)
     : m_structure(0)
@@ -50,23 +61,24 @@ JSArrayBufferView::ConstructionContext::ConstructionContext(
 {
     if (length <= fastSizeLimit) {
         // Attempt GC allocation.
-        void* temp = 0;
+        void* temp;
         size_t size = sizeOf(length, elementSize);
-        // CopiedSpace only allows non-zero size allocations.
-        if (size && !vm.heap.tryAllocateStorage(0, size, &temp))
-            return;
+        if (size) {
+            temp = vm.heap.tryAllocateAuxiliary(nullptr, size);
+            if (!temp)
+                return;
+        } else
+            temp = nullptr;
 
         m_structure = structure;
         m_vector = temp;
         m_mode = FastTypedArray;
 
-#if USE(JSVALUE32_64)
         if (mode == ZeroFill) {
             uint64_t* asWords = static_cast<uint64_t*>(m_vector);
             for (unsigned i = size / sizeof(uint64_t); i--;)
                 asWords[i] = 0;
         }
-#endif // USE(JSVALUE32_64)
         
         return;
     }
@@ -118,7 +130,7 @@ JSArrayBufferView::JSArrayBufferView(VM& vm, ConstructionContext& context)
     , m_length(context.length())
     , m_mode(context.mode())
 {
-    m_vector.setWithoutBarrier(static_cast<char*>(context.vector()));
+    m_vector.setWithoutBarrier(context.vector());
 }
 
 void JSArrayBufferView::finishCreation(VM& vm)
index 2aa62a3..36a8368 100644 (file)
@@ -26,7 +26,7 @@
 #ifndef JSArrayBufferView_h
 #define JSArrayBufferView_h
 
-#include "CopyBarrier.h"
+#include "AuxiliaryBarrier.h"
 #include "JSObject.h"
 
 namespace JSC {
@@ -119,6 +119,9 @@ protected:
         
         JS_EXPORT_PRIVATE ConstructionContext(VM&, Structure*, uint32_t length, uint32_t elementSize, InitializationMode = ZeroFill);
         
+        // This is only for constructing fast typed arrays. It's used by the JIT's slow path.
+        ConstructionContext(Structure*, uint32_t length, void* vector);
+        
         JS_EXPORT_PRIVATE ConstructionContext(
             VM&, Structure*, PassRefPtr<ArrayBuffer>,
             unsigned byteOffset, unsigned length);
@@ -182,7 +185,7 @@ protected:
 
     static String toStringName(const JSObject*, ExecState*);
 
-    CopyBarrier<char> m_vector; // this is really a void*, but void would not work here.
+    AuxiliaryBarrier<void*> m_vector;
     uint32_t m_length;
     TypedArrayMode m_mode;
 };
index cea7a3b..4f0000d 100644 (file)
@@ -106,6 +106,7 @@ protected:
     
 public:
     static JSGenericTypedArrayView* create(ExecState*, Structure*, unsigned length);
+    static JSGenericTypedArrayView* createWithFastVector(ExecState*, Structure*, unsigned length, void* vector);
     static JSGenericTypedArrayView* createUninitialized(ExecState*, Structure*, unsigned length);
     static JSGenericTypedArrayView* create(ExecState*, Structure*, PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned length);
     static JSGenericTypedArrayView* create(VM&, Structure*, PassRefPtr<typename Adaptor::ViewType> impl);
@@ -287,7 +288,6 @@ protected:
 
     static size_t estimatedSize(JSCell*);
     static void visitChildren(JSCell*, SlotVisitor&);
-    static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
 
     // Allocates the full-on native buffer and moves data into the C heap if
     // necessary. Note that this never allocates in the GC heap.
index d803a08..ea08e8a 100644 (file)
@@ -63,6 +63,20 @@ JSGenericTypedArrayView<Adaptor>* JSGenericTypedArrayView<Adaptor>::create(
 }
 
 template<typename Adaptor>
+JSGenericTypedArrayView<Adaptor>* JSGenericTypedArrayView<Adaptor>::createWithFastVector(
+    ExecState* exec, Structure* structure, unsigned length, void* vector)
+{
+    VM& vm = exec->vm();
+    ConstructionContext context(structure, length, vector);
+    RELEASE_ASSERT(context);
+    JSGenericTypedArrayView* result =
+        new (NotNull, allocateCell<JSGenericTypedArrayView>(vm.heap))
+        JSGenericTypedArrayView(vm, context);
+    result->finishCreation(vm);
+    return result;
+}
+
+template<typename Adaptor>
 JSGenericTypedArrayView<Adaptor>* JSGenericTypedArrayView<Adaptor>::createUninitialized(
     ExecState* exec, Structure* structure, unsigned length)
 {
@@ -463,7 +477,7 @@ void JSGenericTypedArrayView<Adaptor>::visitChildren(JSCell* cell, SlotVisitor&
     switch (thisObject->m_mode) {
     case FastTypedArray: {
         if (thisObject->m_vector)
-            visitor.copyLater(thisObject, TypedArrayVectorCopyToken, thisObject->m_vector.get(), thisObject->byteSize());
+            visitor.markAuxiliary(thisObject->m_vector.get());
         break;
     }
         
@@ -484,25 +498,6 @@ void JSGenericTypedArrayView<Adaptor>::visitChildren(JSCell* cell, SlotVisitor&
 }
 
 template<typename Adaptor>
-void JSGenericTypedArrayView<Adaptor>::copyBackingStore(
-    JSCell* cell, CopyVisitor& visitor, CopyToken token)
-{
-    JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(cell);
-    
-    if (token == TypedArrayVectorCopyToken
-        && visitor.checkIfShouldCopy(thisObject->m_vector.get())) {
-        ASSERT(thisObject->m_vector);
-        void* oldVector = thisObject->vector();
-        void* newVector = visitor.allocateNewSpace(thisObject->byteSize());
-        memcpy(newVector, oldVector, thisObject->byteSize());
-        thisObject->m_vector.setWithoutBarrier(static_cast<char*>(newVector));
-        visitor.didCopy(oldVector, thisObject->byteSize());
-    }
-    
-    Base::copyBackingStore(thisObject, visitor, token);
-}
-
-template<typename Adaptor>
 ArrayBuffer* JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory(JSArrayBufferView* object)
 {
     JSGenericTypedArrayView* thisObject = jsCast<JSGenericTypedArrayView*>(object);
@@ -550,7 +545,7 @@ ArrayBuffer* JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory(JSArrayBuf
     }
 
     thisObject->butterfly()->indexingHeader()->setArrayBuffer(buffer.get());
-    thisObject->m_vector.setWithoutBarrier(static_cast<char*>(buffer->data()));
+    thisObject->m_vector.setWithoutBarrier(buffer->data());
     thisObject->m_mode = WastefulTypedArray;
     heap->addReference(thisObject, buffer.get());