Title: [220712] trunk/Source
Revision
220712
Author
[email protected]
Date
2017-08-14 11:33:16 -0700 (Mon, 14 Aug 2017)

Log Message

Put the ScopedArgumentsTable's ScopeOffset array in some gigacage
https://bugs.webkit.org/show_bug.cgi?id=174921

Reviewed by Mark Lam.
        
Source/_javascript_Core:

Uses CagedUniquePtr<> to cage the ScopeOffset array.

* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitScopedArgumentsGetByVal):
* runtime/ScopedArgumentsTable.cpp:
(JSC::ScopedArgumentsTable::create):
(JSC::ScopedArgumentsTable::setLength):
* runtime/ScopedArgumentsTable.h:

Source/WTF:

If you want to std::unique_ptr a class that knows that it should be in the Gigacage, then we
would create the Gigacage equivalent of WTF_MAKE_FAST_ALLOCATED and it would just work.
        
But this does not work if we want to std::unique_ptr a primitive type. So, this patch adds a
solution for this problem: CagedUniquePtr<>. This will handle allocation
(CagedUniquePtr<>::create()) and deallocation (in the style of std::unique_ptr). It has three
variants:
        
- Non-array types.
- Arrays that don't have destructors.
- Arrays that have destructors.
        
Just like std::unique_ptr, the array case is triggered by saying "[]" at the end of the type.
        
Unlike std::unique_ptr and most other smart pointers, the whole point of this smart pointer is
to dictate where the thing you're pointing at is allocated. For this reason, it has to know how
to do things like the array destructor protocol. So it creates its own: the CagedUniquePtr for
arrays with destructors is a fat pointer that remembers the length of the array.
        
CagedUniquePtr<> makes it impossible to leak/release the pointer. This is stricter than what
std::unique_ptr does, and is probably appropriate for all of the places where we would use this
type.
        
So far, we only use it for ScopedArgumentsTable::m_arguments, but I suspect that it will be
useful in other places.

* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/CagedUniquePtr.h: Added.
(WTF::CagedUniquePtr::CagedUniquePtr):
(WTF::CagedUniquePtr::create):
(WTF::CagedUniquePtr::operator=):
(WTF::CagedUniquePtr::~CagedUniquePtr):
(WTF::CagedUniquePtr::get const):
(WTF::CagedUniquePtr::getMayBeNull const):
(WTF::CagedUniquePtr::operator== const):
(WTF::CagedUniquePtr::operator!= const):
(WTF::CagedUniquePtr::operator bool const):
(WTF::CagedUniquePtr::operator* const):
(WTF::CagedUniquePtr::operator-> const):
(WTF::CagedUniquePtr::operator[] const):
(WTF::CagedUniquePtr::destroy):
* wtf/Gigacage.cpp:
(Gigacage::tryMallocArray):
(Gigacage::malloc):
(Gigacage::mallocArray):
* wtf/Gigacage.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (220711 => 220712)


--- trunk/Source/_javascript_Core/ChangeLog	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-08-14 18:33:16 UTC (rev 220712)
@@ -1,3 +1,23 @@
+2017-08-12  Filip Pizlo  <[email protected]>
+
+        Put the ScopedArgumentsTable's ScopeOffset array in some gigacage
+        https://bugs.webkit.org/show_bug.cgi?id=174921
+
+        Reviewed by Mark Lam.
+        
+        Uses CagedUniquePtr<> to cage the ScopeOffset array.
+
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitScopedArgumentsGetByVal):
+        * runtime/ScopedArgumentsTable.cpp:
+        (JSC::ScopedArgumentsTable::create):
+        (JSC::ScopedArgumentsTable::setLength):
+        * runtime/ScopedArgumentsTable.h:
+
 2017-08-14  Mark Lam  <[email protected]>
 
         Gardening: fix Windows build.

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (220711 => 220712)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-08-14 18:33:16 UTC (rev 220712)
@@ -6304,6 +6304,7 @@
     m_jit.loadPtr(
         MacroAssembler::Address(scratchReg, ScopedArgumentsTable::offsetOfArguments()),
         scratchReg);
+    m_jit.cage(ScopedArgumentsTable::ArgumentsPtr::kind, scratchReg);
     m_jit.load32(
         MacroAssembler::BaseIndex(scratchReg, propertyReg, MacroAssembler::TimesFour),
         scratchReg);

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (220711 => 220712)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-08-14 18:33:16 UTC (rev 220712)
@@ -3547,10 +3547,10 @@
             LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
             
             LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
