haikuwebkit/Source/WTF/wtf/CagedUniquePtr.h

99 lines
3.2 KiB
C
Raw Permalink Normal View History

Put the ScopedArgumentsTable's ScopeOffset array in some gigacage https://bugs.webkit.org/show_bug.cgi?id=174921 Reviewed by Mark Lam. Source/JavaScriptCore: 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: Canonical link: https://commits.webkit.org/192235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220712 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-14 18:33:16 +00:00
/*
* Copyright (C) 2017-2020 Apple Inc. All rights reserved.
Put the ScopedArgumentsTable's ScopeOffset array in some gigacage https://bugs.webkit.org/show_bug.cgi?id=174921 Reviewed by Mark Lam. Source/JavaScriptCore: 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: Canonical link: https://commits.webkit.org/192235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220712 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-14 18:33:16 +00:00
*
* 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, bool shouldTag = false>
class CagedUniquePtr : public CagedPtr<kind, T, shouldTag> {
static_assert(std::is_trivially_destructible<T>::value, "We expect the contents of a caged pointer to be trivially destructable.");
Put the ScopedArgumentsTable's ScopeOffset array in some gigacage https://bugs.webkit.org/show_bug.cgi?id=174921 Reviewed by Mark Lam. Source/JavaScriptCore: 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: Canonical link: https://commits.webkit.org/192235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220712 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-14 18:33:16 +00:00
public:
using Base = CagedPtr<kind, T, shouldTag>;
CagedUniquePtr() = default;
JSTests: [JSC] WasmMemory caging should care about nullptr https://bugs.webkit.org/show_bug.cgi?id=224268 <rdar://problem/74654838> Reviewed by Mark Lam. * wasm/stress/4g-memory-cage.js: Added. (async test): * wasm/stress/more-than-4g-offset-access-oom.js: Added. (async test): * wasm/stress/null-memory-cage-explicit.js: Added. (async test): * wasm/stress/null-memory-cage.js: Added. (async test): Source/JavaScriptCore: [JSC] WasmMemory caging should care about nullptr https://bugs.webkit.org/show_bug.cgi?id=224268 <rdar://problem/74654838> Reviewed by Mark Lam. 1. Fix Wasm::MemoryHandle::boundsCheckingSize. We should just return m_mappedCapacity here since UINT32_MAX is not 4GB. This checking size can include redzone for fast-memory, but this is OK: bounds-check pass in LLInt (in upper tiers, we do not use bounds-check for fast-memory), and access to redzone, then fault occurs and signal handler can make it error since signal handler is checking whether the access is within Memory::fastMappedBytes which includes redzone. 2. Fix caging of wasm memory-base pointer in LLInt. We should use pointer sized length since it can be larger than 4GB. And we should handle nullptr case correctly: Wasm::MemoryHandle's memory can be nullptr when mapped size is zero. caging needs to handle this case as we do in CagedPtr::getMayBeNull. * assembler/MacroAssemblerARM64E.h: (JSC::MacroAssemblerARM64E::untagArrayPtrLength32): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage): * llint/LowLevelInterpreter64.asm: * llint/WebAssembly.asm: * offlineasm/arm64e.rb: * offlineasm/ast.rb: * offlineasm/instructions.rb: * runtime/CagedBarrierPtr.h: (JSC::CagedBarrierPtr::CagedBarrierPtr): (JSC::CagedBarrierPtr::set): (JSC::CagedBarrierPtr::get const): (JSC::CagedBarrierPtr::getMayBeNull const): (JSC::CagedBarrierPtr::at const): (JSC::CagedBarrierPtr::setWithoutBarrier): * wasm/WasmInstance.h: (JSC::Wasm::Instance::updateCachedMemory): * wasm/WasmMemory.cpp: (JSC::Wasm::MemoryHandle::MemoryHandle): * wasm/WasmMemory.h: Source/WTF: [JSC] WasmMemory caging should care nullptr https://bugs.webkit.org/show_bug.cgi?id=224268 <rdar://problem/74654838> Reviewed by Mark Lam. Accept size_t since Wasm::Memory's length can be larger than 4GB. * wtf/CagedPtr.h: (WTF::CagedPtr::CagedPtr): (WTF::CagedPtr::get const): (WTF::CagedPtr::getMayBeNull const): (WTF::CagedPtr::at const): (WTF::CagedPtr::recage): * wtf/CagedUniquePtr.h: (WTF::CagedUniquePtr::CagedUniquePtr): (WTF::CagedUniquePtr::create): (WTF::CagedUniquePtr::tryCreate): Canonical link: https://commits.webkit.org/236242@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275597 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-07 09:28:49 +00:00
CagedUniquePtr(T* ptr, size_t size)
: Base(ptr, size)
{ }
Put the ScopedArgumentsTable's ScopeOffset array in some gigacage https://bugs.webkit.org/show_bug.cgi?id=174921 Reviewed by Mark Lam. Source/JavaScriptCore: 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: Canonical link: https://commits.webkit.org/192235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220712 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-14 18:33:16 +00:00
CagedUniquePtr(CagedUniquePtr&& ptr)
: Base(std::forward<CagedUniquePtr&&>(ptr))
{ }
Put the ScopedArgumentsTable's ScopeOffset array in some gigacage https://bugs.webkit.org/show_bug.cgi?id=174921 Reviewed by Mark Lam. Source/JavaScriptCore: 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: Canonical link: https://commits.webkit.org/192235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220712 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-14 18:33:16 +00:00
CagedUniquePtr(const CagedUniquePtr&) = delete;
template<typename... Arguments>
JSTests: [JSC] WasmMemory caging should care about nullptr https://bugs.webkit.org/show_bug.cgi?id=224268 <rdar://problem/74654838> Reviewed by Mark Lam. * wasm/stress/4g-memory-cage.js: Added. (async test): * wasm/stress/more-than-4g-offset-access-oom.js: Added. (async test): * wasm/stress/null-memory-cage-explicit.js: Added. (async test): * wasm/stress/null-memory-cage.js: Added. (async test): Source/JavaScriptCore: [JSC] WasmMemory caging should care about nullptr https://bugs.webkit.org/show_bug.cgi?id=224268 <rdar://problem/74654838> Reviewed by Mark Lam. 1. Fix Wasm::MemoryHandle::boundsCheckingSize. We should just return m_mappedCapacity here since UINT32_MAX is not 4GB. This checking size can include redzone for fast-memory, but this is OK: bounds-check pass in LLInt (in upper tiers, we do not use bounds-check for fast-memory), and access to redzone, then fault occurs and signal handler can make it error since signal handler is checking whether the access is within Memory::fastMappedBytes which includes redzone. 2. Fix caging of wasm memory-base pointer in LLInt. We should use pointer sized length since it can be larger than 4GB. And we should handle nullptr case correctly: Wasm::MemoryHandle's memory can be nullptr when mapped size is zero. caging needs to handle this case as we do in CagedPtr::getMayBeNull. * assembler/MacroAssemblerARM64E.h: (JSC::MacroAssemblerARM64E::untagArrayPtrLength32): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage): * llint/LowLevelInterpreter64.asm: * llint/WebAssembly.asm: * offlineasm/arm64e.rb: * offlineasm/ast.rb: * offlineasm/instructions.rb: * runtime/CagedBarrierPtr.h: (JSC::CagedBarrierPtr::CagedBarrierPtr): (JSC::CagedBarrierPtr::set): (JSC::CagedBarrierPtr::get const): (JSC::CagedBarrierPtr::getMayBeNull const): (JSC::CagedBarrierPtr::at const): (JSC::CagedBarrierPtr::setWithoutBarrier): * wasm/WasmInstance.h: (JSC::Wasm::Instance::updateCachedMemory): * wasm/WasmMemory.cpp: (JSC::Wasm::MemoryHandle::MemoryHandle): * wasm/WasmMemory.h: Source/WTF: [JSC] WasmMemory caging should care nullptr https://bugs.webkit.org/show_bug.cgi?id=224268 <rdar://problem/74654838> Reviewed by Mark Lam. Accept size_t since Wasm::Memory's length can be larger than 4GB. * wtf/CagedPtr.h: (WTF::CagedPtr::CagedPtr): (WTF::CagedPtr::get const): (WTF::CagedPtr::getMayBeNull const): (WTF::CagedPtr::at const): (WTF::CagedPtr::recage): * wtf/CagedUniquePtr.h: (WTF::CagedUniquePtr::CagedUniquePtr): (WTF::CagedUniquePtr::create): (WTF::CagedUniquePtr::tryCreate): Canonical link: https://commits.webkit.org/236242@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275597 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-07 09:28:49 +00:00
static CagedUniquePtr create(size_t length, Arguments&&... arguments)
Put the ScopedArgumentsTable's ScopeOffset array in some gigacage https://bugs.webkit.org/show_bug.cgi?id=174921 Reviewed by Mark Lam. Source/JavaScriptCore: 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: Canonical link: https://commits.webkit.org/192235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220712 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-14 18:33:16 +00:00
{
T* result = static_cast<T*>(Gigacage::malloc(kind, sizeof(T) * length));
while (length--)
new (result + length) T(arguments...);
return CagedUniquePtr(result, length);
Put the ScopedArgumentsTable's ScopeOffset array in some gigacage https://bugs.webkit.org/show_bug.cgi?id=174921 Reviewed by Mark Lam. Source/JavaScriptCore: 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: Canonical link: https://commits.webkit.org/192235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220712 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-14 18:33:16 +00:00
}
template<typename... Arguments>
JSTests: [JSC] WasmMemory caging should care about nullptr https://bugs.webkit.org/show_bug.cgi?id=224268 <rdar://problem/74654838> Reviewed by Mark Lam. * wasm/stress/4g-memory-cage.js: Added. (async test): * wasm/stress/more-than-4g-offset-access-oom.js: Added. (async test): * wasm/stress/null-memory-cage-explicit.js: Added. (async test): * wasm/stress/null-memory-cage.js: Added. (async test): Source/JavaScriptCore: [JSC] WasmMemory caging should care about nullptr https://bugs.webkit.org/show_bug.cgi?id=224268 <rdar://problem/74654838> Reviewed by Mark Lam. 1. Fix Wasm::MemoryHandle::boundsCheckingSize. We should just return m_mappedCapacity here since UINT32_MAX is not 4GB. This checking size can include redzone for fast-memory, but this is OK: bounds-check pass in LLInt (in upper tiers, we do not use bounds-check for fast-memory), and access to redzone, then fault occurs and signal handler can make it error since signal handler is checking whether the access is within Memory::fastMappedBytes which includes redzone. 2. Fix caging of wasm memory-base pointer in LLInt. We should use pointer sized length since it can be larger than 4GB. And we should handle nullptr case correctly: Wasm::MemoryHandle's memory can be nullptr when mapped size is zero. caging needs to handle this case as we do in CagedPtr::getMayBeNull. * assembler/MacroAssemblerARM64E.h: (JSC::MacroAssemblerARM64E::untagArrayPtrLength32): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::cageTypedArrayStorage): * llint/LowLevelInterpreter64.asm: * llint/WebAssembly.asm: * offlineasm/arm64e.rb: * offlineasm/ast.rb: * offlineasm/instructions.rb: * runtime/CagedBarrierPtr.h: (JSC::CagedBarrierPtr::CagedBarrierPtr): (JSC::CagedBarrierPtr::set): (JSC::CagedBarrierPtr::get const): (JSC::CagedBarrierPtr::getMayBeNull const): (JSC::CagedBarrierPtr::at const): (JSC::CagedBarrierPtr::setWithoutBarrier): * wasm/WasmInstance.h: (JSC::Wasm::Instance::updateCachedMemory): * wasm/WasmMemory.cpp: (JSC::Wasm::MemoryHandle::MemoryHandle): * wasm/WasmMemory.h: Source/WTF: [JSC] WasmMemory caging should care nullptr https://bugs.webkit.org/show_bug.cgi?id=224268 <rdar://problem/74654838> Reviewed by Mark Lam. Accept size_t since Wasm::Memory's length can be larger than 4GB. * wtf/CagedPtr.h: (WTF::CagedPtr::CagedPtr): (WTF::CagedPtr::get const): (WTF::CagedPtr::getMayBeNull const): (WTF::CagedPtr::at const): (WTF::CagedPtr::recage): * wtf/CagedUniquePtr.h: (WTF::CagedUniquePtr::CagedUniquePtr): (WTF::CagedUniquePtr::create): (WTF::CagedUniquePtr::tryCreate): Canonical link: https://commits.webkit.org/236242@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275597 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-04-07 09:28:49 +00:00
static CagedUniquePtr tryCreate(size_t length, Arguments&&... arguments)
{
T* result = static_cast<T*>(Gigacage::tryMalloc(kind, sizeof(T) * length));
if (!result)
return { };
while (length--)
new (result + length) T(arguments...);
return CagedUniquePtr(result, length);
}
Put the ScopedArgumentsTable's ScopeOffset array in some gigacage https://bugs.webkit.org/show_bug.cgi?id=174921 Reviewed by Mark Lam. Source/JavaScriptCore: 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: Canonical link: https://commits.webkit.org/192235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220712 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-14 18:33:16 +00:00
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()
{
T* ptr = Base::getUnsafe();
if (!ptr)
Put the ScopedArgumentsTable's ScopeOffset array in some gigacage https://bugs.webkit.org/show_bug.cgi?id=174921 Reviewed by Mark Lam. Source/JavaScriptCore: 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: Canonical link: https://commits.webkit.org/192235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220712 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-14 18:33:16 +00:00
return;
ptr->~T();
Gigacage::free(kind, ptr);
Put the ScopedArgumentsTable's ScopeOffset array in some gigacage https://bugs.webkit.org/show_bug.cgi?id=174921 Reviewed by Mark Lam. Source/JavaScriptCore: 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: Canonical link: https://commits.webkit.org/192235@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@220712 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2017-08-14 18:33:16 +00:00
}
};
} // namespace WTF
using WTF::CagedUniquePtr;