WebKit Bugzilla
Attachment 347421 Details for
Bug 188716
: [WTF] Add WTF::unalignedLoad and WTF::unalignedStore
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188716-20180818111039.patch (text/plain), 10.39 KB, created by
Yusuke Suzuki
on 2018-08-17 19:10:40 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2018-08-17 19:10:40 PDT
Size:
10.39 KB
patch
obsolete
>Subversion Revision: 235004 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 48a6aae498a895d896aa5503ed2a0da9aa093022..d79747cb61de869ada3e68ad594077635c057022 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,32 @@ >+2018-08-17 Yusuke Suzuki <yusukesuzuki@slowstart.org> >+ >+ [WTF] Add WTF::unalignedLoad and WTF::unalignedStore >+ https://bugs.webkit.org/show_bug.cgi?id=188716 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ While some CPUs allow unaligned accesses to memory, doing it in C++ with `reinterpret_cast<>` is >+ undefined behavior. This patch adds WTF::{unalignedLoad,unalignedStore} helper functions, which >+ can load from and store to the pointer in an unaligned manner. >+ Actual implementation uses `memcpy`. This can be optimized to direct unaligned access operations >+ in supported CPUs like x86. Even though a CPU does not support unaligned accesses, memcpy is still >+ safe and the compiler emits appropriate code. >+ >+ * assembler/AssemblerBuffer.h: >+ (JSC::AssemblerBuffer::LocalWriter::putIntegralUnchecked): >+ (JSC::AssemblerBuffer::putIntegral): >+ (JSC::AssemblerBuffer::putIntegralUnchecked): >+ * assembler/MacroAssemblerX86.h: >+ (JSC::MacroAssemblerX86::readCallTarget): >+ * assembler/X86Assembler.h: >+ (JSC::X86Assembler::linkJump): >+ (JSC::X86Assembler::readPointer): >+ (JSC::X86Assembler::replaceWithHlt): >+ (JSC::X86Assembler::replaceWithJump): >+ (JSC::X86Assembler::setPointer): >+ (JSC::X86Assembler::setInt32): >+ (JSC::X86Assembler::setInt8): >+ > 2018-08-17 Yusuke Suzuki <yusukesuzuki@slowstart.org> and Fujii Hironori <Hironori.Fujii@sony.com> > > [JSC] Add GPRReg::InvalidGPRReg and FPRReg::InvalidFPRReg >diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog >index 668e9b81be5948bdf4083ff3653d57f442e4d510..9b96fa2bb6427cdfbe235c2795bdd1fa75c89601 100644 >--- a/Source/WTF/ChangeLog >+++ b/Source/WTF/ChangeLog >@@ -1,3 +1,15 @@ >+2018-08-17 Yusuke Suzuki <yusukesuzuki@slowstart.org> >+ >+ [WTF] Add WTF::unalignedLoad and WTF::unalignedStore >+ https://bugs.webkit.org/show_bug.cgi?id=188716 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * wtf/CMakeLists.txt: >+ * wtf/UnalignedAccess.h: Added. >+ (WTF::unalignedLoad): >+ (WTF::unalignedStore): >+ > 2018-08-17 David Kilzer <ddkilzer@apple.com> > > WTF's internal std::optional implementation should release assert on all bad accesses >diff --git a/Source/JavaScriptCore/assembler/AssemblerBuffer.h b/Source/JavaScriptCore/assembler/AssemblerBuffer.h >index 7340952d53c4f5d4f58855feac7511324e5ef9dd..54b2e9b1eb162e03b9a1e37e9e43161ee0cb1fce 100644 >--- a/Source/JavaScriptCore/assembler/AssemblerBuffer.h >+++ b/Source/JavaScriptCore/assembler/AssemblerBuffer.h >@@ -34,6 +34,7 @@ > #include <wtf/Assertions.h> > #include <wtf/FastMalloc.h> > #include <wtf/StdLibExtras.h> >+#include <wtf/UnalignedAccess.h> > > namespace JSC { > >@@ -239,7 +240,7 @@ namespace JSC { > void putIntegralUnchecked(IntegralType value) > { > ASSERT(m_index + sizeof(IntegralType) <= m_buffer.m_storage.capacity()); >- *reinterpret_cast_ptr<IntegralType*>(m_storageBuffer + m_index) = value; >+ WTF::unalignedStore<IntegralType>(m_storageBuffer + m_index, value); > m_index += sizeof(IntegralType); > } > AssemblerBuffer& m_buffer; >@@ -258,16 +259,14 @@ namespace JSC { > unsigned nextIndex = m_index + sizeof(IntegralType); > if (UNLIKELY(nextIndex > m_storage.capacity())) > outOfLineGrow(); >- ASSERT(isAvailable(sizeof(IntegralType))); >- *reinterpret_cast_ptr<IntegralType*>(m_storage.buffer() + m_index) = value; >- m_index = nextIndex; >+ putIntegralUnchecked<IntegralType>(value); > } > > template<typename IntegralType> > void putIntegralUnchecked(IntegralType value) > { > ASSERT(isAvailable(sizeof(IntegralType))); >- *reinterpret_cast_ptr<IntegralType*>(m_storage.buffer() + m_index) = value; >+ WTF::unalignedStore<IntegralType>(m_storage.buffer() + m_index, value); > m_index += sizeof(IntegralType); > } > >diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h >index 8bc023d571a06ae6f614087bf9b0dc24f719ed96..72def72c6b4b7188909693ac5f1fa0bcbaad4399 100644 >--- a/Source/JavaScriptCore/assembler/MacroAssemblerX86.h >+++ b/Source/JavaScriptCore/assembler/MacroAssemblerX86.h >@@ -302,7 +302,7 @@ class MacroAssemblerX86 : public MacroAssemblerX86Common { > template<PtrTag resultTag, PtrTag locationTag> > static FunctionPtr<resultTag> readCallTarget(CodeLocationCall<locationTag> call) > { >- intptr_t offset = reinterpret_cast<int32_t*>(call.dataLocation())[-1]; >+ intptr_t offset = WTF::unalignedLoad<int32_t>(bitwise_cast<int32_t*>(call.dataLocation()) - 1); > return FunctionPtr<resultTag>(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(call.dataLocation()) + offset)); > } > >diff --git a/Source/JavaScriptCore/assembler/X86Assembler.h b/Source/JavaScriptCore/assembler/X86Assembler.h >index f3a4083c121d571886fdec1d0919eaac9ec0b841..2f5d0c26de6e4531d4a1a20bec349c375118472f 100644 >--- a/Source/JavaScriptCore/assembler/X86Assembler.h >+++ b/Source/JavaScriptCore/assembler/X86Assembler.h >@@ -3680,7 +3680,7 @@ class X86Assembler { > ASSERT(to.isSet()); > > char* code = reinterpret_cast<char*>(m_formatter.data()); >- ASSERT(!reinterpret_cast<int32_t*>(code + from.m_offset)[-1]); >+ ASSERT(!WTF::unalignedLoad<int32_t>(bitwise_cast<int32_t*>(code + from.m_offset) - 1)); > setRel32(code + from.m_offset, code + to.m_offset); > } > >@@ -3739,22 +3739,21 @@ class X86Assembler { > > static void* readPointer(void* where) > { >- return reinterpret_cast<void**>(where)[-1]; >+ return WTF::unalignedLoad<void*>(bitwise_cast<void**>(where) - 1); > } > > static void replaceWithHlt(void* instructionStart) > { >- uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart); >- ptr[0] = static_cast<uint8_t>(OP_HLT); >+ WTF::unalignedStore<uint8_t>(instructionStart, static_cast<uint8_t>(OP_HLT)); > } > > static void replaceWithJump(void* instructionStart, void* to) > { >- uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart); >- uint8_t* dstPtr = reinterpret_cast<uint8_t*>(to); >+ uint8_t* ptr = bitwise_cast<uint8_t*>(instructionStart); >+ uint8_t* dstPtr = bitwise_cast<uint8_t*>(to); > intptr_t distance = (intptr_t)(dstPtr - (ptr + 5)); >- ptr[0] = static_cast<uint8_t>(OP_JMP_rel32); >- *reinterpret_cast<int32_t*>(ptr + 1) = static_cast<int32_t>(distance); >+ WTF::unalignedStore<uint8_t>(ptr, OP_JMP_rel32); >+ WTF::unalignedStore<uint32_t>(ptr + 1, distance); > } > > static ptrdiff_t maxJumpReplacementSize() >@@ -3956,17 +3955,17 @@ class X86Assembler { > > static void setPointer(void* where, void* value) > { >- reinterpret_cast<void**>(where)[-1] = value; >+ WTF::unalignedStore<void*>(bitwise_cast<void**>(where) - 1, value); > } > > static void setInt32(void* where, int32_t value) > { >- reinterpret_cast<int32_t*>(where)[-1] = value; >+ WTF::unalignedStore<int32_t>(bitwise_cast<int32_t*>(where) - 1, value); > } > > static void setInt8(void* where, int8_t value) > { >- reinterpret_cast<int8_t*>(where)[-1] = value; >+ WTF::unalignedStore<int8_t>(bitwise_cast<int8_t*>(where) - 1, value); > } > > static void setRel32(void* from, void* to) >diff --git a/Source/WTF/wtf/CMakeLists.txt b/Source/WTF/wtf/CMakeLists.txt >index 9798b9b8a10585f34f0792c9a3149e09c38ce964..9adb55543d013fea9af5a7aae49432f95f3240f2 100644 >--- a/Source/WTF/wtf/CMakeLists.txt >+++ b/Source/WTF/wtf/CMakeLists.txt >@@ -240,6 +240,7 @@ set(WTF_PUBLIC_HEADERS > TriState.h > TypeCasts.h > UUID.h >+ UnalignedAccess.h > Unexpected.h > UniStdExtras.h > UnionFind.h >diff --git a/Source/WTF/wtf/UnalignedAccess.h b/Source/WTF/wtf/UnalignedAccess.h >new file mode 100644 >index 0000000000000000000000000000000000000000..1a37b4eec1ad2124a35c83c6bc0ecb8edca65336 >--- /dev/null >+++ b/Source/WTF/wtf/UnalignedAccess.h >@@ -0,0 +1,50 @@ >+/* >+ * Copyright (C) 2018 Yusuke Suzuki <yusukesuzuki@slowstart.org>. >+ * >+ * 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 <type_traits> >+#include <wtf/Platform.h> >+#include <wtf/StdLibExtras.h> >+ >+namespace WTF { >+ >+template<typename IntegralType> >+inline IntegralType unalignedLoad(const void* pointer) >+{ >+ static_assert(std::is_integral<IntegralType>::value || std::is_pointer<IntegralType>::value, ""); >+ IntegralType result { }; >+ memcpy(&result, pointer, sizeof(IntegralType)); >+ return result; >+} >+ >+template<typename IntegralType> >+inline void unalignedStore(void* pointer, IntegralType value) >+{ >+ static_assert(std::is_integral<IntegralType>::value || std::is_pointer<IntegralType>::value, ""); >+ memcpy(pointer, &value, sizeof(IntegralType)); >+} >+ >+} // namespace WTF
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188716
:
347421
|
347423
|
347455