Open source arm64e code.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Mar 2019 23:32:26 +0000 (23:32 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 20 Mar 2019 23:32:26 +0000 (23:32 +0000)
https://bugs.webkit.org/show_bug.cgi?id=196012
<rdar://problem/49066237>

Reviewed by Keith Miller.

Source/JavaScriptCore:

* JavaScriptCore.xcodeproj/project.pbxproj:
* Sources.txt:
* assembler/ARM64EAssembler.h: Added.
(JSC::ARM64EAssembler::encodeGroup1):
(JSC::ARM64EAssembler::encodeGroup2):
(JSC::ARM64EAssembler::encodeGroup4):
(JSC::ARM64EAssembler::pacia1716):
(JSC::ARM64EAssembler::pacib1716):
(JSC::ARM64EAssembler::autia1716):
(JSC::ARM64EAssembler::autib1716):
(JSC::ARM64EAssembler::paciaz):
(JSC::ARM64EAssembler::paciasp):
(JSC::ARM64EAssembler::pacibz):
(JSC::ARM64EAssembler::pacibsp):
(JSC::ARM64EAssembler::autiaz):
(JSC::ARM64EAssembler::autiasp):
(JSC::ARM64EAssembler::autibz):
(JSC::ARM64EAssembler::autibsp):
(JSC::ARM64EAssembler::xpaclri):
(JSC::ARM64EAssembler::pacia):
(JSC::ARM64EAssembler::pacib):
(JSC::ARM64EAssembler::pacda):
(JSC::ARM64EAssembler::pacdb):
(JSC::ARM64EAssembler::autia):
(JSC::ARM64EAssembler::autib):
(JSC::ARM64EAssembler::autda):
(JSC::ARM64EAssembler::autdb):
(JSC::ARM64EAssembler::paciza):
(JSC::ARM64EAssembler::pacizb):
(JSC::ARM64EAssembler::pacdza):
(JSC::ARM64EAssembler::pacdzb):
(JSC::ARM64EAssembler::autiza):
(JSC::ARM64EAssembler::autizb):
(JSC::ARM64EAssembler::autdza):
(JSC::ARM64EAssembler::autdzb):
(JSC::ARM64EAssembler::xpaci):
(JSC::ARM64EAssembler::xpacd):
(JSC::ARM64EAssembler::pacga):
(JSC::ARM64EAssembler::braa):
(JSC::ARM64EAssembler::brab):
(JSC::ARM64EAssembler::blraa):
(JSC::ARM64EAssembler::blrab):
(JSC::ARM64EAssembler::braaz):
(JSC::ARM64EAssembler::brabz):
(JSC::ARM64EAssembler::blraaz):
(JSC::ARM64EAssembler::blrabz):
(JSC::ARM64EAssembler::retaa):
(JSC::ARM64EAssembler::retab):
(JSC::ARM64EAssembler::eretaa):
(JSC::ARM64EAssembler::eretab):
(JSC::ARM64EAssembler::linkPointer):
(JSC::ARM64EAssembler::repatchPointer):
(JSC::ARM64EAssembler::setPointer):
(JSC::ARM64EAssembler::readPointer):
(JSC::ARM64EAssembler::readCallTarget):
(JSC::ARM64EAssembler::ret):
* assembler/MacroAssembler.cpp:
* assembler/MacroAssembler.h:
* assembler/MacroAssemblerARM64.cpp:
* assembler/MacroAssemblerARM64E.h: Added.
(JSC::MacroAssemblerARM64E::tagReturnAddress):
(JSC::MacroAssemblerARM64E::untagReturnAddress):
(JSC::MacroAssemblerARM64E::tagPtr):
(JSC::MacroAssemblerARM64E::untagPtr):
(JSC::MacroAssemblerARM64E::removePtrTag):
(JSC::MacroAssemblerARM64E::callTrustedPtr):
(JSC::MacroAssemblerARM64E::call):
(JSC::MacroAssemblerARM64E::callRegister):
(JSC::MacroAssemblerARM64E::jump):
* dfg/DFGOSRExit.cpp:
(JSC::DFG::reifyInlinedCallFrames):
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::reifyInlinedCallFrames):
* ftl/FTLThunks.cpp:
(JSC::FTL::genericGenerationThunkGenerator):
* jit/CCallHelpers.h:
(JSC::CCallHelpers::prepareForTailCallSlow):
* jit/CallFrameShuffler.cpp:
(JSC::CallFrameShuffler::prepareForTailCall):
* jit/ExecutableAllocator.cpp:
(JSC::ExecutableAllocator::allocate):
* jit/ThunkGenerators.cpp:
(JSC::arityFixupGenerator):
* llint/LLIntOfflineAsmConfig.h:
* llint/LowLevelInterpreter.asm:
* llint/LowLevelInterpreter64.asm:
* runtime/ClassInfo.h:
* runtime/InitializeThreading.cpp:
(JSC::initializeThreading):
* runtime/JSCPtrTag.cpp: Added.
(JSC::tagForPtr):
(JSC::ptrTagName):
(JSC::initializePtrTagLookup):
* runtime/JSCPtrTag.h:
(JSC::initializePtrTagLookup):
* runtime/Options.cpp:
(JSC::recomputeDependentOptions):

Source/WTF:

* WTF.xcodeproj/project.pbxproj:
* wtf/BlockPtr.h:
* wtf/Platform.h:
* wtf/PlatformRegisters.cpp: Added.
(WTF::threadStateLRInternal):
(WTF::threadStatePCInternal):
* wtf/PlatformRegisters.h:
* wtf/PointerPreparations.h:
* wtf/PtrTag.cpp: Added.
(WTF::tagForPtr):
(WTF::ptrTagName):
(WTF::registerPtrTagLookup):
(WTF::reportBadTag):
* wtf/PtrTag.h:
(WTF::removeCodePtrTag):
(WTF::tagCodePtrImpl):
(WTF::tagCodePtr):
(WTF::untagCodePtrImplHelper):
(WTF::untagCodePtrImpl):
(WTF::untagCodePtr):
(WTF::retagCodePtrImplHelper):
(WTF::retagCodePtrImpl):
(WTF::retagCodePtr):
(WTF::tagCFunctionPtrImpl):
(WTF::tagCFunctionPtr):
(WTF::untagCFunctionPtrImpl):
(WTF::untagCFunctionPtr):
(WTF::tagInt):
(WTF::assertIsCFunctionPtr):
(WTF::assertIsNullOrCFunctionPtr):
(WTF::assertIsNotTagged):
(WTF::assertIsTagged):
(WTF::assertIsNullOrTagged):
(WTF::isTaggedWith):
(WTF::assertIsTaggedWith):
(WTF::assertIsNullOrTaggedWith):
(WTF::usesPointerTagging):
(WTF::registerPtrTagLookup):
(WTF::reportBadTag):
(WTF::tagForPtr): Deleted.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@243254 268f45cc-cd09-0410-ab3c-d52691b4dbfc

32 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Sources.txt
Source/JavaScriptCore/assembler/ARM64EAssembler.h [new file with mode: 0644]
Source/JavaScriptCore/assembler/MacroAssembler.cpp
Source/JavaScriptCore/assembler/MacroAssembler.h
Source/JavaScriptCore/assembler/MacroAssemblerARM64.cpp
Source/JavaScriptCore/assembler/MacroAssemblerARM64E.h [new file with mode: 0644]
Source/JavaScriptCore/dfg/DFGOSRExit.cpp
Source/JavaScriptCore/dfg/DFGOSRExitCompilerCommon.cpp
Source/JavaScriptCore/ftl/FTLThunks.cpp
Source/JavaScriptCore/jit/CCallHelpers.h
Source/JavaScriptCore/jit/CallFrameShuffler.cpp
Source/JavaScriptCore/jit/ExecutableAllocator.cpp
Source/JavaScriptCore/jit/ThunkGenerators.cpp
Source/JavaScriptCore/llint/LLIntOfflineAsmConfig.h
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/runtime/ClassInfo.h
Source/JavaScriptCore/runtime/InitializeThreading.cpp
Source/JavaScriptCore/runtime/JSCPtrTag.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/JSCPtrTag.h
Source/JavaScriptCore/runtime/Options.cpp
Source/WTF/ChangeLog
Source/WTF/WTF.xcodeproj/project.pbxproj
Source/WTF/wtf/BlockPtr.h
Source/WTF/wtf/Platform.h
Source/WTF/wtf/PlatformRegisters.cpp [new file with mode: 0644]
Source/WTF/wtf/PlatformRegisters.h
Source/WTF/wtf/PointerPreparations.h
Source/WTF/wtf/PtrTag.cpp [new file with mode: 0644]
Source/WTF/wtf/PtrTag.h

index 4de4bd4..eccd6ce 100644 (file)
@@ -1,3 +1,109 @@
+2019-03-20  Mark Lam  <mark.lam@apple.com>
+
+        Open source arm64e code.
+        https://bugs.webkit.org/show_bug.cgi?id=196012
+        <rdar://problem/49066237>
+
+        Reviewed by Keith Miller.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * assembler/ARM64EAssembler.h: Added.
+        (JSC::ARM64EAssembler::encodeGroup1):
+        (JSC::ARM64EAssembler::encodeGroup2):
+        (JSC::ARM64EAssembler::encodeGroup4):
+        (JSC::ARM64EAssembler::pacia1716):
+        (JSC::ARM64EAssembler::pacib1716):
+        (JSC::ARM64EAssembler::autia1716):
+        (JSC::ARM64EAssembler::autib1716):
+        (JSC::ARM64EAssembler::paciaz):
+        (JSC::ARM64EAssembler::paciasp):
+        (JSC::ARM64EAssembler::pacibz):
+        (JSC::ARM64EAssembler::pacibsp):
+        (JSC::ARM64EAssembler::autiaz):
+        (JSC::ARM64EAssembler::autiasp):
+        (JSC::ARM64EAssembler::autibz):
+        (JSC::ARM64EAssembler::autibsp):
+        (JSC::ARM64EAssembler::xpaclri):
+        (JSC::ARM64EAssembler::pacia):
+        (JSC::ARM64EAssembler::pacib):
+        (JSC::ARM64EAssembler::pacda):
+        (JSC::ARM64EAssembler::pacdb):
+        (JSC::ARM64EAssembler::autia):
+        (JSC::ARM64EAssembler::autib):
+        (JSC::ARM64EAssembler::autda):
+        (JSC::ARM64EAssembler::autdb):
+        (JSC::ARM64EAssembler::paciza):
+        (JSC::ARM64EAssembler::pacizb):
+        (JSC::ARM64EAssembler::pacdza):
+        (JSC::ARM64EAssembler::pacdzb):
+        (JSC::ARM64EAssembler::autiza):
+        (JSC::ARM64EAssembler::autizb):
+        (JSC::ARM64EAssembler::autdza):
+        (JSC::ARM64EAssembler::autdzb):
+        (JSC::ARM64EAssembler::xpaci):
+        (JSC::ARM64EAssembler::xpacd):
+        (JSC::ARM64EAssembler::pacga):
+        (JSC::ARM64EAssembler::braa):
+        (JSC::ARM64EAssembler::brab):
+        (JSC::ARM64EAssembler::blraa):
+        (JSC::ARM64EAssembler::blrab):
+        (JSC::ARM64EAssembler::braaz):
+        (JSC::ARM64EAssembler::brabz):
+        (JSC::ARM64EAssembler::blraaz):
+        (JSC::ARM64EAssembler::blrabz):
+        (JSC::ARM64EAssembler::retaa):
+        (JSC::ARM64EAssembler::retab):
+        (JSC::ARM64EAssembler::eretaa):
+        (JSC::ARM64EAssembler::eretab):
+        (JSC::ARM64EAssembler::linkPointer):
+        (JSC::ARM64EAssembler::repatchPointer):
+        (JSC::ARM64EAssembler::setPointer):
+        (JSC::ARM64EAssembler::readPointer):
+        (JSC::ARM64EAssembler::readCallTarget):
+        (JSC::ARM64EAssembler::ret):
+        * assembler/MacroAssembler.cpp:
+        * assembler/MacroAssembler.h:
+        * assembler/MacroAssemblerARM64.cpp:
+        * assembler/MacroAssemblerARM64E.h: Added.
+        (JSC::MacroAssemblerARM64E::tagReturnAddress):
+        (JSC::MacroAssemblerARM64E::untagReturnAddress):
+        (JSC::MacroAssemblerARM64E::tagPtr):
+        (JSC::MacroAssemblerARM64E::untagPtr):
+        (JSC::MacroAssemblerARM64E::removePtrTag):
+        (JSC::MacroAssemblerARM64E::callTrustedPtr):
+        (JSC::MacroAssemblerARM64E::call):
+        (JSC::MacroAssemblerARM64E::callRegister):
+        (JSC::MacroAssemblerARM64E::jump):
+        * dfg/DFGOSRExit.cpp:
+        (JSC::DFG::reifyInlinedCallFrames):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::reifyInlinedCallFrames):
+        * ftl/FTLThunks.cpp:
+        (JSC::FTL::genericGenerationThunkGenerator):
+        * jit/CCallHelpers.h:
+        (JSC::CCallHelpers::prepareForTailCallSlow):
+        * jit/CallFrameShuffler.cpp:
+        (JSC::CallFrameShuffler::prepareForTailCall):
+        * jit/ExecutableAllocator.cpp:
+        (JSC::ExecutableAllocator::allocate):
+        * jit/ThunkGenerators.cpp:
+        (JSC::arityFixupGenerator):
+        * llint/LLIntOfflineAsmConfig.h:
+        * llint/LowLevelInterpreter.asm:
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/ClassInfo.h:
+        * runtime/InitializeThreading.cpp:
+        (JSC::initializeThreading):
+        * runtime/JSCPtrTag.cpp: Added.
+        (JSC::tagForPtr):
+        (JSC::ptrTagName):
+        (JSC::initializePtrTagLookup):
+        * runtime/JSCPtrTag.h:
+        (JSC::initializePtrTagLookup):
+        * runtime/Options.cpp:
+        (JSC::recomputeDependentOptions):
+
 2019-03-20  Tadeu Zagallo  <tzagallo@apple.com>
 
         JSC::createError needs to check for OOM in errorDescriptionForValue
