Title: [226920] trunk/Source
Revision
226920
Author
[email protected]
Date
2018-01-12 15:47:58 -0800 (Fri, 12 Jan 2018)

Log Message

PoisonedWriteBarrier
https://bugs.webkit.org/show_bug.cgi?id=181599
<rdar://problem/36474351>

Reviewed by Mark Lam.

Source/_javascript_Core:

Allow poisoning of WriteBarrier objects, and use this for
WebAssembly because it is perf-neutral, at least on WasmBench on
my MBP. If it indeed is perf-neutral according to the bots, start
using it in more performance-sensitive places.

* heap/HandleTypes.h:
* heap/SlotVisitor.h:
* heap/SlotVisitorInlines.h:
(JSC::SlotVisitor::append):
(JSC::SlotVisitor::appendHidden):
* runtime/JSCJSValue.h:
* runtime/JSCPoison.h:
* runtime/Structure.h:
* runtime/StructureInlines.h:
(JSC::Structure::setPrototypeWithoutTransition):
(JSC::Structure::setGlobalObject):
(JSC::Structure::setPreviousID):
* runtime/WriteBarrier.h:
(JSC::WriteBarrierBase::copyFrom):
(JSC::WriteBarrierBase::get const):
(JSC::WriteBarrierBase::operator* const):
(JSC::WriteBarrierBase::operator-> const):
(JSC::WriteBarrierBase::clear):
(JSC::WriteBarrierBase::slot):
(JSC::WriteBarrierBase::operator bool const):
(JSC::WriteBarrierBase::setWithoutWriteBarrier):
(JSC::WriteBarrierBase::unvalidatedGet const):
(JSC::operator==):
* runtime/WriteBarrierInlines.h:
(JSC::Traits>::set):
(JSC::Traits>::setMayBeNull):
(JSC::Traits>::setEarlyValue):
(JSC::DumbValueTraits<Unknown>>::set):
* wasm/WasmInstance.h:
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
(JSC::JSWebAssemblyInstance::finishCreation):
(JSC::JSWebAssemblyInstance::visitChildren):
(JSC::JSWebAssemblyInstance::create):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::offsetOfPoisonedCallee):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/JSWebAssemblyModule.h:
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::grow):
(JSC::JSWebAssemblyTable::clearFunction):
* wasm/js/JSWebAssemblyTable.h:
* wasm/js/WasmToJS.cpp:
(JSC::Wasm::materializeImportJSCell):
(JSC::Wasm::handleBadI64Use):
(JSC::Wasm::wasmToJS):
* wasm/js/WebAssemblyFunctionBase.h:
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):
* wasm/js/WebAssemblyModuleRecord.h:
* wasm/js/WebAssemblyToJSCallee.h:
* wasm/js/WebAssemblyWrapperFunction.h:

Source/WTF:

Supporting changes needed to allow poisoning of WriteBarrier
objects.

* WTF.xcodeproj/project.pbxproj:
* wtf/DumbPtrTraits.h:
* wtf/DumbValueTraits.h: Copied from Source/WTF/wtf/DumbPtrTraits.h.
(WTF::DumbValueTraits::exchange):
(WTF::DumbValueTraits::swap):
(WTF::DumbValueTraits::unwrap):
* wtf/Forward.h:
* wtf/Poisoned.h:
(WTF::ConstExprPoisonedValueTraits::exchange):
(WTF::ConstExprPoisonedValueTraits::swap):
(WTF::ConstExprPoisonedValueTraits::unwrap):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (226919 => 226920)


