Title: [225363] trunk/Source
Revision
225363
Author
mark....@apple.com
Date
2017-11-30 15:47:35 -0800 (Thu, 30 Nov 2017)

Log Message

Let's scramble MacroAssemblerCodePtr values.
https://bugs.webkit.org/show_bug.cgi?id=180169
<rdar://problem/35758340>

Reviewed by Filip Pizlo, Saam Barati, and JF Bastien.

Source/_javascript_Core:

1. MacroAssemblerCodePtr now stores a ScrambledPtr instead of a void*.

2. MacroAssemblerCodePtr's executableAddress() and dataLocation() now take a
   template argument type that will be used to cast the result.  This makes the
   client code that uses these functions a little less verbose.

3. Change the code base in general to minimize passing void* code pointers around.
   We now pass MacroAssemblerCodePtr as much as possible, and descramble it only
   at the last moment when we need the underlying code pointer.

4. Added some MasmScrambledPtr paranoid asserts that are disabled (not built) by
   default.  I'm leaving them in because they are instrumental in finding bugs
   where not all MacroAssemblerCodePtr values were not scrambled as expected.
   I expect them to be useful in the near future as we add more scrambling.

5. Also disable the casting operator on MacroAssemblerCodePtr (except for
   explicit casts to a boolean).  This ensures that clients will always explicitly
   use scrambledBits() or executableAddress() to get a value based on which value
   they actually need.

5. Added currentThread() id to the logging in LLIntSlowPath trace functions.
   This was helpful when debugging tests that ran multiple VMs concurrently on
   different threads.

MacroAssemblerCodePtr is currently supported on 64-bit builds (including the
CLoop).  It is not yet supported in 32-bit and Windows because we don't
currently have a way to read a global variable from their LLInt code.

* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::differenceBetweenCodePtr):
(JSC::AbstractMacroAssembler::linkPointer):
* assembler/CodeLocation.h:
(JSC::CodeLocationCommon::instructionAtOffset):
(JSC::CodeLocationCommon::labelAtOffset):
(JSC::CodeLocationCommon::jumpAtOffset):
(JSC::CodeLocationCommon::callAtOffset):
(JSC::CodeLocationCommon::nearCallAtOffset):
(JSC::CodeLocationCommon::dataLabelPtrAtOffset):
(JSC::CodeLocationCommon::dataLabel32AtOffset):
(JSC::CodeLocationCommon::dataLabelCompactAtOffset):
(JSC::CodeLocationCommon::convertibleLoadAtOffset):
* assembler/LinkBuffer.cpp:
(JSC::LinkBuffer::finalizeCodeWithDisassembly):
* assembler/LinkBuffer.h:
(JSC::LinkBuffer::link):
(JSC::LinkBuffer::patch):
* assembler/MacroAssemblerCodeRef.cpp:
(JSC::MacroAssemblerCodePtr::initialize):
* assembler/MacroAssemblerCodeRef.h:
(JSC::FunctionPtr::FunctionPtr):
(JSC::FunctionPtr::value const):
(JSC::FunctionPtr::executableAddress const):
(JSC::ReturnAddressPtr::ReturnAddressPtr):
(JSC::ReturnAddressPtr::value const):
(JSC::MacroAssemblerCodePtr::MacroAssemblerCodePtr):
(JSC::MacroAssemblerCodePtr::createFromExecutableAddress):
(JSC::MacroAssemblerCodePtr::scrambledPtr const):
(JSC::MacroAssemblerCodePtr:: const):
(JSC::MacroAssemblerCodePtr::operator! const):
(JSC::MacroAssemblerCodePtr::operator bool const):
(JSC::MacroAssemblerCodePtr::operator== const):
(JSC::MacroAssemblerCodePtr::hash const):
(JSC::MacroAssemblerCodePtr::emptyValue):
(JSC::MacroAssemblerCodePtr::deletedValue):
(JSC::MacroAssemblerCodePtr::executableAddress const): Deleted.
(JSC::MacroAssemblerCodePtr::dataLocation const): Deleted.
* b3/B3LowerMacros.cpp:
* b3/testb3.cpp:
(JSC::B3::testInterpreter):
* dfg/DFGDisassembler.cpp:
(JSC::DFG::Disassembler::dumpDisassembly):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::link):
(JSC::DFG::JITCompiler::compileFunction):
* dfg/DFGOperations.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
(JSC::DFG::SpeculativeJIT::emitSwitchImm):
(JSC::DFG::SpeculativeJIT::emitSwitchCharStringJump):
(JSC::DFG::SpeculativeJIT::emitSwitchChar):
* dfg/DFGSpeculativeJIT.h:
* disassembler/Disassembler.cpp:
(JSC::disassemble):
* disassembler/UDis86Disassembler.cpp:
(JSC::tryToDisassembleWithUDis86):
* ftl/FTLCompile.cpp:
(JSC::FTL::compile):
* ftl/FTLJITCode.cpp:
(JSC::FTL::JITCode::executableAddressAtOffset):
* ftl/FTLLink.cpp:
(JSC::FTL::link):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileMathIC):
(JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstruct):
(JSC::FTL::DFG::LowerDFGToB3::compileTailCall):
(JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstructVarargsSpread):
(JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstructVarargs):
* interpreter/InterpreterInlines.h:
(JSC::Interpreter::getOpcodeID):
* jit/JITArithmetic.cpp:
(JSC::JIT::emitMathICFast):
(JSC::JIT::emitMathICSlow):
* jit/JITCode.cpp:
(JSC::JITCodeWithCodeRef::executableAddressAtOffset):
(JSC::JITCodeWithCodeRef::dataAddressAtOffset):
(JSC::JITCodeWithCodeRef::offsetOf):
* jit/JITDisassembler.cpp:
(JSC::JITDisassembler::dumpDisassembly):
* jit/PCToCodeOriginMap.cpp:
(JSC::PCToCodeOriginMap::PCToCodeOriginMap):
* jit/Repatch.cpp:
(JSC::ftlThunkAwareRepatchCall):
* jit/ThunkGenerators.cpp:
(JSC::virtualThunkFor):
(JSC::boundThisNoArgsFunctionCallGenerator):
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::llint_trace_operand):
(JSC::LLInt::llint_trace_value):
(JSC::LLInt::handleHostCall):
(JSC::LLInt::setUpCall):
* llint/LowLevelInterpreter64.asm:
* offlineasm/cloop.rb:
* runtime/InitializeThreading.cpp:
(JSC::initializeThreading):
* wasm/WasmBBQPlan.cpp:
(JSC::Wasm::BBQPlan::complete):
* wasm/WasmCallee.h:
(JSC::Wasm::Callee::entrypoint const):
* wasm/WasmCodeBlock.cpp:
(JSC::Wasm::CodeBlock::CodeBlock):
* wasm/WasmOMGPlan.cpp:
(JSC::Wasm::OMGPlan::work):
* wasm/js/WasmToJS.cpp:
(JSC::Wasm::wasmToJS):
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
* wasm/js/WebAssemblyFunction.h:
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::create):

Source/WTF:

Introduce a ScrambledPtr class to facilitate scrambling.

* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/ScrambledPtr.cpp: Added.
(WTF::makeScrambledPtrKey):
* wtf/ScrambledPtr.h: Added.
(WTF::ScrambledPtr::ScrambledPtr):
(WTF::ScrambledPtr::paranoidAssertIsScrambled const):
(WTF::ScrambledPtr::paranoidAssertIsNotScrambled const):
(WTF::ScrambledPtr:: const):
(WTF::ScrambledPtr::operator-> const):
(WTF::ScrambledPtr::scrambledBits const):
(WTF::ScrambledPtr::operator! const):
(WTF::ScrambledPtr::operator bool const):
(WTF::ScrambledPtr::operator== const):
(WTF::ScrambledPtr::operator==):
(WTF::ScrambledPtr::scramble):
(WTF::ScrambledPtr::descramble):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (225362 => 225363)