index 6f4b9bb..ab4e1b2 100644 (file)
                FE1BD0211E72027900134BC9 /* CellProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1BD0201E72027000134BC9 /* CellProfile.h */; };
                FE1BD0251E72053800134BC9 /* HeapVerifier.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1BD0231E72052F00134BC9 /* HeapVerifier.h */; };
                FE1C0FFD1B193E9800B53FCA /* Exception.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1C0FFC1B193E9800B53FCA /* Exception.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FE1E2C3F2240DD5800F6B729 /* MacroAssemblerARM64E.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1E2C3E2240D30B00F6B729 /* MacroAssemblerARM64E.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               FE1E2C402240DD6200F6B729 /* ARM64EAssembler.h in Headers */ = {isa = PBXBuildFile; fileRef = FE1E2C3D2240D2F600F6B729 /* ARM64EAssembler.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FE20CE9E15F04A9500DF3430 /* LLIntCLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FE2A87601F02381600EB31B2 /* MinimumReservedZoneSize.h in Headers */ = {isa = PBXBuildFile; fileRef = FE2A875F1F02381600EB31B2 /* MinimumReservedZoneSize.h */; };
                FE3022D31E3D73A500BAC493 /* SigillCrashAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = FE3022D11E3D739600BAC493 /* SigillCrashAnalyzer.h */; settings = {ATTRIBUTES = (Private, ); }; };
                FE1BD0231E72052F00134BC9 /* HeapVerifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapVerifier.h; sourceTree = "<group>"; };
                FE1C0FFC1B193E9800B53FCA /* Exception.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Exception.h; sourceTree = "<group>"; };
                FE1C0FFE1B194FD100B53FCA /* Exception.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Exception.cpp; sourceTree = "<group>"; };
+               FE1E2C3C2240C1EF00F6B729 /* JSCPtrTag.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSCPtrTag.cpp; sourceTree = "<group>"; };
+               FE1E2C3D2240D2F600F6B729 /* ARM64EAssembler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARM64EAssembler.h; sourceTree = "<group>"; };
+               FE1E2C3E2240D30B00F6B729 /* MacroAssemblerARM64E.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacroAssemblerARM64E.h; sourceTree = "<group>"; };
                FE20CE9B15F04A9500DF3430 /* LLIntCLoop.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = LLIntCLoop.cpp; path = llint/LLIntCLoop.cpp; sourceTree = "<group>"; };
                FE20CE9C15F04A9500DF3430 /* LLIntCLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntCLoop.h; path = llint/LLIntCLoop.h; sourceTree = "<group>"; };
                FE2A875F1F02381600EB31B2 /* MinimumReservedZoneSize.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MinimumReservedZoneSize.h; sourceTree = "<group>"; };
                                F692A8870255597D01FF60F7 /* JSCJSValue.cpp */,
                                14ABB36E099C076400E2A24F /* JSCJSValue.h */,
                                865A30F0135007E100CDB49E /* JSCJSValueInlines.h */,
+                               FE1E2C3C2240C1EF00F6B729 /* JSCPtrTag.cpp */,
                                FE7497E5209001B00003565B /* JSCPtrTag.h */,
                                72AAF7CB1D0D318B005E60BE /* JSCustomGetterSetterFunction.cpp */,
                                72AAF7CC1D0D318B005E60BE /* JSCustomGetterSetterFunction.h */,
                                0F3730901C0CD70C00052BFA /* AllowMacroScratchRegisterUsage.h */,
                                AD412B351E7B57C0008AF157 /* AllowMacroScratchRegisterUsageIf.h */,
                                8640923B156EED3B00566CB2 /* ARM64Assembler.h */,
+                               FE1E2C3D2240D2F600F6B729 /* ARM64EAssembler.h */,
                                86ADD1430FDDEA980006EEC2 /* ARMv7Assembler.h */,
                                9688CB130ED12B4E001D649F /* AssemblerBuffer.h */,
                                86D3B2C110156BDE002865E7 /* AssemblerBufferWithConstantPool.h */,
                                86C36EE90EE1289D00B3DF59 /* MacroAssembler.h */,
                                FEB137561BB11EEE00CD5100 /* MacroAssemblerARM64.cpp */,
                                8640923C156EED3B00566CB2 /* MacroAssemblerARM64.h */,
+                               FE1E2C3E2240D30B00F6B729 /* MacroAssemblerARM64E.h */,
                                A729009B17976C6000317298 /* MacroAssemblerARMv7.cpp */,
                                86ADD1440FDDEA980006EEC2 /* MacroAssemblerARMv7.h */,
                                0F6DB7EB1D617D0F00CDBF8E /* MacroAssemblerCodeRef.cpp */,
                                0F2C63B01E60AE4300C13839 /* B3Bank.h in Headers */,
                                0FEC85011BDACDAC0080FF74 /* B3BasicBlock.h in Headers */,
                                0FEC85021BDACDAC0080FF74 /* B3BasicBlockInlines.h in Headers */,
+                               FE1E2C3F2240DD5800F6B729 /* MacroAssemblerARM64E.h in Headers */,
                                0FEC85031BDACDAC0080FF74 /* B3BasicBlockUtils.h in Headers */,
                                0F338E1C1BF286EA0013C88F /* B3BlockInsertionSet.h in Headers */,
                                0FEC85041BDACDAC0080FF74 /* B3BlockWorklist.h in Headers */,
                                0FEC853A1BDACDAC0080FF74 /* B3SwitchValue.h in Headers */,
                                0F4570411BE584CA0062A629 /* B3TimingScope.h in Headers */,
                                0FEC853C1BDACDAC0080FF74 /* B3Type.h in Headers */,
+                               FE1E2C402240DD6200F6B729 /* ARM64EAssembler.h in Headers */,
                                DCFDFBDA1D1F5D9E00FE3D72 /* B3TypeMap.h in Headers */,
                                0FEC853E1BDACDAC0080FF74 /* B3UpsilonValue.h in Headers */,
                                0FEC85401BDACDAC0080FF74 /* B3UseCounts.h in Headers */,
index b7c8e24..c8f8860 100644 (file)
@@ -802,6 +802,7 @@ runtime/JSAsyncGeneratorFunction.cpp
 runtime/JSBigInt.cpp
 runtime/JSBoundFunction.cpp
 runtime/JSCJSValue.cpp
+runtime/JSCPtrTag.cpp
 runtime/JSCallee.cpp
 runtime/JSCell.cpp
 runtime/JSCustomGetterSetterFunction.cpp