-            LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
+            LValue arguments = caged(
+                ScopedArgumentsTable::ArgumentsPtr::kind,
+                m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments));
             
-            // FIXME: I guess we need to cage ScopedArguments?
-            // https://bugs.webkit.org/show_bug.cgi?id=174921
             TypedPointer address = m_out.baseIndex(
                 m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
             LValue scopeOffset = m_out.load32(address);

Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (220711 => 220712)


--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2017-08-14 18:33:16 UTC (rev 220712)
@@ -1544,6 +1544,7 @@
     Jump overflowCase = branch32(AboveOrEqual, property, scratch2);
     loadPtr(Address(base, ScopedArguments::offsetOfScope()), scratch2);
     loadPtr(Address(scratch, ScopedArgumentsTable::offsetOfArguments()), scratch);
+    cage(ScopedArgumentsTable::ArgumentsPtr::kind, scratch);
     load32(BaseIndex(scratch, property, TimesFour), scratch);
     slowCases.append(branch32(Equal, scratch, TrustedImm32(ScopeOffset::invalidOffset)));
     loadValue(BaseIndex(scratch2, scratch, TimesEight, JSEnvironmentRecord::offsetOfVariables()), result);

Modified: trunk/Source/_javascript_Core/runtime/ScopedArgumentsTable.cpp (220711 => 220712)


--- trunk/Source/_javascript_Core/runtime/ScopedArgumentsTable.cpp	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/_javascript_Core/runtime/ScopedArgumentsTable.cpp	2017-08-14 18:33:16 UTC (rev 220712)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -60,7 +60,7 @@
 {
     ScopedArgumentsTable* result = create(vm);
     result->m_length = length;
-    result->m_arguments = std::make_unique<ScopeOffset[]>(length);
+    result->m_arguments = ArgumentsPtr::create(length);
     return result;
 }
 
@@ -75,7 +75,7 @@
 ScopedArgumentsTable* ScopedArgumentsTable::setLength(VM& vm, uint32_t newLength)
 {
     if (LIKELY(!m_locked)) {
-        std::unique_ptr<ScopeOffset[]> newArguments = std::make_unique<ScopeOffset[]>(newLength);
+        ArgumentsPtr newArguments = ArgumentsPtr::create(newLength);
         for (unsigned i = std::min(m_length, newLength); i--;)
             newArguments[i] = m_arguments[i];
         m_length = newLength;

Modified: trunk/Source/_javascript_Core/runtime/ScopedArgumentsTable.h (220711 => 220712)


--- trunk/Source/_javascript_Core/runtime/ScopedArgumentsTable.h	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/_javascript_Core/runtime/ScopedArgumentsTable.h	2017-08-14 18:33:16 UTC (rev 220712)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
 #include "JSCell.h"
 #include "ScopeOffset.h"
 #include <wtf/Assertions.h>
+#include <wtf/CagedUniquePtr.h>
 
 namespace JSC {
 
@@ -77,6 +78,8 @@
     static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(ScopedArgumentsTable, m_length); }
     static ptrdiff_t offsetOfArguments() { return OBJECT_OFFSETOF(ScopedArgumentsTable, m_arguments); }
 
+    typedef CagedUniquePtr<Gigacage::Primitive, ScopeOffset[]> ArgumentsPtr;
+
 private:
     ScopeOffset& at(uint32_t i)
     {
@@ -86,9 +89,7 @@
     
     uint32_t m_length;
     bool m_locked; // Being locked means that there are multiple references to this object and none of them expect to see the others' modifications. This means that modifications need to make a copy first.
-    // FIXME: Allocate this in the primitive gigacage
-    // https://bugs.webkit.org/show_bug.cgi?id=174921
-    std::unique_ptr<ScopeOffset[]> m_arguments;
+    ArgumentsPtr m_arguments;
 };
 
 } // namespace JSC

Modified: trunk/Source/WTF/ChangeLog (220711 => 220712)


--- trunk/Source/WTF/ChangeLog	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/WTF/ChangeLog	2017-08-14 18:33:16 UTC (rev 220712)
@@ -1,3 +1,58 @@
+2017-08-12  Filip Pizlo  <[email protected]>
+
+        Put the ScopedArgumentsTable's ScopeOffset array in some gigacage
+        https://bugs.webkit.org/show_bug.cgi?id=174921
+
+        Reviewed by Mark Lam.
+        
+        If you want to std::unique_ptr a class that knows that it should be in the Gigacage, then we
+        would create the Gigacage equivalent of WTF_MAKE_FAST_ALLOCATED and it would just work.
+        
+        But this does not work if we want to std::unique_ptr a primitive type. So, this patch adds a
+        solution for this problem: CagedUniquePtr<>. This will handle allocation
+        (CagedUniquePtr<>::create()) and deallocation (in the style of std::unique_ptr). It has three
+        variants:
+        
+        - Non-array types.
+        - Arrays that don't have destructors.
+        - Arrays that have destructors.
+        
+        Just like std::unique_ptr, the array case is triggered by saying "[]" at the end of the type.
+        
+        Unlike std::unique_ptr and most other smart pointers, the whole point of this smart pointer is
+        to dictate where the thing you're pointing at is allocated. For this reason, it has to know how
+        to do things like the array destructor protocol. So it creates its own: the CagedUniquePtr for
+        arrays with destructors is a fat pointer that remembers the length of the array.
+        
+        CagedUniquePtr<> makes it impossible to leak/release the pointer. This is stricter than what
+        std::unique_ptr does, and is probably appropriate for all of the places where we would use this
+        type.
+        
+        So far, we only use it for ScopedArgumentsTable::m_arguments, but I suspect that it will be
+        useful in other places.
+
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/CMakeLists.txt:
+        * wtf/CagedUniquePtr.h: Added.
+        (WTF::CagedUniquePtr::CagedUniquePtr):
+        (WTF::CagedUniquePtr::create):
+        (WTF::CagedUniquePtr::operator=):
+        (WTF::CagedUniquePtr::~CagedUniquePtr):
+        (WTF::CagedUniquePtr::get const):
+        (WTF::CagedUniquePtr::getMayBeNull const):
+        (WTF::CagedUniquePtr::operator== const):
+        (WTF::CagedUniquePtr::operator!= const):
+        (WTF::CagedUniquePtr::operator bool const):
+        (WTF::CagedUniquePtr::operator* const):
+        (WTF::CagedUniquePtr::operator-> const):
+        (WTF::CagedUniquePtr::operator[] const):
+        (WTF::CagedUniquePtr::destroy):
+        * wtf/Gigacage.cpp:
+        (Gigacage::tryMallocArray):
+        (Gigacage::malloc):
+        (Gigacage::mallocArray):
+        * wtf/Gigacage.h:
+
 2017-08-11  Ryosuke Niwa  <[email protected]>
 
         Replace DATA_TRANSFER_ITEMS by a runtime flag and add a stub implementation

Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (220711 => 220712)


--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2017-08-14 18:33:16 UTC (rev 220712)
@@ -183,6 +183,7 @@
 		0F5BF1651F2317830029D91D /* NaturalLoops.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NaturalLoops.h; sourceTree = "<group>"; };
 		0F5BF1741F23D49A0029D91D /* Gigacage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Gigacage.cpp; sourceTree = "<group>"; };
 		0F5BF1751F23D49A0029D91D /* Gigacage.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Gigacage.h; sourceTree = "<group>"; };
+		0F5F3D681F3FEBA600B115A2 /* CagedUniquePtr.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CagedUniquePtr.h; sourceTree = "<group>"; };
 		0F60F32D1DFCBD1B00416D6C /* LockedPrintStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LockedPrintStream.cpp; sourceTree = "<group>"; };
 		0F60F32E1DFCBD1B00416D6C /* LockedPrintStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LockedPrintStream.h; sourceTree = "<group>"; };
 		0F66B2801DC97BAB004A1D3F /* ClockType.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClockType.cpp; sourceTree = "<group>"; };
@@ -749,6 +750,7 @@
 				A8A47267151A825A004123FF /* BumpPointerAllocator.h */,
 				EB95E1EF161A72410089A2F5 /* ByteOrder.h */,
 				0FEC3C4F1F323C6800F59B6C /* CagedPtr.h */,
+				0F5F3D681F3FEBA600B115A2 /* CagedUniquePtr.h */,
 				A8A4726A151A825A004123FF /* CheckedArithmetic.h */,
 				A8A4726B151A825A004123FF /* CheckedBoolean.h */,
 				0F66B2801DC97BAB004A1D3F /* ClockType.cpp */,

Modified: trunk/Source/WTF/wtf/CMakeLists.txt (220711 => 220712)


--- trunk/Source/WTF/wtf/CMakeLists.txt	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/WTF/wtf/CMakeLists.txt	2017-08-14 18:33:16 UTC (rev 220712)
@@ -14,6 +14,7 @@
     ByteOrder.h
     CPUTime.h
     CagedPtr.h
+    CagedUniquePtr.h
     ClockType.h
     CompilationThread.h
     Compiler.h

Modified: trunk/Source/WTF/wtf/CagedPtr.h (220711 => 220712)


--- trunk/Source/WTF/wtf/CagedPtr.h	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/WTF/wtf/CagedPtr.h	2017-08-14 18:33:16 UTC (rev 220712)
@@ -73,7 +73,7 @@
     template<typename IndexType>
     T& operator[](IndexType index) const { return get()[index]; }
     
-private:
+protected:
     T* m_ptr;
 };
 

Added: trunk/Source/WTF/wtf/CagedUniquePtr.h (0 => 220712)


--- trunk/Source/WTF/wtf/CagedUniquePtr.h	                        (rev 0)
+++ trunk/Source/WTF/wtf/CagedUniquePtr.h	2017-08-14 18:33:16 UTC (rev 220712)
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2017 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. AND ITS CONTRIBUTORS ``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 ITS 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.
+ */
+
+#pragma once
+
+#include <wtf/CagedPtr.h>
+
+namespace WTF {
+
+template<Gigacage::Kind kind, typename T, typename Enable = void>
+class CagedUniquePtr : public CagedPtr<kind, T> {
+public:
+    CagedUniquePtr(T* ptr = nullptr)
+        : CagedPtr<kind, T>(ptr)
+    {
+    }
+    
+    CagedUniquePtr(CagedUniquePtr&& ptr)
+        : CagedPtr<kind, T>(ptr.m_ptr)
+    {
+        ptr.m_ptr = nullptr;
+    }
+    
+    CagedUniquePtr(const CagedUniquePtr&) = delete;
+    
+    template<typename... Arguments>
+    static CagedUniquePtr create(Arguments&&... arguments)
+    {
+        T* result = static_cast<T*>(Gigacage::malloc(kind, sizeof(T)));
+        new (result) T(std::forward<Arguments>(arguments)...);
+        return CagedUniquePtr(result);
+    }
+    
+    CagedUniquePtr& operator=(CagedUniquePtr&& ptr)
+    {
+        destroy();
+        this->m_ptr = ptr.m_ptr;
+        ptr.m_ptr = nullptr;
+        return *this;
+    }
+    
+    CagedUniquePtr& operator=(const CagedUniquePtr&) = delete;
+    
+    ~CagedUniquePtr()
+    {
+        destroy();
+    }
+    
+private:
+    void destroy()
+    {
+        if (!this->m_ptr)
+            return;
+        this->m_ptr->~T();
+        Gigacage::free(kind, this->m_ptr);
+    }
+};
+
+template<Gigacage::Kind kind, typename T>
+class CagedUniquePtr<kind, T[], typename std::enable_if<std::is_trivially_destructible<T>::value>::type> : public CagedPtr<kind, T> {
+public:
+    CagedUniquePtr() : CagedPtr<kind, T>() { }
+    
+    CagedUniquePtr(T* ptr)
+        : CagedPtr<kind, T>(ptr)
+    {
+    }
+    
+    CagedUniquePtr(CagedUniquePtr&& ptr)
+        : CagedPtr<kind, T>(ptr.m_ptr)
+    {
+        ptr.m_ptr = nullptr;
+    }
+    
+    CagedUniquePtr(const CagedUniquePtr&) = delete;
+    
+    template<typename... Arguments>
+    static CagedUniquePtr create(size_t count, Arguments&&... arguments)
+    {
+        T* result = static_cast<T*>(Gigacage::mallocArray(kind, count, sizeof(T)));
+        while (count--)
+            new (result + count) T(std::forward<Arguments>(arguments)...);
+        return CagedUniquePtr(result);
+    }
+    
+    CagedUniquePtr& operator=(CagedUniquePtr&& ptr)
+    {
+        destroy();
+        this->m_ptr = ptr.m_ptr;
+        ptr.m_ptr = nullptr;
+        return *this;
+    }
+    
+    CagedUniquePtr& operator=(const CagedUniquePtr&) = delete;
+    
+    ~CagedUniquePtr()
+    {
+        destroy();
+    }
+    
+private:
+    void destroy()
+    {
+        if (!this->m_ptr)
+            return;
+        Gigacage::free(kind, this->m_ptr);
+    }
+};
+
+template<Gigacage::Kind kind, typename T>
+class CagedUniquePtr<kind, T[], typename std::enable_if<!std::is_trivially_destructible<T>::value>::type> : public CagedPtr<kind, T> {
+public:
+    CagedUniquePtr() : CagedPtr<kind, T>() { }
+    
+    CagedUniquePtr(T* ptr, size_t count)
+        : CagedPtr<kind, T>(ptr)
+        , m_count(count)
+    {
+    }
+    
+    CagedUniquePtr(CagedUniquePtr&& ptr)
+        : CagedPtr<kind, T>(ptr.m_ptr)
+        , m_count(ptr.m_count)
+    {
+        ptr.clear();
+    }
+    
+    CagedUniquePtr(const CagedUniquePtr&) = delete;
+    
+    template<typename... Arguments>
+    static CagedUniquePtr create(size_t count, Arguments&&... arguments)
+    {
+        T* result = static_cast<T*>(Gigacage::mallocArray(kind, count, sizeof(T)));
+        while (count--)
+            new (result + count) T(std::forward<Arguments>(arguments)...);
+        return CagedUniquePtr(result, count);
+    }
+    
+    CagedUniquePtr& operator=(CagedUniquePtr&& ptr)
+    {
+        destroy();
+        this->m_ptr = ptr.m_ptr;
+        m_count = ptr.m_count;
+        ptr.clear();
+        return *this;
+    }
+    
+    CagedUniquePtr& operator=(const CagedUniquePtr&) = delete;
+    
+    ~CagedUniquePtr()
+    {
+        destroy();
+    }
+    
+    // FIXME: It's weird that we inherit CagedPtr::operator== and friends, which don't do anything
+    // about m_count. It "works" because pointer equality is enough so long as everything is sane, but
+    // it seems like a missed opportunity to assert things.
+    // https://bugs.webkit.org/show_bug.cgi?id=175541
+    
+private:
+    void destroy()
+    {
+        if (!this->m_ptr)
+            return;
+        while (m_count--)
+            this->m_ptr[m_count].~T();
+        Gigacage::free(kind, this->m_ptr);
+    }
+    
+    void clear()
+    {
+        this->m_ptr = nullptr;
+        m_count = 0;
+    }
+    
+    size_t m_count { 0 };
+};
+
+} // namespace WTF
+
+using WTF::CagedUniquePtr;
+

Modified: trunk/Source/WTF/wtf/Gigacage.cpp (220711 => 220712)


--- trunk/Source/WTF/wtf/Gigacage.cpp	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/WTF/wtf/Gigacage.cpp	2017-08-14 18:33:16 UTC (rev 220712)
@@ -118,3 +118,30 @@
 } // namespace Gigacage
 #endif
 