--- trunk/Source/_javascript_Core/ChangeLog	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,3 +1,71 @@
+2018-01-12  JF Bastien  <[email protected]>
+
+        PoisonedWriteBarrier
+        https://bugs.webkit.org/show_bug.cgi?id=181599
+        <rdar://problem/36474351>
+
+        Reviewed by Mark Lam.
+
+        Allow poisoning of WriteBarrier objects, and use this for
+        WebAssembly because it is perf-neutral, at least on WasmBench on
+        my MBP. If it indeed is perf-neutral according to the bots, start
+        using it in more performance-sensitive places.
+
+        * heap/HandleTypes.h:
+        * heap/SlotVisitor.h:
+        * heap/SlotVisitorInlines.h:
+        (JSC::SlotVisitor::append):
+        (JSC::SlotVisitor::appendHidden):
+        * runtime/JSCJSValue.h:
+        * runtime/JSCPoison.h:
+        * runtime/Structure.h:
+        * runtime/StructureInlines.h:
+        (JSC::Structure::setPrototypeWithoutTransition):
+        (JSC::Structure::setGlobalObject):
+        (JSC::Structure::setPreviousID):
+        * runtime/WriteBarrier.h:
+        (JSC::WriteBarrierBase::copyFrom):
+        (JSC::WriteBarrierBase::get const):
+        (JSC::WriteBarrierBase::operator* const):
+        (JSC::WriteBarrierBase::operator-> const):
+        (JSC::WriteBarrierBase::clear):
+        (JSC::WriteBarrierBase::slot):
+        (JSC::WriteBarrierBase::operator bool const):
+        (JSC::WriteBarrierBase::setWithoutWriteBarrier):
+        (JSC::WriteBarrierBase::unvalidatedGet const):
+        (JSC::operator==):
+        * runtime/WriteBarrierInlines.h:
+        (JSC::Traits>::set):
+        (JSC::Traits>::setMayBeNull):
+        (JSC::Traits>::setEarlyValue):
+        (JSC::DumbValueTraits<Unknown>>::set):
+        * wasm/WasmInstance.h:
+        * wasm/js/JSWebAssemblyInstance.cpp:
+        (JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
+        (JSC::JSWebAssemblyInstance::finishCreation):
+        (JSC::JSWebAssemblyInstance::visitChildren):
+        (JSC::JSWebAssemblyInstance::create):
+        * wasm/js/JSWebAssemblyInstance.h:
+        (JSC::JSWebAssemblyInstance::offsetOfPoisonedCallee):
+        * wasm/js/JSWebAssemblyMemory.h:
+        * wasm/js/JSWebAssemblyModule.h:
+        * wasm/js/JSWebAssemblyTable.cpp:
+        (JSC::JSWebAssemblyTable::JSWebAssemblyTable):
+        (JSC::JSWebAssemblyTable::grow):
+        (JSC::JSWebAssemblyTable::clearFunction):
+        * wasm/js/JSWebAssemblyTable.h:
+        * wasm/js/WasmToJS.cpp:
+        (JSC::Wasm::materializeImportJSCell):
+        (JSC::Wasm::handleBadI64Use):
+        (JSC::Wasm::wasmToJS):
+        * wasm/js/WebAssemblyFunctionBase.h:
+        * wasm/js/WebAssemblyModuleRecord.cpp:
+        (JSC::WebAssemblyModuleRecord::link):
+        (JSC::WebAssemblyModuleRecord::evaluate):
+        * wasm/js/WebAssemblyModuleRecord.h:
+        * wasm/js/WebAssemblyToJSCallee.h:
+        * wasm/js/WebAssemblyWrapperFunction.h:
+
 2018-01-12  Saam Barati  <[email protected]>
 
         CheckStructure can be incorrectly subsumed by CheckStructureOrEmpty

Modified: trunk/Source/_javascript_Core/heap/HandleTypes.h (226919 => 226920)


--- trunk/Source/_javascript_Core/heap/HandleTypes.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/heap/HandleTypes.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,7 +29,6 @@
 
 namespace JSC {
 
-typedef enum { } Unknown;
 typedef JSValue* HandleSlot;
 
 template<typename T> struct HandleTypes {

Modified: trunk/Source/_javascript_Core/heap/SlotVisitor.h (226919 => 226920)


--- trunk/Source/_javascript_Core/heap/SlotVisitor.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/heap/SlotVisitor.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #include "IterationStatus.h"
 #include "MarkStack.h"
 #include "VisitRaceKey.h"
+#include <wtf/Forward.h>
 #include <wtf/MonotonicTime.h>
 #include <wtf/text/CString.h>
 
@@ -44,7 +45,7 @@
 class UnconditionalFinalizer;
 template<typename T> class Weak;
 class WeakReferenceHarvester;
-template<typename T> class WriteBarrierBase;
+template<typename T, typename Traits> class WriteBarrierBase;
 
 typedef uint32_t HeapVersion;
 
@@ -70,11 +71,11 @@
 
     void append(ConservativeRoots&);
     
-    template<typename T> void append(const WriteBarrierBase<T>&);
-    template<typename T> void appendHidden(const WriteBarrierBase<T>&);
+    template<typename T, typename Traits> void append(const WriteBarrierBase<T, Traits>&);
+    template<typename T, typename Traits> void appendHidden(const WriteBarrierBase<T, Traits>&);
     template<typename Iterator> void append(Iterator begin , Iterator end);
-    void appendValues(const WriteBarrierBase<Unknown>*, size_t count);
-    void appendValuesHidden(const WriteBarrierBase<Unknown>*, size_t count);
+    void appendValues(const WriteBarrierBase<Unknown, DumbValueTraits<Unknown>>*, size_t count);
+    void appendValuesHidden(const WriteBarrierBase<Unknown, DumbValueTraits<Unknown>>*, size_t count);
     
     // These don't require you to prove that you have a WriteBarrier<>. That makes sense
     // for:

Modified: trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h (226919 => 226920)


--- trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/heap/SlotVisitorInlines.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -103,14 +103,14 @@
     appendUnbarriered(weak.get());
 }
 
-template<typename T>
-ALWAYS_INLINE void SlotVisitor::append(const WriteBarrierBase<T>& slot)
+template<typename T, typename Traits>
+ALWAYS_INLINE void SlotVisitor::append(const WriteBarrierBase<T, Traits>& slot)
 {
     appendUnbarriered(slot.get());
 }
 
-template<typename T>
-ALWAYS_INLINE void SlotVisitor::appendHidden(const WriteBarrierBase<T>& slot)
+template<typename T, typename Traits>
+ALWAYS_INLINE void SlotVisitor::appendHidden(const WriteBarrierBase<T, Traits>& slot)
 {
     appendHiddenUnbarriered(slot.get());
 }

Modified: trunk/Source/_javascript_Core/runtime/JSCJSValue.h (226919 => 226920)


--- trunk/Source/_javascript_Core/runtime/JSCJSValue.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/runtime/JSCJSValue.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten ([email protected])
  *  Copyright (C) 2001 Peter Kelly ([email protected])
- *  Copyright (C) 2003-2017 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2018 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -68,8 +68,13 @@
 struct DumpContext;
 struct Instruction;
 struct MethodTable;
+enum class Unknown { };
 
-template <class T> class WriteBarrierBase;
+template <class T, typename Traits> class WriteBarrierBase;
+template<class T>
+using WriteBarrierTraitsSelect = typename std::conditional<std::is_same<T, Unknown>::value,
+    DumbValueTraits<T>, DumbPtrTraits<T>
+>::type;
 
 enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
 enum ECMAMode { StrictMode, NotStrictMode };
@@ -453,7 +458,7 @@
 #endif
 
 private:
-    template <class T> JSValue(WriteBarrierBase<T>);
+    template <class T> JSValue(WriteBarrierBase<T, WriteBarrierTraitsSelect<T>>);
 
     enum HashTableDeletedValueTag { HashTableDeletedValue };
     JSValue(HashTableDeletedValueTag);

Modified: trunk/Source/_javascript_Core/runtime/JSCPoison.h (226919 => 226920)


--- trunk/Source/_javascript_Core/runtime/JSCPoison.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/runtime/JSCPoison.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -51,6 +51,10 @@
     JSWebAssemblyTablePoison,
     StructureTransitionTablePoison,
     UnlinkedSourceCodePoison,
+    WebAssemblyFunctionBasePoison,
+    WebAssemblyModuleRecordPoison,
+    WebAssemblyToJSCalleePoison,
+    WebAssemblyWrapperFunctionPoison,
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/Structure.h (226919 => 226920)


--- trunk/Source/_javascript_Core/runtime/Structure.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/runtime/Structure.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -211,7 +211,7 @@
     PropertyOffset addPropertyWithoutTransition(VM&, PropertyName, unsigned attributes, const Func&);
     template<typename Func>
     PropertyOffset removePropertyWithoutTransition(VM&, PropertyName, const Func&);
-    void setPrototypeWithoutTransition(VM& vm, JSValue prototype) { m_prototype.set(vm, this, prototype); }
+    void setPrototypeWithoutTransition(VM&, JSValue prototype);
         
     bool isDictionary() const { return dictionaryKind() != NoneDictionaryKind; }
     bool isUncacheableDictionary() const { return dictionaryKind() == UncachedDictionaryKind; }
@@ -265,7 +265,7 @@
 
     // NOTE: This method should only be called during the creation of structures, since the global
     // object of a structure is presumed to be immutable in a bunch of places.
-    void setGlobalObject(VM& vm, JSGlobalObject* globalObject) { m_globalObject.set(vm, this, globalObject); }
+    void setGlobalObject(VM&, JSGlobalObject*);
 
     ALWAYS_INLINE bool hasMonoProto() const
     {
@@ -738,13 +738,7 @@
     PropertyTable* takePropertyTableOrCloneIfPinned(VM&);
     PropertyTable* copyPropertyTableForPinning(VM&);
 
-    void setPreviousID(VM& vm, Structure* structure)
-    {
-        if (hasRareData())
-            rareData()->setPreviousID(vm, structure);
-        else
-            m_previousOrRareData.set(vm, this, structure);
-    }
+    void setPreviousID(VM&, Structure*);
 
     void clearPreviousID()
     {

Modified: trunk/Source/_javascript_Core/runtime/StructureInlines.h (226919 => 226920)


--- trunk/Source/_javascript_Core/runtime/StructureInlines.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/runtime/StructureInlines.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -441,11 +441,29 @@
     return remove(propertyName, func);
 }
 
+ALWAYS_INLINE void Structure::setPrototypeWithoutTransition(VM& vm, JSValue prototype)
+{
+    m_prototype.set(vm, this, prototype);
+}
+
+ALWAYS_INLINE void Structure::setGlobalObject(VM& vm, JSGlobalObject* globalObject)
+{
+    m_globalObject.set(vm, this, globalObject);
+}
+
 ALWAYS_INLINE void Structure::setPropertyTable(VM& vm, PropertyTable* table)
 {
     m_propertyTableUnsafe.setMayBeNull(vm, this, table);
 }
 
+ALWAYS_INLINE void Structure::setPreviousID(VM& vm, Structure* structure)
+{
+    if (hasRareData())
+        rareData()->setPreviousID(vm, structure);
+    else
+        m_previousOrRareData.set(vm, this, structure);
+}
+
 ALWAYS_INLINE bool Structure::shouldConvertToPolyProto(const Structure* a, const Structure* b)
 {
     if (!a || !b)

Modified: trunk/Source/_javascript_Core/runtime/WriteBarrier.h (226919 => 226920)


--- trunk/Source/_javascript_Core/runtime/WriteBarrier.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/runtime/WriteBarrier.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -27,6 +27,11 @@
 
 #include "GCAssertions.h"
 #include "HandleTypes.h"
+#include "JSCPoison.h"
+#include <type_traits>
+#include <wtf/DumbPtrTraits.h>
+#include <wtf/DumbValueTraits.h>
+#include <wtf/Poisoned.h>
 
 namespace JSC {
 
@@ -38,7 +43,12 @@
 class VM;
 class JSGlobalObject;
 
-template<class T> class WriteBarrierBase;
+template<class T>
+using WriteBarrierTraitsSelect = typename std::conditional<std::is_same<T, Unknown>::value,
+    DumbValueTraits<T>, DumbPtrTraits<T>
+>::type;
+
+template<class T, typename Traits = WriteBarrierTraitsSelect<T>> class WriteBarrierBase;
 template<> class WriteBarrierBase<JSValue>;
 
 JS_EXPORT_PRIVATE void slowValidateCell(JSCell*);
@@ -66,15 +76,18 @@
 #endif
 
 // We have a separate base class with no constructors for use in Unions.
-template <typename T> class WriteBarrierBase {
+template <typename T, typename Traits> class WriteBarrierBase {
+    using StorageType = typename Traits::StorageType;
+
 public:
     void set(VM&, const JSCell* owner, T* value);
     
     // This is meant to be used like operator=, but is called copyFrom instead, in
     // order to kindly inform the C++ compiler that its advice is not appreciated.
-    void copyFrom(const WriteBarrierBase<T>& other)
+    void copyFrom(const WriteBarrierBase& other)
     {
-        m_cell = other.m_cell;
+        // FIXME add version with different Traits once needed.
+        Traits::exchange(m_cell, other.m_cell);
     }
 
     void setMayBeNull(VM&, const JSCell* owner, T* value);
@@ -86,32 +99,45 @@
     T* get() const
     {
         // Copy m_cell to a local to avoid multiple-read issues. (See <http://webkit.org/b/110854>)
-        JSCell* cell = m_cell;
+        StorageType cell = m_cell;
         if (cell)
-            validateCell(cell);
-        return reinterpret_cast<T*>(static_cast<void*>(cell));
+            validateCell(reinterpret_cast<JSCell*>(static_cast<void*>(Traits::unwrap(cell))));
+        return Traits::unwrap(cell);
     }
 
     T* operator*() const
     {
-        ASSERT(m_cell);
-        validateCell<T>(static_cast<T*>(m_cell));
-        return static_cast<T*>(m_cell);
+        StorageType cell = m_cell;
+        ASSERT(cell);
+        auto unwrapped = Traits::unwrap(cell);
+        validateCell<T>(unwrapped);
+        return Traits::unwrap(unwrapped);
     }
 
     T* operator->() const
     {
-        ASSERT(m_cell);
-        validateCell(static_cast<T*>(m_cell));
-        return static_cast<T*>(m_cell);
+        StorageType cell = m_cell;
+        ASSERT(cell);
+        auto unwrapped = Traits::unwrap(cell);
+        validateCell(unwrapped);
+        return unwrapped;
     }
 
-    void clear() { m_cell = 0; }
+    void clear() { Traits::exchange(m_cell, nullptr); }
+
+    // Slot cannot be used when pointers aren't stored as-is.
+    template<typename BarrierT, typename BarrierTraits, std::enable_if_t<std::is_same<BarrierTraits, DumbPtrTraits<BarrierT>>::value, void*> = nullptr>
+    struct SlotHelper {
+        static BarrierT** reinterpret(typename BarrierTraits::StorageType* cell) { return reinterpret_cast<T**>(cell); }
+    };
+
+    T** slot()
+    {
+        return SlotHelper<T, Traits>::reinterpret(&m_cell);
+    }
     
-    T** slot() { return reinterpret_cast<T**>(&m_cell); }
+    explicit operator bool() const { return !!m_cell; }
     
-    explicit operator bool() const { return m_cell; }
-    
     bool operator!() const { return !m_cell; }
 
     void setWithoutWriteBarrier(T* value)
@@ -119,16 +145,16 @@
 #if ENABLE(WRITE_BARRIER_PROFILING)
         WriteBarrierCounters::usesWithoutBarrierFromCpp.count();
 #endif
-        this->m_cell = reinterpret_cast<JSCell*>(value);
+        Traits::exchange(this->m_cell, value);
     }
 
-    T* unvalidatedGet() const { return reinterpret_cast<T*>(static_cast<void*>(m_cell)); }
+    T* unvalidatedGet() const { return Traits::unwrap(m_cell); }
 
 private:
-    JSCell* m_cell;
+    StorageType m_cell;
 };
 
-template <> class WriteBarrierBase<Unknown> {
+template <> class WriteBarrierBase<Unknown, DumbValueTraits<Unknown>> {
 public:
     void set(VM&, const JSCell* owner, JSValue);
     void setWithoutWriteBarrier(JSValue value)
@@ -165,9 +191,12 @@
     EncodedJSValue m_value;
 };
 
-template <typename T> class WriteBarrier : public WriteBarrierBase<T> {
+template <typename T, typename Traits = WriteBarrierTraitsSelect<T>>
+class WriteBarrier : public WriteBarrierBase<T, Traits> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
+    static constexpr auto poison = Traits::poison;
+
     WriteBarrier()
     {
         this->setWithoutWriteBarrier(0);
@@ -192,9 +221,12 @@
 };
 
 enum UndefinedWriteBarrierTagType { UndefinedWriteBarrierTag };
-template <> class WriteBarrier<Unknown> : public WriteBarrierBase<Unknown> {
+template <>
+class WriteBarrier<Unknown, DumbValueTraits<Unknown>> : public WriteBarrierBase<Unknown, DumbValueTraits<Unknown>> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
+    static constexpr auto poison = DumbValueTraits<Unknown>::poison;
+
     WriteBarrier()
     {
         this->setWithoutWriteBarrier(JSValue());
@@ -216,9 +248,18 @@
     }
 };
 
-template <typename U, typename V> inline bool operator==(const WriteBarrierBase<U>& lhs, const WriteBarrierBase<V>& rhs)
+template <typename U, typename V, typename TraitsU, typename TraitsV>
+inline bool operator==(const WriteBarrierBase<U, TraitsU>& lhs, const WriteBarrierBase<V, TraitsV>& rhs)
 {
     return lhs.get() == rhs.get();
 }
 
+template<uint32_t key, class T>
+using PoisonedWriteBarrierTraitsSelect = typename std::conditional<std::is_same<T, Unknown>::value,
+    WTF::ConstExprPoisonedValueTraits<key, T>, WTF::ConstExprPoisonedPtrTraits<key, T>
+>::type;
+
+template <uint32_t key, typename T>
+using PoisonedWriteBarrier = WriteBarrier<T, PoisonedWriteBarrierTraitsSelect<key, T>>;
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/WriteBarrierInlines.h (226919 => 226920)


--- trunk/Source/_javascript_Core/runtime/WriteBarrierInlines.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/runtime/WriteBarrierInlines.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -30,8 +30,8 @@
 
 namespace JSC {
 
-template <typename T>
-inline void WriteBarrierBase<T>::set(VM& vm, const JSCell* owner, T* value)
+template <typename T, typename Traits>
+inline void WriteBarrierBase<T, Traits>::set(VM& vm, const JSCell* owner, T* value)
 {
     ASSERT(value);
     ASSERT(!Options::useConcurrentJIT() || !isCompilationThread());
@@ -39,8 +39,8 @@
     setEarlyValue(vm, owner, value);
 }
 
-template <typename T>
-inline void WriteBarrierBase<T>::setMayBeNull(VM& vm, const JSCell* owner, T* value)
+template <typename T, typename Traits>
+inline void WriteBarrierBase<T, Traits>::setMayBeNull(VM& vm, const JSCell* owner, T* value)
 {
     if (value)
         validateCell(value);
@@ -47,14 +47,14 @@
     setEarlyValue(vm, owner, value);
 }
 
-template <typename T>
-inline void WriteBarrierBase<T>::setEarlyValue(VM& vm, const JSCell* owner, T* value)
+template <typename T, typename Traits>
+inline void WriteBarrierBase<T, Traits>::setEarlyValue(VM& vm, const JSCell* owner, T* value)
 {
-    this->m_cell = reinterpret_cast<JSCell*>(value);
-    vm.heap.writeBarrier(owner, this->m_cell);
+    Traits::exchange(this->m_cell, value);
+    vm.heap.writeBarrier(owner, static_cast<JSCell*>(value));
 }
 
-inline void WriteBarrierBase<Unknown>::set(VM& vm, const JSCell* owner, JSValue value)
+inline void WriteBarrierBase<Unknown, DumbValueTraits<Unknown>>::set(VM& vm, const JSCell* owner, JSValue value)
 {
     ASSERT(!Options::useConcurrentJIT() || !isCompilationThread());
     m_value = JSValue::encode(value);

Modified: trunk/Source/_javascript_Core/wasm/WasmInstance.h (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/WasmInstance.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/WasmInstance.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -100,7 +100,7 @@
         Instance* targetInstance { nullptr };
         Wasm::WasmEntrypointLoadLocation wasmEntrypoint { nullptr };
         void* wasmToEmbedderStubExecutableAddress { nullptr };
-        void* importFunction { nullptr }; // In a JS embedding, this is a WriteBarrier<JSObject>.
+        void* importFunction { nullptr }; // In a JS embedding, this is a PoisonedBarrier<JSObject>.
     };
     unsigned numImportFunctions() const { return m_numImportFunctions; }
     ImportFunctionInfo* importFunctionInfo(size_t importFunctionNum)

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp	2018-01-12 23:47:58 UTC (rev 226920)
@@ -54,7 +54,7 @@
     , m_instance(WTFMove(instance))
 {
     for (unsigned i = 0; i < this->instance().numImportFunctions(); ++i)
-        new (this->instance().importFunction<WriteBarrier<JSObject>>(i)) WriteBarrier<JSObject>();
+        new (this->instance().importFunction<PoisonedBarrier<JSObject>>(i)) PoisonedBarrier<JSObject>();
 }
 
 void JSWebAssemblyInstance::finishCreation(VM& vm, JSWebAssemblyModule* module, JSModuleNamespaceObject* moduleNamespaceObject)
@@ -65,7 +65,7 @@
     m_module.set(vm, this, module);
     m_moduleNamespaceObject.set(vm, this, moduleNamespaceObject);
     m_callee.set(vm, this, module->callee());
-    
+
     heap()->reportExtraMemoryAllocated(m_instance->extraMemoryAllocated());
 }
 
@@ -88,7 +88,7 @@
     visitor.append(thisObject->m_callee);
     visitor.reportExtraMemoryVisited(thisObject->m_instance->extraMemoryAllocated());
     for (unsigned i = 0; i < thisObject->instance().numImportFunctions(); ++i)
-        visitor.append(*thisObject->instance().importFunction<WriteBarrier<JSObject>>(i)); // This also keeps the functions' JSWebAssemblyInstance alive.
+        visitor.append(*thisObject->instance().importFunction<PoisonedBarrier<JSObject>>(i)); // This also keeps the functions' JSWebAssemblyInstance alive.
 }
 
 void JSWebAssemblyInstance::finalizeCreation(VM& vm, ExecState* exec, Ref<Wasm::CodeBlock>&& wasmCodeBlock)
@@ -236,7 +236,7 @@
             auto* info = jsInstance->instance().importFunctionInfo(numImportFunctions);
             info->targetInstance = calleeInstance;
             info->wasmEntrypoint = wasmEntrypoint;
-            jsInstance->instance().importFunction<WriteBarrier<JSObject>>(numImportFunctions)->set(vm, jsInstance, function);
+            jsInstance->instance().importFunction<PoisonedBarrier<JSObject>>(numImportFunctions)->set(vm, jsInstance, function);
             ++numImportFunctions;
             // v. Append closure to imports.
             break;

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -77,8 +77,11 @@
     }
 
     static size_t offsetOfPoisonedInstance() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_instance); }
-    static size_t offsetOfCallee() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_callee); }
+    static size_t offsetOfPoisonedCallee() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_callee); }
 