diff --git a/Source/JavaScriptCore/assembler/ARM64EAssembler.h b/Source/JavaScriptCore/assembler/ARM64EAssembler.h
new file mode 100644 (file)
index 0000000..0581c2a
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2018-2019 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. ``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
+
+#if ENABLE(ASSEMBLER) && CPU(ARM64E)
+
+#include "ARM64Assembler.h"
+
+namespace JSC {
+
+class ARM64EAssembler : public ARM64Assembler {
+protected:
+    static constexpr RegisterID unusedID = static_cast<RegisterID>(0b11111);
+
+    // Group 1 instructions from section 3.2.3.1.1.
+    enum class Group1Op {
+        PACIA1716 = 0b0001 << 8 | 0b000 << 5,
+        PACIB1716 = 0b0001 << 8 | 0b010 << 5,
+        AUTIA1716 = 0b0001 << 8 | 0b100 << 5,
+        AUTIB1716 = 0b0001 << 8 | 0b110 << 5,
+        PACIAZ    = 0b0011 << 8 | 0b000 << 5,
+        PACIASP   = 0b0011 << 8 | 0b001 << 5,
+        PACIBZ    = 0b0011 << 8 | 0b010 << 5,
+        PACIBSP   = 0b0011 << 8 | 0b011 << 5,
+        AUTIAZ    = 0b0011 << 8 | 0b100 << 5,
+        AUTIASP   = 0b0011 << 8 | 0b101 << 5,
+        AUTIBZ    = 0b0011 << 8 | 0b110 << 5,
+        AUTIBSP   = 0b0011 << 8 | 0b111 << 5,
+        XPACLRI   = 0b0000 << 8 | 0b111 << 5,
+    };
+
+    ALWAYS_INLINE static int encodeGroup1(Group1Op op)
+    {
+        return static_cast<int>(op) | 0b1101 << 28 | 0b0101 << 24 | 0b011 << 16 | 0b0010 << 12 | 0b11111;
+    }
+
+    // Group 2 instructions from section 3.2.3.1.1.
+    enum class Group2Op {
+        PACIA  = 1 << 30 | 0b00001 << 16 | 0b00000 << 10,
+        PACIB  = 1 << 30 | 0b00001 << 16 | 0b00001 << 10,
+        PACDA  = 1 << 30 | 0b00001 << 16 | 0b00010 << 10,
+        PACDB  = 1 << 30 | 0b00001 << 16 | 0b00011 << 10,
+        AUTIA  = 1 << 30 | 0b00001 << 16 | 0b00100 << 10,
+        AUTIB  = 1 << 30 | 0b00001 << 16 | 0b00101 << 10,
+        AUTDA  = 1 << 30 | 0b00001 << 16 | 0b00110 << 10,
+        AUTDB  = 1 << 30 | 0b00001 << 16 | 0b00111 << 10,
+        PACIZA = 1 << 30 | 0b00001 << 16 | 0b01000 << 10,
+        PACIZB = 1 << 30 | 0b00001 << 16 | 0b01001 << 10,
+        PACDZA = 1 << 30 | 0b00001 << 16 | 0b01010 << 10,
+        PACDZB = 1 << 30 | 0b00001 << 16 | 0b01011 << 10,
+        AUTIZA = 1 << 30 | 0b00001 << 16 | 0b01100 << 10,
+        AUTIZB = 1 << 30 | 0b00001 << 16 | 0b01101 << 10,
+        AUTDZA = 1 << 30 | 0b00001 << 16 | 0b01110 << 10,
+        AUTDZB = 1 << 30 | 0b00001 << 16 | 0b01111 << 10,
+        XPACI  = 1 << 30 | 0b00001 << 16 | 0b10000 << 10,
+        XPACD  = 1 << 30 | 0b00001 << 16 | 0b10001 << 10,
+
+        PACGA  = 0 << 30 | 0b01100,
+    };
+
+    ALWAYS_INLINE static int encodeGroup2(Group2Op op, RegisterID rn, RegisterID rd, RegisterID rm)
+    {
+        ASSERT((rn & 0b11111) == rn);
+        ASSERT((rd & 0b11111) == rd);
+        ASSERT((rm & 0b11111) == rm);
+        return static_cast<int>(op) | 1 << 31 | 0b11010110 << 21 | rm << 16 | rn << 5 | rd;
+    }
+
+    ALWAYS_INLINE static int encodeGroup2(Group2Op op, RegisterID rn, RegisterID rd)
+    {
+        return encodeGroup2(op, rn, rd, static_cast<RegisterID>(0));
+    }
+
+    ALWAYS_INLINE static int encodeGroup2(Group2Op op, RegisterID rd)
+    {
+        return encodeGroup2(op, unusedID, rd);
+    }
+
+    // Group 4 instructions from section 3.2.3.2.1.
+    enum class Group4Op {
+        BRAA   = 0b1000 << 21 | 0 << 10,
+        BRAB   = 0b1000 << 21 | 1 << 10,
+        BLRAA  = 0b1001 << 21 | 0 << 10,
+        BLRAB  = 0b1001 << 21 | 1 << 10,
+
+        BRAAZ  = 0b0000 << 21 | 0 << 10,
+        BRABZ  = 0b0000 << 21 | 1 << 10,
+        BLRAAZ = 0b0001 << 21 | 0 << 10,
+        BLRABZ = 0b0001 << 21 | 1 << 10,
+        RETAA  = 0b0010 << 21 | 0 << 10 | 0b11111 << 5,
+        RETAB  = 0b0010 << 21 | 1 << 10 | 0b11111 << 5,
+        ERETAA = 0b0100 << 21 | 0 << 10 | 0b11111 << 5,
+        ERETAB = 0b0100 << 21 | 1 << 10 | 0b11111 << 5,
+    };
+
+    ALWAYS_INLINE static int encodeGroup4(Group4Op op, RegisterID rn = unusedID, RegisterID rm = unusedID)
+    {
+        ASSERT((rn & 0b11111) == rn);
+        ASSERT((rm & 0b11111) == rm);
+        return (0b1101011 << 25 | static_cast<int>(op) | 0b11111 << 16 | 0b00001 << 11 | rn << 5 | rm);
+    }
+
+public:
+    ALWAYS_INLINE void pacia1716() { insn(encodeGroup1(Group1Op::PACIA1716)); }
+    ALWAYS_INLINE void pacib1716() { insn(encodeGroup1(Group1Op::PACIB1716)); }
+    ALWAYS_INLINE void autia1716() { insn(encodeGroup1(Group1Op::AUTIA1716)); }
+    ALWAYS_INLINE void autib1716() { insn(encodeGroup1(Group1Op::AUTIB1716)); }
+    ALWAYS_INLINE void paciaz() { insn(encodeGroup1(Group1Op::PACIAZ)); }
+    ALWAYS_INLINE void paciasp() { insn(encodeGroup1(Group1Op::PACIASP)); }
+    ALWAYS_INLINE void pacibz() { insn(encodeGroup1(Group1Op::PACIBZ)); }
+    ALWAYS_INLINE void pacibsp() { insn(encodeGroup1(Group1Op::PACIBSP)); }
+    ALWAYS_INLINE void autiaz() { insn(encodeGroup1(Group1Op::AUTIAZ)); }
+    ALWAYS_INLINE void autiasp() { insn(encodeGroup1(Group1Op::AUTIASP)); }
+    ALWAYS_INLINE void autibz() { insn(encodeGroup1(Group1Op::AUTIBZ)); }
+    ALWAYS_INLINE void autibsp() { insn(encodeGroup1(Group1Op::AUTIBSP)); }
+    ALWAYS_INLINE void xpaclri() { insn(encodeGroup1(Group1Op::XPACLRI)); }
+
+    ALWAYS_INLINE void pacia(RegisterID rd, RegisterID rn)
+    {
+        insn(encodeGroup2(Group2Op::PACIA, rn, rd));
+    }
+
+    ALWAYS_INLINE void pacib(RegisterID rd, RegisterID rn)
+    {
+        insn(encodeGroup2(Group2Op::PACIB, rn, rd));
+    }
+
+    ALWAYS_INLINE void pacda(RegisterID rd, RegisterID rn)
+    {
+        insn(encodeGroup2(Group2Op::PACDA, rn, rd));
+    }
+
+    ALWAYS_INLINE void pacdb(RegisterID rd, RegisterID rn)
+    {
+        insn(encodeGroup2(Group2Op::PACDB, rn, rd));
+    }
+
+    ALWAYS_INLINE void autia(RegisterID rd, RegisterID rn)
+    {
+        insn(encodeGroup2(Group2Op::AUTIA, rn, rd));
+    }
+
+    ALWAYS_INLINE void autib(RegisterID rd, RegisterID rn)
+    {
+        insn(encodeGroup2(Group2Op::AUTIB, rn, rd));
+    }
+
+    ALWAYS_INLINE void autda(RegisterID rd, RegisterID rn)
+    {
+        insn(encodeGroup2(Group2Op::AUTDA, rn, rd));
+    }
+
+    ALWAYS_INLINE void autdb(RegisterID rd, RegisterID rn)
+    {
+        insn(encodeGroup2(Group2Op::AUTDB, rn, rd));
+    }
+
+    ALWAYS_INLINE void paciza(RegisterID rd)
+    {
+        insn(encodeGroup2(Group2Op::PACIZA, rd));
+    }
+
+    ALWAYS_INLINE void pacizb(RegisterID rd)
+    {
+        insn(encodeGroup2(Group2Op::PACIZB, rd));
+    }
+
+    ALWAYS_INLINE void pacdza(RegisterID rd)
+    {
+        insn(encodeGroup2(Group2Op::PACDZA, rd));
+    }
+
+    ALWAYS_INLINE void pacdzb(RegisterID rd)
+    {
+        insn(encodeGroup2(Group2Op::PACDZB, rd));
+    }
+
+    ALWAYS_INLINE void autiza(RegisterID rd)
+    {
+        insn(encodeGroup2(Group2Op::AUTIZA, rd));
+    }
+
+    ALWAYS_INLINE void autizb(RegisterID rd)
+    {
+        insn(encodeGroup2(Group2Op::AUTIZB, rd));
+    }
+
+    ALWAYS_INLINE void autdza(RegisterID rd)
+    {
+        insn(encodeGroup2(Group2Op::AUTDZA, rd));
+    }
+
+    ALWAYS_INLINE void autdzb(RegisterID rd)
+    {
+        insn(encodeGroup2(Group2Op::AUTDZB, rd));
+    }
+
+    ALWAYS_INLINE void xpaci(RegisterID rd)
+    {
+        insn(encodeGroup2(Group2Op::XPACI, rd));
+    }
+
+    ALWAYS_INLINE void xpacd(RegisterID rd)
+    {
+        insn(encodeGroup2(Group2Op::XPACD, rd));
+    }
+
+    ALWAYS_INLINE void pacga(RegisterID rd, RegisterID rn, RegisterID rm)
+    {
+        insn(encodeGroup2(Group2Op::PACGA, rn, rd, rm));
+    }
+
+    // Group 4 instructions from section 3.2.3.2.1.
+    ALWAYS_INLINE void braa(RegisterID dest, RegisterID diversity)
+    {
+        insn(encodeGroup4(Group4Op::BRAA, dest, diversity));
+    }
+
+    ALWAYS_INLINE void brab(RegisterID dest, RegisterID diversity)
+    {
+        insn(encodeGroup4(Group4Op::BRAB, dest, diversity));
+    }
+
+    ALWAYS_INLINE void blraa(RegisterID dest, RegisterID diversity)
+    {
+        insn(encodeGroup4(Group4Op::BLRAA, dest, diversity));
+    }
+
+    ALWAYS_INLINE void blrab(RegisterID dest, RegisterID diversity)
+    {
+        insn(encodeGroup4(Group4Op::BLRAB, dest, diversity));
+    }
+
+    ALWAYS_INLINE void braaz(RegisterID dest)
+    {
+        insn(encodeGroup4(Group4Op::BLRAAZ, dest));
+    }
+
+    ALWAYS_INLINE void brabz(RegisterID dest)
+    {
+        insn(encodeGroup4(Group4Op::BLRABZ, dest));
+    }
+
+    ALWAYS_INLINE void blraaz(RegisterID dest)
+    {
+        insn(encodeGroup4(Group4Op::BLRAAZ, dest));
+    }
+
+    ALWAYS_INLINE void blrabz(RegisterID dest)
+    {
+        insn(encodeGroup4(Group4Op::BLRABZ, dest));
+    }
+
+    ALWAYS_INLINE void retaa() { insn(encodeGroup4(Group4Op::RETAA)); }
+    ALWAYS_INLINE void retab() { insn(encodeGroup4(Group4Op::RETAB)); }
+    ALWAYS_INLINE void eretaa() { insn(encodeGroup4(Group4Op::ERETAA)); }
+    ALWAYS_INLINE void eretab() { insn(encodeGroup4(Group4Op::ERETAB)); }
+
+    // Overload of the ARM64 equivalents.
+
+    // Needed because we need to call our overloaded linkPointer below.
+    static void linkPointer(void* code, AssemblerLabel where, void* valuePtr)
+    {
+        linkPointer(addressOf(code, where), valuePtr);
+    }
+
+    // Needed because we need to add the assert for address[3], and because we need to
+    // call our own version of setPointer() below.
+    static void linkPointer(int* address, void* valuePtr, bool flush = false)
+    {
+        Datasize sf;
+        MoveWideOp opc;
+        int hw;
+        uint16_t imm16;
+        RegisterID rd;
+        bool expected = disassembleMoveWideImediate(address, sf, opc, hw, imm16, rd);
+        ASSERT_UNUSED(expected, expected && sf && opc == MoveWideOp_Z && !hw);
+        ASSERT(checkMovk<Datasize_64>(address[1], 1, rd));
+        ASSERT(checkMovk<Datasize_64>(address[2], 2, rd));
+        if (NUMBER_OF_ADDRESS_ENCODING_INSTRUCTIONS > 3)
+            ASSERT(checkMovk<Datasize_64>(address[3], 3, rd));
+
+        setPointer(address, valuePtr, rd, flush);
+    }
+
+    // Needed because we need to call our overloaded linkPointer above.
+    static void repatchPointer(void* where, void* valuePtr)
+    {
+        linkPointer(static_cast<int*>(where), valuePtr, true);
+    }
+
+    // Needed because we need to set buffer[3]: signed pointers take up more than 48 bits.
+    static void setPointer(int* address, void* valuePtr, RegisterID rd, bool flush)
+    {
+        uintptr_t value = reinterpret_cast<uintptr_t>(valuePtr);
+        int buffer[4];
+        buffer[0] = moveWideImediate(Datasize_64, MoveWideOp_Z, 0, getHalfword(value, 0), rd);
+        buffer[1] = moveWideImediate(Datasize_64, MoveWideOp_K, 1, getHalfword(value, 1), rd);
+        buffer[2] = moveWideImediate(Datasize_64, MoveWideOp_K, 2, getHalfword(value, 2), rd);
+        if (NUMBER_OF_ADDRESS_ENCODING_INSTRUCTIONS > 3)
+            buffer[3] = moveWideImediate(Datasize_64, MoveWideOp_K, 3, getHalfword(value, 3), rd);
+        RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(address) == address);
+        performJITMemcpy(address, buffer, sizeof(int) * 4);
+
+        if (flush)
+            cacheFlush(address, sizeof(int) * 4);
+    }
+
+    static void* readPointer(void* where)
+    {
+        int* address = static_cast<int*>(where);
+
+        Datasize sf;
+        MoveWideOp opc;
+        int hw;
+        uint16_t imm16;
+        RegisterID rdFirst, rd;
+
+        bool expected = disassembleMoveWideImediate(address, sf, opc, hw, imm16, rdFirst);
+        ASSERT_UNUSED(expected, expected && sf && opc == MoveWideOp_Z && !hw);
+        uintptr_t result = imm16;
+
+        expected = disassembleMoveWideImediate(address + 1, sf, opc, hw, imm16, rd);
+        ASSERT_UNUSED(expected, expected && sf && opc == MoveWideOp_K && hw == 1 && rd == rdFirst);
+        result |= static_cast<uintptr_t>(imm16) << 16;
+
+        expected = disassembleMoveWideImediate(address + 2, sf, opc, hw, imm16, rd);
+        ASSERT_UNUSED(expected, expected && sf && opc == MoveWideOp_K && hw == 2 && rd == rdFirst);
+        result |= static_cast<uintptr_t>(imm16) << 32;
+
+        if (NUMBER_OF_ADDRESS_ENCODING_INSTRUCTIONS > 3) {
+            expected = disassembleMoveWideImediate(address + 3, sf, opc, hw, imm16, rd);
+            ASSERT_UNUSED(expected, expected && sf && opc == MoveWideOp_K && hw == 3 && rd == rdFirst);
+            result |= static_cast<uintptr_t>(imm16) << 48;
+        }
+
+        return reinterpret_cast<void*>(result);
+    }
+
+    static void* readCallTarget(void* from)
+    {
+        constexpr ptrdiff_t callInstruction = 1;
+        return readPointer(reinterpret_cast<int*>(from) - callInstruction - NUMBER_OF_ADDRESS_ENCODING_INSTRUCTIONS);
+    }
+
+    ALWAYS_INLINE void ret() { retab(); }
+
+    // Needed because we need to call our overloaded ret() above.
+    ALWAYS_INLINE void ret(RegisterID rn)
+    {
+        RELEASE_ASSERT(rn == ARM64Registers::lr);
+        ret();
+    }
+
+    static constexpr ptrdiff_t MAX_POINTER_BITS = 64;
+    static constexpr ptrdiff_t BITS_ENCODEABLE_PER_INSTRUCTION = 16;
+    static constexpr ptrdiff_t NUMBER_OF_ADDRESS_ENCODING_INSTRUCTIONS = MAX_POINTER_BITS / BITS_ENCODEABLE_PER_INSTRUCTION;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER) && CPU(ARM64E)
index ecab4d1..df02842 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include <wtf/PrintStream.h>
 #include <wtf/ScopedLambda.h>
 
