]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - jit/JITWriteBarrier.h
JavaScriptCore-903.tar.gz
[apple/javascriptcore.git] / jit / JITWriteBarrier.h
diff --git a/jit/JITWriteBarrier.h b/jit/JITWriteBarrier.h
new file mode 100644 (file)
index 0000000..10e0710
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef JITWriteBarrier_h
+#define JITWriteBarrier_h
+
+#if ENABLE(JIT)
+
+#include "MacroAssembler.h"
+#include "MarkStack.h"
+#include "WriteBarrier.h"
+
+namespace JSC {
+
+class JSCell;
+class JSGlobalData;
+
+// Needs to be even to appease some of the backends.
+#define JITWriteBarrierFlag ((void*)2)
+class JITWriteBarrierBase {
+public:
+    typedef void* (JITWriteBarrierBase::*UnspecifiedBoolType);
+    operator UnspecifiedBoolType*() const { return get() ? reinterpret_cast<UnspecifiedBoolType*>(1) : 0; }
+    bool operator!() const { return !get(); }
+
+    void setFlagOnBarrier()
+    {
+        ASSERT(!m_location);
+        m_location = CodeLocationDataLabelPtr(JITWriteBarrierFlag);
+    }
+
+    bool isFlagged() const
+    {
+        return !!m_location;
+    }
+
+    void setLocation(CodeLocationDataLabelPtr location)
+    {
+        ASSERT(!m_location);
+        m_location = location;
+    }
+
+    CodeLocationDataLabelPtr location() const
+    {
+        ASSERT((!!m_location) && m_location.executableAddress() != JITWriteBarrierFlag);
+        return m_location;
+    }
+    
+    void clear() { clear(0); }
+
+protected:
+    JITWriteBarrierBase()
+    {
+    }
+
+    void set(JSGlobalData&, CodeLocationDataLabelPtr location, JSCell* owner, JSCell* value)
+    {
+        Heap::writeBarrier(owner, value);
+        m_location = location;
+        ASSERT(((!!m_location) && m_location.executableAddress() != JITWriteBarrierFlag) || (location.executableAddress() == m_location.executableAddress()));
+        MacroAssembler::repatchPointer(m_location, value);
+        ASSERT(get() == value);
+    }
+
+    JSCell* get() const
+    {
+        if (!m_location || m_location.executableAddress() == JITWriteBarrierFlag)
+            return 0;
+        void* result = static_cast<JSCell*>(MacroAssembler::readPointer(m_location));
+        // We use -1 to indicate a "safe" empty value in the instruction stream
+        if (result == (void*)-1)
+            return 0;
+        return static_cast<JSCell*>(result);
+    }
+
+private:
+    void clear(void* clearedValue)
+    {
+        if (!m_location)
+            return;
+        if (m_location.executableAddress() != JITWriteBarrierFlag)
+            MacroAssembler::repatchPointer(m_location, clearedValue);
+    }
+
+    CodeLocationDataLabelPtr m_location;
+};
+
+#undef JITWriteBarrierFlag
+
+template <typename T> class JITWriteBarrier : public JITWriteBarrierBase {
+public:
+    JITWriteBarrier()
+    {
+    }
+
+    void set(JSGlobalData& globalData, CodeLocationDataLabelPtr location, JSCell* owner, T* value)
+    {
+        validateCell(owner);
+        validateCell(value);
+        JITWriteBarrierBase::set(globalData, location, owner, value);
+    }
+    T* get() const
+    {
+        T* result = static_cast<T*>(JITWriteBarrierBase::get());
+        if (result)
+            validateCell(result);
+        return result;
+    }
+};
+
+template<typename T> inline void MarkStack::append(JITWriteBarrier<T>* slot)
+{
+    internalAppend(slot->get());
+}
+
+}
+
+#endif // ENABLE(JIT)
+
+#endif