--- trunk/Source/_javascript_Core/ChangeLog	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,3 +1,151 @@
+2017-11-30  Mark Lam  <mark....@apple.com>
+
+        Let's scramble MacroAssemblerCodePtr values.
+        https://bugs.webkit.org/show_bug.cgi?id=180169
+        <rdar://problem/35758340>
+
+        Reviewed by Filip Pizlo, Saam Barati, and JF Bastien.
+
+        1. MacroAssemblerCodePtr now stores a ScrambledPtr instead of a void*.
+
+        2. MacroAssemblerCodePtr's executableAddress() and dataLocation() now take a
+           template argument type that will be used to cast the result.  This makes the
+           client code that uses these functions a little less verbose.
+
+        3. Change the code base in general to minimize passing void* code pointers around.
+           We now pass MacroAssemblerCodePtr as much as possible, and descramble it only
+           at the last moment when we need the underlying code pointer.
+
+        4. Added some MasmScrambledPtr paranoid asserts that are disabled (not built) by
+           default.  I'm leaving them in because they are instrumental in finding bugs
+           where not all MacroAssemblerCodePtr values were not scrambled as expected.
+           I expect them to be useful in the near future as we add more scrambling.
+
+        5. Also disable the casting operator on MacroAssemblerCodePtr (except for
+           explicit casts to a boolean).  This ensures that clients will always explicitly
+           use scrambledBits() or executableAddress() to get a value based on which value
+           they actually need.
+
+        5. Added currentThread() id to the logging in LLIntSlowPath trace functions.
+           This was helpful when debugging tests that ran multiple VMs concurrently on
+           different threads.
+
+        MacroAssemblerCodePtr is currently supported on 64-bit builds (including the
+        CLoop).  It is not yet supported in 32-bit and Windows because we don't
+        currently have a way to read a global variable from their LLInt code.
+
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::AbstractMacroAssembler::differenceBetweenCodePtr):
+        (JSC::AbstractMacroAssembler::linkPointer):
+        * assembler/CodeLocation.h:
+        (JSC::CodeLocationCommon::instructionAtOffset):
+        (JSC::CodeLocationCommon::labelAtOffset):
+        (JSC::CodeLocationCommon::jumpAtOffset):
+        (JSC::CodeLocationCommon::callAtOffset):
+        (JSC::CodeLocationCommon::nearCallAtOffset):
+        (JSC::CodeLocationCommon::dataLabelPtrAtOffset):
+        (JSC::CodeLocationCommon::dataLabel32AtOffset):
+        (JSC::CodeLocationCommon::dataLabelCompactAtOffset):
+        (JSC::CodeLocationCommon::convertibleLoadAtOffset):
+        * assembler/LinkBuffer.cpp:
+        (JSC::LinkBuffer::finalizeCodeWithDisassembly):
+        * assembler/LinkBuffer.h:
+        (JSC::LinkBuffer::link):
+        (JSC::LinkBuffer::patch):
+        * assembler/MacroAssemblerCodeRef.cpp:
+        (JSC::MacroAssemblerCodePtr::initialize):
+        * assembler/MacroAssemblerCodeRef.h:
+        (JSC::FunctionPtr::FunctionPtr):
+        (JSC::FunctionPtr::value const):
+        (JSC::FunctionPtr::executableAddress const):
+        (JSC::ReturnAddressPtr::ReturnAddressPtr):
+        (JSC::ReturnAddressPtr::value const):
+        (JSC::MacroAssemblerCodePtr::MacroAssemblerCodePtr):
+        (JSC::MacroAssemblerCodePtr::createFromExecutableAddress):
+        (JSC::MacroAssemblerCodePtr::scrambledPtr const):
+        (JSC::MacroAssemblerCodePtr:: const):
+        (JSC::MacroAssemblerCodePtr::operator! const):
+        (JSC::MacroAssemblerCodePtr::operator bool const):
+        (JSC::MacroAssemblerCodePtr::operator== const):
+        (JSC::MacroAssemblerCodePtr::hash const):
+        (JSC::MacroAssemblerCodePtr::emptyValue):
+        (JSC::MacroAssemblerCodePtr::deletedValue):
+        (JSC::MacroAssemblerCodePtr::executableAddress const): Deleted.
+        (JSC::MacroAssemblerCodePtr::dataLocation const): Deleted.
+        * b3/B3LowerMacros.cpp:
+        * b3/testb3.cpp:
+        (JSC::B3::testInterpreter):
+        * dfg/DFGDisassembler.cpp:
+        (JSC::DFG::Disassembler::dumpDisassembly):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::link):
+        (JSC::DFG::JITCompiler::compileFunction):
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::emitSwitchIntJump):
+        (JSC::DFG::SpeculativeJIT::emitSwitchImm):
+        (JSC::DFG::SpeculativeJIT::emitSwitchCharStringJump):
+        (JSC::DFG::SpeculativeJIT::emitSwitchChar):
+        * dfg/DFGSpeculativeJIT.h:
+        * disassembler/Disassembler.cpp:
+        (JSC::disassemble):
+        * disassembler/UDis86Disassembler.cpp:
+        (JSC::tryToDisassembleWithUDis86):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::compile):
+        * ftl/FTLJITCode.cpp:
+        (JSC::FTL::JITCode::executableAddressAtOffset):
+        * ftl/FTLLink.cpp:
+        (JSC::FTL::link):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileMathIC):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstruct):
+        (JSC::FTL::DFG::LowerDFGToB3::compileTailCall):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstructVarargsSpread):
+        (JSC::FTL::DFG::LowerDFGToB3::compileCallOrConstructVarargs):
+        * interpreter/InterpreterInlines.h:
+        (JSC::Interpreter::getOpcodeID):
+        * jit/JITArithmetic.cpp:
+        (JSC::JIT::emitMathICFast):
+        (JSC::JIT::emitMathICSlow):
+        * jit/JITCode.cpp:
+        (JSC::JITCodeWithCodeRef::executableAddressAtOffset):
+        (JSC::JITCodeWithCodeRef::dataAddressAtOffset):
+        (JSC::JITCodeWithCodeRef::offsetOf):
+        * jit/JITDisassembler.cpp:
+        (JSC::JITDisassembler::dumpDisassembly):
+        * jit/PCToCodeOriginMap.cpp:
+        (JSC::PCToCodeOriginMap::PCToCodeOriginMap):
+        * jit/Repatch.cpp:
+        (JSC::ftlThunkAwareRepatchCall):
+        * jit/ThunkGenerators.cpp:
+        (JSC::virtualThunkFor):
+        (JSC::boundThisNoArgsFunctionCallGenerator):
+        * llint/LLIntSlowPaths.cpp:
+        (JSC::LLInt::llint_trace_operand):
+        (JSC::LLInt::llint_trace_value):
+        (JSC::LLInt::handleHostCall):
+        (JSC::LLInt::setUpCall):
+        * llint/LowLevelInterpreter64.asm:
+        * offlineasm/cloop.rb:
+        * runtime/InitializeThreading.cpp:
+        (JSC::initializeThreading):
+        * wasm/WasmBBQPlan.cpp:
+        (JSC::Wasm::BBQPlan::complete):
+        * wasm/WasmCallee.h:
+        (JSC::Wasm::Callee::entrypoint const):
+        * wasm/WasmCodeBlock.cpp:
+        (JSC::Wasm::CodeBlock::CodeBlock):
+        * wasm/WasmOMGPlan.cpp:
+        (JSC::Wasm::OMGPlan::work):
+        * wasm/js/WasmToJS.cpp:
+        (JSC::Wasm::wasmToJS):
+        * wasm/js/WebAssemblyFunction.cpp:
+        (JSC::callWebAssemblyFunction):
+        * wasm/js/WebAssemblyFunction.h:
+        * wasm/js/WebAssemblyWrapperFunction.cpp:
+        (JSC::WebAssemblyWrapperFunction::create):
+
 2017-11-30  Yusuke Suzuki  <utatane....@gmail.com>
 
         [JSC] Remove easy toRemove & map.remove() use

Modified: trunk/Source/_javascript_Core/assembler/AbstractMacroAssembler.h (225362 => 225363)


--- trunk/Source/_javascript_Core/assembler/AbstractMacroAssembler.h	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/assembler/AbstractMacroAssembler.h	2017-11-30 23:47:35 UTC (rev 225363)
@@ -830,7 +830,7 @@
 
     static ptrdiff_t differenceBetweenCodePtr(const MacroAssemblerCodePtr& a, const MacroAssemblerCodePtr& b)
     {
-        return reinterpret_cast<ptrdiff_t>(b.executableAddress()) - reinterpret_cast<ptrdiff_t>(a.executableAddress());
+        return b.executableAddress<ptrdiff_t>() - a.executableAddress<ptrdiff_t>();
     }
 
     unsigned debugOffset() { return m_assembler.debugOffset(); }
@@ -852,6 +852,11 @@
         AssemblerType::linkPointer(code, label, value);
     }
 