-#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/MacroAssemblerSupport.h>)
-#include <WebKitAdditions/MacroAssemblerSupport.h>
-#endif
-
 namespace JSC {
 
 const double MacroAssembler::twoToThe32 = (double)0x100000000ull;
index c18ed83..e3ba8cd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "MacroAssemblerARMv7.h"
 namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; };
 
-#elif CPU(ARM64E) && __has_include(<WebKitAdditions/MacroAssemblerARM64E.h>)
+#elif CPU(ARM64E)
 #define TARGET_ASSEMBLER ARM64EAssembler
 #define TARGET_MACROASSEMBLER MacroAssemblerARM64E
-#include <WebKitAdditions/MacroAssemblerARM64E.h>
+#include "MacroAssemblerARM64E.h"
 
 #elif CPU(ARM64)
 #define TARGET_ASSEMBLER ARM64Assembler
index f15b5b0..bc70168 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -381,7 +381,11 @@ asm (
     // Note: we haven't changed the value of fp. Hence, it is still pointing to the frame of
     // the caller of the probe (which is what we want in order to play nice with debuggers e.g. lldb).
     "mov       x0, sp" "\n" // Set the Probe::State* arg.
-    CALL_WITH_PTRTAG("blr", "x28", CFunctionPtrTag) // Call the probe handler.
+#if CPU(ARM64E)
+    "blraaz    x28" "\n" // Call the probe handler.
+#else
+    "blr       x28" "\n" // Call the probe handler.
+#endif
 
     // Make sure the Probe::State is entirely below the result stack pointer so
     // that register values are still preserved when we call the initializeStack
@@ -417,7 +421,11 @@ asm (
     "cbz       x2, " LOCAL_LABEL_STRING(ctiMasmProbeTrampolineRestoreRegisters) "\n"
 
     "mov       x0, x27" "\n" // Set the Probe::State* arg.
-    CALL_WITH_PTRTAG("blr", "x2", CFunctionPtrTag) // Call the initializeStackFunction (loaded into x2 above).
+#if CPU(ARM64E)
+    "blraaz    x2" "\n" // Call the initializeStackFunction (loaded into x2 above).
+#else
+    "blr       x2" "\n" // Call the initializeStackFunction (loaded into x2 above).
+#endif
 
     LOCAL_LABEL_STRING(ctiMasmProbeTrampolineRestoreRegisters) ":" "\n"
 
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerARM64E.h b/Source/JavaScriptCore/assembler/MacroAssemblerARM64E.h
new file mode 100644 (file)
index 0000000..41940cd
--- /dev/null
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2018-2019 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. ``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
+
+#if ENABLE(ASSEMBLER) && CPU(ARM64E)
+
+// We need to include this before MacroAssemblerARM64.h because MacroAssemblerARM64
+// will be defined in terms of ARM64EAssembler for ARM64E.
+#include "ARM64EAssembler.h"
+#include "JSCPtrTag.h"
+#include "MacroAssemblerARM64.h"
+
+namespace JSC {
+
+using Assembler = TARGET_ASSEMBLER;
+
+class MacroAssemblerARM64E : public MacroAssemblerARM64 {
+public:
+    ALWAYS_INLINE void tagReturnAddress()
+    {
+        tagPtr(ARM64Registers::lr, ARM64Registers::sp);
+    }
+
+    ALWAYS_INLINE void untagReturnAddress()
+    {
+        untagPtr(ARM64Registers::lr, ARM64Registers::sp);
+    }
+
+    ALWAYS_INLINE void tagPtr(RegisterID target, PtrTag tag)
+    {
+        auto tagGPR = getCachedDataTempRegisterIDAndInvalidate();
+        move(TrustedImm64(tag), tagGPR);
+        m_assembler.pacib(target, tagGPR);
+    }
+
+    ALWAYS_INLINE void tagPtr(RegisterID target, RegisterID tag)
+    {
+        if (target == ARM64Registers::lr && tag == ARM64Registers::sp) {
+            m_assembler.pacibsp();
+            return;
+        }
+        m_assembler.pacib(target, tag);
+    }
+
+    ALWAYS_INLINE void untagPtr(RegisterID target, PtrTag tag)
+    {
+        auto tagGPR = getCachedDataTempRegisterIDAndInvalidate();
+        move(TrustedImm64(tag), tagGPR);
+        m_assembler.autib(target, tagGPR);
+    }
+
+    ALWAYS_INLINE void untagPtr(RegisterID target, RegisterID tag)
+    {
+        m_assembler.autib(target, tag);
+    }
+
+    ALWAYS_INLINE void removePtrTag(RegisterID target)
+    {
+        m_assembler.xpaci(target);
+    }
+
+    static const RegisterID InvalidGPR  = static_cast<RegisterID>(-1);
+
+    enum class CallSignatureType {
+        CFunctionCall,
+        OtherCall
+    };
+
+    template<CallSignatureType type>
+    ALWAYS_INLINE Call callTrustedPtr(RegisterID tagGPR = InvalidGPR)
+    {
+        ASSERT(tagGPR != dataTempRegister);
+        AssemblerLabel pointerLabel = m_assembler.label();
+        moveWithFixedWidth(TrustedImmPtr(nullptr), getCachedDataTempRegisterIDAndInvalidate());
+        invalidateAllTempRegisters();
+        if (type == CallSignatureType::CFunctionCall)
+            m_assembler.blraaz(dataTempRegister);
+        else
+            m_assembler.blrab(dataTempRegister, tagGPR);
+        AssemblerLabel callLabel = m_assembler.label();
+        ASSERT_UNUSED(pointerLabel, ARM64Assembler::getDifferenceBetweenLabels(callLabel, pointerLabel) == REPATCH_OFFSET_CALL_TO_POINTER);
+        return Call(callLabel, Call::Linkable);
+    }
+
+    ALWAYS_INLINE Call call(PtrTag tag)
+    {
+        if (tag == NoPtrTag)
+            return MacroAssemblerARM64::call(tag);
+        if (tag == CFunctionPtrTag)
+            return callTrustedPtr<CallSignatureType::CFunctionCall>();
+        move(TrustedImm64(tag), ARM64Registers::lr);
+        return callTrustedPtr<CallSignatureType::OtherCall>(ARM64Registers::lr);
+    }
+
+    ALWAYS_INLINE Call call(RegisterID tagGPR)
+    {
+        return callTrustedPtr<CallSignatureType::OtherCall>(tagGPR);
+    }
+
+    template<CallSignatureType type>
+    ALWAYS_INLINE Call callRegister(RegisterID targetGPR, RegisterID tagGPR = InvalidGPR)
+    {
+        ASSERT(tagGPR != targetGPR);
+        invalidateAllTempRegisters();
+        if (type == CallSignatureType::CFunctionCall)
+            m_assembler.blraaz(targetGPR);
+        else
+            m_assembler.blrab(targetGPR, tagGPR);
+        return Call(m_assembler.label(), Call::None);
+    }
+
+    ALWAYS_INLINE Call call(RegisterID targetGPR, PtrTag tag)
+    {
+        if (tag == NoPtrTag)
+            return MacroAssemblerARM64::call(targetGPR, tag);
+        if (tag == CFunctionPtrTag)
+            return callRegister<CallSignatureType::CFunctionCall>(targetGPR);
+        move(TrustedImm64(tag), ARM64Registers::lr);
+        return callRegister<CallSignatureType::OtherCall>(targetGPR, ARM64Registers::lr);
+    }
+
+    ALWAYS_INLINE Call call(RegisterID targetGPR, RegisterID tagGPR)
+    {
+        return callRegister<CallSignatureType::OtherCall>(targetGPR, tagGPR);
+    }
+
+    ALWAYS_INLINE Call call(Address address, PtrTag tag)
+    {
+        if (tag == NoPtrTag)
+            return MacroAssemblerARM64::call(address, tag);
+
+        load64(address, getCachedDataTempRegisterIDAndInvalidate());
+        return call(dataTempRegister, tag);
+    }
+
+    ALWAYS_INLINE Call call(Address address, RegisterID tag)
+    {
+        ASSERT(tag != dataTempRegister);
+        load64(address, getCachedDataTempRegisterIDAndInvalidate());
+        return call(dataTempRegister, tag);
+    }
+
+    ALWAYS_INLINE Jump jump() { return MacroAssemblerARM64::jump(); }
+
+    void jump(RegisterID target, PtrTag tag)
+    {
+        if (tag == NoPtrTag)
+            return MacroAssemblerARM64::jump(target, tag);
+
+        ASSERT(tag != CFunctionPtrTag);
+        RegisterID diversityGPR = getCachedDataTempRegisterIDAndInvalidate();
+        move(TrustedImm64(tag), diversityGPR);
+        jump(target, diversityGPR);
+    }
+
+    void jump(RegisterID target, RegisterID tag)
+    {
+        ASSERT(tag != target);
+        m_assembler.brab(target, tag);
+    }
+
+    void jump(Address address, PtrTag tag)
+    {
+        if (tag == NoPtrTag)
+            return MacroAssemblerARM64::jump(address, tag);
+
+        ASSERT(tag != CFunctionPtrTag);
+        RegisterID targetGPR = getCachedDataTempRegisterIDAndInvalidate();
+        RegisterID diversityGPR = getCachedMemoryTempRegisterIDAndInvalidate();
+        load64(address, targetGPR);
+        move(TrustedImm64(tag), diversityGPR);
+        m_assembler.brab(targetGPR, diversityGPR);
+    }
+
+    void jump(Address address, RegisterID tag)
+    {
+        RegisterID targetGPR = getCachedDataTempRegisterIDAndInvalidate();
+        ASSERT(tag != targetGPR);
+        load64(address, targetGPR);
+        m_assembler.brab(targetGPR, tag);
+    }
+
+    void jump(BaseIndex address, PtrTag tag)
+    {
+        if (tag == NoPtrTag)
+            return MacroAssemblerARM64::jump(address, tag);
+
+        ASSERT(tag != CFunctionPtrTag);
+        RegisterID targetGPR = getCachedDataTempRegisterIDAndInvalidate();
+        RegisterID diversityGPR = getCachedMemoryTempRegisterIDAndInvalidate();
+        load64(address, targetGPR);
+        move(TrustedImm64(tag), diversityGPR);
+        m_assembler.brab(targetGPR, diversityGPR);
+    }
+
+    void jump(BaseIndex address, RegisterID tag)
+    {
+        RegisterID targetGPR = getCachedDataTempRegisterIDAndInvalidate();
+        ASSERT(tag != targetGPR);
+        load64(address, targetGPR);
+        m_assembler.brab(targetGPR, tag);
+    }
+
+    void jump(AbsoluteAddress address, PtrTag tag)
+    {
+        if (tag == NoPtrTag)
+            return MacroAssemblerARM64::jump(address, tag);
+
+        RegisterID targetGPR = getCachedDataTempRegisterIDAndInvalidate();
+        RegisterID diversityGPR = getCachedMemoryTempRegisterIDAndInvalidate();
+        move(TrustedImmPtr(address.m_ptr), targetGPR);
+        load64(Address(targetGPR), targetGPR);
+        move(TrustedImm64(tag), diversityGPR);
+        m_assembler.brab(targetGPR, diversityGPR);
+    }
+
+    void jump(AbsoluteAddress address, RegisterID tag)
+    {
+        RegisterID targetGPR = getCachedDataTempRegisterIDAndInvalidate();
+        ASSERT(tag != targetGPR);
+        move(TrustedImmPtr(address.m_ptr), targetGPR);
+        load64(Address(targetGPR), targetGPR);
+        m_assembler.brab(targetGPR, tag);
+    }
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER) && CPU(ARM64E)
index bcebede..63fed3f 100644 (file)
@@ -758,7 +758,7 @@ static void reifyInlinedCallFrames(Context& context, CodeBlock* outermostBaselin
         if (!trueCaller) {
             ASSERT(inlineCallFrame->isTail());
             void* returnPC = frame.get<void*>(CallFrame::returnPCOffset());
-#if USE(POINTER_PROFILING)
+#if CPU(ARM64E)
             void* oldEntrySP = cpu.fp<uint8_t*>() + sizeof(CallerFrameAndPC);
             void* newEntrySP = cpu.fp<uint8_t*>() + inlineCallFrame->returnPCOffset() + sizeof(void*);
             returnPC = retagCodePtr(returnPC, bitwise_cast<PtrTag>(oldEntrySP), bitwise_cast<PtrTag>(newEntrySP));
@@ -803,7 +803,7 @@ static void reifyInlinedCallFrames(Context& context, CodeBlock* outermostBaselin
                 callerFrame = cpu.fp<uint8_t*>() + trueCaller->inlineCallFrame()->stackOffset * sizeof(EncodedJSValue);
 
             void* targetAddress = jumpTarget.executableAddress();
-#if USE(POINTER_PROFILING)
+#if CPU(ARM64E)
             void* newEntrySP = cpu.fp<uint8_t*>() + inlineCallFrame->returnPCOffset() + sizeof(void*);
             targetAddress = retagCodePtr(targetAddress, JSInternalPtrTag, bitwise_cast<PtrTag>(newEntrySP));
 #endif
index 60331f5..8353800 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -155,7 +155,7 @@ void reifyInlinedCallFrames(CCallHelpers& jit, const OSRExitBase& exit)
         if (!trueCaller) {
             ASSERT(inlineCallFrame->isTail());
             jit.loadPtr(AssemblyHelpers::Address(GPRInfo::callFrameRegister, CallFrame::returnPCOffset()), GPRInfo::regT3);
-#if USE(POINTER_PROFILING)
+#if CPU(ARM64E)
             jit.addPtr(AssemblyHelpers::TrustedImm32(sizeof(CallerFrameAndPC)), GPRInfo::callFrameRegister, GPRInfo::regT2);
             jit.untagPtr(GPRInfo::regT3, GPRInfo::regT2);
             jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->returnPCOffset() + sizeof(void*)), GPRInfo::callFrameRegister, GPRInfo::regT2);
@@ -206,7 +206,7 @@ void reifyInlinedCallFrames(CCallHelpers& jit, const OSRExitBase& exit)
                 callerFrameGPR = GPRInfo::regT3;
             }
 
-#if USE(POINTER_PROFILING)
+#if CPU(ARM64E)
             jit.addPtr(AssemblyHelpers::TrustedImm32(inlineCallFrame->returnPCOffset() + sizeof(void*)), GPRInfo::callFrameRegister, GPRInfo::regT2);
             jit.move(AssemblyHelpers::TrustedImmPtr(jumpTarget), GPRInfo::nonArgGPR0);
             jit.tagPtr(GPRInfo::nonArgGPR0, GPRInfo::regT2);
index 0c6a676..1263a79 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -115,7 +115,7 @@ static MacroAssemblerCodeRef<JITThunkPtrTag> genericGenerationThunkGenerator(
 
     restoreAllRegisters(jit, buffer);
 
-#if CPU(ARM64) && USE(POINTER_PROFILING)
+#if CPU(ARM64E)
     jit.untagPtr(AssemblyHelpers::linkRegister, resultTag);
     jit.tagReturnAddress();
 #else
index 6121018..e21286f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -805,7 +805,7 @@ public:
 #if CPU(ARM_THUMB2) || CPU(ARM64)
         loadPtr(Address(framePointerRegister, CallFrame::returnPCOffset()), linkRegister);
         subPtr(TrustedImm32(2 * sizeof(void*)), newFrameSizeGPR);
-#if USE(POINTER_PROFILING)
+#if CPU(ARM64E)
         addPtr(TrustedImm32(sizeof(CallerFrameAndPC)), MacroAssembler::framePointerRegister, tempGPR);
         untagPtr(linkRegister, tempGPR);
 #endif
index 81c3e2d..02e372c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -454,7 +454,7 @@ void CallFrameShuffler::prepareForTailCall()
 #if CPU(ARM_THUMB2) || CPU(ARM64)
     m_jit.loadPtr(MacroAssembler::Address(MacroAssembler::framePointerRegister, CallFrame::returnPCOffset()),
         MacroAssembler::linkRegister);
-#if USE(POINTER_PROFILING)
+#if CPU(ARM64E)
     m_jit.addPtr(MacroAssembler::TrustedImm32(sizeof(CallerFrameAndPC)), MacroAssembler::framePointerRegister);
     m_jit.untagPtr(MacroAssembler::linkRegister, MacroAssembler::framePointerRegister);
     m_jit.subPtr(MacroAssembler::TrustedImm32(sizeof(CallerFrameAndPC)), MacroAssembler::framePointerRegister);
index 4606756..bc6c33c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -501,7 +501,7 @@ RefPtr<ExecutableMemoryHandle> ExecutableAllocator::allocate(size_t sizeInBytes,
         return nullptr;
     }
 
-#if USE(POINTER_PROFILING)
+#if CPU(ARM64E)
     void* start = allocator->memoryStart();
     void* end = allocator->memoryEnd();
     void* resultStart = result->start().untaggedPtr();
index ec5483b..8e96351 100644 (file)
@@ -456,7 +456,7 @@ MacroAssemblerCodeRef<JITThunkPtrTag> arityFixupGenerator(VM* vm)
     jit.pop(JSInterfaceJIT::regT4);
 #  endif
     jit.tagReturnAddress();
-#if CPU(ARM64) && USE(POINTER_PROFILING)
+#if CPU(ARM64E)
     jit.loadPtr(JSInterfaceJIT::Address(GPRInfo::callFrameRegister, CallFrame::returnPCOffset()), GPRInfo::regT3);
     jit.addPtr(JSInterfaceJIT::TrustedImm32(sizeof(CallerFrameAndPC)), GPRInfo::callFrameRegister, extraTemp);
     jit.untagPtr(GPRInfo::regT3, extraTemp);
@@ -512,7 +512,7 @@ MacroAssemblerCodeRef<JITThunkPtrTag> arityFixupGenerator(VM* vm)
     
     done.link(&jit);
 
-#if CPU(ARM64) && USE(POINTER_PROFILING)
+#if CPU(ARM64E)
     jit.loadPtr(JSInterfaceJIT::Address(GPRInfo::callFrameRegister, CallFrame::returnPCOffset()), GPRInfo::regT3);
     jit.move(JSInterfaceJIT::TrustedImmPtr(tempReturnPCTag), extraTemp);
     jit.untagPtr(GPRInfo::regT3, extraTemp);
index f05e2fc..de5a145 100644 (file)
 #define OFFLINE_ASM_TRACING 0
 #endif
 
-#if USE(POINTER_PROFILING)
-#define OFFLINE_ASM_POINTER_PROFILING 1
-#else
-#define OFFLINE_ASM_POINTER_PROFILING 0
-#endif
-
 #define OFFLINE_ASM_GIGACAGE_ENABLED GIGACAGE_ENABLED
index 793572e..bc419ed 100644 (file)
@@ -948,7 +948,7 @@ macro prepareForTailCall(callee, temp1, temp2, temp3, callPtrTag)
         storep temp3, [sp]
     end
 
-    if POINTER_PROFILING
+    if ARM64E
         addp 16, cfr, temp3
         untagReturnAddress temp3
     end
index 7961a7e..3a13c67 100644 (file)
@@ -585,11 +585,8 @@ macro functionArityCheck(doneLabel, slowPath)
     btiz t1, .continue
 
 .noExtraSlot:
-    if POINTER_PROFILING
-        if ARM64 or ARM64E
-            loadp 8[cfr], lr
-        end
-
+    if ARM64E
+        loadp 8[cfr], lr
         addp 16, cfr, t3
         untagReturnAddress t3
     end
@@ -618,13 +615,10 @@ macro functionArityCheck(doneLabel, slowPath)
     addp 8, t3
     baddinz 1, t2, .fillLoop
 
-    if POINTER_PROFILING
+    if ARM64E
         addp 16, cfr, t1
         tagReturnAddress t1
-
-        if ARM64 or ARM64E
-            storep lr, 8[cfr]
-        end
+        storep lr, 8[cfr]
     end
 
 .continue:
index d825a91..5e341bd 100644 (file)
@@ -1,7 +1,7 @@
 /*
  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
- *  Copyright (C) 2003-2018 Apple Inc. All rights reserved.
+ *  Copyright (C) 2003-2019 Apple Inc. All rights reserved.
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Library General Public
 #include "ConstructData.h"
 #include "JSCast.h"
 
+#if CPU(ARM64E)
+#include <ptrauth.h>
+#endif
+
 namespace WTF {
 class PrintStream;
 };
@@ -37,6 +41,13 @@ class JSArrayBufferView;
 class Snippet;
 struct HashTable;
 
+#if CPU(ARM64E)
+#define WTF_METHOD_TABLE_ENTRY(method) \
+    __ptrauth(ptrauth_key_process_independent_code, true, ptrauth_string_discriminator("MethodTable." #method)) method
+#else
+#define WTF_METHOD_TABLE_ENTRY(method) method
+#endif
+
 struct MethodTable {
     using DestroyFunctionPtr = void (*)(JSCell*);
     DestroyFunctionPtr WTF_METHOD_TABLE_ENTRY(destroy);
index d0a37f4..a1ac058 100644 (file)
@@ -33,6 +33,7 @@
 #include "ExecutableAllocator.h"
 #include "Heap.h"
 #include "Identifier.h"
+#include "JSCPtrTag.h"
 #include "JSDateMath.h"
 #include "JSGlobalObject.h"
 #include "JSLock.h"
@@ -61,6 +62,8 @@ void initializeThreading()
         WTF::initializeThreading();
         Options::initialize();
 
+        initializePtrTagLookup();
+
 #if ENABLE(WRITE_BARRIER_PROFILING)
         WriteBarrierCounters::initialize();
 #endif
diff --git a/Source/JavaScriptCore/runtime/JSCPtrTag.cpp b/Source/JavaScriptCore/runtime/JSCPtrTag.cpp
new file mode 100644 (file)
index 0000000..35435f3
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2018-2019 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. ``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.
+ */
+
+#include "config.h"
+#include "JSCPtrTag.h"
+
+namespace JSC {
+
+#if CPU(ARM64E)
+
+static const char* tagForPtr(const void* ptr)
+{
+#define RETURN_NAME_IF_TAG_MATCHES(tag) \
+    if (WTF::untagCodePtrImpl<WTF::PtrTagAction::NoAssert>(ptr, JSC::tag) == removeCodePtrTag(ptr)) \
+        return #tag;
+    FOR_EACH_JSC_PTRTAG(RETURN_NAME_IF_TAG_MATCHES)
+#undef RETURN_NAME_IF_TAG_MATCHES
+    return nullptr; // Matching tag not found.
+}
+
+static const char* ptrTagName(PtrTag tag)
+{
+#define RETURN_PTRTAG_NAME(_tagName) case _tagName: return #_tagName;
+    switch (static_cast<unsigned>(tag)) {
+        FOR_EACH_JSC_PTRTAG(RETURN_PTRTAG_NAME)
+    }
+#undef RETURN_PTRTAG_NAME
+    return nullptr; // Matching tag not found.
+}
+
+void initializePtrTagLookup()
+{
+    static WTF::PtrTagLookup lookup = { tagForPtr, ptrTagName };
+    WTF::registerPtrTagLookup(&lookup);
+}
+
+#endif // CPU(ARM64E)
+
+} // namespace JSC
index e44b913..82fbb27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -47,8 +47,6 @@ using PtrTag = WTF::PtrTag;
     v(OperationPtrTag) \
     v(OSREntryPtrTag) \
     v(OSRExitPtrTag) \
-    v(PlatformRegistersLRPtrTag) \
-    v(PlatformRegistersPCPtrTag) \
     v(SlowPathPtrTag) \
     v(WasmEntryPtrTag) \
     v(Yarr8BitPtrTag) \
@@ -68,5 +66,11 @@ FOR_EACH_JSC_PTRTAG(WTF_DECLARE_PTRTAG)
 #pragma warning(pop)
 #endif
 
+void initializePtrTagLookup();
+
+#if !CPU(ARM64E)
+inline void initializePtrTagLookup() { }
+#endif
+
 } // namespace JSC
 
index 3c31deb..bef9773 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -420,8 +420,6 @@ static void recomputeDependentOptions()
         Options::useJIT() = false;
 #endif
 
-    WTF_SET_POINTER_PREPARATION_OPTIONS();
-
     if (!Options::useJIT())
         Options::useWebAssembly() = false;
 
index abb668d..d78fe1f 100644 (file)
@@ -1,3 +1,52 @@
+2019-03-20  Mark Lam  <mark.lam@apple.com>
+
+        Open source arm64e code.
+        https://bugs.webkit.org/show_bug.cgi?id=196012
+        <rdar://problem/49066237>
+
+        Reviewed by Keith Miller.
+
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/BlockPtr.h:
+        * wtf/Platform.h:
+        * wtf/PlatformRegisters.cpp: Added.
+        (WTF::threadStateLRInternal):
+        (WTF::threadStatePCInternal):
+        * wtf/PlatformRegisters.h:
+        * wtf/PointerPreparations.h:
+        * wtf/PtrTag.cpp: Added.
+        (WTF::tagForPtr):
+        (WTF::ptrTagName):
+        (WTF::registerPtrTagLookup):
+        (WTF::reportBadTag):
+        * wtf/PtrTag.h:
+        (WTF::removeCodePtrTag):
+        (WTF::tagCodePtrImpl):
+        (WTF::tagCodePtr):
+        (WTF::untagCodePtrImplHelper):
+        (WTF::untagCodePtrImpl):
+        (WTF::untagCodePtr):
+        (WTF::retagCodePtrImplHelper):
+        (WTF::retagCodePtrImpl):
+        (WTF::retagCodePtr):
+        (WTF::tagCFunctionPtrImpl):
+        (WTF::tagCFunctionPtr):
+        (WTF::untagCFunctionPtrImpl):
+        (WTF::untagCFunctionPtr):
+        (WTF::tagInt):
+        (WTF::assertIsCFunctionPtr):
+        (WTF::assertIsNullOrCFunctionPtr):
+        (WTF::assertIsNotTagged):
+        (WTF::assertIsTagged):
+        (WTF::assertIsNullOrTagged):
+        (WTF::isTaggedWith):
+        (WTF::assertIsTaggedWith):
+        (WTF::assertIsNullOrTaggedWith):
+        (WTF::usesPointerTagging):
+        (WTF::registerPtrTagLookup):
+        (WTF::reportBadTag):
+        (WTF::tagForPtr): Deleted.
+
 2019-03-20  Keith Rollin  <krollin@apple.com>
 
         Update checks that determine if WebKit is system WebKit
index 7490fde..f994941 100644 (file)
                E4A0AD391A96245500536DF6 /* WorkQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A0AD371A96245500536DF6 /* WorkQueue.cpp */; };
                E4A0AD3D1A96253C00536DF6 /* WorkQueueCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A0AD3C1A96253C00536DF6 /* WorkQueueCocoa.cpp */; };
                FE05FAFF1FE5007500093230 /* WTFAssertions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE05FAFE1FE5007500093230 /* WTFAssertions.cpp */; };
+               FE1E2C3B2240C06600F6B729 /* PtrTag.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE1E2C392240C05400F6B729 /* PtrTag.cpp */; };
+               FE1E2C42224187C600F6B729 /* PlatformRegisters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE1E2C41224187C600F6B729 /* PlatformRegisters.cpp */; };
                FEDACD3D1630F83F00C69634 /* StackStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDACD3B1630F83F00C69634 /* StackStats.cpp */; };
                FEEA4DF9216D7BE400AC0602 /* StackPointer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEEA4DF8216D7BE400AC0602 /* StackPointer.cpp */; };
 /* End PBXBuildFile section */
                F72BBDB107FA424886178B9E /* SymbolImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolImpl.cpp; sourceTree = "<group>"; };
                FE05FAE61FDB214300093230 /* DumbPtrTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DumbPtrTraits.h; sourceTree = "<group>"; };
                FE05FAFE1FE5007500093230 /* WTFAssertions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WTFAssertions.cpp; sourceTree = "<group>"; };
+               FE1E2C392240C05400F6B729 /* PtrTag.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PtrTag.cpp; sourceTree = "<group>"; };
+               FE1E2C41224187C600F6B729 /* PlatformRegisters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformRegisters.cpp; sourceTree = "<group>"; };
                FE7497E4208FFCAA0003565B /* PtrTag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PtrTag.h; sourceTree = "<group>"; };
                FE7497ED209163060003565B /* MetaAllocatorPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MetaAllocatorPtr.h; sourceTree = "<group>"; };
                FE8225301B2A1E5B00BA68FD /* NakedPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NakedPtr.h; sourceTree = "<group>"; };
                                0F824A641B7443A0002E345D /* ParkingLot.cpp */,
                                0F824A651B7443A0002E345D /* ParkingLot.h */,
                                A876DBD7151816E500DADB95 /* Platform.h */,
