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;
+