Diff
Modified: branches/safari-605-branch/Source/_javascript_Core/ChangeLog (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/ChangeLog 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/ChangeLog 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,3 +1,69 @@
+2018-01-09 Jason Marcell <[email protected]>
+
+ Cherry-pick r226530. rdar://problem/36392325
+
+ 2018-01-07 Mark Lam <[email protected]>
+
+ Apply poisoning to more pointers in JSC.
+ https://bugs.webkit.org/show_bug.cgi?id=181096
+ <rdar://problem/36182970>
+
+ Reviewed by JF Bastien.
+
+ * assembler/MacroAssembler.h:
+ (JSC::MacroAssembler::xorPtr):
+ * assembler/MacroAssemblerARM64.h:
+ (JSC::MacroAssemblerARM64::xor64):
+ * assembler/MacroAssemblerX86_64.h:
+ (JSC::MacroAssemblerX86_64::xor64):
+ - Add xorPtr implementation.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::inferredName const):
+ (JSC::CodeBlock::CodeBlock):
+ (JSC::CodeBlock::finishCreation):
+ (JSC::CodeBlock::~CodeBlock):
+ (JSC::CodeBlock::setConstantRegisters):
+ (JSC::CodeBlock::visitWeakly):
+ (JSC::CodeBlock::visitChildren):
+ (JSC::CodeBlock::propagateTransitions):
+ (JSC::CodeBlock::WeakReferenceHarvester::visitWeakReferences):
+ (JSC::CodeBlock::finalizeLLIntInlineCaches):
+ (JSC::CodeBlock::finalizeBaselineJITInlineCaches):
+ (JSC::CodeBlock::UnconditionalFinalizer::finalizeUnconditionally):
+ (JSC::CodeBlock::jettison):
+ (JSC::CodeBlock::predictedMachineCodeSize):
+ (JSC::CodeBlock::findPC):
+ * bytecode/CodeBlock.h:
+ (JSC::CodeBlock::UnconditionalFinalizer::UnconditionalFinalizer):
+ (JSC::CodeBlock::WeakReferenceHarvester::WeakReferenceHarvester):
+ (JSC::CodeBlock::stubInfoBegin):
+ (JSC::CodeBlock::stubInfoEnd):
+ (JSC::CodeBlock::callLinkInfosBegin):
+ (JSC::CodeBlock::callLinkInfosEnd):
+ (JSC::CodeBlock::instructions):
+ (JSC::CodeBlock::instructions const):
+ (JSC::CodeBlock::vm const):
+ * dfg/DFGOSRExitCompilerCommon.h:
+ (JSC::DFG::adjustFrameAndStackInOSRExitCompilerThunk):
+ * jit/JIT.h:
+ * llint/LLIntOfflineAsmConfig.h:
+ * llint/LowLevelInterpreter.asm:
+ * llint/LowLevelInterpreter64.asm:
+ * parser/UnlinkedSourceCode.h:
+ * runtime/JSCPoison.h:
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::init):
+ * runtime/JSGlobalObject.h:
+ * runtime/JSScriptFetchParameters.h:
+ * runtime/JSScriptFetcher.h:
+ * runtime/StructureTransitionTable.h:
+ * wasm/js/JSWebAssemblyCodeBlock.cpp:
+ (JSC::JSWebAssemblyCodeBlock::JSWebAssemblyCodeBlock):
+ (JSC::JSWebAssemblyCodeBlock::visitChildren):
+ (JSC::JSWebAssemblyCodeBlock::UnconditionalFinalizer::finalizeUnconditionally):
+ * wasm/js/JSWebAssemblyCodeBlock.h:
+
2018-01-06 Yusuke Suzuki <[email protected]>
Object.getOwnPropertyNames includes "arguments" and "caller" for bound functions
Modified: branches/safari-605-branch/Source/_javascript_Core/assembler/MacroAssembler.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/assembler/MacroAssembler.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/assembler/MacroAssembler.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -652,6 +652,11 @@
xor32(imm, srcDest);
}
+ void xorPtr(TrustedImmPtr imm, RegisterID srcDest)
+ {
+ xor32(TrustedImm32(imm), srcDest);
+ }
+
void xorPtr(Address src, RegisterID dest)
{
xor32(src, dest);
@@ -991,6 +996,12 @@
xor64(imm, srcDest);
}
+ // FIXME: Look into making the need for a scratch register explicit, or providing the option to specify a scratch register.
+ void xorPtr(TrustedImmPtr imm, RegisterID srcDest)
+ {
+ xor64(TrustedImm64(imm), srcDest);
+ }
+
void loadPtr(ImplicitAddress address, RegisterID dest)
{
load64(address, dest);
Modified: branches/safari-605-branch/Source/_javascript_Core/assembler/MacroAssemblerARM64.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/assembler/MacroAssemblerARM64.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/assembler/MacroAssemblerARM64.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -991,6 +991,11 @@
}
}
+ void xor64(TrustedImm64 imm, RegisterID srcDest)
+ {
+ xor64(imm, srcDest, srcDest);
+ }
+
void xor64(TrustedImm32 imm, RegisterID src, RegisterID dest)
{
if (imm.m_value == -1)
Modified: branches/safari-605-branch/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/assembler/MacroAssemblerX86_64.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -809,6 +809,12 @@
m_assembler.xorq_ir(imm.m_value, srcDest);
}
+ void xor64(TrustedImm64 imm, RegisterID srcDest)
+ {
+ move(imm, scratchRegister());
+ xor64(scratchRegister(), srcDest);
+ }
+
void not64(RegisterID srcDest)
{
m_assembler.notq_r(srcDest);
Modified: branches/safari-605-branch/Source/_javascript_Core/bytecode/CodeBlock.cpp (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/bytecode/CodeBlock.cpp 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/bytecode/CodeBlock.cpp 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
@@ -307,12 +307,12 @@
, m_isConstructor(other.m_isConstructor)
, m_isStrictMode(other.m_isStrictMode)
, m_codeType(other.m_codeType)
- , m_unlinkedCode(*other.m_vm, this, other.m_unlinkedCode.get())
+ , m_unlinkedCode(*other.vm(), this, other.m_unlinkedCode.get())
, m_numberOfArgumentsToSkip(other.m_numberOfArgumentsToSkip)
, m_hasDebuggerStatement(false)
, m_steppingMode(SteppingModeDisabled)
, m_numBreakpoints(0)
- , m_ownerExecutable(*other.m_vm, this, other.m_ownerExecutable.get())
+ , m_ownerExecutable(*other.vm(), this, other.m_ownerExecutable.get())
, m_vm(other.m_vm)
, m_instructions(other.m_instructions)
, m_thisRegister(other.m_thisRegister)
@@ -329,6 +329,8 @@
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
, m_creationTime(MonotonicTime::now())
+ , m_unconditionalFinalizer(makePoisonedUnique<UnconditionalFinalizer>(*this))
+ , m_weakReferenceHarvester(makePoisonedUnique<WeakReferenceHarvester>(*this))
{
m_visitWeaklyHasBeenCalled = false;
@@ -387,6 +389,8 @@
, m_optimizationDelayCounter(0)
, m_reoptimizationRetryCounter(0)
, m_creationTime(MonotonicTime::now())
+ , m_unconditionalFinalizer(makePoisonedUnique<UnconditionalFinalizer>(*this))
+ , m_weakReferenceHarvester(makePoisonedUnique<WeakReferenceHarvester>(*this))
{
m_visitWeaklyHasBeenCalled = false;
@@ -422,12 +426,12 @@
RETURN_IF_EXCEPTION(throwScope, false);
if (unlinkedCodeBlock->usesGlobalObject())
- m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(*m_vm, this, m_globalObject.get());
+ m_constantRegisters[unlinkedCodeBlock->globalObjectRegister().toConstantIndex()].set(vm, this, m_globalObject.get());
for (unsigned i = 0; i < LinkTimeConstantCount; i++) {
LinkTimeConstant type = static_cast<LinkTimeConstant>(i);
if (unsigned registerIndex = unlinkedCodeBlock->registerIndexForLinkTimeConstant(type))
- m_constantRegisters[registerIndex].set(*m_vm, this, m_globalObject->jsCellForLinkTimeConstant(type));
+ m_constantRegisters[registerIndex].set(vm, this, m_globalObject->jsCellForLinkTimeConstant(type));
}
// We already have the cloned symbol table for the module environment since we need to instantiate
@@ -434,7 +438,7 @@
// the module environments before linking the code block. We replace the stored symbol table with the already cloned one.
if (UnlinkedModuleProgramCodeBlock* unlinkedModuleProgramCodeBlock = jsDynamicCast<UnlinkedModuleProgramCodeBlock*>(vm, unlinkedCodeBlock)) {
SymbolTable* clonedSymbolTable = jsCast<ModuleProgramExecutable*>(ownerExecutable)->moduleEnvironmentSymbolTable();
- if (m_vm->typeProfiler()) {
+ if (vm.typeProfiler()) {
ConcurrentJSLocker locker(clonedSymbolTable->m_lock);
clonedSymbolTable->prepareForTypeProfiling(locker);
}
@@ -447,7 +451,7 @@
UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionDecl(i);
if (shouldUpdateFunctionHasExecutedCache)
vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
- m_functionDecls[i].set(*m_vm, this, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
+ m_functionDecls[i].set(vm, this, unlinkedExecutable->link(vm, ownerExecutable->source()));
}
m_functionExprs = RefCountedArray<WriteBarrier<FunctionExecutable>>(unlinkedCodeBlock->numberOfFunctionExprs());
@@ -455,7 +459,7 @@
UnlinkedFunctionExecutable* unlinkedExecutable = unlinkedCodeBlock->functionExpr(i);
if (shouldUpdateFunctionHasExecutedCache)
vm.functionHasExecutedCache()->insertUnexecutedRange(ownerExecutable->sourceID(), unlinkedExecutable->typeProfilingStartOffset(), unlinkedExecutable->typeProfilingEndOffset());
- m_functionExprs[i].set(*m_vm, this, unlinkedExecutable->link(*m_vm, ownerExecutable->source()));
+ m_functionExprs[i].set(vm, this, unlinkedExecutable->link(vm, ownerExecutable->source()));
}
if (unlinkedCodeBlock->hasRareData()) {
@@ -853,8 +857,9 @@
CodeBlock::~CodeBlock()
{
- if (UNLIKELY(m_vm->m_perBytecodeProfiler))
- m_vm->m_perBytecodeProfiler->notifyDestruction(this);
+ VM& vm = *m_vm;
+ if (UNLIKELY(vm.m_perBytecodeProfiler))
+ vm.m_perBytecodeProfiler->notifyDestruction(this);
if (unlinkedCodeBlock()->didOptimize() == MixedTriState)
unlinkedCodeBlock()->setDidOptimize(FalseTriState);
@@ -876,7 +881,7 @@
// destructors.
#if ENABLE(JIT)
- for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) {
+ for (auto iter = m_stubInfos.begin(); !!iter; ++iter) {
StructureStubInfo* stub = *iter;
stub->aboutToDie();
stub->deref();
@@ -909,7 +914,8 @@
void CodeBlock::setConstantRegisters(const Vector<WriteBarrier<Unknown>>& constants, const Vector<SourceCodeRepresentation>& constantsSourceCodeRepresentation)
{
- auto scope = DECLARE_THROW_SCOPE(*m_vm);
+ VM& vm = *m_vm;
+ auto scope = DECLARE_THROW_SCOPE(vm);
JSGlobalObject* globalObject = m_globalObject.get();
ExecState* exec = globalObject->globalExec();
@@ -916,23 +922,23 @@
ASSERT(constants.size() == constantsSourceCodeRepresentation.size());
size_t count = constants.size();
m_constantRegisters.resizeToFit(count);
- bool hasTypeProfiler = !!m_vm->typeProfiler();
+ bool hasTypeProfiler = !!vm.typeProfiler();
for (size_t i = 0; i < count; i++) {
JSValue constant = constants[i].get();
if (!constant.isEmpty()) {
- if (SymbolTable* symbolTable = jsDynamicCast<SymbolTable*>(*m_vm, constant)) {
+ if (SymbolTable* symbolTable = jsDynamicCast<SymbolTable*>(vm, constant)) {
if (hasTypeProfiler) {
ConcurrentJSLocker locker(symbolTable->m_lock);
symbolTable->prepareForTypeProfiling(locker);
}
- SymbolTable* clone = symbolTable->cloneScopePart(*m_vm);
+ SymbolTable* clone = symbolTable->cloneScopePart(vm);
if (wasCompiledWithDebuggingOpcodes())
clone->setRareDataCodeBlock(this);
constant = clone;
- } else if (isTemplateRegistryKey(*m_vm, constant)) {
+ } else if (isTemplateRegistryKey(vm, constant)) {
auto* templateObject = globalObject->templateRegistry().getTemplateObject(exec, jsCast<JSTemplateRegistryKey*>(constant));
RETURN_IF_EXCEPTION(scope, void());
constant = templateObject;
@@ -939,7 +945,7 @@
}
}
- m_constantRegisters[i].set(*m_vm, this, constant);
+ m_constantRegisters[i].set(vm, this, constant);
}
m_constantsSourceCodeRepresentation = constantsSourceCodeRepresentation;
@@ -989,7 +995,7 @@
// and jettisoning. The probability of us wanting to do at least one of those things
// is probably quite close to 1. So we add one no matter what and when it runs, it
// figures out whether it has any work to do.
- visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer);
+ visitor.addUnconditionalFinalizer(m_unconditionalFinalizer.get());
if (!JITCode::isOptimizingJIT(jitType()))
return;
@@ -1001,7 +1007,7 @@
// There are two things that we use weak reference harvesters for: DFG fixpoint for
// jettisoning, and trying to find structures that would be live based on some
// inline cache. So it makes sense to register them regardless.
- visitor.addWeakReferenceHarvester(&m_weakReferenceHarvester);
+ visitor.addWeakReferenceHarvester(m_weakReferenceHarvester.get());
#if ENABLE(DFG_JIT)
// We get here if we're live in the sense that our owner executable is live,
@@ -1045,7 +1051,7 @@
// and jettisoning. The probability of us wanting to do at least one of those things
// is probably quite close to 1. So we add one no matter what and when it runs, it
// figures out whether it has any work to do.
- visitor.addUnconditionalFinalizer(&m_unconditionalFinalizer);
+ visitor.addUnconditionalFinalizer(m_unconditionalFinalizer.get());
if (CodeBlock* otherBlock = specialOSREntryBlockOrNull())
visitor.appendUnbarriered(otherBlock);
@@ -1161,6 +1167,7 @@
if (m_allTransitionsHaveBeenMarked)
return;
+ VM& vm = *m_vm;
bool allAreMarkedSoFar = true;
if (jitType() == JITCode::InterpreterThunk) {
@@ -1174,9 +1181,9 @@
if (!oldStructureID || !newStructureID)
break;
Structure* oldStructure =
- m_vm->heap.structureIDTable().get(oldStructureID);
+ vm.heap.structureIDTable().get(oldStructureID);
Structure* newStructure =
- m_vm->heap.structureIDTable().get(newStructureID);
+ vm.heap.structureIDTable().get(newStructureID);
if (Heap::isMarked(oldStructure))
visitor.appendUnbarriered(newStructure);
else
@@ -1191,7 +1198,7 @@
#if ENABLE(JIT)
if (JITCode::isJIT(jitType())) {
- for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter)
+ for (auto iter = m_stubInfos.begin(); !!iter; ++iter)
allAreMarkedSoFar &= (*iter)->propagateTransitions(visitor);
}
#endif // ENABLE(JIT)
@@ -1279,12 +1286,8 @@
void CodeBlock::WeakReferenceHarvester::visitWeakReferences(SlotVisitor& visitor)
{
- CodeBlock* codeBlock =
- bitwise_cast<CodeBlock*>(
- bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_weakReferenceHarvester));
-
- codeBlock->propagateTransitions(NoLockingNecessary, visitor);
- codeBlock->determineLiveness(NoLockingNecessary, visitor);
+ codeBlock.propagateTransitions(NoLockingNecessary, visitor);
+ codeBlock.determineLiveness(NoLockingNecessary, visitor);
}
void CodeBlock::clearLLIntGetByIdCache(Instruction* instruction)
@@ -1297,6 +1300,7 @@
void CodeBlock::finalizeLLIntInlineCaches()
{
+ VM& vm = *m_vm;
const Vector<unsigned>& propertyAccessInstructions = m_unlinkedCode->propertyAccessInstructions();
for (size_t size = propertyAccessInstructions.size(), i = 0; i < size; ++i) {
Instruction* curInstruction = &instructions()[propertyAccessInstructions[i]];
@@ -1305,7 +1309,7 @@
case op_get_by_id_proto_load:
case op_get_by_id_unset: {
StructureID oldStructureID = curInstruction[4].u.structureID;
- if (!oldStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(oldStructureID)))
+ if (!oldStructureID || Heap::isMarked(vm.heap.structureIDTable().get(oldStructureID)))
break;
if (Options::verboseOSR())
dataLogF("Clearing LLInt property access.\n");
@@ -1316,9 +1320,9 @@
StructureID oldStructureID = curInstruction[4].u.structureID;
StructureID newStructureID = curInstruction[6].u.structureID;
StructureChain* chain = curInstruction[7].u.structureChain.get();
- if ((!oldStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(oldStructureID))) &&
- (!newStructureID || Heap::isMarked(m_vm->heap.structureIDTable().get(newStructureID))) &&
- (!chain || Heap::isMarked(chain)))
+ if ((!oldStructureID || Heap::isMarked(vm.heap.structureIDTable().get(oldStructureID)))
+ && (!newStructureID || Heap::isMarked(vm.heap.structureIDTable().get(newStructureID)))
+ && (!chain || Heap::isMarked(chain)))
break;
if (Options::verboseOSR())
dataLogF("Clearing LLInt put transition.\n");
@@ -1410,7 +1414,7 @@
for (auto iter = callLinkInfosBegin(); !!iter; ++iter)
(*iter)->visitWeak(*vm());
- for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) {
+ for (auto iter = m_stubInfos.begin(); !!iter; ++iter) {
StructureStubInfo& stubInfo = **iter;
stubInfo.visitWeakReferences(this);
}
@@ -1419,25 +1423,22 @@
void CodeBlock::UnconditionalFinalizer::finalizeUnconditionally()
{
- CodeBlock* codeBlock = bitwise_cast<CodeBlock*>(
- bitwise_cast<char*>(this) - OBJECT_OFFSETOF(CodeBlock, m_unconditionalFinalizer));
+ codeBlock.updateAllPredictions();
- codeBlock->updateAllPredictions();
-
- if (!Heap::isMarked(codeBlock)) {
- if (codeBlock->shouldJettisonDueToWeakReference())
- codeBlock->jettison(Profiler::JettisonDueToWeakReference);
+ if (!Heap::isMarked(&codeBlock)) {
+ if (codeBlock.shouldJettisonDueToWeakReference())
+ codeBlock.jettison(Profiler::JettisonDueToWeakReference);
else
- codeBlock->jettison(Profiler::JettisonDueToOldAge);
+ codeBlock.jettison(Profiler::JettisonDueToOldAge);
return;
}
- if (JITCode::couldBeInterpreted(codeBlock->jitType()))
- codeBlock->finalizeLLIntInlineCaches();
+ if (JITCode::couldBeInterpreted(codeBlock.jitType()))
+ codeBlock.finalizeLLIntInlineCaches();
#if ENABLE(JIT)
- if (!!codeBlock->jitCode())
- codeBlock->finalizeBaselineJITInlineCaches();
+ if (!!codeBlock.jitCode())
+ codeBlock.finalizeBaselineJITInlineCaches();
#endif
}
@@ -1959,6 +1960,7 @@
}
#endif // ENABLE(DFG_JIT)
+ VM& vm = *m_vm;
DeferGCForAWhile deferGC(*heap());
// We want to accomplish two things here:
@@ -1975,7 +1977,7 @@
// This accomplishes (1), and does its own book-keeping about whether it has already happened.
if (!jitCode()->dfgCommon()->invalidate()) {
// We've already been invalidated.
- RELEASE_ASSERT(this != replacement() || (m_vm->heap.isCurrentThreadBusy() && !Heap::isMarked(ownerScriptExecutable())));
+ RELEASE_ASSERT(this != replacement() || (vm.heap.isCurrentThreadBusy() && !Heap::isMarked(ownerScriptExecutable())));
return;
}
}
@@ -2007,12 +2009,11 @@
// Jettison can happen during GC. We don't want to install code to a dead executable
// because that would add a dead object to the remembered set.
- if (m_vm->heap.isCurrentThreadBusy() && !Heap::isMarked(ownerScriptExecutable()))
+ if (vm.heap.isCurrentThreadBusy() && !Heap::isMarked(ownerScriptExecutable()))
return;
// This accomplishes (2).
- ownerScriptExecutable()->installCode(
- *m_vm, alternative(), codeType(), specializationKind());
+ ownerScriptExecutable()->installCode(vm, alternative(), codeType(), specializationKind());
#if ENABLE(DFG_JIT)
if (DFG::shouldDumpDisassembly())
@@ -2767,18 +2768,19 @@
size_t CodeBlock::predictedMachineCodeSize()
{
+ VM* vm = m_vm.unpoisoned();
// This will be called from CodeBlock::CodeBlock before either m_vm or the
// instructions have been initialized. It's OK to return 0 because what will really
// matter is the recomputation of this value when the slow path is triggered.
- if (!m_vm)
+ if (!vm)
return 0;
- if (!*m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT)
+ if (!*vm->machineCodeBytesPerBytecodeWordForBaselineJIT)
return 0; // It's as good of a prediction as we'll get.
// Be conservative: return a size that will be an overestimation 84% of the time.
- double multiplier = m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT->mean() +
- m_vm->machineCodeBytesPerBytecodeWordForBaselineJIT->standardDeviation();
+ double multiplier = vm->machineCodeBytesPerBytecodeWordForBaselineJIT->mean() +
+ vm->machineCodeBytesPerBytecodeWordForBaselineJIT->standardDeviation();
// Be paranoid: silently reject bogus multipiers. Silently doing the "wrong" thing
// here is OK, since this whole method is just a heuristic.
@@ -3066,7 +3068,7 @@
return codeOrigin;
}
- for (Bag<StructureStubInfo>::iterator iter = m_stubInfos.begin(); !!iter; ++iter) {
+ for (auto iter = m_stubInfos.begin(); !!iter; ++iter) {
StructureStubInfo* stub = *iter;
if (stub->containsPC(pc))
return std::optional<CodeOrigin>(stub->codeOrigin);
Modified: branches/safari-605-branch/Source/_javascript_Core/bytecode/CodeBlock.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/bytecode/CodeBlock.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/bytecode/CodeBlock.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
@@ -50,6 +50,7 @@
#include "Instruction.h"
#include "JITCode.h"
#include "JITMathICForwards.h"
+#include "JSCPoison.h"
#include "JSCell.h"
#include "JSGlobalObject.h"
#include "JumpTable.h"
@@ -106,12 +107,20 @@
friend class JIT;
friend class LLIntOffsetsExtractor;
- class UnconditionalFinalizer : public JSC::UnconditionalFinalizer {
+ struct UnconditionalFinalizer : public JSC::UnconditionalFinalizer {
+ UnconditionalFinalizer(CodeBlock& codeBlock)
+ : codeBlock(codeBlock)
+ { }
void finalizeUnconditionally() override;
+ CodeBlock& codeBlock;
};
- class WeakReferenceHarvester : public JSC::WeakReferenceHarvester {
+ struct WeakReferenceHarvester : public JSC::WeakReferenceHarvester {
+ WeakReferenceHarvester(CodeBlock& codeBlock)
+ : codeBlock(codeBlock)
+ { }
void visitWeakReferences(SlotVisitor&) override;
+ CodeBlock& codeBlock;
};
public:
@@ -255,9 +264,9 @@
JITMulIC* addJITMulIC(ArithProfile*);
JITNegIC* addJITNegIC(ArithProfile*);
JITSubIC* addJITSubIC(ArithProfile*);
- Bag<StructureStubInfo>::iterator stubInfoBegin() { return m_stubInfos.begin(); }
- Bag<StructureStubInfo>::iterator stubInfoEnd() { return m_stubInfos.end(); }
-
+ auto stubInfoBegin() { return m_stubInfos.begin(); }
+ auto stubInfoEnd() { return m_stubInfos.end(); }
+
// O(n) operation. Use getStubInfoMap() unless you really only intend to get one
// stub info.
StructureStubInfo* findStubInfo(CodeOrigin);
@@ -265,8 +274,8 @@
ByValInfo* addByValInfo();
CallLinkInfo* addCallLinkInfo();
- Bag<CallLinkInfo>::iterator callLinkInfosBegin() { return m_callLinkInfos.begin(); }
- Bag<CallLinkInfo>::iterator callLinkInfosEnd() { return m_callLinkInfos.end(); }
+ auto callLinkInfosBegin() { return m_callLinkInfos.begin(); }
+ auto callLinkInfosEnd() { return m_callLinkInfos.end(); }
// This is a slow function call used primarily for compiling OSR exits in the case
// that there had been inlining. Chances are if you want to use this, you're really
@@ -308,11 +317,11 @@
}
typedef JSC::Instruction Instruction;
- typedef RefCountedArray<Instruction>& UnpackedInstructions;
+ typedef PoisonedRefCountedArray<CodeBlockPoison, Instruction>& UnpackedInstructions;
unsigned numberOfInstructions() const { return m_instructions.size(); }
- RefCountedArray<Instruction>& instructions() { return m_instructions; }
- const RefCountedArray<Instruction>& instructions() const { return m_instructions; }
+ PoisonedRefCountedArray<CodeBlockPoison, Instruction>& instructions() { return m_instructions; }
+ const PoisonedRefCountedArray<CodeBlockPoison, Instruction>& instructions() const { return m_instructions; }
size_t predictedMachineCodeSize();
@@ -361,7 +370,7 @@
ExecutableBase* ownerExecutable() const { return m_ownerExecutable.get(); }
ScriptExecutable* ownerScriptExecutable() const { return jsCast<ScriptExecutable*>(m_ownerExecutable.get()); }
- VM* vm() const { return m_vm; }
+ VM* vm() const { return m_vm.unpoisoned(); }
void setThisRegister(VirtualRegister thisRegister) { m_thisRegister = thisRegister; }
VirtualRegister thisRegister() const { return m_thisRegister; }
@@ -895,6 +904,8 @@
bool hasTailCalls() const { return m_unlinkedCode->hasTailCalls(); }
+ static constexpr uintptr_t s_poison = makeConstExprPoison(CodeBlockPoison);
+
protected:
void finalizeLLIntInlineCaches();
void finalizeBaselineJITInlineCaches();
@@ -953,6 +964,12 @@
void insertBasicBlockBoundariesForControlFlowProfiler(RefCountedArray<Instruction>&);
void ensureCatchLivenessIsComputedForBytecodeOffsetSlow(unsigned);
+ template<typename T, typename... Arguments, typename Enable = void>
+ static PoisonedUniquePtr<CodeBlockPoison, T> makePoisonedUnique(Arguments&&... arguments)
+ {
+ return WTF::makePoisonedUnique<CodeBlockPoison, T>(std::forward<Arguments>(arguments)...);
+ }
+
WriteBarrier<UnlinkedCodeBlock> m_unlinkedCode;
int m_numParameters;
int m_numberOfArgumentsToSkip { 0 };
@@ -965,14 +982,14 @@
};
};
WriteBarrier<ExecutableBase> m_ownerExecutable;
- VM* m_vm;
+ ConstExprPoisoned<CodeBlockPoison, VM*> m_vm;
- RefCountedArray<Instruction> m_instructions;
+ PoisonedRefCountedArray<CodeBlockPoison, Instruction> m_instructions;
VirtualRegister m_thisRegister;
VirtualRegister m_scopeRegister;
mutable CodeBlockHash m_hash;
- RefPtr<SourceProvider> m_source;
+ PoisonedRefPtr<CodeBlockPoison, SourceProvider> m_source;
unsigned m_sourceOffset;
unsigned m_firstLineColumnOffset;
@@ -979,16 +996,16 @@
RefCountedArray<LLIntCallLinkInfo> m_llintCallLinkInfos;
SentinelLinkedList<LLIntCallLinkInfo, BasicRawSentinelNode<LLIntCallLinkInfo>> m_incomingLLIntCalls;
StructureWatchpointMap m_llintGetByIdWatchpointMap;
- RefPtr<JITCode> m_jitCode;
+ PoisonedRefPtr<CodeBlockPoison, JITCode> m_jitCode;
#if ENABLE(JIT)
std::unique_ptr<RegisterAtOffsetList> m_calleeSaveRegisters;
- Bag<StructureStubInfo> m_stubInfos;
- Bag<JITAddIC> m_addICs;
- Bag<JITMulIC> m_mulICs;
- Bag<JITNegIC> m_negICs;
- Bag<JITSubIC> m_subICs;
- Bag<ByValInfo> m_byValInfos;
- Bag<CallLinkInfo> m_callLinkInfos;
+ PoisonedBag<CodeBlockPoison, StructureStubInfo> m_stubInfos;
+ PoisonedBag<CodeBlockPoison, JITAddIC> m_addICs;
+ PoisonedBag<CodeBlockPoison, JITMulIC> m_mulICs;
+ PoisonedBag<CodeBlockPoison, JITNegIC> m_negICs;
+ PoisonedBag<CodeBlockPoison, JITSubIC> m_subICs;
+ PoisonedBag<CodeBlockPoison, ByValInfo> m_byValInfos;
+ PoisonedBag<CodeBlockPoison, CallLinkInfo> m_callLinkInfos;
SentinelLinkedList<CallLinkInfo, BasicRawSentinelNode<CallLinkInfo>> m_incomingCalls;
SentinelLinkedList<PolymorphicCallNode, BasicRawSentinelNode<PolymorphicCallNode>> m_incomingPolymorphicCalls;
std::unique_ptr<PCToCodeOriginMap> m_pcToCodeOriginMap;
@@ -1030,8 +1047,8 @@
std::unique_ptr<RareData> m_rareData;
- UnconditionalFinalizer m_unconditionalFinalizer;
- WeakReferenceHarvester m_weakReferenceHarvester;
+ PoisonedUniquePtr<CodeBlockPoison, UnconditionalFinalizer> m_unconditionalFinalizer;
+ PoisonedUniquePtr<CodeBlockPoison, WeakReferenceHarvester> m_weakReferenceHarvester;
};
inline Register& ExecState::r(int index)
Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -87,6 +87,7 @@
// We need to make sure SP is correct in case of an exception.
jit.loadPtr(MacroAssembler::Address(GPRInfo::callFrameRegister, CallFrameSlot::codeBlock * static_cast<int>(sizeof(Register))), GPRInfo::regT0);
jit.loadPtr(MacroAssembler::Address(GPRInfo::regT0, CodeBlock::jitCodeOffset()), GPRInfo::regT0);
+ jit.xorPtr(MacroAssembler::TrustedImmPtr(CodeBlock::s_poison), GPRInfo::regT0);
jit.addPtr(MacroAssembler::TrustedImm32(JITCodeType::commonDataOffset()), GPRInfo::regT0);
jit.load32(MacroAssembler::Address(GPRInfo::regT0, CommonData::frameRegisterCountOffset()), GPRInfo::regT0);
// This does virtualRegisterForLocal(frameRegisterCount - 1)*sizeof(Register) where:
Modified: branches/safari-605-branch/Source/_javascript_Core/jit/JIT.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/jit/JIT.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/jit/JIT.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -903,9 +903,9 @@
Instruction* copiedInstruction(Instruction*);
Interpreter* m_interpreter;
-
- RefCountedArray<Instruction> m_instructions;
+ PoisonedRefCountedArray<CodeBlockPoison, Instruction> m_instructions;
+
Vector<CallRecord> m_calls;
Vector<Label> m_labels;
Vector<JITGetByIdGenerator> m_getByIds;
Modified: branches/safari-605-branch/Source/_javascript_Core/llint/LLIntOfflineAsmConfig.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/llint/LLIntOfflineAsmConfig.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/llint/LLIntOfflineAsmConfig.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
#include "LLIntCommon.h"
#include <wtf/Assertions.h>
#include <wtf/Gigacage.h>
+#include <wtf/Poisoned.h>
#if !ENABLE(JIT)
#define OFFLINE_ASM_C_LOOP 1
@@ -142,6 +143,12 @@
#define OFFLINE_ASM_JSVALUE64 0
#endif
+#if ENABLE(POISON)
+#define OFFLINE_ASM_POISON 1
+#else
+#define OFFLINE_ASM_POISON 0
+#endif
+
#if !ASSERT_DISABLED
#define OFFLINE_ASM_ASSERT_ENABLED 1
#else
Modified: branches/safari-605-branch/Source/_javascript_Core/llint/LowLevelInterpreter.asm (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/llint/LowLevelInterpreter.asm 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2017 Apple Inc. All rights reserved.
+# Copyright (C) 2011-2018 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,6 +204,10 @@
const LowestTag = DeletedValueTag
end
+if POISON
+ const CodeBlockPoison = constexpr CodeBlock::s_poison
+end
+
# PutByIdFlags data
const PutByIdPrimaryTypeMask = constexpr PutByIdPrimaryTypeMask
const PutByIdPrimaryTypeSecondary = constexpr PutByIdPrimaryTypeSecondary
@@ -752,6 +756,12 @@
end
end
+macro unpoison(poison, field)
+ if POISON
+ xorp poison, field
+ end
+end
+
macro functionPrologue()
if X86 or X86_WIN or X86_64 or X86_64_WIN
push cfr
@@ -1014,6 +1024,7 @@
# Set up the PC.
if JSVALUE64
loadp CodeBlock::m_instructions[t1], PB
+ unpoison(CodeBlockPoison, PB)
move 0, PC
else
loadp CodeBlock::m_instructions[t1], PC
@@ -1024,6 +1035,7 @@
subp cfr, t0, t0
bpa t0, cfr, .needStackCheck
loadp CodeBlock::m_vm[t1], t2
+ unpoison(CodeBlockPoison, t2)
if C_LOOP
bpbeq VM::m_cloopStackLimit[t2], t0, .stackHeightOK
else
@@ -1611,6 +1623,7 @@
traceExecution()
loadp CodeBlock[cfr], t1
loadp CodeBlock::m_vm[t1], t1
+ unpoison(CodeBlockPoison, t1)
loadb VM::m_traps+VMTraps::m_needTrapHandling[t1], t0
btpnz t0, .handleTraps
.afterHandlingTraps:
@@ -1626,6 +1639,7 @@
macro acquireShadowChickenPacket(slow)
loadp CodeBlock[cfr], t1
loadp CodeBlock::m_vm[t1], t1
+ unpoison(CodeBlockPoison, t1)
loadp VM::m_shadowChicken[t1], t2
loadp ShadowChicken::m_logCursor[t2], t0
bpaeq t0, ShadowChicken::m_logEnd[t2], slow
Modified: branches/safari-605-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/llint/LowLevelInterpreter64.asm 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,4 +1,4 @@
-# Copyright (C) 2011-2017 Apple Inc. All rights reserved.
+# Copyright (C) 2011-2018 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -45,6 +45,7 @@
loadi ArgumentCount + TagOffset[cfr], PC
loadp CodeBlock[cfr], PB
loadp CodeBlock::m_instructions[PB], PB
+ unpoison(CodeBlockPoison, PB)
loadisFromInstruction(1, t1)
storeq r0, [cfr, t1, 8]
valueProfile(r0, (CallOpCodeSize - 1), t3)
@@ -482,6 +483,7 @@
macro structureIDToStructureWithScratch(structureIDThenStructure, scratch)
loadp CodeBlock[cfr], scratch
loadp CodeBlock::m_vm[scratch], scratch
+ unpoison(CodeBlockPoison, scratch)
loadp VM::heap + Heap::m_structureIDTable + StructureIDTable::m_table[scratch], scratch
loadp [scratch, structureIDThenStructure, 8], structureIDThenStructure
end
@@ -495,6 +497,7 @@
loadi JSCell::m_structureID[cell], structure
loadp CodeBlock[cfr], cell
loadp CodeBlock::m_vm[cell], cell
+ unpoison(CodeBlockPoison, cell)
loadp VM::heap + Heap::m_structureIDTable + StructureIDTable::m_table[cell], cell
loadp [cell, structure, 8], structure
end
@@ -559,6 +562,7 @@
# Reload CodeBlock and reset PC, since the slow_path clobbered them.
loadp CodeBlock[cfr], t1
loadp CodeBlock::m_instructions[t1], PB
+ unpoison(CodeBlockPoison, PB)
move 0, PC
jmp doneLabel
end
@@ -1949,14 +1953,14 @@
storei PC, ArgumentCount + TagOffset[cfr]
storei t2, ArgumentCount + PayloadOffset[t3]
move t3, sp
- if X86_64_WIN
- prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
- callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
- else
+ if POISON
loadp _g_jitCodePoison, t2
xorp LLIntCallLinkInfo::machineCodeTarget[t1], t2
prepareCall(t2, t1, t3, t4)
callTargetFunction(t2)
+ else
+ prepareCall(LLIntCallLinkInfo::machineCodeTarget[t1], t2, t3, t4)
+ callTargetFunction(LLIntCallLinkInfo::machineCodeTarget[t1])
end
.opCallSlow:
@@ -2003,6 +2007,7 @@
loadp CodeBlock[cfr], PB
loadp CodeBlock::m_instructions[PB], PB
+ unpoison(CodeBlockPoison, PB)
loadp VM::targetInterpreterPCForThrow[t3], PC
subp PB, PC
rshiftp 3, PC
@@ -2495,6 +2500,7 @@
traceExecution()
loadp CodeBlock[cfr], t1
loadp CodeBlock::m_vm[t1], t1
+ unpoison(CodeBlockPoison, t1)
# t1 is holding the pointer to the typeProfilerLog.
loadp VM::m_typeProfilerLog[t1], t1
# t2 is holding the pointer to the current log entry.
Modified: branches/safari-605-branch/Source/_javascript_Core/parser/UnlinkedSourceCode.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/parser/UnlinkedSourceCode.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/parser/UnlinkedSourceCode.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2013, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,6 +28,7 @@
#pragma once
+#include "JSCPoison.h"
#include "SourceProvider.h"
#include <wtf/RefPtr.h>
@@ -98,9 +99,9 @@
int length() const { return m_endOffset - m_startOffset; }
protected:
- // FIXME: Make it Ref<SourceProvidier>.
+ // FIXME: Make it PoisonedRef<SourceProvidier>.
// https://bugs.webkit.org/show_bug.cgi?id=168325
- RefPtr<SourceProvider> m_provider;
+ PoisonedRefPtr<UnlinkedSourceCodePoison, SourceProvider> m_provider;
int m_startOffset;
int m_endOffset;
};
Modified: branches/safari-605-branch/Source/_javascript_Core/runtime/JSCPoison.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/runtime/JSCPoison.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/runtime/JSCPoison.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -30,14 +30,22 @@
namespace JSC {
enum Poison {
- NotPoisoned = 0,
+ NotPoisoned = 0, // Reserved (and unused) so that poison keys are never 0.
+
+ // Add new poison keys below in alphabetical order. The order doesn't really
+ // matter, but we might as well keep them in alphabetically order for
+ // greater readability.
+ CodeBlockPoison,
+ JSGlobalObjectPoison,
+ JSScriptFetchParametersPoison,
+ JSScriptFetcherPoison,
JSWebAssemblyCodeBlockPoison,
JSWebAssemblyInstancePoison,
JSWebAssemblyMemoryPoison,
JSWebAssemblyModulePoison,
JSWebAssemblyTablePoison,
- TransitionMapPoison,
- WeakImplPoison,
+ StructureTransitionTablePoison,
+ UnlinkedSourceCodePoison,
};
} // namespace JSC
Modified: branches/safari-605-branch/Source/_javascript_Core/runtime/JSGlobalObject.cpp (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2018 Apple Inc. All rights reserved.
* Copyright (C) 2008 Cameron Zwarich ([email protected])
*
* Redistribution and use in source and binary forms, with or without
@@ -188,7 +188,7 @@
namespace JSC {
-static JSValue createProxyProperty(VM& vm, JSObject* object)
+ static JSValue createProxyProperty(VM& vm, JSObject* object)
{
JSGlobalObject* global = jsCast<JSGlobalObject*>(object);
return ProxyConstructor::create(vm, ProxyConstructor::createStructure(vm, global, global->functionPrototype()));
@@ -401,8 +401,8 @@
m_debugger = 0;
#if ENABLE(REMOTE_INSPECTOR)
- m_inspectorController = std::make_unique<Inspector::JSGlobalObjectInspectorController>(*this);
- m_inspectorDebuggable = std::make_unique<JSGlobalObjectDebuggable>(*this);
+ m_inspectorController = makePoisonedUnique<Inspector::JSGlobalObjectInspectorController>(*this);
+ m_inspectorDebuggable = makePoisonedUnique<JSGlobalObjectDebuggable>(*this);
m_inspectorDebuggable->init();
m_consoleClient = m_inspectorController->consoleClient();
#endif
@@ -1011,63 +1011,63 @@
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(arrayIteratorPrototype, m_vm.propertyNames->next);
- m_arrayIteratorPrototypeNext = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_arrayIteratorProtocolWatchpoint);
+ m_arrayIteratorPrototypeNext = makePoisonedUnique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_arrayIteratorProtocolWatchpoint);
m_arrayIteratorPrototypeNext->install();
}
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(this->arrayPrototype(), m_vm.propertyNames->iteratorSymbol);
- m_arrayPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_arrayIteratorProtocolWatchpoint);
+ m_arrayPrototypeSymbolIteratorWatchpoint = makePoisonedUnique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_arrayIteratorProtocolWatchpoint);
m_arrayPrototypeSymbolIteratorWatchpoint->install();
}
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(mapIteratorPrototype, m_vm.propertyNames->next);
- m_mapIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_mapIteratorProtocolWatchpoint);
+ m_mapIteratorPrototypeNextWatchpoint = makePoisonedUnique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_mapIteratorProtocolWatchpoint);
m_mapIteratorPrototypeNextWatchpoint->install();
}
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_mapPrototype.get(), m_vm.propertyNames->iteratorSymbol);
- m_mapPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_mapIteratorProtocolWatchpoint);
+ m_mapPrototypeSymbolIteratorWatchpoint = makePoisonedUnique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_mapIteratorProtocolWatchpoint);
m_mapPrototypeSymbolIteratorWatchpoint->install();
}
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(setIteratorPrototype, m_vm.propertyNames->next);
- m_setIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_setIteratorProtocolWatchpoint);
+ m_setIteratorPrototypeNextWatchpoint = makePoisonedUnique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_setIteratorProtocolWatchpoint);
m_setIteratorPrototypeNextWatchpoint->install();
}
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_setPrototype.get(), m_vm.propertyNames->iteratorSymbol);
- m_setPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_setIteratorProtocolWatchpoint);
+ m_setPrototypeSymbolIteratorWatchpoint = makePoisonedUnique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_setIteratorProtocolWatchpoint);
m_setPrototypeSymbolIteratorWatchpoint->install();
}
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_stringIteratorPrototype.get(), m_vm.propertyNames->next);
- m_stringIteratorPrototypeNextWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_stringIteratorProtocolWatchpoint);
+ m_stringIteratorPrototypeNextWatchpoint = makePoisonedUnique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_stringIteratorProtocolWatchpoint);
m_stringIteratorPrototypeNextWatchpoint->install();
}
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_stringPrototype.get(), m_vm.propertyNames->iteratorSymbol);
- m_stringPrototypeSymbolIteratorWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_stringIteratorProtocolWatchpoint);
+ m_stringPrototypeSymbolIteratorWatchpoint = makePoisonedUnique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_stringIteratorProtocolWatchpoint);
m_stringPrototypeSymbolIteratorWatchpoint->install();
}
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_mapPrototype.get(), m_vm.propertyNames->set);
- m_mapPrototypeSetWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_mapSetWatchpoint);
+ m_mapPrototypeSetWatchpoint = makePoisonedUnique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_mapSetWatchpoint);
m_mapPrototypeSetWatchpoint->install();
}
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(m_setPrototype.get(), m_vm.propertyNames->add);
- m_setPrototypeAddWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_setAddWatchpoint);
+ m_setPrototypeAddWatchpoint = makePoisonedUnique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_setAddWatchpoint);
m_setPrototypeAddWatchpoint->install();
}
{
ObjectPropertyCondition condition = setupAdaptiveWatchpoint(numberPrototype(), m_vm.propertyNames->toString);
- m_numberPrototypeToStringWatchpoint = std::make_unique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_numberToStringWatchpoint);
+ m_numberPrototypeToStringWatchpoint = makePoisonedUnique<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>>(vm, condition, m_numberToStringWatchpoint);
m_numberPrototypeToStringWatchpoint->install();
m_numberProtoToStringFunction.set(vm, this, jsCast<JSFunction*>(numberPrototype()->getDirect(vm, vm.propertyNames->toString)));
}
Modified: branches/safari-605-branch/Source/_javascript_Core/runtime/JSGlobalObject.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/runtime/JSGlobalObject.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/runtime/JSGlobalObject.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 Eric Seidel <[email protected]>
- * Copyright (C) 2007-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2018 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -29,6 +29,7 @@
#include "InternalFunction.h"
#include "JSArray.h"
#include "JSArrayBufferPrototype.h"
+#include "JSCPoison.h"
#include "JSClassRef.h"
#include "JSGlobalLexicalEnvironment.h"
#include "JSSegmentedVariableObject.h"
@@ -46,6 +47,7 @@
#include <_javascript_Core/JSBase.h>
#include <array>
#include <wtf/HashSet.h>
+#include <wtf/PoisonedUniquePtr.h>
#include <wtf/RetainPtr.h>
struct OpaqueJSClass;
@@ -399,9 +401,11 @@
VM& m_vm;
+ template<typename T> using PoisonedUniquePtr = WTF::PoisonedUniquePtr<JSGlobalObjectPoison, T>;
+
#if ENABLE(REMOTE_INSPECTOR)
- std::unique_ptr<Inspector::JSGlobalObjectInspectorController> m_inspectorController;
- std::unique_ptr<JSGlobalObjectDebuggable> m_inspectorDebuggable;
+ PoisonedUniquePtr<Inspector::JSGlobalObjectInspectorController> m_inspectorController;
+ PoisonedUniquePtr<JSGlobalObjectDebuggable> m_inspectorDebuggable;
#endif
#if ENABLE(INTL)
@@ -436,17 +440,17 @@
InlineWatchpointSet m_setAddWatchpoint;
InlineWatchpointSet m_arraySpeciesWatchpoint;
InlineWatchpointSet m_numberToStringWatchpoint;
- std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_arrayPrototypeSymbolIteratorWatchpoint;
- std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_arrayIteratorPrototypeNext;
- std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_mapPrototypeSymbolIteratorWatchpoint;
- std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_mapIteratorPrototypeNextWatchpoint;
- std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setPrototypeSymbolIteratorWatchpoint;
- std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setIteratorPrototypeNextWatchpoint;
- std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_stringPrototypeSymbolIteratorWatchpoint;
- std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_stringIteratorPrototypeNextWatchpoint;
- std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_mapPrototypeSetWatchpoint;
- std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setPrototypeAddWatchpoint;
- std::unique_ptr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_numberPrototypeToStringWatchpoint;
+ PoisonedUniquePtr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_arrayPrototypeSymbolIteratorWatchpoint;
+ PoisonedUniquePtr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_arrayIteratorPrototypeNext;
+ PoisonedUniquePtr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_mapPrototypeSymbolIteratorWatchpoint;
+ PoisonedUniquePtr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_mapIteratorPrototypeNextWatchpoint;
+ PoisonedUniquePtr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setPrototypeSymbolIteratorWatchpoint;
+ PoisonedUniquePtr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setIteratorPrototypeNextWatchpoint;
+ PoisonedUniquePtr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_stringPrototypeSymbolIteratorWatchpoint;
+ PoisonedUniquePtr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_stringIteratorPrototypeNextWatchpoint;
+ PoisonedUniquePtr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_mapPrototypeSetWatchpoint;
+ PoisonedUniquePtr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_setPrototypeAddWatchpoint;
+ PoisonedUniquePtr<ObjectPropertyChangeAdaptiveWatchpoint<InlineWatchpointSet>> m_numberPrototypeToStringWatchpoint;
bool isArrayPrototypeIteratorProtocolFastAndNonObservable();
bool isMapPrototypeIteratorProtocolFastAndNonObservable();
@@ -916,6 +920,12 @@
JS_EXPORT_PRIVATE static void clearRareData(JSCell*);
+ template<typename T, typename... Arguments, typename Enable = void>
+ static JSGlobalObject::PoisonedUniquePtr<T> makePoisonedUnique(Arguments&&... arguments)
+ {
+ return WTF::makePoisonedUnique<JSGlobalObjectPoison, T>(std::forward<Arguments>(arguments)...);
+ }
+
bool m_needsSiteSpecificQuirks { false };
#if JSC_OBJC_API_ENABLED
RetainPtr<JSWrapperMap> m_wrapperMap;
Modified: branches/safari-605-branch/Source/_javascript_Core/runtime/JSScriptFetchParameters.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/runtime/JSScriptFetchParameters.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/runtime/JSScriptFetchParameters.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2017 Yusuke Suzuki <[email protected]>
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,9 +26,11 @@
#pragma once
+#include "JSCPoison.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
#include "ScriptFetchParameters.h"
+#include <wtf/Ref.h>
namespace JSC {
@@ -71,7 +74,7 @@
{
}
- Ref<ScriptFetchParameters> m_parameters;
+ PoisonedRef<JSScriptFetchParametersPoison, ScriptFetchParameters> m_parameters;
};
} // namespace JSC
Modified: branches/safari-605-branch/Source/_javascript_Core/runtime/JSScriptFetcher.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/runtime/JSScriptFetcher.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/runtime/JSScriptFetcher.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2017 Yusuke Suzuki <[email protected]>
+ * Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,9 +26,11 @@
#pragma once
+#include "JSCPoison.h"
#include "JSGlobalObject.h"
#include "JSObject.h"
#include "ScriptFetcher.h"
+#include <wtf/RefPtr.h>
namespace JSC {
@@ -71,7 +74,7 @@
{
}
- RefPtr<ScriptFetcher> m_fetcher;
+ PoisonedRefPtr<JSScriptFetcherPoison, ScriptFetcher> m_fetcher;
};
} // namespace JSC
Modified: branches/safari-605-branch/Source/_javascript_Core/runtime/StructureTransitionTable.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/runtime/StructureTransitionTable.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/runtime/StructureTransitionTable.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -187,8 +187,8 @@
private:
friend class SingleSlotTransitionWeakOwner;
- using PoisonedTransitionMapPtr = ConstExprPoisoned<TransitionMapPoison, TransitionMap*>;
- using PoisonedWeakImplPtr = ConstExprPoisoned<WeakImplPoison, WeakImpl*>;
+ using PoisonedTransitionMapPtr = ConstExprPoisoned<StructureTransitionTablePoison, TransitionMap*>;
+ using PoisonedWeakImplPtr = ConstExprPoisoned<StructureTransitionTablePoison, WeakImpl*>;
bool isUsingSingleSlot() const
{
Modified: branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyCodeBlock.cpp (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyCodeBlock.cpp 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyCodeBlock.cpp 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -51,6 +51,8 @@
: Base(vm, vm.webAssemblyCodeBlockStructure.get())
, m_codeBlock(WTFMove(codeBlock))
{
+ m_unconditionalFinalizer = PoisonedUniquePtr<JSWebAssemblyCodeBlockPoison, UnconditionalFinalizer>::create(*this);
+
// FIXME: We should not need to do this synchronously.
// https://bugs.webkit.org/show_bug.cgi?id=170567
m_wasmToJSExitStubs.reserveCapacity(m_codeBlock->functionImportCount());
@@ -92,15 +94,13 @@
Base::visitChildren(thisObject, visitor);
- visitor.addUnconditionalFinalizer(&thisObject->m_unconditionalFinalizer);
+ visitor.addUnconditionalFinalizer(thisObject->m_unconditionalFinalizer.get());
}
void JSWebAssemblyCodeBlock::UnconditionalFinalizer::finalizeUnconditionally()
{
- JSWebAssemblyCodeBlock* thisObject = bitwise_cast<JSWebAssemblyCodeBlock*>(
- bitwise_cast<char*>(this) - OBJECT_OFFSETOF(JSWebAssemblyCodeBlock, m_unconditionalFinalizer));
- for (auto iter = thisObject->m_callLinkInfos.begin(); !!iter; ++iter)
- (*iter)->visitWeak(*thisObject->vm());
+ for (auto iter = codeBlock.m_callLinkInfos.begin(); !!iter; ++iter)
+ (*iter)->visitWeak(*codeBlock.vm());
}
} // namespace JSC
Modified: branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyCodeBlock.h (226683 => 226684)
--- branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyCodeBlock.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyCodeBlock.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -37,6 +37,7 @@
#include "WasmFormat.h"
#include "WasmModule.h"
#include <wtf/Bag.h>
+#include <wtf/PoisonedUniquePtr.h>
#include <wtf/Ref.h>
#include <wtf/Vector.h>
@@ -88,13 +89,17 @@
static void destroy(JSCell*);
static void visitChildren(JSCell*, SlotVisitor&);
- class UnconditionalFinalizer : public JSC::UnconditionalFinalizer {
+ struct UnconditionalFinalizer : public JSC::UnconditionalFinalizer {
+ UnconditionalFinalizer(JSWebAssemblyCodeBlock& codeBlock)
+ : codeBlock(codeBlock)
+ { }
void finalizeUnconditionally() override;
+ JSWebAssemblyCodeBlock& codeBlock;
};
PoisonedRef<JSWebAssemblyCodeBlockPoison, Wasm::CodeBlock> m_codeBlock;
Vector<MacroAssemblerCodeRef> m_wasmToJSExitStubs;
- UnconditionalFinalizer m_unconditionalFinalizer;
+ PoisonedUniquePtr<JSWebAssemblyCodeBlockPoison, UnconditionalFinalizer> m_unconditionalFinalizer;
Bag<CallLinkInfo> m_callLinkInfos;
String m_errorMessage;
};
Modified: branches/safari-605-branch/Source/WTF/ChangeLog (226683 => 226684)
--- branches/safari-605-branch/Source/WTF/ChangeLog 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/WTF/ChangeLog 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,3 +1,47 @@
+2018-01-09 Jason Marcell <[email protected]>
+
+ Cherry-pick r226530. rdar://problem/36392325
+
+ 2018-01-07 Mark Lam <[email protected]>
+
+ Apply poisoning to more pointers in JSC.
+ https://bugs.webkit.org/show_bug.cgi?id=181096
+ <rdar://problem/36182970>
+
+ Reviewed by JF Bastien.
+
+ Added support for PoisonedBag and PoisonedRefCountedArray.
+
+ * wtf/Bag.h:
+ (WTF::Private::BagNode::BagNode):
+ (WTF::Bag::Bag):
+ (WTF::Bag::operator=):
+ (WTF::Bag::clear):
+ (WTF::Bag::add):
+ (WTF::Bag::begin):
+ (WTF::Bag::unwrappedHead):
+ (WTF::Bag::Node::Node): Deleted.
+ * wtf/BagToHashMap.h:
+ (WTF::toHashMap):
+ * wtf/Poisoned.h:
+ (WTF::constExprPoisonRandom):
+ (WTF::makeConstExprPoison):
+ * wtf/RefCountedArray.h:
+ (WTF::RefCountedArray::RefCountedArray):
+ (WTF::RefCountedArray::clone const):
+ (WTF::RefCountedArray::operator=):
+ (WTF::RefCountedArray::~RefCountedArray):
+ (WTF::RefCountedArray::refCount const):
+ (WTF::RefCountedArray::size const):
+ (WTF::RefCountedArray::data):
+ (WTF::RefCountedArray::begin):
+ (WTF::RefCountedArray::end):
+ (WTF::RefCountedArray::data const):
+ (WTF::RefCountedArray::begin const):
+ (WTF::RefCountedArray::operator== const):
+ (WTF::RefCountedArray::Header::fromPayload):
+ * wtf/WTFAssertions.cpp:
+
2018-01-05 JF Bastien <[email protected]>
WebAssembly: poison JS object's secrets
Modified: branches/safari-605-branch/Source/WTF/wtf/Bag.h (226683 => 226684)
--- branches/safari-605-branch/Source/WTF/wtf/Bag.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/WTF/wtf/Bag.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,44 +26,50 @@
#ifndef Bag_h
#define Bag_h
+#include <wtf/DumbPtrTraits.h>
#include <wtf/FastMalloc.h>
#include <wtf/Noncopyable.h>
namespace WTF {
+namespace Private {
+
template<typename T>
+class BagNode {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ template<typename... Args>
+ BagNode(Args&&... args)
+ : m_item(std::forward<Args>(args)...)
+ { }
+
+ T m_item;
+ BagNode* m_next { nullptr };
+};
+
+} // namespace Private
+
+template<typename T, typename PtrTraits = DumbPtrTraits<Private::BagNode<T>>>
class Bag {
WTF_MAKE_NONCOPYABLE(Bag);
WTF_MAKE_FAST_ALLOCATED;
-private:
- class Node {
- WTF_MAKE_FAST_ALLOCATED;
- public:
- template<typename... Args>
- Node(Args&&... args)
- : m_item(std::forward<Args>(args)...)
- {
- }
-
- T m_item;
- Node* m_next { nullptr };
- };
-
+ using Node = Private::BagNode<T>;
+
public:
- Bag()
- {
- }
+ Bag() = default;
- Bag(Bag<T>&& other)
+ template<typename U>
+ Bag(Bag<T, U>&& other)
{
ASSERT(!m_head);
- m_head = other.m_head;
+ m_head = other.unwrappedHead();
other.m_head = nullptr;
}
- Bag& operator=(Bag<T>&& other)
+ template<typename U>
+ Bag& operator=(Bag<T, U>&& other)
{
- m_head = other.m_head;
+ m_head = other.unwrappedHead();
other.m_head = nullptr;
return *this;
}
@@ -75,9 +81,10 @@
void clear()
{
- while (m_head) {
- Node* current = m_head;
- m_head = current->m_next;
+ Node* head = this->unwrappedHead();
+ while (head) {
+ Node* current = head;
+ head = current->m_next;
delete current;
}
m_head = nullptr;
@@ -87,7 +94,7 @@
T* add(Args&&... args)
{
Node* newNode = new Node(std::forward<Args>(args)...);
- newNode->m_next = m_head;
+ newNode->m_next = unwrappedHead();
m_head = newNode;
return &newNode->m_item;
}
@@ -121,7 +128,7 @@
}
private:
- template<typename U> friend class WTF::Bag;
+ template<typename, typename> friend class WTF::Bag;
Node* m_node;
};
@@ -128,7 +135,7 @@
iterator begin()
{
iterator result;
- result.m_node = m_head;
+ result.m_node = unwrappedHead();
return result;
}
@@ -137,12 +144,20 @@
bool isEmpty() const { return !m_head; }
private:
- Node* m_head { nullptr };
+ Node* unwrappedHead() { return PtrTraits::unwrap(m_head); }
+
+ typename PtrTraits::StorageType m_head { nullptr };
};
+template<uint32_t key, typename T> struct ConstExprPoisonedPtrTraits;
+
+template<uint32_t key, typename T>
+using PoisonedBag = Bag<T, ConstExprPoisonedPtrTraits<key, Private::BagNode<T>>>;
+
} // namespace WTF
using WTF::Bag;
+using WTF::PoisonedBag;
#endif // Bag_h
Modified: branches/safari-605-branch/Source/WTF/wtf/BagToHashMap.h (226683 => 226684)
--- branches/safari-605-branch/Source/WTF/wtf/BagToHashMap.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/WTF/wtf/BagToHashMap.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -31,10 +31,10 @@
namespace WTF {
-template<typename ElementType, typename KeyType, typename HashArg, typename KeyGetterFunctor>
-void toHashMap(Bag<ElementType>& bag, KeyGetterFunctor& getKey, HashMap<KeyType, ElementType*, HashArg>& result)
+template<typename ElementType, typename BagPtrTraits, typename KeyType, typename HashArg, typename KeyGetterFunctor>
+void toHashMap(Bag<ElementType, BagPtrTraits>& bag, KeyGetterFunctor& getKey, HashMap<KeyType, ElementType*, HashArg>& result)
{
- for (typename Bag<ElementType>::iterator iter = bag.begin(); !!iter; ++iter) {
+ for (typename Bag<ElementType, BagPtrTraits>::iterator iter = bag.begin(); !!iter; ++iter) {
ElementType* element = *iter;
KeyType key = getKey(*element);
result.add(key, element);
Modified: branches/safari-605-branch/Source/WTF/wtf/Poisoned.h (226683 => 226684)
--- branches/safari-605-branch/Source/WTF/wtf/Poisoned.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/WTF/wtf/Poisoned.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -87,6 +87,7 @@
} // namespace PoisonedImplHelper
+// FIXME: once we have C++17, we can make the key of type auto and remove the need for KeyType.
template<typename KeyType, KeyType key, typename T, typename = std::enable_if_t<std::is_pointer<T>::value>>
class PoisonedImpl {
public:
@@ -227,13 +228,20 @@
WTF_EXPORT_PRIVATE uintptr_t makePoison();
+#if ENABLE(POISON)
+// FIXME: once we have C++17, we can make this a lambda in makeConstExprPoison().
+inline constexpr uintptr_t constExprPoisonRandom(uintptr_t seed)
+{
+ uintptr_t result1 = seed * 6906969069 + 1234567;
+ uintptr_t result2 = seed * 8253729 + 2396403;
+ return (result1 << 3) ^ (result2 << 16);
+}
+#endif
+
inline constexpr uintptr_t makeConstExprPoison(uint32_t key)
{
#if ENABLE(POISON)
- uintptr_t uintptrKey = key;
- uintptr_t poison1 = uintptrKey * 6906969069 + 1234567;
- uintptr_t poison2 = uintptrKey * 8253729 + 2396403;
- uintptr_t poison = (poison1 << 3) ^ (poison2 << 16);
+ uintptr_t poison = constExprPoisonRandom(key);
poison &= ~(static_cast<uintptr_t>(0xffff) << 48); // Ensure that poisoned bits look like a pointer.
poison |= (1 << 2); // Ensure that poisoned bits cannot be 0.
return poison;
Modified: branches/safari-605-branch/Source/WTF/wtf/RefCountedArray.h (226683 => 226684)
--- branches/safari-605-branch/Source/WTF/wtf/RefCountedArray.h 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/WTF/wtf/RefCountedArray.h 2018-01-10 04:31:27 UTC (rev 226684)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
#ifndef RefCountedArray_h
#define RefCountedArray_h
+#include <wtf/DumbPtrTraits.h>
#include <wtf/FastMalloc.h>
#include <wtf/StdLibExtras.h>
#include <wtf/Vector.h>
@@ -43,21 +44,22 @@
namespace WTF {
-template<typename T>
+template<typename T, typename PtrTraits = DumbPtrTraits<T>>
class RefCountedArray {
+ enum CommonCopyConstructorTag { CommonCopyConstructor };
+
public:
- RefCountedArray()
- : m_data(0)
- {
- }
+ RefCountedArray() = default;
RefCountedArray(const RefCountedArray& other)
- : m_data(other.m_data)
- {
- if (m_data)
- Header::fromPayload(m_data)->refCount++;
- }
+ : RefCountedArray(CommonCopyConstructor, other)
+ { }
+ template<typename OtherTraits>
+ RefCountedArray(const RefCountedArray<T, OtherTraits>& other)
+ : RefCountedArray(CommonCopyConstructor, other)
+ { }
+
explicit RefCountedArray(size_t size)
{
if (!size) {
@@ -65,18 +67,22 @@
return;
}
- m_data = (static_cast<Header*>(fastMalloc(Header::size() + sizeof(T) * size)))->payload();
- Header::fromPayload(m_data)->refCount = 1;
- Header::fromPayload(m_data)->length = size;
- ASSERT(Header::fromPayload(m_data)->length == size);
+ T* data = "" + sizeof(T) * size)))->payload();
+ m_data = data;
+ Header::fromPayload(data)->refCount = 1;
+ Header::fromPayload(data)->length = size;
+ ASSERT(Header::fromPayload(data)->length == size);
VectorTypeOperations<T>::initialize(begin(), end());
}
- RefCountedArray clone() const
+ template<typename OtherTraits = PtrTraits>
+ RefCountedArray<T, OtherTraits> clone() const
{
- RefCountedArray result(size());
+ RefCountedArray<T, OtherTraits> result(size());
+ const T* data = ""
+ T* resultData = result.data();
for (unsigned i = size(); i--;)
- result[i] = at(i);
+ resultData[i] = data[i];
return result;
}
@@ -88,20 +94,23 @@
return;
}
- m_data = (static_cast<Header*>(fastMalloc(Header::size() + sizeof(T) * other.size())))->payload();
- Header::fromPayload(m_data)->refCount = 1;
- Header::fromPayload(m_data)->length = other.size();
- ASSERT(Header::fromPayload(m_data)->length == other.size());
- VectorTypeOperations<T>::uninitializedCopy(other.begin(), other.end(), m_data);
+ T* data = "" + sizeof(T) * other.size())))->payload();
+ m_data = data;
+ Header::fromPayload(data)->refCount = 1;
+ Header::fromPayload(data)->length = other.size();
+ ASSERT(Header::fromPayload(data)->length == other.size());
+ VectorTypeOperations<T>::uninitializedCopy(other.begin(), other.end(), data);
}
- RefCountedArray& operator=(const RefCountedArray& other)
+ template<typename OtherTraits = PtrTraits>
+ RefCountedArray& operator=(const RefCountedArray<T, OtherTraits>& other)
{
- T* oldData = m_data;
- m_data = other.m_data;
- if (m_data)
- Header::fromPayload(m_data)->refCount++;
-
+ T* oldData = data();
+ T* otherData = const_cast<T*>(other.data());
+ if (otherData)
+ Header::fromPayload(otherData)->refCount++;
+ m_data = otherData;
+
if (!oldData)
return *this;
if (--Header::fromPayload(oldData)->refCount)
@@ -110,15 +119,18 @@
fastFree(Header::fromPayload(oldData));
return *this;
}
-
+
+ RefCountedArray& operator=(const RefCountedArray& other) { return this->operator=<PtrTraits>(other); }
+
~RefCountedArray()
{
if (!m_data)
return;
- if (--Header::fromPayload(m_data)->refCount)
+ T* data = ""
+ if (--Header::fromPayload(data)->refCount)
return;
VectorTypeOperations<T>::destruct(begin(), end());
- fastFree(Header::fromPayload(m_data));
+ fastFree(Header::fromPayload(data));
}
unsigned refCount() const
@@ -125,7 +137,7 @@
{
if (!m_data)
return 0;
- return Header::fromPayload(m_data)->refCount;
+ return Header::fromPayload(data())->refCount;
}
size_t size() const
@@ -132,22 +144,23 @@
{
if (!m_data)
return 0;
- return Header::fromPayload(m_data)->length;
+ return Header::fromPayload(data())->length;
}
size_t byteSize() const { return size() * sizeof(T); }
- T* data() { return m_data; }
- T* begin() { return m_data; }
+ T* data() { return PtrTraits::unwrap(m_data); }
+ T* begin() { return data(); }
T* end()
{
if (!m_data)
return 0;
- return m_data + Header::fromPayload(m_data)->length;
+ T* data = ""
+ return data + Header::fromPayload(data)->length;
}
- const T* data() const { return m_data; }
- const T* begin() const { return m_data; }
+ const T* data() const { return const_cast<RefCountedArray*>(this)->data(); }
+ const T* begin() const { return const_cast<RefCountedArray*>(this)->begin(); }
const T* end() const { return const_cast<RefCountedArray*>(this)->end(); }
T& at(size_t i)
@@ -165,21 +178,26 @@
T& operator[](size_t i) { return at(i); }
const T& operator[](size_t i) const { return at(i); }
- bool operator==(const RefCountedArray& other) const
+ template<typename OtherTraits = PtrTraits>
+ bool operator==(const RefCountedArray<T, OtherTraits>& other) const
{
- if (m_data == other.m_data)
+ T* data = ""
+ T* otherData = const_cast<T*>(other.data());
+ if (data == otherData)
return true;
- if (!m_data || !other.m_data)
+ if (!data || !otherData)
return false;
- unsigned length = Header::fromPayload(m_data)->length;
- if (length != Header::fromPayload(other.m_data)->length)
+ unsigned length = Header::fromPayload(data)->length;
+ if (length != Header::fromPayload(otherData)->length)
return false;
for (unsigned i = 0; i < length; ++i) {
- if (m_data[i] != other.m_data[i])
+ if (data[i] != otherData[i])
return false;
}
return true;
}
+
+ bool operator==(const RefCountedArray& other) const { return this->operator==<PtrTraits>(other); }
private:
struct Header {
@@ -202,13 +220,32 @@
{
return reinterpret_cast_ptr<Header*>(reinterpret_cast<char*>(payload) - size());
}
+
+ static const Header* fromPayload(const T* payload)
+ {
+ return fromPayload(const_cast<T*>(payload));
+ }
};
-
- T* m_data;
+
+ template<typename OtherTraits>
+ RefCountedArray(CommonCopyConstructorTag, const RefCountedArray<T, OtherTraits>& other)
+ : m_data(const_cast<T*>(other.data()))
+ {
+ if (m_data)
+ Header::fromPayload(data())->refCount++;
+ }
+
+ typename PtrTraits::StorageType m_data { nullptr };
};
+template<uint32_t key, typename T> struct ConstExprPoisonedPtrTraits;
+
+template<uint32_t key, typename T>
+using PoisonedRefCountedArray = RefCountedArray<T, ConstExprPoisonedPtrTraits<key, T>>;
+
} // namespace WTF
+using WTF::PoisonedRefCountedArray;
using WTF::RefCountedArray;
#endif // RefCountedArray_h
Modified: branches/safari-605-branch/Source/WTF/wtf/WTFAssertions.cpp (226683 => 226684)
--- branches/safari-605-branch/Source/WTF/wtf/WTFAssertions.cpp 2018-01-10 04:31:21 UTC (rev 226683)
+++ branches/safari-605-branch/Source/WTF/wtf/WTFAssertions.cpp 2018-01-10 04:31:27 UTC (rev 226684)
@@ -25,8 +25,10 @@
#include "config.h"
+#include <wtf/Bag.h>
#include <wtf/Poisoned.h>
#include <wtf/PoisonedUniquePtr.h>
+#include <wtf/RefCountedArray.h>
#include <wtf/RefPtr.h>
namespace WTF {
@@ -33,6 +35,7 @@
namespace {
struct DummyStruct { };
+const uint32_t dummyPoison = 0xffff;
}
#if ENABLE(POISON)
@@ -65,15 +68,21 @@
static_assert(!(makeConstExprPoison(0xffffffff) & 0x3), "ensure bottom 2 alignment bits are available for use as flag bits.");
#endif // ENABLE(POISON)
+static_assert(sizeof(Bag<DummyStruct>) == sizeof(void*), "");
+static_assert(sizeof(PoisonedBag<dummyPoison, DummyStruct>) == sizeof(void*), "");
+
static_assert(sizeof(Ref<DummyStruct>) == sizeof(DummyStruct*), "");
-static_assert(sizeof(PoisonedRef<0xffff, DummyStruct>) == sizeof(DummyStruct*), "");
+static_assert(sizeof(PoisonedRef<dummyPoison, DummyStruct>) == sizeof(DummyStruct*), "");
static_assert(sizeof(RefPtr<DummyStruct>) == sizeof(DummyStruct*), "");
-static_assert(sizeof(PoisonedRefPtr<0xffff, DummyStruct>) == sizeof(DummyStruct*), "");
+static_assert(sizeof(PoisonedRefPtr<dummyPoison, DummyStruct>) == sizeof(DummyStruct*), "");
-static_assert(sizeof(PoisonedUniquePtr<0xffff, DummyStruct>) == sizeof(DummyStruct*), "");
-static_assert(sizeof(PoisonedUniquePtr<0xffff, int[]>) == sizeof(int*), "");
-static_assert(sizeof(PoisonedUniquePtr<0xffff, DummyStruct[]>) == sizeof(DummyStruct*), "");
+static_assert(sizeof(PoisonedUniquePtr<dummyPoison, DummyStruct>) == sizeof(DummyStruct*), "");
+static_assert(sizeof(PoisonedUniquePtr<dummyPoison, int[]>) == sizeof(int*), "");
+static_assert(sizeof(PoisonedUniquePtr<dummyPoison, DummyStruct[]>) == sizeof(DummyStruct*), "");
+static_assert(sizeof(RefCountedArray<DummyStruct>) == sizeof(void*), "");
+static_assert(sizeof(PoisonedRefCountedArray<dummyPoison, DummyStruct>) == sizeof(void*), "");
+
} // namespace WTF