+                               FE1E2C41224187C600F6B729 /* PlatformRegisters.cpp */,
                                E3200AB41E9A536D003B59D2 /* PlatformRegisters.h */,
                                0FF860941BCCBD740045127F /* PointerComparison.h */,
                                FEB6B035201BE0B600B958C1 /* PointerPreparations.h */,
                                0FC4488216FE9FE100844BE9 /* ProcessID.h */,
                                7AF023B42061E16F00A8EFD6 /* ProcessPrivilege.cpp */,
                                7AF023B32061E16C00A8EFD6 /* ProcessPrivilege.h */,
+                               FE1E2C392240C05400F6B729 /* PtrTag.cpp */,
                                FE7497E4208FFCAA0003565B /* PtrTag.h */,
                                143F611D1565F0F900DB514A /* RAMSize.cpp */,
                                143F611E1565F0F900DB514A /* RAMSize.h */,
                                A8A473C3151A825B004123FF /* FastMalloc.cpp in Sources */,
                                0F9D3360165DBA73005AD387 /* FilePrintStream.cpp in Sources */,
                                A331D95B21F24992009F02AA /* FileSystem.cpp in Sources */,
+                               FE1E2C42224187C600F6B729 /* PlatformRegisters.cpp in Sources */,
                                A331D95D21F249E4009F02AA /* FileSystemCF.cpp in Sources */,
                                A331D95F21F249F6009F02AA /* FileSystemCocoa.mm in Sources */,
                                A331D96121F24A0A009F02AA /* FileSystemMac.mm in Sources */,
                                1C181C8F1D307AB800F5FA16 /* UTextProvider.cpp in Sources */,
                                1C181C911D307AB800F5FA16 /* UTextProviderLatin1.cpp in Sources */,
                                1C181C931D307AB800F5FA16 /* UTextProviderUTF16.cpp in Sources */,