+    template<typename T>
+    using PoisonedBarrier = PoisonedWriteBarrier<JSWebAssemblyInstancePoison, T>;
+
 protected:
     JSWebAssemblyInstance(VM&, Structure*, Ref<Wasm::Instance>&&);
     void finishCreation(VM&, JSWebAssemblyModule*, JSModuleNamespaceObject*);
@@ -90,12 +93,12 @@
 
     PoisonedRef<JSWebAssemblyInstancePoison, Wasm::Instance> m_instance;
 
-    WriteBarrier<JSWebAssemblyModule> m_module;
-    WriteBarrier<JSWebAssemblyCodeBlock> m_codeBlock;
-    WriteBarrier<JSModuleNamespaceObject> m_moduleNamespaceObject;
-    WriteBarrier<JSWebAssemblyMemory> m_memory;
-    WriteBarrier<JSWebAssemblyTable> m_table;
-    WriteBarrier<WebAssemblyToJSCallee> m_callee;
+    PoisonedBarrier<JSWebAssemblyModule> m_module;
+    PoisonedBarrier<JSWebAssemblyCodeBlock> m_codeBlock;
+    PoisonedBarrier<JSModuleNamespaceObject> m_moduleNamespaceObject;
+    PoisonedBarrier<JSWebAssemblyMemory> m_memory;
+    PoisonedBarrier<JSWebAssemblyTable> m_table;
+    PoisonedBarrier<WebAssemblyToJSCallee> m_callee;
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.h (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -68,7 +68,7 @@
     static void visitChildren(JSCell*, SlotVisitor&);
 
     PoisonedRef<JSWebAssemblyMemoryPoison, Wasm::Memory> m_memory;
-    WriteBarrier<JSArrayBuffer> m_bufferWrapper;
+    PoisonedWriteBarrier<JSWebAssemblyMemoryPoison, JSArrayBuffer> m_bufferWrapper;
     PoisonedRefPtr<JSWebAssemblyMemoryPoison, ArrayBuffer> m_buffer;
 };
 

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.h (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyModule.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -82,9 +82,13 @@
     static void visitChildren(JSCell*, SlotVisitor&);
 
     PoisonedRef<JSWebAssemblyModulePoison, Wasm::Module> m_module;
-    WriteBarrier<SymbolTable> m_exportSymbolTable;
-    WriteBarrier<JSWebAssemblyCodeBlock> m_codeBlocks[Wasm::NumberOfMemoryModes];
-    WriteBarrier<WebAssemblyToJSCallee> m_callee;
+
+    template<typename T>
+    using PoisonedBarrier = PoisonedWriteBarrier<JSWebAssemblyModulePoison, T>;
+
+    PoisonedBarrier<SymbolTable> m_exportSymbolTable;
+    PoisonedBarrier<JSWebAssemblyCodeBlock> m_codeBlocks[Wasm::NumberOfMemoryModes];
+    PoisonedBarrier<WebAssemblyToJSCallee> m_callee;
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.cpp (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.cpp	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.cpp	2018-01-12 23:47:58 UTC (rev 226920)
@@ -63,9 +63,9 @@
     // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so.
     // But for now, we're not doing that.
     // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=181425
-    m_jsFunctions = MallocPtr<WriteBarrier<JSObject>>::malloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(allocatedLength())).unsafeGet());
+    m_jsFunctions = MallocPtr<PoisonedBarrier<JSObject>>::malloc((sizeof(PoisonedBarrier<JSObject>) * Checked<size_t>(allocatedLength())).unsafeGet());
     for (uint32_t i = 0; i < allocatedLength(); ++i)