+namespace Gigacage {
+
+void* tryMallocArray(Kind kind, size_t numElements, size_t elementSize)
+{
+    Checked<size_t, RecordOverflow> checkedSize = elementSize;
+    checkedSize *= numElements;
+    if (checkedSize.hasOverflowed())
+        return nullptr;
+    return tryMalloc(kind, checkedSize.unsafeGet());
+}
+
+void* malloc(Kind kind, size_t size)
+{
+    void* result = tryMalloc(kind, size);
+    RELEASE_ASSERT(result);
+    return result;
+}
+
+void* mallocArray(Kind kind, size_t numElements, size_t elementSize)
+{
+    void* result = tryMallocArray(kind, numElements, elementSize);
+    RELEASE_ASSERT(result);
+    return result;
+}
+
+} // namespace Gigacage
+

Modified: trunk/Source/WTF/wtf/Gigacage.h (220711 => 220712)


--- trunk/Source/WTF/wtf/Gigacage.h	2017-08-14 18:32:28 UTC (rev 220711)
+++ trunk/Source/WTF/wtf/Gigacage.h	2017-08-14 18:33:16 UTC (rev 220712)
@@ -102,3 +102,13 @@
 } // namespace Gigacage
 #endif
 
+namespace Gigacage {
+
+WTF_EXPORT_PRIVATE void* tryMallocArray(Kind, size_t numElements, size_t elementSize);
+
+WTF_EXPORT_PRIVATE void* malloc(Kind, size_t);
+WTF_EXPORT_PRIVATE void* mallocArray(Kind, size_t numElements, size_t elementSize);
+
+} // namespace Gigacage
+
+
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to