+                               FE1E2C3B2240C06600F6B729 /* PtrTag.cpp in Sources */,
                                A8A47469151A825B004123FF /* UTF8Conversion.cpp in Sources */,
                                7AFEC6B11EB22B5900DADE36 /* UUID.cpp in Sources */,
                                0F66B2921DC97BAB004A1D3F /* WallTime.cpp in Sources */,
index 411b1c9..1151091 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include <wtf/Assertions.h>
 #include <wtf/StdLibExtras.h>
 
-#if CPU(ARM64E)
-#include <WebKitAdditions/BlockQualifiers.h>
+#if __has_include(<ptrauth.h>)
+#include <ptrauth.h>
+#define WTF_COPY_FUNCTION_POINTER_QUALIFIER __ptrauth_block_copy_helper
+#define WTF_DISPOSE_FUNCTION_POINTER_QUALIFIER __ptrauth_block_destroy_helper
+#define WTF_INVOKE_FUNCTION_POINTER_QUALIFIER __ptrauth_block_invocation_pointer
 #else
 #define WTF_COPY_FUNCTION_POINTER_QUALIFIER
 #define WTF_DISPOSE_FUNCTION_POINTER_QUALIFIER
index 7920c11..6980013 100644 (file)
 #define ENABLE_SIGNAL_BASED_VM_TRAPS 1
 #endif
 
-#if !defined(USE_POINTER_PROFILING) || USE(JSVALUE32_64) || !ENABLE(JIT)
-#undef USE_POINTER_PROFILING
-#define USE_POINTER_PROFILING 0
-#endif
-
 /* CSS Selector JIT Compiler */
 #if !defined(ENABLE_CSS_SELECTOR_JIT)
 #if (CPU(X86_64) || CPU(ARM64) || (CPU(ARM_THUMB2) && PLATFORM(IOS_FAMILY))) && ENABLE(JIT) && (OS(DARWIN) || PLATFORM(GTK) || PLATFORM(WPE))
diff --git a/Source/WTF/wtf/PlatformRegisters.cpp b/Source/WTF/wtf/PlatformRegisters.cpp
new file mode 100644 (file)
index 0000000..779fa2e
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2018-2019 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. ``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.
+ */
+
+#include "config.h"
+#include <wtf/PlatformRegisters.h>
+
+#include <wtf/PtrTag.h>
+
+namespace WTF {
+
+#if USE(PLATFORM_REGISTERS_WITH_PROFILE) && CPU(ARM64E)
+
+#define USE_UNTAGGED_THREAD_STATE_PTR 1
+
+void* threadStateLRInternal(PlatformRegisters& regs)
+{
+    void* candidateLR = arm_thread_state64_get_lr_fptr(regs);
+
+#if USE(UNTAGGED_THREAD_STATE_PTR)
+    if (candidateLR && isTaggedWith(candidateLR, CFunctionPtrTag))
+        return retagCodePtr<CFunctionPtrTag, PlatformRegistersLRPtrTag>(candidateLR);
+    candidateLR = bitwise_cast<void*>(arm_thread_state64_get_lr(regs));
+    if (!candidateLR)
+        return candidateLR;
+    return tagCodePtr<PlatformRegistersLRPtrTag>(candidateLR);
+
+#else
+    return retagCodePtr<CFunctionPtrTag, PlatformRegistersLRPtrTag>(candidateLR);
+#endif
+}
+
+void* threadStatePCInternal(PlatformRegisters& regs)
+{
+    void* candidatePC = arm_thread_state64_get_pc_fptr(regs);
+
+#if USE(UNTAGGED_THREAD_STATE_PTR)
+    if (candidatePC && isTaggedWith(candidatePC, CFunctionPtrTag))
+        return retagCodePtr<CFunctionPtrTag, PlatformRegistersPCPtrTag>(candidatePC);
+    candidatePC = bitwise_cast<void*>(arm_thread_state64_get_pc(regs));
+    if (!candidatePC)
+        return candidatePC;
+    return tagCodePtr<PlatformRegistersPCPtrTag>(candidatePC);
+
+#else
+    return retagCodePtr<CFunctionPtrTag, PlatformRegistersPCPtrTag>(candidatePC);
+#endif
+}
+
+#endif // USE(PLATFORM_REGISTERS_WITH_PROFILE) && CPU(ARM64E)
+
+} // namespace WTF
index 92cd789..d26ef98 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2017 Yusuke Suzuki <utatane.tea@gmail.com>
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -91,4 +92,71 @@ struct PlatformRegisters {
 
 } // namespace WTF
 
