Changeset 235071 in webkit


Ignore:
Timestamp:
Aug 20, 2018 7:07:52 AM (6 years ago)
Author:
Carlos Garcia Campos
Message:

Merge r235018 - [WTF] Add WTF::unalignedLoad and WTF::unalignedStore
https://bugs.webkit.org/show_bug.cgi?id=188716

Reviewed by Darin Adler.

Source/JavaScriptCore:

Use WTF::unalignedLoad and WTF::unalignedStore to avoid undefined behavior.
The compiler can emit appropriate mov operations in x86 even if we use these
helper functions.

  • 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):

  • interpreter/InterpreterInlines.h:

(JSC::Interpreter::getOpcodeID): Embedded opcode may be misaligned. Actually UBSan detects misaligned accesses here.

Source/WTF:

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.

We name these functions unalignedLoad and unalignedStore instead of loadUnaligned and storeUnaligned
in order to align them to atomicLoad and atomicStore.

  • WTF.xcodeproj/project.pbxproj:
  • wtf/CMakeLists.txt:
  • wtf/UnalignedAccess.h: Added.

(WTF::unalignedLoad):
(WTF::unalignedStore):

  • wtf/text/StringCommon.h:

(WTF::equal):
(WTF::loadUnaligned): Deleted.

Location:
releases/WebKitGTK/webkit-2.22/Source
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • releases/WebKitGTK/webkit-2.22/Source/JavaScriptCore/ChangeLog

    r235067 r235071  
     12018-08-19  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
     2
     3        [WTF] Add WTF::unalignedLoad and WTF::unalignedStore
     4        https://bugs.webkit.org/show_bug.cgi?id=188716
     5
     6        Reviewed by Darin Adler.
     7
     8        Use WTF::unalignedLoad and WTF::unalignedStore to avoid undefined behavior.
     9        The compiler can emit appropriate mov operations in x86 even if we use these
     10        helper functions.
     11
     12        * assembler/AssemblerBuffer.h:
     13        (JSC::AssemblerBuffer::LocalWriter::putIntegralUnchecked):
     14        (JSC::AssemblerBuffer::putIntegral):
     15        (JSC::AssemblerBuffer::putIntegralUnchecked):
     16        * assembler/MacroAssemblerX86.h:
     17        (JSC::MacroAssemblerX86::readCallTarget):
     18        * assembler/X86Assembler.h:
     19        (JSC::X86Assembler::linkJump):
     20        (JSC::X86Assembler::readPointer):
     21        (JSC::X86Assembler::replaceWithHlt):
     22        (JSC::X86Assembler::replaceWithJump):
     23        (JSC::X86Assembler::setPointer):
     24        (JSC::X86Assembler::setInt32):
     25        (JSC::X86Assembler::setInt8):
     26        * interpreter/InterpreterInlines.h:
     27        (JSC::Interpreter::getOpcodeID): Embedded opcode may be misaligned. Actually UBSan detects misaligned accesses here.
     28
    1292018-08-17  Saam barati  <sbarati@apple.com>
    230
  • releases/WebKitGTK/webkit-2.22/Source/JavaScriptCore/assembler/AssemblerBuffer.h

    r228582 r235071  
    3535#include <wtf/FastMalloc.h>
    3636#include <wtf/StdLibExtras.h>
     37#include <wtf/UnalignedAccess.h>
    3738
    3839namespace JSC {
     
    240241            {
    241242                ASSERT(m_index + sizeof(IntegralType) <= m_buffer.m_storage.capacity());
    242                 *reinterpret_cast_ptr<IntegralType*>(m_storageBuffer + m_index) = value;
     243                WTF::unalignedStore<IntegralType>(m_storageBuffer + m_index, value);
    243244                m_index += sizeof(IntegralType);
    244245            }
     
    259260            if (UNLIKELY(nextIndex > m_storage.capacity()))
    260261                outOfLineGrow();
    261             ASSERT(isAvailable(sizeof(IntegralType)));
    262             *reinterpret_cast_ptr<IntegralType*>(m_storage.buffer() + m_index) = value;
    263             m_index = nextIndex;
     262            putIntegralUnchecked<IntegralType>(value);
    264263        }
    265264
     
    268267        {
    269268            ASSERT(isAvailable(sizeof(IntegralType)));
    270             *reinterpret_cast_ptr<IntegralType*>(m_storage.buffer() + m_index) = value;
     269            WTF::unalignedStore<IntegralType>(m_storage.buffer() + m_index, value);
    271270            m_index += sizeof(IntegralType);
    272271        }
  • releases/WebKitGTK/webkit-2.22/Source/JavaScriptCore/assembler/MacroAssemblerX86.h

    r230748 r235071  
    303303    static FunctionPtr<resultTag> readCallTarget(CodeLocationCall<locationTag> call)
    304304    {
    305         intptr_t offset = reinterpret_cast<int32_t*>(call.dataLocation())[-1];
     305        intptr_t offset = WTF::unalignedLoad<int32_t>(bitwise_cast<int32_t*>(call.dataLocation()) - 1);
    306306        return FunctionPtr<resultTag>(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(call.dataLocation()) + offset));
    307307    }
  • releases/WebKitGTK/webkit-2.22/Source/JavaScriptCore/assembler/X86Assembler.h

    r235057 r235071  
    36813681
    36823682        char* code = reinterpret_cast<char*>(m_formatter.data());
    3683         ASSERT(!reinterpret_cast<int32_t*>(code + from.m_offset)[-1]);
     3683        ASSERT(!WTF::unalignedLoad<int32_t>(bitwise_cast<int32_t*>(code + from.m_offset) - 1));
    36843684        setRel32(code + from.m_offset, code + to.m_offset);
    36853685    }
     
    37403740    static void* readPointer(void* where)
    37413741    {
    3742         return reinterpret_cast<void**>(where)[-1];
     3742        return WTF::unalignedLoad<void*>(bitwise_cast<void**>(where) - 1);
    37433743    }
    37443744
    37453745    static void replaceWithHlt(void* instructionStart)
    37463746    {
    3747         uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
    3748         ptr[0] = static_cast<uint8_t>(OP_HLT);
     3747        WTF::unalignedStore<uint8_t>(instructionStart, static_cast<uint8_t>(OP_HLT));
    37493748    }
    37503749
    37513750    static void replaceWithJump(void* instructionStart, void* to)
    37523751    {
    3753         uint8_t* ptr = reinterpret_cast<uint8_t*>(instructionStart);
    3754         uint8_t* dstPtr = reinterpret_cast<uint8_t*>(to);
     3752        uint8_t* ptr = bitwise_cast<uint8_t*>(instructionStart);
     3753        uint8_t* dstPtr = bitwise_cast<uint8_t*>(to);
    37553754        intptr_t distance = (intptr_t)(dstPtr - (ptr + 5));
    3756         ptr[0] = static_cast<uint8_t>(OP_JMP_rel32);
    3757         *reinterpret_cast<int32_t*>(ptr + 1) = static_cast<int32_t>(distance);
     3755        WTF::unalignedStore<uint8_t>(ptr, static_cast<uint8_t>(OP_JMP_rel32));
     3756        WTF::unalignedStore<int32_t>(ptr + 1, static_cast<int32_t>(distance));
    37583757    }
    37593758   
     
    39573956    static void setPointer(void* where, void* value)
    39583957    {
    3959         reinterpret_cast<void**>(where)[-1] = value;
     3958        WTF::unalignedStore<void*>(bitwise_cast<void**>(where) - 1, value);
    39603959    }
    39613960
    39623961    static void setInt32(void* where, int32_t value)
    39633962    {
    3964         reinterpret_cast<int32_t*>(where)[-1] = value;
     3963        WTF::unalignedStore<int32_t>(bitwise_cast<int32_t*>(where) - 1, value);
    39653964    }
    39663965   
    39673966    static void setInt8(void* where, int8_t value)
    39683967    {
    3969         reinterpret_cast<int8_t*>(where)[-1] = value;
     3968        WTF::unalignedStore<int8_t>(bitwise_cast<int8_t*>(where) - 1, value);
    39703969    }
    39713970
  • releases/WebKitGTK/webkit-2.22/Source/JavaScriptCore/interpreter/InterpreterInlines.h

    r231741 r235071  
    3434#include "LLIntData.h"
    3535#include "UnlinkedCodeBlock.h"
     36#include <wtf/UnalignedAccess.h>
    3637
    3738namespace JSC {
     
    5253    auto codePtr = MacroAssemblerCodePtr<BytecodePtrTag>::createFromExecutableAddress(opcode);
    5354    int32_t* opcodeIDAddress = codePtr.dataLocation<int32_t*>() - 1;
    54     OpcodeID opcodeID = static_cast<OpcodeID>(*opcodeIDAddress);
     55    OpcodeID opcodeID = static_cast<OpcodeID>(WTF::unalignedLoad<int32_t>(opcodeIDAddress));
    5556    ASSERT(opcodeID < NUMBER_OF_BYTECODE_IDS);
    5657    return opcodeID;
  • releases/WebKitGTK/webkit-2.22/Source/WTF/ChangeLog

    r235054 r235071  
     12018-08-19  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
     2
     3        [WTF] Add WTF::unalignedLoad and WTF::unalignedStore
     4        https://bugs.webkit.org/show_bug.cgi?id=188716
     5
     6        Reviewed by Darin Adler.
     7
     8        While some CPUs allow unaligned accesses to memory, doing it in C++ with `reinterpret_cast<>` is
     9        undefined behavior. This patch adds WTF::{unalignedLoad,unalignedStore} helper functions, which
     10        can load from and store to the pointer in an unaligned manner.
     11        Actual implementation uses `memcpy`. This can be optimized to direct unaligned access operations
     12        in supported CPUs like x86. Even though a CPU does not support unaligned accesses, memcpy is still
     13        safe and the compiler emits appropriate code.
     14
     15        We name these functions `unalignedLoad` and `unalignedStore` instead of `loadUnaligned` and `storeUnaligned`
     16        in order to align them to `atomicLoad` and `atomicStore`.
     17
     18        * WTF.xcodeproj/project.pbxproj:
     19        * wtf/CMakeLists.txt:
     20        * wtf/UnalignedAccess.h: Added.
     21        (WTF::unalignedLoad):
     22        (WTF::unalignedStore):
     23        * wtf/text/StringCommon.h:
     24        (WTF::equal):
     25        (WTF::loadUnaligned): Deleted.
     26
    1272018-08-17  David Kilzer  <ddkilzer@apple.com>
    228
  • releases/WebKitGTK/webkit-2.22/Source/WTF/WTF.xcodeproj/project.pbxproj

    r234685 r235071  
    624624                E3200AB41E9A536D003B59D2 /* PlatformRegisters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRegisters.h; sourceTree = "<group>"; };
    625625                E33D5F871FBED66700BF625E /* RecursableLambda.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecursableLambda.h; sourceTree = "<group>"; };
     626                E360C7642127B85B00C90F0E /* UnalignedAccess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnalignedAccess.h; sourceTree = "<group>"; };
     627                E360C7652127B85C00C90F0E /* Unexpected.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Unexpected.h; sourceTree = "<group>"; };
    626628                E388886D20C9095100E632BC /* WorkerPool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WorkerPool.cpp; sourceTree = "<group>"; };
    627629                E388886E20C9095100E632BC /* WorkerPool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WorkerPool.h; sourceTree = "<group>"; };
     
    11181120                                149EF16216BBFE0D000A4331 /* TriState.h */,
    11191121                                83FBA93119DF459700F30ADB /* TypeCasts.h */,
     1122                                E360C7642127B85B00C90F0E /* UnalignedAccess.h */,
     1123                                E360C7652127B85C00C90F0E /* Unexpected.h */,
    11201124                                A8A4735C151A825B004123FF /* UnionFind.h */,
    11211125                                E300E521203D645F00DA79BE /* UniqueArray.h */,
  • releases/WebKitGTK/webkit-2.22/Source/WTF/wtf/CMakeLists.txt

    r234677 r235071  
    241241    TypeCasts.h
    242242    UUID.h
     243    UnalignedAccess.h
    243244    Unexpected.h
    244245    UniStdExtras.h
  • releases/WebKitGTK/webkit-2.22/Source/WTF/wtf/text/StringCommon.h

    r225618 r235071  
    3131#include <wtf/ASCIICType.h>
    3232#include <wtf/NotFound.h>
     33#include <wtf/UnalignedAccess.h>
    3334
    3435namespace WTF {
     
    4849bool equalIgnoringASCIICase(const char*, const char*);
    4950template<unsigned lowercaseLettersLength> bool equalLettersIgnoringASCIICase(const char*, const char (&lowercaseLetters)[lowercaseLettersLength]);
    50 
    51 template<typename T>
    52 inline T loadUnaligned(const char* s)
    53 {
    54 #if COMPILER(CLANG)
    55     T tmp;
    56     memcpy(&tmp, s, sizeof(T));
    57     return tmp;
    58 #else
    59     // This may result in undefined behavior due to unaligned access.
    60     return *reinterpret_cast<const T*>(s);
    61 #endif
    62 }
    6351
    6452// Do comparisons 8 or 4 bytes-at-a-time on architectures where it's safe.
     
    7361    if (dwordLength) {
    7462        for (unsigned i = 0; i != dwordLength; ++i) {
    75             if (loadUnaligned<uint64_t>(a) != loadUnaligned<uint64_t>(b))
     63            if (unalignedLoad<uint64_t>(a) != unalignedLoad<uint64_t>(b))
    7664                return false;
    7765
     
    8270
    8371    if (length & 4) {
    84         if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
     72        if (unalignedLoad<uint32_t>(a) != unalignedLoad<uint32_t>(b))
    8573            return false;
    8674
     
    9078
    9179    if (length & 2) {
    92         if (loadUnaligned<uint16_t>(a) != loadUnaligned<uint16_t>(b))
     80        if (unalignedLoad<uint16_t>(a) != unalignedLoad<uint16_t>(b))
    9381            return false;
    9482
     
    112100    if (dwordLength) {
    113101        for (unsigned i = 0; i != dwordLength; ++i) {
    114             if (loadUnaligned<uint64_t>(a) != loadUnaligned<uint64_t>(b))
     102            if (unalignedLoad<uint64_t>(a) != unalignedLoad<uint64_t>(b))
    115103                return false;
    116104
     
    121109
    122110    if (length & 2) {
    123         if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
     111        if (unalignedLoad<uint32_t>(a) != unalignedLoad<uint32_t>(b))
    124112            return false;
    125113
     
    141129    unsigned wordLength = length >> 2;
    142130    for (unsigned i = 0; i != wordLength; ++i) {
    143         if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
     131        if (unalignedLoad<uint32_t>(a) != unalignedLoad<uint32_t>(b))
    144132            return false;
    145133        a += sizeof(uint32_t);
     
    169157    unsigned wordLength = length >> 1;
    170158    for (unsigned i = 0; i != wordLength; ++i) {
    171         if (loadUnaligned<uint32_t>(a) != loadUnaligned<uint32_t>(b))
     159        if (unalignedLoad<uint32_t>(a) != unalignedLoad<uint32_t>(b))
    172160            return false;
    173161        a += sizeof(uint32_t);
Note: See TracChangeset for help on using the changeset viewer.