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
+
+