+#if USE(PLATFORM_REGISTERS_WITH_PROFILE)
+#if CPU(ARM64E)
+
+namespace WTF {
+
+extern void* threadStateLRInternal(PlatformRegisters&);
+extern void* threadStatePCInternal(PlatformRegisters&);
+
+} // namespace WTF
+
+using WTF::threadStateLRInternal;
+using WTF::threadStatePCInternal;
+
+#else // not CPU(ARM64E)
+
+#define threadStateLRInternal(regs) bitwise_cast<void*>(arm_thread_state64_get_lr(regs))
+#define threadStatePCInternal(regs) bitwise_cast<void*>(arm_thread_state64_get_pc(regs))
+
+#endif // CPU(ARM64E)
+
+#define WTF_READ_PLATFORM_REGISTERS_SP_WITH_PROFILE(regs) \
+    reinterpret_cast<void*>(arm_thread_state64_get_sp(const_cast<PlatformRegisters&>(regs)))
+
+#define WTF_WRITE_PLATFORM_REGISTERS_SP_WITH_PROFILE(regs, newPointer) \
+    arm_thread_state64_set_sp(regs, reinterpret_cast<uintptr_t>(newPointer))
+
+#define WTF_READ_PLATFORM_REGISTERS_FP_WITH_PROFILE(regs) \
+    reinterpret_cast<void*>(arm_thread_state64_get_fp(const_cast<PlatformRegisters&>(regs)))
+
+#define WTF_WRITE_PLATFORM_REGISTERS_FP_WITH_PROFILE(regs, newPointer) \
+    arm_thread_state64_set_fp(regs, reinterpret_cast<uintptr_t>(newPointer))
+
+#define WTF_READ_PLATFORM_REGISTERS_LR_WITH_PROFILE(regs) \
+    threadStateLRInternal(const_cast<PlatformRegisters&>(regs))
+
+#define WTF_WRITE_PLATFORM_REGISTERS_LR_WITH_PROFILE(regs, newPointer) \
+    arm_thread_state64_set_lr_fptr(regs, newPointer)
+
+#define WTF_READ_PLATFORM_REGISTERS_PC_WITH_PROFILE(regs) \
+    threadStatePCInternal(const_cast<PlatformRegisters&>(regs))
+
+#define WTF_WRITE_PLATFORM_REGISTERS_PC_WITH_PROFILE(regs, newPointer) \
+    arm_thread_state64_set_pc_fptr(regs, newPointer)
+
+#define WTF_READ_MACHINE_CONTEXT_SP_WITH_PROFILE(machineContext) \
+    WTF_READ_PLATFORM_REGISTERS_SP_WITH_PROFILE(machineContext->__ss)
+
+#define WTF_WRITE_MACHINE_CONTEXT_SP_WITH_PROFILE(machineContext, newPointer) \
+    WTF_WRITE_PLATFORM_REGISTERS_SP_WITH_PROFILE(machineContext->__ss, newPointer)
+
+#define WTF_READ_MACHINE_CONTEXT_FP_WITH_PROFILE(machineContext) \
+    WTF_READ_PLATFORM_REGISTERS_FP_WITH_PROFILE(machineContext->__ss)
+
+#define WTF_WRITE_MACHINE_CONTEXT_FP_WITH_PROFILE(machineContext, newPointer) \
+    WTF_WRITE_PLATFORM_REGISTERS_FP_WITH_PROFILE(machineContext->__ss, newPointer)
+
+#define WTF_WRITE_MACHINE_CONTEXT_LR_WITH_PROFILE(machineContext, newPointer) \
+    WTF_WRITE_PLATFORM_REGISTERS_LR_WITH_PROFILE(machineContext->__ss, newPointer)
+
+#define WTF_READ_MACHINE_CONTEXT_PC_WITH_PROFILE(machineContext) \
+    WTF_READ_PLATFORM_REGISTERS_PC_WITH_PROFILE(machineContext->__ss)
+
+#define WTF_WRITE_MACHINE_CONTEXT_PC_WITH_PROFILE(machineContext, newPointer) \
+    WTF_WRITE_PLATFORM_REGISTERS_PC_WITH_PROFILE(machineContext->__ss, newPointer)
+
+#endif // USE(PLATFORM_REGISTERS_WITH_PROFILE)
+
 using WTF::PlatformRegisters;
index 8160fd3..ada5673 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #pragma once
 
-#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/PointerPreparations.h>)
-#include <WebKitAdditions/PointerPreparations.h>
-#endif
+namespace WTF {
+
+#if CPU(ARM64E)
+#include <ptrauth.h>
+
+#define WTF_PREPARE_VTBL_POINTER_FOR_INSPECTION(vtblPtr) \
+    (reinterpret_cast<void*>(ptrauth_sign_unauthenticated(vtblPtr, ptrauth_key_cxx_vtable_pointer, 0)))
+
+#else // not CPU(ARM64E)
 
-#ifndef WTF_PREPARE_VTBL_POINTER_FOR_INSPECTION
 #define WTF_PREPARE_VTBL_POINTER_FOR_INSPECTION(vtblPtr) (reinterpret_cast<void*>(vtblPtr))
-#endif
 
-#ifndef WTF_SET_POINTER_PREPARATION_OPTIONS
-#define WTF_SET_POINTER_PREPARATION_OPTIONS() do { } while (false)
-#endif
+#endif // not CPU(ARM64E)
 
-#ifndef WTF_METHOD_TABLE_ENTRY
-#define WTF_METHOD_TABLE_ENTRY(method) method
-#endif
+} // namespace WTF
diff --git a/Source/WTF/wtf/PtrTag.cpp b/Source/WTF/wtf/PtrTag.cpp
new file mode 100644 (file)
index 0000000..59ea370
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2018-2019 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. ``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.
+ */
+
+#include "config.h"
+#include <wtf/PtrTag.h>
+
+namespace WTF {
+
+#if CPU(ARM64E)
+
+static PtrTagLookup* s_ptrTagLookup = nullptr;
+
+static const char* tagForPtr(const void* ptr)
+{
+    PtrTagLookup* lookup = s_ptrTagLookup;
+    while (lookup) {
+        const char* tagName = lookup->tagForPtr(ptr);
+        if (tagName)
+            return tagName;
+        lookup = lookup->next;
+    }
+
+    if (ptr == removeCodePtrTag(ptr))
+        return "NoPtrTag";
+
+#define RETURN_NAME_IF_TAG_MATCHES(tag) \
+    if (untagCodePtrImpl<PtrTagAction::NoAssert>(ptr, tag) == removeCodePtrTag(ptr)) \
+        return #tag;
+    FOR_EACH_WTF_PTRTAG(RETURN_NAME_IF_TAG_MATCHES)
+#undef RETURN_NAME_IF_TAG_MATCHES
+
+    return "<unknown PtrTag>";
+}
+
+static const char* ptrTagName(PtrTag tag)
+{
+    PtrTagLookup* lookup = s_ptrTagLookup;
+    while (lookup) {
+        const char* tagName = lookup->ptrTagName(tag);
+        if (tagName)
+            return tagName;
+        lookup = lookup->next;
+    }
+
+#define RETURN_WTF_PTRTAG_NAME(_tagName) case _tagName: return #_tagName;
+    switch (tag) {
+        FOR_EACH_WTF_PTRTAG(RETURN_WTF_PTRTAG_NAME)
+    default: return "<unknown>";
+    }
+#undef RETURN_WTF_PTRTAG_NAME
+}
+
+void registerPtrTagLookup(PtrTagLookup* lookup)
+{
+    lookup->next = s_ptrTagLookup;
+    s_ptrTagLookup = lookup;
+}
+
+void reportBadTag(const void* ptr, PtrTag expectedTag)
+{
+    dataLog("PtrTag ASSERTION FAILED on pointer ", RawPointer(ptr), ", actual tag = ", tagForPtr(ptr));
+    if (expectedTag == AnyPtrTag)
+        dataLogLn(", expected any tag but NoPtrTag");
+    else
+        dataLogLn(", expected tag = ", ptrTagName(expectedTag));
+}
+
+#endif // CPU(ARM64E)
+
+} // namespace WTF
index 6e8ef65..342a40f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2018-2019 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -25,7 +25,8 @@
 
 #pragma once
 