-        new(&m_jsFunctions.get()[i]) WriteBarrier<JSObject>();
+        new(&m_jsFunctions.get()[i]) PoisonedBarrier<JSObject>();
 }
 
 void JSWebAssemblyTable::finishCreation(VM& vm)
@@ -104,10 +104,10 @@
     size_t newLength = grew.value();
     if (newLength > m_table->allocatedLength(oldLength))
         // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=181425
-        m_jsFunctions.realloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(m_table->allocatedLength(newLength))).unsafeGet());
+        m_jsFunctions.realloc((sizeof(PoisonedBarrier<JSObject>) * Checked<size_t>(m_table->allocatedLength(newLength))).unsafeGet());
 
     for (size_t i = oldLength; i < m_table->allocatedLength(newLength); ++i)
-        new (&m_jsFunctions.get()[i]) WriteBarrier<JSObject>();
+        new (&m_jsFunctions.get()[i]) PoisonedBarrier<JSObject>();
 
     return true;
 }
@@ -121,7 +121,7 @@
 void JSWebAssemblyTable::clearFunction(uint32_t index)
 {
     m_table->clearFunction(index);
-    m_jsFunctions.get()[index & m_table->mask()] = WriteBarrier<JSObject>();
+    m_jsFunctions.get()[index & m_table->mask()] = PoisonedBarrier<JSObject>();
 }
 
 void JSWebAssemblyTable::setFunction(VM& vm, uint32_t index, WebAssemblyFunction* function)

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.h (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -67,7 +67,11 @@
     static void visitChildren(JSCell*, SlotVisitor&);
 
     PoisonedRef<JSWebAssemblyTablePoison, Wasm::Table> m_table;
-    MallocPtr<WriteBarrier<JSObject>> m_jsFunctions;
+
+    template<typename T>
+    using PoisonedBarrier = PoisonedWriteBarrier<JSWebAssemblyTablePoison, T>;
+
+    MallocPtr<PoisonedBarrier<JSObject>> m_jsFunctions;
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -46,13 +46,14 @@
 
 using JIT = CCallHelpers;
 
-static void materializeImportJSCell(JIT& jit, unsigned importIndex, GPRReg result)
+static void materializeImportJSCell(JIT& jit, unsigned importIndex, GPRReg poison, GPRReg result)
 {
     // We're calling out of the current WebAssembly.Instance. That Instance has a list of all its import functions.
     jit.loadWasmContextInstance(result);
     jit.loadPtr(JIT::Address(result, Instance::offsetOfImportFunction(importIndex)), result);
+    jit.xor64(poison, result);
 }
-    
+
 static Expected<MacroAssemblerCodeRef, BindingFailure> handleBadI64Use(VM* vm, JIT& jit, const Signature& signature, unsigned importIndex)
 {
     unsigned argCount = signature.argumentCount();
@@ -84,9 +85,14 @@
 
         // Store Callee.
         jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR1, Instance::offsetOfOwner()), GPRInfo::argumentGPR1);