+    static void linkPointer(void* code, AssemblerLabel label, MacroAssemblerCodePtr value)
+    {
+        AssemblerType::linkPointer(code, label, value.executableAddress());
+    }
+
     static void* getLinkerAddress(void* code, AssemblerLabel label)
     {
         return AssemblerType::getRelocatedAddress(code, label);

Modified: trunk/Source/_javascript_Core/assembler/CodeLocation.h (225362 => 225363)


--- trunk/Source/_javascript_Core/assembler/CodeLocation.h	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/assembler/CodeLocation.h	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -164,55 +164,55 @@
 inline CodeLocationInstruction CodeLocationCommon::instructionAtOffset(int offset)
 {
     ASSERT_VALID_CODE_OFFSET(offset);
-    return CodeLocationInstruction(reinterpret_cast<char*>(dataLocation()) + offset);
+    return CodeLocationInstruction(dataLocation<char*>() + offset);
 }
 
 inline CodeLocationLabel CodeLocationCommon::labelAtOffset(int offset)
 {
     ASSERT_VALID_CODE_OFFSET(offset);
-    return CodeLocationLabel(reinterpret_cast<char*>(dataLocation()) + offset);
+    return CodeLocationLabel(dataLocation<char*>() + offset);
 }
 
 inline CodeLocationJump CodeLocationCommon::jumpAtOffset(int offset)
 {
     ASSERT_VALID_CODE_OFFSET(offset);
-    return CodeLocationJump(reinterpret_cast<char*>(dataLocation()) + offset);
+    return CodeLocationJump(dataLocation<char*>() + offset);
 }
 
 inline CodeLocationCall CodeLocationCommon::callAtOffset(int offset)
 {
     ASSERT_VALID_CODE_OFFSET(offset);
-    return CodeLocationCall(reinterpret_cast<char*>(dataLocation()) + offset);
+    return CodeLocationCall(dataLocation<char*>() + offset);
 }
 
 inline CodeLocationNearCall CodeLocationCommon::nearCallAtOffset(int offset, NearCallMode callMode)
 {
     ASSERT_VALID_CODE_OFFSET(offset);
-    return CodeLocationNearCall(reinterpret_cast<char*>(dataLocation()) + offset, callMode);
+    return CodeLocationNearCall(dataLocation<char*>() + offset, callMode);
 }
 
 inline CodeLocationDataLabelPtr CodeLocationCommon::dataLabelPtrAtOffset(int offset)
 {
     ASSERT_VALID_CODE_OFFSET(offset);
-    return CodeLocationDataLabelPtr(reinterpret_cast<char*>(dataLocation()) + offset);
+    return CodeLocationDataLabelPtr(dataLocation<char*>() + offset);
 }
 
 inline CodeLocationDataLabel32 CodeLocationCommon::dataLabel32AtOffset(int offset)
 {
     ASSERT_VALID_CODE_OFFSET(offset);
-    return CodeLocationDataLabel32(reinterpret_cast<char*>(dataLocation()) + offset);
+    return CodeLocationDataLabel32(dataLocation<char*>() + offset);
 }
 
 inline CodeLocationDataLabelCompact CodeLocationCommon::dataLabelCompactAtOffset(int offset)
 {
     ASSERT_VALID_CODE_OFFSET(offset);
-    return CodeLocationDataLabelCompact(reinterpret_cast<char*>(dataLocation()) + offset);
+    return CodeLocationDataLabelCompact(dataLocation<char*>() + offset);
 }
 
 inline CodeLocationConvertibleLoad CodeLocationCommon::convertibleLoadAtOffset(int offset)
 {
     ASSERT_VALID_CODE_OFFSET(offset);
-    return CodeLocationConvertibleLoad(reinterpret_cast<char*>(dataLocation()) + offset);
+    return CodeLocationConvertibleLoad(dataLocation<char*>() + offset);
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/assembler/LinkBuffer.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/assembler/LinkBuffer.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/assembler/LinkBuffer.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -70,7 +70,7 @@
     va_end(argList);
     out.printf(":\n");
 
-    out.printf("    Code at [%p, %p):\n", result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size());
+    out.printf("    Code at [%p, %p):\n", result.code().executableAddress(), result.code().executableAddress<char*>() + result.size());
     
     CString header = out.toCString();
     

Modified: trunk/Source/_javascript_Core/assembler/LinkBuffer.h (225362 => 225363)


--- trunk/Source/_javascript_Core/assembler/LinkBuffer.h	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/assembler/LinkBuffer.h	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, 2010, 2012-2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -130,7 +130,7 @@
     
     void link(Call call, CodeLocationLabel label)
     {
-        link(call, FunctionPtr(label.executableAddress()));
+        link(call, FunctionPtr(label));
     }
     
     void link(Jump jump, CodeLocationLabel label)
@@ -154,7 +154,7 @@
     void patch(DataLabelPtr label, CodeLocationLabel value)
     {
         AssemblerLabel target = applyOffset(label.m_label);
-        MacroAssembler::linkPointer(code(), target, value.executableAddress());
+        MacroAssembler::linkPointer(code(), target, value);
     }
 
     // These methods are used to obtain handles to allow the code to be relinked / repatched later.

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerCodeRef.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerCodeRef.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerCodeRef.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,9 +29,20 @@
 #include "Disassembler.h"
 #include "JSCInlines.h"
 #include "LLIntData.h"
+#include <mutex>
 
 namespace JSC {
 
+uintptr_t g_masmScrambledPtrKey;
+
+void MacroAssemblerCodePtr::initialize()
+{
+    static std::once_flag initializeOnceFlag;
+    std::call_once(initializeOnceFlag, [] {
+        g_masmScrambledPtrKey = makeScrambledPtrKey();
+    });
+}
+
 MacroAssemblerCodePtr MacroAssemblerCodePtr::createLLIntCodePtr(OpcodeID codeId)
 {
     return createFromExecutableAddress(LLInt::getCodePtr(codeId));

Modified: trunk/Source/_javascript_Core/assembler/MacroAssemblerCodeRef.h (225362 => 225363)


--- trunk/Source/_javascript_Core/assembler/MacroAssemblerCodeRef.h	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/assembler/MacroAssemblerCodeRef.h	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009, 2012, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2009-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -29,6 +29,7 @@
 #include <wtf/DataLog.h>
 #include <wtf/PrintStream.h>
 #include <wtf/RefPtr.h>
+#include <wtf/ScrambledPtr.h>
 #include <wtf/text/CString.h>
 
 // ASSERT_VALID_CODE_POINTER checks that ptr is a non-null pointer, and that it is a valid
@@ -50,6 +51,12 @@
 
 namespace JSC {
 
+extern "C" JS_EXPORTDATA uintptr_t g_masmScrambledPtrKey;
+
+using MasmScrambledPtr = ScrambledPtr<g_masmScrambledPtrKey>;
+
+class MacroAssemblerCodePtr;
+
 enum OpcodeID : unsigned;
 
 // FunctionPtr:
@@ -58,15 +65,13 @@
 // (particularly, the stub functions).
 class FunctionPtr {
 public:
-    FunctionPtr()
-        : m_value(0)
-    {
-    }
+    FunctionPtr() { }
 
     template<typename returnType>
     FunctionPtr(returnType(*value)())
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -74,6 +79,7 @@
     FunctionPtr(returnType(*value)(argType1))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -81,6 +87,7 @@
     FunctionPtr(returnType(*value)(argType1, argType2))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -88,6 +95,7 @@
     FunctionPtr(returnType(*value)(argType1, argType2, argType3))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -95,6 +103,7 @@
     FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -102,6 +111,7 @@
     FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4, argType5))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -109,6 +119,7 @@
     FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4, argType5, argType6))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 // MSVC doesn't seem to treat functions with different calling conventions as
@@ -119,6 +130,7 @@
     FunctionPtr(returnType (CDECL *value)())
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -126,6 +138,7 @@
     FunctionPtr(returnType (CDECL *value)(argType1))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -133,6 +146,7 @@
     FunctionPtr(returnType (CDECL *value)(argType1, argType2))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -140,6 +154,7 @@
     FunctionPtr(returnType (CDECL *value)(argType1, argType2, argType3))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -147,6 +162,7 @@
     FunctionPtr(returnType (CDECL *value)(argType1, argType2, argType3, argType4))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 #endif
@@ -157,6 +173,7 @@
     FunctionPtr(returnType (FASTCALL *value)())
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -164,6 +181,7 @@
     FunctionPtr(returnType (FASTCALL *value)(argType1))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -171,6 +189,7 @@
     FunctionPtr(returnType (FASTCALL *value)(argType1, argType2))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -178,6 +197,7 @@
     FunctionPtr(returnType (FASTCALL *value)(argType1, argType2, argType3))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -185,6 +205,7 @@
     FunctionPtr(returnType (FASTCALL *value)(argType1, argType2, argType3, argType4))
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 #endif
@@ -196,15 +217,25 @@
         // (I guess on RVTC function pointers have a different constness to GCC/MSVC?)
         : m_value((void*)value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
-    void* value() const { return m_value; }
-    void* executableAddress() const { return m_value; }
+    explicit FunctionPtr(MacroAssemblerCodePtr);
 
+    void* value() const
+    {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
+        return m_value;
+    }
+    void* executableAddress() const
+    {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
+        return m_value;
+    }
 
 private:
-    void* m_value;
+    void* m_value { nullptr };
 };
 
 // ReturnAddressPtr:
@@ -215,14 +246,12 @@
 // that is the source of the return address.
 class ReturnAddressPtr {
 public:
-    ReturnAddressPtr()
-        : m_value(0)
-    {
-    }
+    ReturnAddressPtr() { }
 
     explicit ReturnAddressPtr(void* value)
         : m_value(value)
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
@@ -229,10 +258,15 @@
     explicit ReturnAddressPtr(FunctionPtr function)
         : m_value(function.value())
     {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
-    void* value() const { return m_value; }
+    void* value() const
+    {
+        MasmScrambledPtr::assertIsNotScrambled(m_value);
+        return m_value;
+    }
     
     void dump(PrintStream& out) const
     {
@@ -240,7 +274,7 @@
     }
 
 private:
-    void* m_value;
+    void* m_value { nullptr };
 };
 
 // MacroAssemblerCodePtr:
@@ -248,10 +282,7 @@
 // MacroAssemblerCodePtr should be used to wrap pointers to JIT generated code.
 class MacroAssemblerCodePtr {
 public:
-    MacroAssemblerCodePtr()
-        : m_value(0)
-    {
-    }
+    MacroAssemblerCodePtr() { }
 
     explicit MacroAssemblerCodePtr(void* value)
 #if CPU(ARM_THUMB2)
@@ -261,14 +292,18 @@
         : m_value(value)
 #endif
     {
+        m_value.assertIsScrambled();
+        ASSERT(value);
         ASSERT_VALID_CODE_POINTER(m_value);
     }
     
     static MacroAssemblerCodePtr createFromExecutableAddress(void* value)
     {
+        ASSERT(value);
         ASSERT_VALID_CODE_POINTER(value);
         MacroAssemblerCodePtr result;
-        result.m_value = value;
+        result.m_value = MasmScrambledPtr(value);
+        result.m_value.assertIsScrambled();
         return result;
     }
 
@@ -277,24 +312,64 @@
     explicit MacroAssemblerCodePtr(ReturnAddressPtr ra)
         : m_value(ra.value())
     {
+        ASSERT(ra.value());
+        m_value.assertIsScrambled();
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
-    void* executableAddress() const { return m_value; }
+    MasmScrambledPtr scrambledPtr() const { return m_value; }
+
+    template<typename T = void*>
+    T executableAddress() const
+    {
+        m_value.assertIsScrambled();
+        return m_value ? m_value.descramble<T>() : static_cast<T>(0);
+    }
 #if CPU(ARM_THUMB2)
     // To use this pointer as a data address remove the decoration.
-    void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return reinterpret_cast<char*>(m_value) - 1; }
+    template<typename T = void*>
+    T dataLocation() const
+    {
+        m_value.assertIsScrambled();
+        ASSERT_VALID_CODE_POINTER(m_value);
+        return bitwise_cast<T>(m_value ? m_value.descramble<char*>() - 1 : nullptr);
+    }
 #else
-    void* dataLocation() const { ASSERT_VALID_CODE_POINTER(m_value); return m_value; }
+    template<typename T = void*>
+    T dataLocation() const
+    {
+        m_value.assertIsScrambled();
+        ASSERT_VALID_CODE_POINTER(m_value);
+        return m_value ? m_value.descramble<T>() : static_cast<T>(0);
+    }
 #endif
 
-    explicit operator bool() const { return m_value; }
+    bool operator!() const
+    {
+#if ENABLE(SCRAMBLED_PTR_ASSERTS)
+        if (!isEmptyValue() && !isDeletedValue())
+            m_value.assertIsScrambled();
+#endif
+        return !m_value;
+    }
+    explicit operator bool() const { return !(!*this); }
     
     bool operator==(const MacroAssemblerCodePtr& other) const
     {
+#if ENABLE(SCRAMBLED_PTR_ASSERTS)
+        if (!isEmptyValue() && !isDeletedValue())
+            m_value.assertIsScrambled();
+        if (!other.isEmptyValue() && !other.isDeletedValue())
+            other.m_value.assertIsScrambled();
+#endif
         return m_value == other.m_value;
     }
 
+    // Disallow any casting operations (except for booleans). Instead, the client
+    // should be asking for scrambledPtr() or executableAddress() explicitly.
+    template<typename T, typename = std::enable_if_t<!std::is_same<T, bool>::value>>
+    operator T() = delete;
+
     void dumpWithName(const char* name, PrintStream& out) const;
     
     void dump(PrintStream& out) const;
@@ -304,24 +379,24 @@
     
     MacroAssemblerCodePtr(EmptyValueTag)
         : m_value(emptyValue())
-    {
-    }
+    { }
     
     MacroAssemblerCodePtr(DeletedValueTag)
         : m_value(deletedValue())
-    {
-    }
+    { }
     
     bool isEmptyValue() const { return m_value == emptyValue(); }
     bool isDeletedValue() const { return m_value == deletedValue(); }
-    
-    unsigned hash() const { return PtrHash<void*>::hash(m_value); }
 
+    unsigned hash() const { return IntHash<uintptr_t>::hash(m_value.scrambledBits()); }
+
+    static void initialize();
+
 private:
-    static void* emptyValue() { return bitwise_cast<void*>(static_cast<intptr_t>(1)); }
-    static void* deletedValue() { return bitwise_cast<void*>(static_cast<intptr_t>(2)); }
-    
-    void* m_value;
+    static MasmScrambledPtr emptyValue() { return MasmScrambledPtr(1); }
+    static MasmScrambledPtr deletedValue() { return MasmScrambledPtr(2); }
+
+    MasmScrambledPtr m_value;
 };
 
 struct MacroAssemblerCodePtrHash {
@@ -405,6 +480,13 @@
     RefPtr<ExecutableMemoryHandle> m_executableMemory;
 };
 
+inline FunctionPtr::FunctionPtr(MacroAssemblerCodePtr ptr)
+    : m_value(ptr.executableAddress())
+{
+    MasmScrambledPtr::assertIsNotScrambled(m_value);
+    ASSERT_VALID_CODE_POINTER(m_value);
+}
+
 } // namespace JSC
 
 namespace WTF {

Modified: trunk/Source/_javascript_Core/b3/B3LowerMacros.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/b3/B3LowerMacros.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/b3/B3LowerMacros.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -470,7 +470,7 @@
                 patchpoint->effects.terminal = true;
                 
                 patchpoint->appendSomeRegister(index);
-                patchpoint->numGPScratchRegisters++;
+                patchpoint->numGPScratchRegisters = 2;
                 // Technically, we don't have to clobber macro registers on X86_64. This is probably
                 // OK though.
                 patchpoint->clobber(RegisterSet::macroScratchRegisters());
@@ -505,10 +505,14 @@
                         
                         GPRReg index = params[0].gpr();
                         GPRReg scratch = params.gpScratch(0);
-                        
+                        GPRReg descramblerKey = params.gpScratch(1);
+
+                        jit.move(CCallHelpers::TrustedImm64(g_masmScrambledPtrKey), descramblerKey);
                         jit.move(CCallHelpers::TrustedImmPtr(jumpTable), scratch);
-                        jit.jump(CCallHelpers::BaseIndex(scratch, index, CCallHelpers::timesPtr()));
-                        
+                        jit.load64(CCallHelpers::BaseIndex(scratch, index, CCallHelpers::timesPtr()), scratch);
+                        jit.xor64(descramblerKey, scratch);
+                        jit.jump(scratch);
+
                         // These labels are guaranteed to be populated before either late paths or
                         // link tasks run.
                         Vector<Box<CCallHelpers::Label>> labels = params.successorLabels();

Modified: trunk/Source/_javascript_Core/b3/testb3.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/b3/testb3.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/b3/testb3.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -13007,7 +13007,7 @@
     polyJump->effects.terminal = true;
     polyJump->appendSomeRegister(opcode);
     polyJump->clobber(RegisterSet::macroScratchRegisters());
-    polyJump->numGPScratchRegisters++;
+    polyJump->numGPScratchRegisters = 2;
     dispatch->appendSuccessor(FrequentedBlock(addToDataPointer));
     dispatch->appendSuccessor(FrequentedBlock(addToCodePointer));
     dispatch->appendSuccessor(FrequentedBlock(addToData));
@@ -13029,9 +13029,15 @@
             MacroAssemblerCodePtr* jumpTable = bitwise_cast<MacroAssemblerCodePtr*>(
                 params.proc().addDataSection(sizeof(MacroAssemblerCodePtr) * labels.size()));
 
-            jit.move(CCallHelpers::TrustedImmPtr(jumpTable), params.gpScratch(0));
-            jit.jump(CCallHelpers::BaseIndex(params.gpScratch(0), params[0].gpr(), CCallHelpers::timesPtr()));
-            
+            GPRReg scratch = params.gpScratch(0);
+            GPRReg descramblerKey = params.gpScratch(1);
+
+            jit.move(CCallHelpers::TrustedImmPtr(jumpTable), scratch);
+            jit.move(CCallHelpers::TrustedImm64(g_masmScrambledPtrKey), descramblerKey);
+            jit.load64(CCallHelpers::BaseIndex(scratch, params[0].gpr(), CCallHelpers::timesPtr()), scratch);
+            jit.xor64(descramblerKey, scratch);
+            jit.jump(scratch);
+
             jit.addLinkTask(
                 [&, jumpTable, labels] (LinkBuffer& linkBuffer) {
                     for (unsigned i = labels.size(); i--;)

Modified: trunk/Source/_javascript_Core/dfg/DFGDisassembler.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/dfg/DFGDisassembler.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/dfg/DFGDisassembler.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -168,8 +168,8 @@
     CodeLocationLabel start = linkBuffer.locationOf(previousLabel);
     CodeLocationLabel end = linkBuffer.locationOf(currentLabel);
     previousLabel = currentLabel;
-    ASSERT(bitwise_cast<uintptr_t>(end.executableAddress()) >= bitwise_cast<uintptr_t>(start.executableAddress()));
-    disassemble(start, bitwise_cast<uintptr_t>(end.executableAddress()) - bitwise_cast<uintptr_t>(start.executableAddress()), prefixBuffer.get(), out);
+    ASSERT(end.executableAddress<uintptr_t>() >= start.executableAddress<uintptr_t>());
+    disassemble(start, end.executableAddress<uintptr_t>() - start.executableAddress<uintptr_t>(), prefixBuffer.get(), out);
 }
 
 } } // namespace JSC::DFG

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -288,7 +288,7 @@
     
     for (auto& record : m_jsCalls) {
         CallLinkInfo& info = *record.info;
-        linkBuffer.link(record.slowCall, FunctionPtr(vm()->getCTIStub(linkCallThunkGenerator).code().executableAddress()));
+        linkBuffer.link(record.slowCall, FunctionPtr(vm()->getCTIStub(linkCallThunkGenerator).code()));
         info.setCallLocations(
             CodeLocationLabel(linkBuffer.locationOfNearCall(record.slowCall)),
             CodeLocationLabel(linkBuffer.locationOf(record.targetToCheck)),
@@ -525,9 +525,9 @@
     
     m_jitCode->shrinkToFit();
     codeBlock()->shrinkToFit(CodeBlock::LateShrink);
-    
-    linkBuffer->link(m_callArityFixup, FunctionPtr((vm()->getCTIStub(arityFixupGenerator)).code().executableAddress()));
-    
+
+    linkBuffer->link(m_callArityFixup, FunctionPtr(vm()->getCTIStub(arityFixupGenerator).code()));
+
     disassemble(*linkBuffer);
 
     MacroAssemblerCodePtr withArityCheck = linkBuffer->locationOf(m_arityCheck);

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -2041,8 +2041,8 @@
     double asDouble = value.asDouble();
     int32_t asInt32 = static_cast<int32_t>(asDouble);
     if (asDouble == asInt32)
-        return static_cast<char*>(table.ctiForValue(asInt32).executableAddress());
-    return static_cast<char*>(table.ctiDefault.executableAddress());
+        return table.ctiForValue(asInt32).executableAddress<char*>();
+    return table.ctiDefault.executableAddress<char*>();
 }
 
 char* JIT_OPERATION operationSwitchString(ExecState* exec, size_t tableIndex, JSString* string)
@@ -2050,7 +2050,7 @@
     VM& vm = exec->vm();
     NativeCallFrameTracer tracer(&vm, exec);
 
-    return static_cast<char*>(exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress());
+    return exec->codeBlock()->stringSwitchJumpTable(tableIndex).ctiForValue(string->value(exec).impl()).executableAddress<char*>();
 }
 
 int32_t JIT_OPERATION operationSwitchStringAndGetBranchOffset(ExecState* exec, size_t tableIndex, JSString* string)

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -9770,7 +9770,7 @@
 }
 
 void SpeculativeJIT::emitSwitchIntJump(
-    SwitchData* data, GPRReg value, GPRReg scratch)
+    SwitchData* data, GPRReg value, GPRReg scratch, GPRReg descramblerKeyScratch)
 {
     SimpleJumpTable& table = m_jit.codeBlock()->switchJumpTable(data->switchTableIndex);
     table.ensureCTITable();
@@ -9778,8 +9778,16 @@
     addBranch(
         m_jit.branch32(JITCompiler::AboveOrEqual, value, Imm32(table.ctiOffsets.size())),
         data->fallThrough.block);
+    UNUSED_PARAM(descramblerKeyScratch); // Placate the 32-bit build.
+#if USE(JSVALUE64)
+    m_jit.move(TrustedImm64(g_masmScrambledPtrKey), descramblerKeyScratch);
+#endif
     m_jit.move(TrustedImmPtr(table.ctiOffsets.begin()), scratch);
     m_jit.loadPtr(JITCompiler::BaseIndex(scratch, value, JITCompiler::timesPtr()), scratch);
+    
+#if USE(JSVALUE64)
+    m_jit.xor64(descramblerKeyScratch, scratch);
+#endif
     m_jit.jump(scratch);
     data->didUseJumpTable = true;
 }