-#include <wtf/PointerPreparations.h>
+#include <wtf/Assertions.h>
+#include <wtf/DataLog.h>
 
 namespace WTF {
 
@@ -36,6 +37,8 @@ namespace WTF {
 #define FOR_EACH_ADDITIONAL_WTF_PTRTAG(v) \
     v(FreeSpacePtrTag) \
     v(HandleMemoryPtrTag) \
+    v(PlatformRegistersLRPtrTag) \
+    v(PlatformRegistersPCPtrTag) \
 
 #define FOR_EACH_WTF_PTRTAG(v) \
     FOR_EACH_BASE_WTF_PTRTAG(v) \
@@ -46,7 +49,11 @@ enum PtrTag : uintptr_t {
     CFunctionPtrTag,
 };
 
-#ifndef WTF_PTRTAG_HASH
+#if CPU(ARM64E)
+#define WTF_PTRTAG_HASH(tag) ptrauth_string_discriminator(#tag)
+
+#else // not CPU(ARM64E)
+
 template<size_t N>
 constexpr uintptr_t makePtrTagHash(const char (&str)[N])
 {
@@ -57,7 +64,7 @@ constexpr uintptr_t makePtrTagHash(const char (&str)[N])
 }
 
 #define WTF_PTRTAG_HASH(tag) WTF::makePtrTagHash(#tag)
-#endif
+#endif // not CPU(ARM64E)
 
 #define WTF_DECLARE_PTRTAG(tag) \
     constexpr PtrTag tag = static_cast<PtrTag>(WTF_PTRTAG_HASH(#tag)); \
@@ -77,9 +84,315 @@ FOR_EACH_ADDITIONAL_WTF_PTRTAG(WTF_DECLARE_PTRTAG)
 #pragma warning(pop)
 #endif
 
-#if !USE(POINTER_PROFILING)
+struct PtrTagLookup {
+    const char* (*tagForPtr)(const void*);
+    const char* (*ptrTagName)(PtrTag);
+    PtrTagLookup* next { nullptr };
+};
+
+#if CPU(ARM64E)
+
+enum class PtrTagAction {
+    ReleaseAssert,
+    DebugAssert,
+    NoAssert,
+};
+
+constexpr PtrTag AnyPtrTag = static_cast<PtrTag>(-1); // Only used for assertion messages.
+
+WTF_EXPORT_PRIVATE void registerPtrTagLookup(PtrTagLookup*);
+WTF_EXPORT_PRIVATE void reportBadTag(const void*, PtrTag expectedTag);
+
+#if ASSERT_DISABLED
+constexpr bool enablePtrTagDebugAssert = false;
+#else
+constexpr bool enablePtrTagDebugAssert = true;
+#endif
+
+#define WTF_PTRTAG_ASSERT(action, ptr, expectedTag, assertion) \
+    do { \
+        if (action == PtrTagAction::ReleaseAssert \
+            || (WTF::enablePtrTagDebugAssert && action == PtrTagAction::DebugAssert)) { \
+            bool passed = (assertion); \
+            if (UNLIKELY(!passed)) { \
+                reportBadTag(reinterpret_cast<const void*>(ptr), expectedTag); \
+            } \
+            RELEASE_ASSERT(passed && #assertion); \
+        } \
+    } while (false)
+
+template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
+inline constexpr T removeCodePtrTag(PtrType ptr)
+{
+    return bitwise_cast<T>(ptrauth_strip(ptr, ptrauth_key_process_dependent_code));
+}
+
+template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline constexpr PtrType removeCodePtrTag(PtrType ptr)
+{
+    return ptrauth_strip(ptr, ptrauth_key_process_dependent_code);
+}
+
+template<PtrTagAction tagAction, typename PtrType>
+inline PtrType tagCodePtrImpl(PtrType ptr, PtrTag tag)
+{
+    if (!ptr)
+        return nullptr;
+    WTF_PTRTAG_ASSERT(tagAction, ptr, NoPtrTag, removeCodePtrTag(ptr) == ptr);
+    if (tag == NoPtrTag)
+        return ptr;
+    if (tag == CFunctionPtrTag)
+        return ptrauth_sign_unauthenticated(ptr, ptrauth_key_function_pointer, 0);
+    return ptrauth_sign_unauthenticated(ptr, ptrauth_key_process_dependent_code, tag);
+}
+
+template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
+inline T tagCodePtr(PtrType ptr, PtrTag tag)
+{
+    return bitwise_cast<T>(tagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
+}
+
+template<typename T, PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline T tagCodePtr(PtrType ptr)
+{
+    return bitwise_cast<T>(tagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
+}
+
+template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline PtrType tagCodePtr(PtrType ptr, PtrTag tag)
+{
+    return tagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, tag);
+}
+
+template<PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline PtrType tagCodePtr(PtrType ptr) { return tagCodePtr(ptr, tag); }
+
+template<typename PtrType>
+inline PtrType untagCodePtrImplHelper(PtrType ptr, PtrTag tag)
+{
+    if (tag == NoPtrTag)
+        return ptr;
+    if (tag == CFunctionPtrTag)
+        return __builtin_ptrauth_auth(ptr, ptrauth_key_function_pointer, 0);
+    return __builtin_ptrauth_auth(ptr, ptrauth_key_process_dependent_code, tag);
+}
+
+template<PtrTagAction tagAction, typename PtrType>
+inline PtrType untagCodePtrImpl(PtrType ptr, PtrTag tag)
+{
+    if (!ptr)
+        return nullptr;
+    PtrType result = untagCodePtrImplHelper(ptr, tag);
+    WTF_PTRTAG_ASSERT(tagAction, ptr, tag, removeCodePtrTag(ptr) == result);
+    return result;
+}
+
+template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
+inline T untagCodePtr(PtrType ptr, PtrTag tag)
+{
+    return bitwise_cast<T>(untagCodePtrImpl<PtrTagAction::ReleaseAssert>(ptr, tag));
+}
+
+template<typename T, PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline T untagCodePtr(PtrType ptr)
+{
+    return bitwise_cast<T>(untagCodePtrImpl<PtrTagAction::ReleaseAssert>(ptr, tag));
+}
+
+template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline PtrType untagCodePtr(PtrType ptr, PtrTag tag)
+{
+    return untagCodePtrImpl<PtrTagAction::ReleaseAssert>(ptr, tag);
+}
+
+template<PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline PtrType untagCodePtr(PtrType ptr) { return untagCodePtr(ptr, tag); }
+
+template<PtrTagAction tagAction, typename PtrType>
+inline PtrType retagCodePtrImplHelper(PtrType ptr, PtrTag oldTag, PtrTag newTag)
+{
+    if (oldTag == newTag || (oldTag == NoPtrTag && newTag == NoPtrTag))
+        return ptr;
+    if (newTag == NoPtrTag)
+        return untagCodePtrImpl<tagAction>(ptr, oldTag);
+    if (oldTag == NoPtrTag)
+        return tagCodePtrImpl<tagAction>(ptr, newTag);
+    if (oldTag == CFunctionPtrTag)
+        return ptrauth_auth_and_resign(ptr, ptrauth_key_function_pointer, 0, ptrauth_key_process_dependent_code, newTag);
+    if (newTag == CFunctionPtrTag)
+        return ptrauth_auth_and_resign(ptr, ptrauth_key_process_dependent_code, oldTag, ptrauth_key_function_pointer, 0);
+    return ptrauth_auth_and_resign(ptr, ptrauth_key_process_dependent_code, oldTag, ptrauth_key_process_dependent_code, newTag);
+}
+
+template<PtrTagAction tagAction, typename PtrType>
+inline PtrType retagCodePtrImpl(PtrType ptr, PtrTag oldTag, PtrTag newTag)
+{
+    if (!ptr)
+        return nullptr;
+    PtrTagAction untagAction = (tagAction == PtrTagAction::NoAssert) ? PtrTagAction::NoAssert : PtrTagAction::ReleaseAssert;
+    WTF_PTRTAG_ASSERT(untagAction, ptr, oldTag, removeCodePtrTag(ptr) == untagCodePtrImpl<PtrTagAction::NoAssert>(ptr, oldTag));
+    PtrType result = retagCodePtrImplHelper<tagAction>(ptr, oldTag, newTag);
+    WTF_PTRTAG_ASSERT(tagAction, ptr, newTag, result == tagCodePtrImpl<PtrTagAction::NoAssert>(removeCodePtrTag(ptr), newTag));
+    return result;
+}
+
+template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
+inline T retagCodePtr(PtrType ptr, PtrTag oldTag, PtrTag newTag)
+{
+    return bitwise_cast<T>(retagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, oldTag, newTag));
+}
+
+template<typename T, PtrTag oldTag, PtrTag newTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline T retagCodePtr(PtrType ptr)
+{
+    return bitwise_cast<T>(retagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, oldTag, newTag));
+}
+
+template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline PtrType retagCodePtr(PtrType ptr, PtrTag oldTag, PtrTag newTag)
+{
+    return retagCodePtrImpl<PtrTagAction::DebugAssert>(ptr, oldTag, newTag);
+}
+
+template<PtrTag oldTag, PtrTag newTag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline PtrType retagCodePtr(PtrType ptr) { return retagCodePtr(ptr, oldTag, newTag); }
 
-inline const char* tagForPtr(const void*) { return "<no tag>"; }
+template<PtrTagAction tagAction, typename PtrType>
+inline PtrType tagCFunctionPtrImpl(PtrType ptr, PtrTag tag)
+{
+    if (!ptr)
+        return nullptr;
+    WTF_PTRTAG_ASSERT(tagAction, ptr, CFunctionPtrTag, removeCodePtrTag(ptr) == untagCodePtrImpl<PtrTagAction::NoAssert>(ptr, CFunctionPtrTag));
+    return retagCodePtrImpl<tagAction>(ptr, CFunctionPtrTag, tag);
+}
+
+template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
+inline T tagCFunctionPtr(PtrType ptr, PtrTag tag)
+{
+    return bitwise_cast<T>(tagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
+}
+
+template<typename T, PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline T tagCFunctionPtr(PtrType ptr)
+{
+    return bitwise_cast<T>(tagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
+}
+
+template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline PtrType tagCFunctionPtr(PtrType ptr, PtrTag tag)
+{
+    return tagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag);
+}
+
+template<PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline PtrType tagCFunctionPtr(PtrType ptr) { return tagCFunctionPtr(ptr, tag); }
+
+template<PtrTagAction tagAction, typename PtrType>
+inline PtrType untagCFunctionPtrImpl(PtrType ptr, PtrTag tag)
+{
+    if (!ptr)
+        return nullptr;
+    WTF_PTRTAG_ASSERT(tagAction, ptr, tag, removeCodePtrTag(ptr) == untagCodePtrImpl<PtrTagAction::NoAssert>(ptr, tag));
+    return retagCodePtrImpl<tagAction>(ptr, tag, CFunctionPtrTag);
+}
+
+template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
+inline T untagCFunctionPtr(PtrType ptr, PtrTag tag)
+{
+    return bitwise_cast<T>(untagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
+}
+
+template<typename T, PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline T untagCFunctionPtr(PtrType ptr)
+{
+    return bitwise_cast<T>(untagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag));
+}
+
+template<typename T, PtrTag tag, PtrTagAction tagAction, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline T untagCFunctionPtr(PtrType ptr)
+{
+    return bitwise_cast<T>(untagCFunctionPtrImpl<tagAction>(ptr, tag));
+}
+
+template<typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline PtrType untagCFunctionPtr(PtrType ptr, PtrTag tag)
+{
+    return untagCFunctionPtrImpl<PtrTagAction::DebugAssert>(ptr, tag);
+}
+
+template<PtrTag tag, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value>>
+inline PtrType untagCFunctionPtr(PtrType ptr) { return untagCFunctionPtr(ptr, tag); }
+
+template <typename IntType>
+inline IntType tagInt(IntType ptrInt, PtrTag tag)
+{
+    static_assert(sizeof(IntType) == sizeof(uintptr_t), "");
+    return bitwise_cast<IntType>(ptrauth_sign_unauthenticated(bitwise_cast<void*>(ptrInt), ptrauth_key_process_dependent_data, tag));
+}
+
+template<typename PtrType>
+void assertIsCFunctionPtr(PtrType value)
+{
+    void* ptr = bitwise_cast<void*>(value);
+    WTF_PTRTAG_ASSERT(PtrTagAction::ReleaseAssert, ptr, CFunctionPtrTag, untagCodePtrImpl<PtrTagAction::NoAssert>(ptr, CFunctionPtrTag) == removeCodePtrTag(ptr));
+}
+
+template<typename PtrType>
+void assertIsNullOrCFunctionPtr(PtrType ptr)
+{
+    if (ptr)
+        assertIsCFunctionPtr(ptr);
+}
+
+template<typename PtrType>
+void assertIsNotTagged(PtrType value)
+{
+    void* ptr = bitwise_cast<void*>(value);
+    WTF_PTRTAG_ASSERT(PtrTagAction::ReleaseAssert, ptr, NoPtrTag, ptr == removeCodePtrTag(ptr));
+}
+
+template<typename PtrType>
+void assertIsTagged(PtrType value)
+{
+    void* ptr = bitwise_cast<void*>(value);
+    WTF_PTRTAG_ASSERT(PtrTagAction::ReleaseAssert, ptr, AnyPtrTag, ptr != removeCodePtrTag(ptr));
+}
+
+template<typename PtrType>
+void assertIsNullOrTagged(PtrType ptr)
+{
+    if (ptr)
+        assertIsTagged(ptr);
+}
+
+template<typename PtrType>
+bool isTaggedWith(PtrType value, PtrTag tag)
+{
+    void* ptr = bitwise_cast<void*>(value);
+    if (tag == NoPtrTag)
+        return ptr == removeCodePtrTag(ptr);
+    return untagCodePtrImpl<PtrTagAction::NoAssert>(ptr, tag) == removeCodePtrTag(ptr);
+}
+
+template<typename PtrType>
+void assertIsTaggedWith(PtrType value, PtrTag tag)
+{
+    WTF_PTRTAG_ASSERT(PtrTagAction::ReleaseAssert, value, tag, isTaggedWith(value, tag));
+}
+
+template<typename PtrType>
+void assertIsNullOrTaggedWith(PtrType ptr, PtrTag tag)
+{
+    if (ptr)
+        assertIsTaggedWith(ptr, tag);
+}
+
+inline bool usesPointerTagging() { return true; }
+
+#else // not CPU(ARM64E)
+
+inline void registerPtrTagLookup(PtrTagLookup*) { }
+inline void reportBadTag(const void*, PtrTag) { }
 
 template<typename T, typename PtrType, typename = std::enable_if_t<std::is_pointer<PtrType>::value && !std::is_same<T, PtrType>::value>>
 constexpr T tagCodePtr(PtrType ptr, PtrTag) { return bitwise_cast<T>(ptr); }
@@ -168,22 +481,17 @@ template<typename PtrType> void assertIsNullOrTaggedWith(PtrType, PtrTag) { }
 
 inline bool usesPointerTagging() { return false; }
 
-#define CALL_WITH_PTRTAG(callInstructionString, targetRegisterString, tag) \
-    callInstructionString " " targetRegisterString "\n"
-
-#endif // !USE(POINTER_PROFILING)
+#endif // CPU(ARM64E)
 
 } // namespace WTF
 
 using WTF::CFunctionPtrTag;
 using WTF::NoPtrTag;
+using WTF::PlatformRegistersLRPtrTag;
+using WTF::PlatformRegistersPCPtrTag;
 using WTF::PtrTag;
 
-#if USE(APPLE_INTERNAL_SDK) && __has_include(<WebKitAdditions/PtrTagSupport.h>)
-#include <WebKitAdditions/PtrTagSupport.h>
-#endif
-
-using WTF::tagForPtr;
+using WTF::reportBadTag;
 
 using WTF::tagCodePtr;
 using WTF::untagCodePtr;