-        jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR1, JSWebAssemblyInstance::offsetOfCallee()), GPRInfo::argumentGPR2);
+        jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR1, JSWebAssemblyInstance::offsetOfPoisonedCallee()), GPRInfo::argumentGPR2);
+        jit.move(CCallHelpers::TrustedImm64(JSWebAssemblyInstance::PoisonedBarrier<WebAssemblyToJSCallee>::poison), GPRInfo::argumentGPR3);
+        jit.xor64(GPRInfo::argumentGPR3, GPRInfo::argumentGPR2);
         jit.storePtr(GPRInfo::argumentGPR2, JIT::Address(GPRInfo::callFrameRegister, CallFrameSlot::callee * static_cast<int>(sizeof(Register))));
 
+        // Let's be paranoid on the exception path and zero out the poison instead of leaving it in an argument GPR.
+        jit.move(CCallHelpers::TrustedImm32(0), GPRInfo::argumentGPR3);
+
         auto call = jit.call();
         jit.jumpToExceptionHandler(*vm);
 
@@ -284,10 +290,16 @@
         
         jit.loadWasmContextInstance(GPRInfo::argumentGPR0);
         jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0, Instance::offsetOfOwner()), GPRInfo::argumentGPR0);
-        jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0, JSWebAssemblyInstance::offsetOfCallee()), GPRInfo::argumentGPR0);
+        jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0, JSWebAssemblyInstance::offsetOfPoisonedCallee()), GPRInfo::argumentGPR0);
+        jit.move(CCallHelpers::TrustedImm64(JSWebAssemblyInstance::PoisonedBarrier<WebAssemblyToJSCallee>::poison), GPRInfo::argumentGPR3);
+        jit.xor64(GPRInfo::argumentGPR3, GPRInfo::argumentGPR0);
         jit.storePtr(GPRInfo::argumentGPR0, JIT::Address(GPRInfo::callFrameRegister, CallFrameSlot::callee * static_cast<int>(sizeof(Register))));
         