@@ -9790,7 +9798,8 @@
     case Int32Use: {
         SpeculateInt32Operand value(this, node->child1());
         GPRTemporary temp(this);
-        emitSwitchIntJump(data, value.gpr(), temp.gpr());
+        GPRTemporary temp2(this);
+        emitSwitchIntJump(data, value.gpr(), temp.gpr(), temp2.gpr());
         noResult(node);
         break;
     }
@@ -9798,15 +9807,17 @@
     case UntypedUse: {
         JSValueOperand value(this, node->child1());
         GPRTemporary temp(this);
+        GPRTemporary temp2(this);
         JSValueRegs valueRegs = value.jsValueRegs();
         GPRReg scratch = temp.gpr();
-        
+        GPRReg scratch2 = temp2.gpr();
+
         value.use();
         
 #if USE(JSVALUE64)
         JITCompiler::Jump notInt = m_jit.branch64(
             JITCompiler::Below, valueRegs.gpr(), GPRInfo::tagTypeNumberRegister);
-        emitSwitchIntJump(data, valueRegs.gpr(), scratch);
+        emitSwitchIntJump(data, valueRegs.gpr(), scratch, scratch2);
         notInt.link(&m_jit);
         addBranch(
             m_jit.branchTest64(
@@ -9819,7 +9830,7 @@
 #else
         JITCompiler::Jump notInt = m_jit.branch32(
             JITCompiler::NotEqual, valueRegs.tagGPR(), TrustedImm32(JSValue::Int32Tag));
-        emitSwitchIntJump(data, valueRegs.payloadGPR(), scratch);
+        emitSwitchIntJump(data, valueRegs.payloadGPR(), scratch, scratch2);
         notInt.link(&m_jit);
         addBranch(
             m_jit.branch32(
@@ -9843,7 +9854,7 @@
 }
 
 void SpeculativeJIT::emitSwitchCharStringJump(
-    SwitchData* data, GPRReg value, GPRReg scratch)
+    SwitchData* data, GPRReg value, GPRReg scratch, GPRReg scratch2)
 {
     addBranch(
         m_jit.branch32(
@@ -9874,7 +9885,7 @@
     m_jit.load8(MacroAssembler::Address(value), scratch);
     
     ready.link(&m_jit);
-    emitSwitchIntJump(data, scratch, value);
+    emitSwitchIntJump(data, scratch, value, scratch2);
 }
 
 void SpeculativeJIT::emitSwitchChar(Node* node, SwitchData* data)
@@ -9883,14 +9894,16 @@
     case StringUse: {
         SpeculateCellOperand op1(this, node->child1());
         GPRTemporary temp(this);
-        
+        GPRTemporary temp2(this);
+
         GPRReg op1GPR = op1.gpr();
         GPRReg tempGPR = temp.gpr();
-        
+        GPRReg temp2GPR = temp2.gpr();
+
         op1.use();
 
         speculateString(node->child1(), op1GPR);
-        emitSwitchCharStringJump(data, op1GPR, tempGPR);
+        emitSwitchCharStringJump(data, op1GPR, tempGPR, temp2GPR);
         noResult(node, UseChildrenCalledExplicitly);
         break;
     }
@@ -9898,10 +9911,12 @@
     case UntypedUse: {
         JSValueOperand op1(this, node->child1());
         GPRTemporary temp(this);
-        
+        GPRTemporary temp2(this);
+
         JSValueRegs op1Regs = op1.jsValueRegs();
         GPRReg tempGPR = temp.gpr();
-        
+        GPRReg temp2GPR = temp2.gpr();
+
         op1.use();
         
         addBranch(m_jit.branchIfNotCell(op1Regs), data->fallThrough.block);
@@ -9908,7 +9923,7 @@
         
         addBranch(m_jit.branchIfNotString(op1Regs.payloadGPR()), data->fallThrough.block);
         
-        emitSwitchCharStringJump(data, op1Regs.payloadGPR(), tempGPR);
+        emitSwitchCharStringJump(data, op1Regs.payloadGPR(), tempGPR, temp2GPR);
         noResult(node, UseChildrenCalledExplicitly);
         break;
     }

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (225362 => 225363)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h	2017-11-30 23:47:35 UTC (rev 225363)
@@ -2858,9 +2858,9 @@
         BasicBlock* target;
     };
     
-    void emitSwitchIntJump(SwitchData*, GPRReg value, GPRReg scratch);
+    void emitSwitchIntJump(SwitchData*, GPRReg value, GPRReg scratch, GPRReg scratch2);
     void emitSwitchImm(Node*, SwitchData*);
-    void emitSwitchCharStringJump(SwitchData*, GPRReg value, GPRReg scratch);
+    void emitSwitchCharStringJump(SwitchData*, GPRReg value, GPRReg scratch, GPRReg scratch2);
     void emitSwitchChar(Node*, SwitchData*);
     void emitBinarySwitchStringRecurse(
         SwitchData*, const Vector<StringSwitchCase>&, unsigned numChecked,

Modified: trunk/Source/_javascript_Core/disassembler/Disassembler.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/disassembler/Disassembler.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/disassembler/Disassembler.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -42,7 +42,7 @@
     if (tryToDisassemble(codePtr, size, prefix, out))
         return;
     
-    out.printf("%sdisassembly not available for range %p...%p\n", prefix, codePtr.executableAddress(), static_cast<char*>(codePtr.executableAddress()) + size);
+    out.printf("%sdisassembly not available for range %p...%p\n", prefix, codePtr.executableAddress(), codePtr.executableAddress<char*>() + size);
 }
 
 namespace {

Modified: trunk/Source/_javascript_Core/disassembler/UDis86Disassembler.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/disassembler/UDis86Disassembler.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/disassembler/UDis86Disassembler.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012, 2013, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -37,13 +37,13 @@
 {
     ud_t disassembler;
     ud_init(&disassembler);
-    ud_set_input_buffer(&disassembler, static_cast<unsigned char*>(codePtr.executableAddress()), size);
+    ud_set_input_buffer(&disassembler, codePtr.executableAddress<unsigned char*>(), size);
 #if CPU(X86_64)
     ud_set_mode(&disassembler, 64);
 #else
     ud_set_mode(&disassembler, 32);
 #endif
-    ud_set_pc(&disassembler, bitwise_cast<uintptr_t>(codePtr.executableAddress()));
+    ud_set_pc(&disassembler, codePtr.executableAddress<uintptr_t>());
     ud_set_syntax(&disassembler, UD_SYN_ATT);
     
     uint64_t currentPC = disassembler.pc;

Modified: trunk/Source/_javascript_Core/ftl/FTLCompile.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/ftl/FTLCompile.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/ftl/FTLCompile.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -152,8 +152,8 @@
     if (vm.shouldBuilderPCToCodeOriginMapping())
         codeBlock->setPCToCodeOriginMap(std::make_unique<PCToCodeOriginMap>(PCToCodeOriginMapBuilder(vm, WTFMove(originMap)), *state.finalizer->b3CodeLinkBuffer));
 
-    state.generatedFunction = bitwise_cast<GeneratedFunction>(
-        state.finalizer->b3CodeLinkBuffer->locationOf(state.proc->entrypointLabel(0)));
+    CodeLocationLabel label = state.finalizer->b3CodeLinkBuffer->locationOf(state.proc->entrypointLabel(0));
+    state.generatedFunction = label.executableAddress<GeneratedFunction>();
     state.jitCode->initializeB3Byproducts(state.proc->releaseByproducts());
 
     for (auto pair : state.graph.m_entrypointIndexToCatchBytecodeOffset) {

Modified: trunk/Source/_javascript_Core/ftl/FTLJITCode.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/ftl/FTLJITCode.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/ftl/FTLJITCode.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -84,7 +84,7 @@
 
 void* JITCode::executableAddressAtOffset(size_t offset)
 {
-    return reinterpret_cast<char*>(m_addressForCall.executableAddress()) + offset;
+    return m_addressForCall.executableAddress<char*>() + offset;
 }
 
 void* JITCode::dataAddressAtOffset(size_t)

Modified: trunk/Source/_javascript_Core/ftl/FTLLink.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/ftl/FTLLink.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/ftl/FTLLink.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -170,7 +170,7 @@
             }
             linkBuffer->link(callArityCheck, codeBlock->m_isConstructor ? operationConstructArityCheck : operationCallArityCheck);
             linkBuffer->link(callLookupExceptionHandlerFromCallerFrame, lookupExceptionHandlerFromCallerFrame);
-            linkBuffer->link(callArityFixup, FunctionPtr((vm.getCTIStub(arityFixupGenerator)).code().executableAddress()));
+            linkBuffer->link(callArityFixup, FunctionPtr((vm.getCTIStub(arityFixupGenerator)).code()));
             linkBuffer->link(mainPathJumps, CodeLocationLabel(bitwise_cast<void*>(state.generatedFunction)));
         }
         

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1821,7 +1821,7 @@
 #if ENABLE(MATH_IC_STATS)
                         auto slowPathEnd = jit.label();
                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
-                            size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
+                            size_t size = linkBuffer.locationOf(slowPathEnd).executableAddress<char*>() - linkBuffer.locationOf(slowPathStart).executableAddress<char*>();
                             mathIC->m_generatedCodeSize += size;
                         });
 #endif
@@ -1835,7 +1835,7 @@
 #if ENABLE(MATH_IC_STATS)
                 auto inlineEnd = jit.label();
                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
-                    size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
+                    size_t size = linkBuffer.locationOf(inlineEnd).executableAddress<char*>() - linkBuffer.locationOf(inlineStart).executableAddress<char*>();
                     mathIC->m_generatedCodeSize += size;
                 });
 #endif
@@ -1914,7 +1914,7 @@
 #if ENABLE(MATH_IC_STATS)
                         auto slowPathEnd = jit.label();
                         jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
-                            size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
+                            size_t size = linkBuffer.locationOf(slowPathEnd).executableAddress<char*>() - linkBuffer.locationOf(slowPathStart).executableAddress<char*>();
                             mathIC->m_generatedCodeSize += size;
                         });
 #endif