-        materializeImportJSCell(jit, importIndex, GPRInfo::argumentGPR1);
+        materializeImportJSCell(jit, importIndex, GPRInfo::argumentGPR3, GPRInfo::argumentGPR1);
+        
+        // Let's be paranoid before the call and zero out the poison instead of leaving it in an argument GPR.
+        jit.move(CCallHelpers::TrustedImm32(0), GPRInfo::argumentGPR3);
+
         static_assert(GPRInfo::numberOfArgumentRegisters >= 4, "We rely on this with the call below.");
         jit.setupArgumentsWithExecState(GPRInfo::argumentGPR1, CCallHelpers::TrustedImm32(signatureIndex), CCallHelpers::TrustedImmPtr(buffer));
         auto call = jit.call();
@@ -465,15 +477,24 @@
         }
     }
 
+    GPRReg poison = GPRInfo::argumentGPR1;
+    ASSERT(poison != GPRInfo::argumentGPR0); // Both are used at the same time below.
+
     jit.loadWasmContextInstance(GPRInfo::argumentGPR0);
     jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0, Instance::offsetOfOwner()), GPRInfo::argumentGPR0);
-    jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0, JSWebAssemblyInstance::offsetOfCallee()), GPRInfo::argumentGPR0);
+    jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0, JSWebAssemblyInstance::offsetOfPoisonedCallee()), GPRInfo::argumentGPR0);
+    jit.move(CCallHelpers::TrustedImm64(JSWebAssemblyInstance::PoisonedBarrier<WebAssemblyToJSCallee>::poison), poison);
+    jit.xor64(poison, GPRInfo::argumentGPR0);
     jit.storePtr(GPRInfo::argumentGPR0, JIT::Address(GPRInfo::callFrameRegister, CallFrameSlot::callee * static_cast<int>(sizeof(Register))));
 
     GPRReg importJSCellGPRReg = GPRInfo::regT0; // Callee needs to be in regT0 for slow path below.