@@ -1928,7 +1928,7 @@
 #if ENABLE(MATH_IC_STATS)
                 auto inlineEnd = jit.label();
                 jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
-                    size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
+                    size_t size = linkBuffer.locationOf(inlineEnd).executableAddress<char*>() - linkBuffer.locationOf(inlineStart).executableAddress<char*>();
                     mathIC->m_generatedCodeSize += size;
                 });
 #endif
@@ -6765,7 +6765,7 @@
                     [=] (LinkBuffer& linkBuffer) {
                         MacroAssemblerCodePtr linkCall =
                             vm->getCTIStub(linkCallThunkGenerator).code();
-                        linkBuffer.link(slowCall, FunctionPtr(linkCall.executableAddress()));
+                        linkBuffer.link(slowCall, FunctionPtr(linkCall));
 
                         callLinkInfo->setCallLocations(
                             CodeLocationLabel(linkBuffer.locationOfNearCall(slowCall)),
@@ -7076,7 +7076,7 @@
                     [=] (LinkBuffer& linkBuffer) {
                         MacroAssemblerCodePtr linkCall =
                             vm->getCTIStub(linkCallThunkGenerator).code();
-                        linkBuffer.link(slowCall, FunctionPtr(linkCall.executableAddress()));
+                        linkBuffer.link(slowCall, FunctionPtr(linkCall));
 
                         callLinkInfo->setCallLocations(
                             CodeLocationLabel(linkBuffer.locationOfNearCall(slowCall)),
@@ -7346,7 +7346,7 @@
                     [=] (LinkBuffer& linkBuffer) {
                         MacroAssemblerCodePtr linkCall =
                             vm->getCTIStub(linkCallThunkGenerator).code();
-                        linkBuffer.link(slowCall, FunctionPtr(linkCall.executableAddress()));
+                        linkBuffer.link(slowCall, FunctionPtr(linkCall));
                         
                         callLinkInfo->setCallLocations(
                             CodeLocationLabel(linkBuffer.locationOfNearCall(slowCall)),
@@ -7629,7 +7629,7 @@
                     [=] (LinkBuffer& linkBuffer) {
                         MacroAssemblerCodePtr linkCall =
                             vm->getCTIStub(linkCallThunkGenerator).code();
-                        linkBuffer.link(slowCall, FunctionPtr(linkCall.executableAddress()));
+                        linkBuffer.link(slowCall, FunctionPtr(linkCall));
                         
                         callLinkInfo->setCallLocations(
                             CodeLocationLabel(linkBuffer.locationOfNearCall(slowCall)),

Modified: trunk/Source/_javascript_Core/interpreter/InterpreterInlines.h (225362 => 225363)


--- trunk/Source/_javascript_Core/interpreter/InterpreterInlines.h	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/interpreter/InterpreterInlines.h	2017-11-30 23:47:35 UTC (rev 225363)
@@ -47,7 +47,7 @@
     // the LLInt code for the opcode (see the EMBED_OPCODE_ID_IF_NEEDED macro
     // in LowLevelInterpreter.cpp).
     MacroAssemblerCodePtr codePtr(reinterpret_cast<void*>(opcode));
-    int32_t* opcodeIDAddress = reinterpret_cast<int32_t*>(codePtr.dataLocation()) - 1;
+    int32_t* opcodeIDAddress = codePtr.dataLocation<int32_t*>() - 1;
     OpcodeID opcodeID = static_cast<OpcodeID>(*opcodeIDAddress);
     ASSERT(opcodeID < NUMBER_OF_BYTECODE_IDS);
     return opcodeID;

Modified: trunk/Source/_javascript_Core/jit/JITArithmetic.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/jit/JITArithmetic.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/jit/JITArithmetic.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -716,7 +716,7 @@
 #if ENABLE(MATH_IC_STATS)
     auto inlineEnd = label();
     addLinkTask([=] (LinkBuffer& linkBuffer) {
-        size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
+        size_t size = linkBuffer.locationOf(inlineEnd).executableAddress<char*>() - linkBuffer.locationOf(inlineStart).executableAddress<char*>();
         mathIC->m_generatedCodeSize += size;
     });
 #endif
@@ -789,7 +789,7 @@
 #if ENABLE(MATH_IC_STATS)
     auto inlineEnd = label();
     addLinkTask([=] (LinkBuffer& linkBuffer) {
-        size_t size = static_cast<char*>(linkBuffer.locationOf(inlineEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(inlineStart).executableAddress());
+        size_t size = linkBuffer.locationOf(inlineEnd).executableAddress<char*>() - linkBuffer.locationOf(inlineStart).executableAddress<char*>();
         mathIC->m_generatedCodeSize += size;
     });
 #endif
@@ -829,7 +829,7 @@
 #if ENABLE(MATH_IC_STATS)
     auto slowPathEnd = label();
     addLinkTask([=] (LinkBuffer& linkBuffer) {
-        size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
+        size_t size = linkBuffer.locationOf(slowPathEnd).executableAddress<char*>() - linkBuffer.locationOf(slowPathStart).executableAddress<char*>();
         mathIC->m_generatedCodeSize += size;
     });
 #endif
@@ -895,7 +895,7 @@
 #if ENABLE(MATH_IC_STATS)
     auto slowPathEnd = label();
     addLinkTask([=] (LinkBuffer& linkBuffer) {
-        size_t size = static_cast<char*>(linkBuffer.locationOf(slowPathEnd).executableAddress()) - static_cast<char*>(linkBuffer.locationOf(slowPathStart).executableAddress());
+        size_t size = linkBuffer.locationOf(slowPathEnd).executableAddress<char*>() - linkBuffer.locationOf(slowPathStart).executableAddress<char*>();
         mathIC->m_generatedCodeSize += size;
     });
 #endif

Modified: trunk/Source/_javascript_Core/jit/JITCode.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/jit/JITCode.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/jit/JITCode.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -127,7 +127,7 @@
 void* JITCodeWithCodeRef::executableAddressAtOffset(size_t offset)
 {
     RELEASE_ASSERT(m_ref);
-    return reinterpret_cast<char*>(m_ref.code().executableAddress()) + offset;
+    return m_ref.code().executableAddress<char*>() + offset;
 }
 
 void* JITCodeWithCodeRef::dataAddressAtOffset(size_t offset)
@@ -134,13 +134,13 @@
 {
     RELEASE_ASSERT(m_ref);
     ASSERT(offset <= size()); // use <= instead of < because it is valid to ask for an address at the exclusive end of the code.
-    return reinterpret_cast<char*>(m_ref.code().dataLocation()) + offset;
+    return m_ref.code().dataLocation<char*>() + offset;
 }
 
 unsigned JITCodeWithCodeRef::offsetOf(void* pointerIntoCode)
 {
     RELEASE_ASSERT(m_ref);
-    intptr_t result = reinterpret_cast<intptr_t>(pointerIntoCode) - reinterpret_cast<intptr_t>(m_ref.code().executableAddress());
+    intptr_t result = reinterpret_cast<intptr_t>(pointerIntoCode) - m_ref.code().executableAddress<intptr_t>();
     ASSERT(static_cast<intptr_t>(static_cast<unsigned>(result)) == result);
     return static_cast<unsigned>(result);
 }

Modified: trunk/Source/_javascript_Core/jit/JITDisassembler.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/jit/JITDisassembler.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/jit/JITDisassembler.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -163,7 +163,7 @@
 {
     CodeLocationLabel fromLocation = linkBuffer.locationOf(from);
     CodeLocationLabel toLocation = linkBuffer.locationOf(to);
-    disassemble(fromLocation, bitwise_cast<uintptr_t>(toLocation.executableAddress()) - bitwise_cast<uintptr_t>(fromLocation.executableAddress()), "        ", out);
+    disassemble(fromLocation, toLocation.executableAddress<uintptr_t>() - fromLocation.executableAddress<uintptr_t>(), "        ", out);
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/jit/PCToCodeOriginMap.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/jit/PCToCodeOriginMap.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/jit/PCToCodeOriginMap.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -204,8 +204,8 @@
             codeOriginCompressor.write<uintptr_t>(bitwise_cast<uintptr_t>(codeOrigin.inlineCallFrame));
     };
 
-    m_pcRangeStart = bitwise_cast<uintptr_t>(linkBuffer.locationOf(builder.m_codeRanges.first().start).dataLocation());
-    m_pcRangeEnd = bitwise_cast<uintptr_t>(linkBuffer.locationOf(builder.m_codeRanges.last().end).dataLocation());
+    m_pcRangeStart = linkBuffer.locationOf(builder.m_codeRanges.first().start).dataLocation<uintptr_t>();
+    m_pcRangeEnd = linkBuffer.locationOf(builder.m_codeRanges.last().end).dataLocation<uintptr_t>();
     m_pcRangeEnd -= 1;
 
     for (unsigned i = 0; i < builder.m_codeRanges.size(); i++) {

Modified: trunk/Source/_javascript_Core/jit/Repatch.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/jit/Repatch.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/jit/Repatch.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -91,8 +91,7 @@
             MacroAssemblerCodePtr::createFromExecutableAddress(
                 MacroAssembler::readCallTarget(call).executableAddress()));
         key = key.withCallTarget(newCalleeFunction.executableAddress());
-        newCalleeFunction = FunctionPtr(
-            thunks.getSlowPathCallThunk(key).code().executableAddress());
+        newCalleeFunction = FunctionPtr(thunks.getSlowPathCallThunk(key).code());
     }
 #else // ENABLE(FTL_JIT)
     UNUSED_PARAM(codeBlock);

Modified: trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/jit/ThunkGenerators.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010, 2012-2014, 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -213,7 +213,11 @@
     
     // Now we know that we have a CodeBlock, and we're committed to making a fast
     // call.
-    
+#if USE(JSVALUE64)
+    jit.move(CCallHelpers::TrustedImm64(g_masmScrambledPtrKey), GPRInfo::regT1);
+    jit.xor64(GPRInfo::regT1, GPRInfo::regT4);
+#endif
+
     // Make a tail call. This will return back to JIT code.
     JSInterfaceJIT::Label callCode(jit.label());
     emitPointerValidation(jit, GPRInfo::regT4);
@@ -1158,6 +1162,10 @@
         GPRInfo::regT0);
     CCallHelpers::Jump noCode = jit.branchTestPtr(CCallHelpers::Zero, GPRInfo::regT0);
     
+#if USE(JSVALUE64)
+    jit.move(CCallHelpers::TrustedImm64(g_masmScrambledPtrKey), GPRInfo::regT1);
+    jit.xor64(GPRInfo::regT1, GPRInfo::regT0);
+#endif
     emitPointerValidation(jit, GPRInfo::regT0);
     jit.call(GPRInfo::regT0);
     

Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -191,7 +191,8 @@
 extern "C" SlowPathReturnType llint_trace_operand(ExecState* exec, Instruction* pc, int fromWhere, int operand)
 {
     LLINT_BEGIN();
-    dataLogF("%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
+    dataLogF("<%d> %p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d\n",
+            currentThread(),
             exec->codeBlock(),
             exec,
             static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
@@ -214,7 +215,8 @@
     } u;
     u.asValue = JSValue::encode(value);
     dataLogF(
-        "%p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
+        "<%d> %p / %p: executing bc#%zu, op#%u: Trace(%d): %d: %d: %08x:%08x: %s\n",
+        currentThread(),
         exec->codeBlock(),
         exec,
         static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
@@ -230,7 +232,7 @@
 
 LLINT_SLOW_PATH_DECL(trace_prologue)
 {
-    dataLogF("%p / %p: in prologue of ", exec->codeBlock(), exec);
+    dataLogF("<%d> %p / %p: in prologue of ", currentThread(), exec->codeBlock(), exec);
     dataLog(*exec->codeBlock(), "\n");
     LLINT_END_IMPL();
 }
@@ -240,7 +242,7 @@
     JSFunction* callee = jsCast<JSFunction*>(exec->jsCallee());
     FunctionExecutable* executable = callee->jsExecutable();
     CodeBlock* codeBlock = executable->codeBlockFor(kind);
-    dataLogF("%p / %p: in %s of ", codeBlock, exec, comment);
+    dataLogF("<%d> %p / %p: in %s of ", currentThread(), codeBlock, exec, comment);
     dataLog(*codeBlock);
     dataLogF(" function %p, executable %p; numVars = %u, numParameters = %u, numCalleeLocals = %u, caller = %p.\n",
         callee, executable, codeBlock->m_numVars, codeBlock->numParameters(), codeBlock->m_numCalleeLocals, exec->callerFrame());
@@ -273,7 +275,8 @@
 LLINT_SLOW_PATH_DECL(trace)
 {
     OpcodeID opcodeID = Interpreter::getOpcodeID(pc[0].u.opcode);
-    dataLogF("%p / %p: executing bc#%zu, %s, pc = %p\n",
+    dataLogF("<%d> %p / %p: executing bc#%zu, %s, pc = %p\n",
+            currentThread(),
             exec->codeBlock(),
             exec,
             static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
@@ -291,7 +294,8 @@
 
 LLINT_SLOW_PATH_DECL(special_trace)
 {
-    dataLogF("%p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
+    dataLogF("<%d> %p / %p: executing special case bc#%zu, op#%u, return PC is %p\n",
+            currentThread(),
             exec->codeBlock(),
             exec,
             static_cast<intptr_t>(pc - exec->codeBlock()->instructions().begin()),
@@ -1305,6 +1309,7 @@
             execCallee->setCallee(asObject(callee));
             vm.hostCallReturnValue = JSValue::decode(callData.native.function(execCallee));
             
+            MasmScrambledPtr::assertIsNotScrambled(LLInt::getCodePtr(getHostCallReturnValue));
             LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
         }
         
@@ -1328,6 +1333,7 @@
         execCallee->setCallee(asObject(callee));
         vm.hostCallReturnValue = JSValue::decode(constructData.native.function(execCallee));
 
+        MasmScrambledPtr::assertIsNotScrambled(LLInt::getCodePtr(getHostCallReturnValue));
         LLINT_CALL_RETURN(execCallee, execCallee, LLInt::getCodePtr(getHostCallReturnValue));
     }
     
@@ -1368,6 +1374,7 @@
                 callLinkInfo->machineCodeTarget = codePtr;
             }
 
+            MasmScrambledPtr::assertIsNotScrambled(codePtr.executableAddress());
             LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress());
         }
         throwScope.release();
@@ -1418,6 +1425,7 @@
             codeBlock->linkIncomingCall(exec, callLinkInfo);
     }
 
+    MasmScrambledPtr::assertIsNotScrambled(codePtr.executableAddress());
     LLINT_CALL_RETURN(exec, execCallee, codePtr.executableAddress());
 }
 

Modified: trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (225362 => 225363)


--- trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/llint/LowLevelInterpreter64.asm	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1946,8 +1946,15 @@
     storei PC, ArgumentCount + TagOffset[cfr]
     storei t2, ArgumentCount + PayloadOffset[t3]
     move t3, sp
-    prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
-    callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
+    if X86_64_WIN
+        prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
+        callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
+    else
+        loadp _g_masmScrambledPtrKey, t2
+        xorp LLIntCallLinkInfo::machineCodeTarget[t1], t2
+        prepareCall(t2, t1, t3, t4)
+        callTargetFunction(t2)
+    end
 
 .opCallSlow:
     slowPathForCall(slowPath, prepareCall)

Modified: trunk/Source/_javascript_Core/offlineasm/cloop.rb (225362 => 225363)


--- trunk/Source/_javascript_Core/offlineasm/cloop.rb	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/offlineasm/cloop.rb	2017-11-30 23:47:35 UTC (rev 225363)
@@ -302,7 +302,13 @@
     end
 end
 
+class LabelReference
+    def intMemRef
+        "*CAST<intptr_t*>(&#{cLabel})"
+    end
+end
 
+
 #
 # Lea support.
 #

Modified: trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -37,6 +37,7 @@
 #include "JSGlobalObject.h"
 #include "JSLock.h"
 #include "LLIntData.h"
+#include "MacroAssemblerCodeRef.h"
 #include "Options.h"
 #include "StructureIDTable.h"
 #include "SuperSampler.h"
@@ -58,6 +59,7 @@
 
     std::call_once(initializeThreadingOnceFlag, []{
         WTF::initializeThreading();
+        MacroAssemblerCodePtr::initialize();
         Options::initialize();
 #if ENABLE(WRITE_BARRIER_PROFILING)
         WriteBarrierCounters::initialize();

Modified: trunk/Source/_javascript_Core/wasm/WasmBBQPlan.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/wasm/WasmBBQPlan.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/wasm/WasmBBQPlan.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -327,12 +327,12 @@
 
         for (auto& unlinked : m_unlinkedWasmToWasmCalls) {
             for (auto& call : unlinked) {
-                void* executableAddress;
+                MacroAssemblerCodePtr executableAddress;
                 if (m_moduleInformation->isImportedFunctionFromFunctionIndexSpace(call.functionIndexSpace)) {
                     // FIXME imports could have been linked in B3, instead of generating a patchpoint. This condition should be replaced by a RELEASE_ASSERT. https://bugs.webkit.org/show_bug.cgi?id=166462
-                    executableAddress = m_wasmToWasmExitStubs.at(call.functionIndexSpace).code().executableAddress();
+                    executableAddress = m_wasmToWasmExitStubs.at(call.functionIndexSpace).code();
                 } else
-                    executableAddress = m_wasmInternalFunctions.at(call.functionIndexSpace - m_moduleInformation->importFunctionCount())->entrypoint.compilation->code().executableAddress();
+                    executableAddress = m_wasmInternalFunctions.at(call.functionIndexSpace - m_moduleInformation->importFunctionCount())->entrypoint.compilation->code();
                 MacroAssembler::repatchNearCall(call.callLocation, CodeLocationLabel(executableAddress));
             }
         }

Modified: trunk/Source/_javascript_Core/wasm/WasmCallee.h (225362 => 225363)


--- trunk/Source/_javascript_Core/wasm/WasmCallee.h	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/wasm/WasmCallee.h	2017-11-30 23:47:35 UTC (rev 225363)
@@ -50,7 +50,7 @@
         return adoptRef(*callee);
     }
 
-    void* entrypoint() const { return m_entrypoint.compilation->code().executableAddress(); }
+    MacroAssemblerCodePtr entrypoint() const { return m_entrypoint.compilation->code(); }
 
     RegisterAtOffsetList* calleeSaveRegisters() { return &m_entrypoint.calleeSaveRegisters; }
     IndexOrName indexOrName() const { return m_indexOrName; }

Modified: trunk/Source/_javascript_Core/wasm/WasmCodeBlock.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/wasm/WasmCodeBlock.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/wasm/WasmCodeBlock.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -67,7 +67,7 @@
                 ASSERT_UNUSED(result, result.isNewEntry);
             }
             m_callees[calleeIndex] = WTFMove(wasmEntrypointCallee);
-            m_wasmIndirectCallEntryPoints[calleeIndex] = m_callees[calleeIndex]->entrypoint();
+            m_wasmIndirectCallEntryPoints[calleeIndex] = m_callees[calleeIndex]->entrypoint().executableAddress();
         });
 
         m_wasmToWasmExitStubs = m_plan->takeWasmToWasmExitStubs();

Modified: trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/wasm/WasmOMGPlan.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -103,7 +103,7 @@
 
     omgEntrypoint.calleeSaveRegisters = WTFMove(parseAndCompileResult.value()->entrypoint.calleeSaveRegisters);
 
-    void* entrypoint;
+    MacroAssemblerCodePtr entrypoint;
     {
         ASSERT(m_codeBlock.ptr() == m_module->codeBlockFor(mode()));
         Ref<Callee> callee = Callee::create(WTFMove(omgEntrypoint), functionIndexSpace, m_moduleInformation->nameSection->get(functionIndexSpace));
@@ -119,9 +119,9 @@
         m_codeBlock->m_optimizedCallees[m_functionIndex] = WTFMove(callee);
 
         for (auto& call : unlinkedCalls) {
-            void* entrypoint;
+            MacroAssemblerCodePtr entrypoint;
             if (call.functionIndexSpace < m_module->moduleInformation().importFunctionCount())
-                entrypoint = m_codeBlock->m_wasmToWasmExitStubs[call.functionIndexSpace].code().executableAddress();
+                entrypoint = m_codeBlock->m_wasmToWasmExitStubs[call.functionIndexSpace].code();
             else
                 entrypoint = m_codeBlock->wasmEntrypointCalleeFromFunctionIndexSpace(call.functionIndexSpace).entrypoint();
 
@@ -136,7 +136,7 @@
     resetInstructionCacheOnAllThreads();
     WTF::storeStoreFence(); // This probably isn't necessary but it's good to be paranoid.
 
-    m_codeBlock->m_wasmIndirectCallEntryPoints[m_functionIndex] = entrypoint;
+    m_codeBlock->m_wasmIndirectCallEntryPoints[m_functionIndex] = entrypoint.executableAddress();
     {
         LockHolder holder(m_codeBlock->m_lock);
 
@@ -144,7 +144,7 @@
             for (auto& call : callsites) {
                 dataLogLnIf(WasmOMGPlanInternal::verbose, "Considering repatching call at: ", RawPointer(call.callLocation.dataLocation()), " that targets ", call.functionIndexSpace);
                 if (call.functionIndexSpace == functionIndexSpace) {
-                    dataLogLnIf(WasmOMGPlanInternal::verbose, "Repatching call at: ", RawPointer(call.callLocation.dataLocation()), " to ", RawPointer(entrypoint));
+                    dataLogLnIf(WasmOMGPlanInternal::verbose, "Repatching call at: ", RawPointer(call.callLocation.dataLocation()), " to ", RawPointer(entrypoint.executableAddress()));
                     MacroAssembler::repatchNearCall(call.callLocation, CodeLocationLabel(entrypoint));
                 }
             }

Modified: trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/wasm/js/WasmToJS.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -627,7 +627,7 @@
     if (UNLIKELY(patchBuffer.didFailToAllocate()))
         return makeUnexpected(BindingFailure::OutOfMemory);
 
-    patchBuffer.link(slowCall, FunctionPtr(vm->getCTIStub(linkCallThunkGenerator).code().executableAddress()));
+    patchBuffer.link(slowCall, FunctionPtr(vm->getCTIStub(linkCallThunkGenerator).code()));
     CodeLocationLabel callReturnLocation(patchBuffer.locationOfNearCall(slowCall));
     CodeLocationLabel hotPathBegin(patchBuffer.locationOf(targetToCheck));
     CodeLocationNearCall hotPathOther = patchBuffer.locationOfNearCall(fastCall);

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp (225362 => 225363)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -141,7 +141,7 @@
     vm.wasmContext.store(wasmInstance, vm.softStackLimit());
     ASSERT(wasmFunction->instance());
     ASSERT(&wasmFunction->instance()->instance() == vm.wasmContext.load());
-    EncodedJSValue rawResult = vmEntryToWasm(wasmFunction->jsEntrypoint(), &vm, &protoCallFrame);
+    EncodedJSValue rawResult = vmEntryToWasm(wasmFunction->jsEntrypoint().executableAddress(), &vm, &protoCallFrame);
     // We need to make sure this is in a register or on the stack since it's stored in Vector<JSValue>.
     // This probably isn't strictly necessary, since the WebAssemblyFunction* should keep the instance
     // alive. But it's good hygiene.

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.h (225362 => 225363)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.h	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyFunction.h	2017-11-30 23:47:35 UTC (rev 225363)
@@ -27,6 +27,7 @@
 
 #if ENABLE(WEBASSEMBLY)
 
+#include "MacroAssemblerCodeRef.h"
 #include "WasmCallee.h"
 #include "WebAssemblyFunctionBase.h"
 #include <wtf/Noncopyable.h>
@@ -56,7 +57,7 @@
     Wasm::WasmEntrypointLoadLocation wasmEntrypointLoadLocation() const { return m_wasmFunction.code; }
     Wasm::CallableFunction callableFunction() const { return m_wasmFunction; }
 
-    void* jsEntrypoint() { return m_jsEntrypoint; }
+    MacroAssemblerCodePtr jsEntrypoint() { return m_jsEntrypoint; }
 
     static ptrdiff_t offsetOfWasmEntrypointLoadLocation() { return OBJECT_OFFSETOF(WebAssemblyFunction, m_wasmFunction) + Wasm::CallableFunction::offsetOfWasmEntrypointLoadLocation(); }
 
@@ -66,7 +67,7 @@
     // It's safe to just hold the raw CallableFunction/jsEntrypoint because we have a reference
     // to our Instance, which points to the Module that exported us, which
     // ensures that the actual Signature/code doesn't get deallocated.
-    void* m_jsEntrypoint;
+    MacroAssemblerCodePtr m_jsEntrypoint;
     Wasm::CallableFunction m_wasmFunction;
 };
 

Modified: trunk/Source/WTF/ChangeLog (225362 => 225363)


--- trunk/Source/WTF/ChangeLog	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/WTF/ChangeLog	2017-11-30 23:47:35 UTC (rev 225363)
@@ -1,3 +1,31 @@
+2017-11-30  Mark Lam  <mark....@apple.com>
+
+        Let's scramble MacroAssemblerCodePtr values.
+        https://bugs.webkit.org/show_bug.cgi?id=180169
+        <rdar://problem/35758340>
+
+        Reviewed by Filip Pizlo, Saam Barati, and JF Bastien.
+
+        Introduce a ScrambledPtr class to facilitate scrambling.
+
+        * WTF.xcodeproj/project.pbxproj:
+        * wtf/CMakeLists.txt:
+        * wtf/ScrambledPtr.cpp: Added.
+        (WTF::makeScrambledPtrKey):
+        * wtf/ScrambledPtr.h: Added.
+        (WTF::ScrambledPtr::ScrambledPtr):
+        (WTF::ScrambledPtr::paranoidAssertIsScrambled const):
+        (WTF::ScrambledPtr::paranoidAssertIsNotScrambled const):
+        (WTF::ScrambledPtr:: const):
+        (WTF::ScrambledPtr::operator-> const):
+        (WTF::ScrambledPtr::scrambledBits const):
+        (WTF::ScrambledPtr::operator! const):
+        (WTF::ScrambledPtr::operator bool const):
+        (WTF::ScrambledPtr::operator== const):
+        (WTF::ScrambledPtr::operator==):
+        (WTF::ScrambledPtr::scramble):
+        (WTF::ScrambledPtr::descramble):
+
 2017-11-30  Yusuke Suzuki  <utatane....@gmail.com>
 
         [JSC] Remove easy toRemove & map.remove() use

Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (225362 => 225363)


--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj	2017-11-30 23:47:35 UTC (rev 225363)
@@ -146,6 +146,7 @@
 		E38D6E271F5522E300A75CC4 /* StringBuilderJSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E38D6E261F5522E300A75CC4 /* StringBuilderJSON.cpp */; };
 		E4A0AD391A96245500536DF6 /* WorkQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A0AD371A96245500536DF6 /* WorkQueue.cpp */; };
 		E4A0AD3D1A96253C00536DF6 /* WorkQueueCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4A0AD3C1A96253C00536DF6 /* WorkQueueCocoa.cpp */; };
+		FE85416E1FBE285D008DA5DA /* ScrambledPtr.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FE85416C1FBE285B008DA5DA /* ScrambledPtr.cpp */; };
 		FEDACD3D1630F83F00C69634 /* StackStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEDACD3B1630F83F00C69634 /* StackStats.cpp */; };
 /* End PBXBuildFile section */
 
@@ -597,6 +598,8 @@
 		EF7D6CD59D8642A8A0DA86AD /* StackTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StackTrace.h; sourceTree = "<group>"; };
 		F72BBDB107FA424886178B9E /* SymbolImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolImpl.cpp; sourceTree = "<group>"; };
 		FE8225301B2A1E5B00BA68FD /* NakedPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NakedPtr.h; sourceTree = "<group>"; };
+		FE85416C1FBE285B008DA5DA /* ScrambledPtr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrambledPtr.cpp; sourceTree = "<group>"; };
+		FE85416D1FBE285C008DA5DA /* ScrambledPtr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrambledPtr.h; sourceTree = "<group>"; };
 		FE86A8741E59440200111BBF /* ForbidHeapAllocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ForbidHeapAllocation.h; sourceTree = "<group>"; };
 		FE8925AF1D00DAEC0046907E /* Indenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Indenter.h; sourceTree = "<group>"; };
 		FEDACD3B1630F83F00C69634 /* StackStats.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StackStats.cpp; sourceTree = "<group>"; };
@@ -980,6 +983,8 @@
 				1469419516EAAFF80024E146 /* SchedulePairMac.mm */,
 				1A3524AA1D63A2FF0031729B /* Scope.h */,
 				0FEC84B01BDACD390080FF74 /* ScopedLambda.h */,
+				FE85416C1FBE285B008DA5DA /* ScrambledPtr.cpp */,
+				FE85416D1FBE285C008DA5DA /* ScrambledPtr.h */,
 				0F66B2841DC97BAB004A1D3F /* Seconds.cpp */,
 				0F66B2851DC97BAB004A1D3F /* Seconds.h */,
 				A8A47306151A825B004123FF /* SegmentedVector.h */,
@@ -1459,6 +1464,7 @@
 				1C181C7F1D3078DA00F5FA16 /* TextBreakIterator.cpp in Sources */,
 				1C181C961D30800A00F5FA16 /* TextBreakIteratorInternalICUMac.mm in Sources */,
 				A3E4DD931F3A803400DED0B4 /* TextStream.cpp in Sources */,
+				FE85416E1FBE285D008DA5DA /* ScrambledPtr.cpp in Sources */,
 				E311FB171F0A568B003C08DE /* ThreadGroup.cpp in Sources */,
 				A8A4744A151A825B004123FF /* Threading.cpp in Sources */,
 				A8A4744E151A825B004123FF /* ThreadingPthreads.cpp in Sources */,

Modified: trunk/Source/WTF/wtf/CMakeLists.txt (225362 => 225363)


--- trunk/Source/WTF/wtf/CMakeLists.txt	2017-11-30 23:44:24 UTC (rev 225362)
+++ trunk/Source/WTF/wtf/CMakeLists.txt	2017-11-30 23:47:35 UTC (rev 225363)
@@ -127,6 +127,7 @@
     SharedTask.h
     SaturatedArithmetic.h
     ScopedLambda.h
+    ScrambledPtr.h
     Seconds.h
     SegmentedVector.h
     SmallPtrSet.h
@@ -256,6 +257,7 @@
     RefCountedLeakCounter.cpp
     RunLoop.cpp
     SHA1.cpp
+    ScrambledPtr.cpp
     Seconds.cpp
     SixCharacterHash.cpp
     StackBounds.cpp

Added: trunk/Source/WTF/wtf/ScrambledPtr.cpp (0 => 225363)


--- trunk/Source/WTF/wtf/ScrambledPtr.cpp	                        (rev 0)
+++ trunk/Source/WTF/wtf/ScrambledPtr.cpp	2017-11-30 23:47:35 UTC (rev 225363)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``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 "ScrambledPtr.h"
+
+#include <wtf/CryptographicallyRandomNumber.h>
+
+namespace WTF {
+
+uintptr_t makeScrambledPtrKey()
+{
+    uintptr_t key = cryptographicallyRandomNumber();
+#if USE(JSVALUE64) && !OS(WINDOWS)
+    key = (key << 32) ^ (static_cast<uintptr_t>(cryptographicallyRandomNumber()) << 3);
+    // Ensure that the scrambled bits (pointer ^ key) do not make a valid pointer and
+    // cannot be 0. We ensure that it is zero so that the scrambled bits can also be
+    // used for a notmal zero check without needing to descramble first.
+    key |= (static_cast<uintptr_t>(0x1) << 63);
+#else
+    key = 0; // Scrambling is not supported on 32-bit or non-darwin platforms yet.
+#endif
+    return key;
+}
+
+} // namespace WTF
+

Added: trunk/Source/WTF/wtf/ScrambledPtr.h (0 => 225363)


--- trunk/Source/WTF/wtf/ScrambledPtr.h	                        (rev 0)
+++ trunk/Source/WTF/wtf/ScrambledPtr.h	2017-11-30 23:47:35 UTC (rev 225363)
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/Assertions.h>
+
+#define ENABLE_SCRAMBLED_PTR_ASSERTS 0
+
+// Not currently supported for 32-bit or OS(WINDOWS) builds (because of missing llint support).
+// Make sure it's disabled.
+#if USE(JSVALUE32_64) || OS(WINDOWS)
+#undef ENABLE_SCRAMBLED_PTR_ASSERTS
+#define ENABLE_SCRAMBLED_PTR_ASSERTS 0
+#endif
+
+namespace WTF {
+
+using ScrambledPtrBits = uintptr_t;
+
+template<uintptr_t& key>
+class ScrambledPtr {
+public:
+    ScrambledPtr() { }
+
+    template<typename T, typename = typename std::enable_if<std::is_pointer<T>::value>::type>
+    explicit ScrambledPtr(T ptr)
+        : m_scrambledBits(scramble(ptr))
+    {
+        ASSERT(ptr && m_scrambledBits);
+    }
+
+    ScrambledPtr(const ScrambledPtr&) = default;
+
+    explicit ScrambledPtr(ScrambledPtrBits scrambledBits)
+        : m_scrambledBits(scrambledBits)
+    {
+        ASSERT(m_scrambledBits);
+    }
+
+#if ENABLE(SCRAMBLED_PTR_ASSERTS)
+    template<typename T = void*>
+    static bool isScrambled(T value) { return !value || (reinterpret_cast<uintptr_t>(value) & 0xffff000000000000); }
+    template<typename T = void*>
+    static void assertIsScrambled(T value) { RELEASE_ASSERT(isScrambled(value)); }
+    template<typename T = void*>
+    static void assertIsNotScrambled(T value) { RELEASE_ASSERT(!isScrambled(value)); }
+#else
+    template<typename T = void*> static void assertIsScrambled(T) { }
+    template<typename T = void*> static void assertIsNotScrambled(T) { }
+#endif
+    void assertIsScrambled() const { assertIsScrambled(m_scrambledBits); }
+    void assertIsNotScrambled() const { assertIsNotScrambled(m_scrambledBits); }
+
+    template<typename T = void*>
+    T descramble() const { return descramble<T>(m_scrambledBits); }
+
+    template<typename T, typename = typename std::enable_if<std::is_pointer<T>::value>::type>
+    ALWAYS_INLINE T operator->() const { return descramble<T>(m_scrambledBits); }
+
+    ScrambledPtrBits scrambledBits() const { return m_scrambledBits; }
+
+    bool operator!() const { return !m_scrambledBits; }
+    explicit operator bool() const { return !!m_scrambledBits; }
+
+    bool operator==(const ScrambledPtr& b) const
+    {
+        return m_scrambledBits == b.m_scrambledBits;
+    }
+
+    template<typename PtrType = void*, typename = typename std::enable_if<std::is_pointer<PtrType>::value>::type>
+    bool operator==(const PtrType b)
+    {
+        return descramble<PtrType>() == b;
+    }
+
+private:
+#if USE(JSVALUE64)
+    template<typename T>
+    ALWAYS_INLINE static ScrambledPtrBits scramble(T ptr) { return bitwise_cast<ScrambledPtrBits>(ptr) ^ key; }
+    template<typename T>
+    ALWAYS_INLINE static T descramble(ScrambledPtrBits scrambledBits) { return bitwise_cast<T>(scrambledBits ^ key); }
+#else
+    template<typename T>
+    ALWAYS_INLINE static ScrambledPtrBits scramble(T ptr) { return bitwise_cast<ScrambledPtrBits>(ptr); }
+    template<typename T>
+    ALWAYS_INLINE static T descramble(ScrambledPtrBits scrambledBits) { return bitwise_cast<T>(scrambledBits); }
+#endif
+
+    ScrambledPtrBits m_scrambledBits { 0 };
+};
+
+void initializeScrambledPtr();
+WTF_EXPORT_PRIVATE uintptr_t makeScrambledPtrKey();
+
+} // namespace WTF
+
+using WTF::ScrambledPtr;
+using WTF::ScrambledPtrBits;
+using WTF::makeScrambledPtrKey;
+
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to