+    ASSERT(poison != importJSCellGPRReg);
+
     ASSERT(!wasmCC.m_calleeSaveRegisters.get(importJSCellGPRReg));
+    materializeImportJSCell(jit, importIndex, poison, importJSCellGPRReg);
 
-    materializeImportJSCell(jit, importIndex, importJSCellGPRReg);
+    // Let's be paranoid zero out the poison instead of leaving it in an argument GPR.
+    jit.move(CCallHelpers::TrustedImm32(0), poison);
 
     jit.store64(importJSCellGPRReg, calleeFrame.withOffset(CallFrameSlot::callee * static_cast<int>(sizeof(Register))));
     jit.store32(JIT::TrustedImm32(numberOfParameters), calleeFrame.withOffset(CallFrameSlot::argumentCount * static_cast<int>(sizeof(Register)) + PayloadOffset));

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunctionBase.h (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunctionBase.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunctionBase.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -49,7 +49,8 @@
     static void visitChildren(JSCell*, SlotVisitor&);
     void finishCreation(VM&, NativeExecutable*, unsigned length, const String& name, JSWebAssemblyInstance*);
     WebAssemblyFunctionBase(VM&, JSGlobalObject*, Structure*);
-    WriteBarrier<JSWebAssemblyInstance> m_instance;
+
+    PoisonedWriteBarrier<WebAssemblyFunctionBasePoison, JSWebAssemblyInstance> m_instance;
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp	2018-01-12 23:47:58 UTC (rev 226920)
@@ -110,7 +110,7 @@
             //   ii. (Note: At most one wrapper is created for any closure, so func is unique, even if there are multiple occurrances in the list. Moreover, if the item was an import that is already an Exported Function Exotic Object, then the original function object will be found. For imports that are regular JS functions, a new wrapper will be created.)
             if (exp.kindIndex < functionImportCount) {
                 unsigned functionIndex = exp.kindIndex;
-                JSObject* functionImport = instance->instance().importFunction<WriteBarrier<JSObject>>(functionIndex)->get();
+                JSObject* functionImport = instance->instance().importFunction<JSWebAssemblyInstance::PoisonedBarrier<JSObject>>(functionIndex)->get();
                 if (isWebAssemblyHostFunction(vm, functionImport))
                     exportedValue = functionImport;
                 else {
@@ -191,7 +191,7 @@
         ASSERT(!signature.argumentCount());
         ASSERT(signature.returnType() == Wasm::Void);
         if (startFunctionIndexSpace < codeBlock->functionImportCount()) {
-            JSObject* startFunction = instance->instance().importFunction<WriteBarrier<JSObject>>(startFunctionIndexSpace)->get();
+            JSObject* startFunction = instance->instance().importFunction<JSWebAssemblyInstance::PoisonedBarrier<JSObject>>(startFunctionIndexSpace)->get();
             m_startFunction.set(vm, this, startFunction);
         } else {
             Wasm::Callee& embedderEntrypointCallee = codeBlock->embedderEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace);
@@ -295,7 +295,7 @@
             uint32_t functionIndex = element.functionIndices[i];
             Wasm::SignatureIndex signatureIndex = module.signatureIndexFromFunctionIndexSpace(functionIndex);
             if (functionIndex < codeBlock->functionImportCount()) {
-                JSObject* functionImport = m_instance->instance().importFunction<WriteBarrier<JSObject>>(functionIndex)->get();
+                JSObject* functionImport = m_instance->instance().importFunction<JSWebAssemblyInstance::PoisonedBarrier<JSObject>>(functionIndex)->get();
                 if (isWebAssemblyHostFunction(vm, functionImport)) {
                     WebAssemblyFunction* wasmFunction = jsDynamicCast<WebAssemblyFunction*>(vm, functionImport);
                     // If we ever import a WebAssemblyWrapperFunction, we set the import as the unwrapped value.

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -59,8 +59,11 @@
 
     static void visitChildren(JSCell*, SlotVisitor&);
 
-    WriteBarrier<JSWebAssemblyInstance> m_instance;
-    WriteBarrier<JSObject> m_startFunction;
+    template<typename T>
+    using PoisonedBarrier = PoisonedWriteBarrier<WebAssemblyModuleRecordPoison, T>;
+
+    PoisonedBarrier<JSWebAssemblyInstance> m_instance;
+    PoisonedBarrier<JSObject> m_startFunction;
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyToJSCallee.h (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyToJSCallee.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyToJSCallee.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -51,7 +51,7 @@
     void finishCreation(VM&, JSWebAssemblyModule*);
     WebAssemblyToJSCallee(VM&, Structure*);
 
-    WriteBarrier<JSWebAssemblyModule> m_module;
+    PoisonedWriteBarrier<WebAssemblyToJSCalleePoison, JSWebAssemblyModule> m_module;
 };
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyWrapperFunction.h (226919 => 226920)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyWrapperFunction.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyWrapperFunction.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -56,7 +56,7 @@
 private:
     WebAssemblyWrapperFunction(VM&, JSGlobalObject*, Structure*, Wasm::CallableFunction);
 
-    WriteBarrier<JSObject> m_function;
+    PoisonedWriteBarrier<WebAssemblyWrapperFunctionPoison, JSObject> m_function;
     // It's safe to just hold the raw CallableFunction because we have a reference
     // to our Instance, which points to the CodeBlock, which points to the Module
     // that exported us, which ensures that the actual Signature/code doesn't get deallocated.

Modified: trunk/Source/WTF/ChangeLog (226919 => 226920)


--- trunk/Source/WTF/ChangeLog	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/WTF/ChangeLog	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,3 +1,26 @@
+2018-01-12  JF Bastien  <[email protected]>
+
+        PoisonedWriteBarrier
+        https://bugs.webkit.org/show_bug.cgi?id=181599
+        <rdar://problem/36474351>
+
+        Reviewed by Mark Lam.
+
+        Supporting changes needed to allow poisoning of WriteBarrier
+        objects.
+
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/DumbPtrTraits.h:
+        * wtf/DumbValueTraits.h: Copied from Source/WTF/wtf/DumbPtrTraits.h.
+        (WTF::DumbValueTraits::exchange):
+        (WTF::DumbValueTraits::swap):
+        (WTF::DumbValueTraits::unwrap):
+        * wtf/Forward.h:
+        * wtf/Poisoned.h:
+        (WTF::ConstExprPoisonedValueTraits::exchange):
+        (WTF::ConstExprPoisonedValueTraits::swap):
+        (WTF::ConstExprPoisonedValueTraits::unwrap):
+
 2018-01-11  Basuke Suzuki  <[email protected]>
 
         Remove noexcept from definition of std::tie()

Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (226919 => 226920)


--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2018-01-12 23:47:58 UTC (rev 226920)
@@ -574,6 +574,7 @@
 		A8A47372151A825B004123FF /* VMTags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMTags.h; sourceTree = "<group>"; };
 		A8A4748B151A8264004123FF /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
 		A9A4727F151A825A004123FF /* DisallowCType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisallowCType.h; sourceTree = "<group>"; };
+		AD653DA82006B6C200D820D7 /* DumbValueTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DumbValueTraits.h; sourceTree = "<group>"; };
 		AD7C434A1DD2A4A70026888B /* Expected.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Expected.h; sourceTree = "<group>"; };
 		AD89B6B51E6415080090707F /* MemoryPressureHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryPressureHandler.cpp; sourceTree = "<group>"; };
 		AD89B6B61E6415080090707F /* MemoryPressureHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryPressureHandler.h; sourceTree = "<group>"; };
@@ -854,6 +855,7 @@
 				0F4570421BE5B58F0062A629 /* Dominators.h */,
 				A8A47280151A825A004123FF /* DoublyLinkedList.h */,
 				FE05FAE61FDB214300093230 /* DumbPtrTraits.h */,
+				AD653DA82006B6C200D820D7 /* DumbValueTraits.h */,
 				A8A47297151A825A004123FF /* dtoa.cpp */,
 				A8A47298151A825A004123FF /* dtoa.h */,
 				1AEA88E11D6BBCF400E5AD64 /* EnumTraits.h */,

Modified: trunk/Source/WTF/wtf/DumbPtrTraits.h (226919 => 226920)


--- trunk/Source/WTF/wtf/DumbPtrTraits.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/WTF/wtf/DumbPtrTraits.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include <cstdint>
 #include <utility>
 
 namespace WTF {
@@ -31,6 +32,8 @@
     
 template<typename T>
 struct DumbPtrTraits {
+    static constexpr uintptr_t poison = 0;
+
     using StorageType = T*;
 
     template<typename U>
@@ -42,3 +45,4 @@
 
 } // namespace WTF
 
+using WTF::DumbPtrTraits;

Copied: trunk/Source/WTF/wtf/DumbValueTraits.h (from rev 226919, trunk/Source/WTF/wtf/DumbPtrTraits.h) (0 => 226920)


--- trunk/Source/WTF/wtf/DumbValueTraits.h	                        (rev 0)
+++ trunk/Source/WTF/wtf/DumbValueTraits.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2018 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. ``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
+ * 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 <cstdint>
+#include <utility>
+
+namespace WTF {
+
+template<typename T>
+struct DumbValueTraits {
+    static constexpr uintptr_t poison = 0;
+
+    using StorageType = T;
+
+    template<typename U>
+    static ALWAYS_INLINE T exchange(StorageType& val, U&& newValue) { return std::exchange(val, newValue); }
+
+    static ALWAYS_INLINE void swap(StorageType& a, StorageType& b) { std::swap(a, b); }
+    static ALWAYS_INLINE T unwrap(const StorageType& val) { return val; }
+};
+
+} // namespace WTF
+
+using WTF::DumbValueTraits;

Modified: trunk/Source/WTF/wtf/Forward.h (226919 => 226920)


--- trunk/Source/WTF/wtf/Forward.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/WTF/wtf/Forward.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2006-2017 Apple Inc. All rights reserved.
+ *  Copyright (C) 2006-2018 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
@@ -52,6 +52,7 @@
 
 template<typename> class CompletionHandler;
 template<typename T> struct DumbPtrTraits;
+template<typename T> struct DumbValueTraits;
 template<typename> class Function;
 template<typename> class LazyNeverDestroyed;
 template<typename> class NeverDestroyed;
@@ -84,6 +85,8 @@
 using WTF::BinarySemaphore;
 using WTF::CString;
 using WTF::CompletionHandler;
+using WTF::DumbPtrTraits;
+using WTF::DumbValueTraits;
 using WTF::Function;
 using WTF::FunctionDispatcher;
 using WTF::HashCountedSet;

Modified: trunk/Source/WTF/wtf/Poisoned.h (226919 => 226920)


--- trunk/Source/WTF/wtf/Poisoned.h	2018-01-12 23:35:55 UTC (rev 226919)
+++ trunk/Source/WTF/wtf/Poisoned.h	2018-01-12 23:47:58 UTC (rev 226920)
@@ -262,6 +262,8 @@
 
 template<uint32_t key, typename T>
 struct ConstExprPoisonedPtrTraits {
+    static constexpr auto poison = makeConstExprPoison(key);
+
     using StorageType = ConstExprPoisoned<key, T*>;
 
     template<class U> static ALWAYS_INLINE T* exchange(StorageType& ptr, U&& newValue) { return ptr.exchange(newValue); }
@@ -275,6 +277,23 @@
     static ALWAYS_INLINE T* unwrap(const StorageType& ptr) { return ptr.unpoisoned(); }
 };
 
+template<uint32_t key, typename T>
+struct ConstExprPoisonedValueTraits {
+    static constexpr auto poison = makeConstExprPoison(key);
+
+    using StorageType = ConstExprPoisoned<key, T>;
+
+    template<class U> static ALWAYS_INLINE T exchange(StorageType& val, U&& newValue) { return val.exchange(newValue); }
+
+    template<typename K1, K1 k1, typename T1>
+    static ALWAYS_INLINE void swap(PoisonedImpl<K1, k1, T1>& a, T1& b) { a.swap(b); }
+
+    template<typename K1, K1 k1, typename T1, typename K2, K2 k2, typename T2>
+    static ALWAYS_INLINE void swap(PoisonedImpl<K1, k1, T1>& a, PoisonedImpl<K2, k2, T2>& b) { a.swap(b); }
+
+    static ALWAYS_INLINE T unwrap(const StorageType& val) { return val.unpoisoned(); }
+};
+
 } // namespace WTF
 
 using WTF::ConstExprPoisoned;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to