Skip to content

Commit

Permalink
8324337: Cherry-pick WebKit 617.1 stabilization fixes
Browse files Browse the repository at this point in the history
Backport-of: 52840a1
  • Loading branch information
Johan Vos committed Mar 8, 2024
1 parent da5918f commit 426f4eb
Show file tree
Hide file tree
Showing 161 changed files with 1,186 additions and 545 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2021 Apple Inc. All rights reserved.
* Copyright (C) 2008-2023 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
Expand Down Expand Up @@ -259,8 +259,8 @@ namespace JSC {

static ALWAYS_INLINE uint32_t nextValue(uint64_t instruction, uint64_t index, uint32_t currentValue)
{
uint64_t a = tagInt(instruction, makeDiversifier(0x12, index, currentValue));
uint64_t b = tagInt(instruction, makeDiversifier(0x13, index, currentValue));
uint64_t a = tagInt<PACKeyType::ProcessIndependent>(instruction, makeDiversifier(0x12, index, currentValue));
uint64_t b = tagInt<PACKeyType::ProcessIndependent>(instruction, makeDiversifier(0x13, index, currentValue));
return (a >> 39) ^ (b >> 23);
}

Expand All @@ -272,14 +272,14 @@ namespace JSC {
ALWAYS_INLINE uint32_t currentHash(uint32_t index)
{
if constexpr (shouldSign == ShouldSign::Yes)
return untagInt(m_hash, makeDiversifier(initializationNamespace, index, pin()));
return untagInt<PACKeyType::ProcessIndependent>(m_hash, makeDiversifier(initializationNamespace, index, pin()));
return m_hash;
}

ALWAYS_INLINE void setUpdatedHash(uint32_t value, uint32_t index)
{
if constexpr (shouldSign == ShouldSign::Yes)
m_hash = tagInt(static_cast<uint64_t>(value), makeDiversifier(initializationNamespace, index, pin()));
m_hash = tagInt<PACKeyType::ProcessIndependent>(static_cast<uint64_t>(value), makeDiversifier(initializationNamespace, index, pin()));
else
m_hash = static_cast<uint64_t>(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4230,15 +4230,21 @@ class MacroAssemblerARM64 : public AbstractMacroAssembler<Assembler> {
Jump branchMul64(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID scratch1, RegisterID dest)
{
ASSERT(cond != Signed);
ASSERT(src1 != scratch1);
ASSERT(src2 != scratch1);

// This is a signed multiple of two 64-bit values, producing a 64-bit result.
// mul<64> does a signed multiple of two 64-bit values, producing a 64-bit result.
if (cond != Overflow) {
m_assembler.mul<64>(dest, src1, src2);

if (cond != Overflow)
return branchTest64(cond, dest);
}

// Compute bits 127..64 of the result into scratch1.
m_assembler.smulh(scratch1, src1, src2);
// dest may equal src1 or src2. So, we should always compute dest after we've
// computed the smulh result in scratch1 so as not to corrupt src1 and src2.
m_assembler.mul<64>(dest, src1, src2);

// Splat bit 63 of the result to bits 63..0 of scratch1.
m_assembler.cmp<64>(scratch1, dest, Assembler::ASR, 63);
// Check that bits 31..63 of the original result were all equal.
Expand All @@ -4250,11 +4256,6 @@ class MacroAssemblerARM64 : public AbstractMacroAssembler<Assembler> {
return branchMul64(cond, src1, src2, getCachedDataTempRegisterIDAndInvalidate(), dest);
}

Jump branchMul64(ResultCondition cond, RegisterID src, RegisterID dest)
{
return branchMul64(cond, dest, src, dest);
}

Jump branchNeg32(ResultCondition cond, RegisterID dest)
{
m_assembler.neg<32, S>(dest, dest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3379,7 +3379,7 @@ class LowerToAir {
uint64_t highWidth = highWidthValue->asInt();
uint64_t lowWidth = lowWidthValue->asInt();
uint64_t datasize = opcode == ExtractRegister32 ? 32 : 64;
if (lowWidth + highWidth != datasize || maskBitCount != lowWidth)
if (lowWidth + highWidth != datasize || maskBitCount != lowWidth || lowWidth == datasize)
return false;

append(opcode, tmp(nValue), tmp(mValue), imm(lowWidthValue), tmp(m_value));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,12 @@ class IntRange {
template<typename T>
static IntRange rangeForMask(T mask)
{
if (!(mask + 1))
if (mask == static_cast<T>(-1))
return top<T>();
if constexpr (std::is_signed_v<T>) {
if (mask < 0)
return IntRange(INT_MIN & mask, mask & INT_MAX);
return IntRange(std::numeric_limits<T>::min() & mask, mask & std::numeric_limits<T>::max());
}
return IntRange(0, mask);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,14 @@ class Validater {
VALIDATE(elementByteSize(inst.args[0].simdInfo().lane) <= 8, ("At ", inst, " in ", *block));
VALIDATE(elementByteSize(inst.args[0].simdInfo().lane) >= 2, ("At ", inst, " in ", *block));
break;
case ExtractRegister64:
VALIDATE(inst.args[2].isImm(), ("At ", inst, " in ", *block));
VALIDATE(inst.args[2].asTrustedImm32().m_value < 64, ("At ", inst, " in ", *block));
break;
case ExtractRegister32:
VALIDATE(inst.args[2].isImm(), ("At ", inst, " in ", *block));
VALIDATE(inst.args[2].asTrustedImm32().m_value < 32, ("At ", inst, " in ", *block));
break;
default:
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,7 @@ void testCheckAddImmCommute();
void testCheckAddImmSomeRegister();
void testCheckAdd();
void testCheckAdd64();
void testCheckAdd64Range();
void testCheckAddFold(int, int);
void testCheckAddFoldFail(int, int);
void test42();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,7 @@ void run(const TestConfig* config)
RUN(testCheckAddImmSomeRegister());
RUN(testCheckAdd());
RUN(testCheckAdd64());
RUN(testCheckAdd64Range());
RUN(testCheckAddFold(100, 200));
RUN(testCheckAddFoldFail(2147483647, 100));
RUN(testCheckAddArgumentAliasing64());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,32 @@ void testCheckAdd64()
CHECK(invoke<double>(*code, 9223372036854775807ll, 42ll) == static_cast<double>(9223372036854775807ll) + 42.0);
}

void testCheckAdd64Range()
{
Procedure proc;
BasicBlock* root = proc.addBlock();

Value* x0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
Value* b1 = root->appendNew<Value>(proc, JSC::B3::BitAnd, Origin(), x0, root->appendNew<Const64Value>(proc, Origin(), 0xffffffff00000000LL));
Value* b2 = root->appendNew<Value>(proc, JSC::B3::Sub, Origin(), b1, root->appendNew<Const64Value>(proc, Origin(), 0xffffffff00000000LL));
Value* b3 = root->appendNew<Value>(proc, JSC::B3::ZShr, Origin(), b2, root->appendNew<Const32Value>(proc, Origin(), 28));
Value* b4 = root->appendNew<Const64Value>(proc, Origin(), 0x7fffffffffffff00LL);

CheckValue* checkAdd = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), b3, b4);
checkAdd->setGenerator(
[&] (CCallHelpers& jit, const StackmapGenerationParams&) {
AllowMacroScratchRegisterUsage allowScratch(jit);
jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
jit.emitFunctionEpilogue();
jit.ret();
});
root->appendNewControlValue(proc, Return, Origin(), checkAdd);

auto code = compileProc(proc);

CHECK(invoke<int64_t>(*code, 0x8ffffffe00000000LL) == 42.0);
}

void testCheckAddFold(int a, int b)
{
Procedure proc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,11 @@ bool CodeBlock::finishCreation(VM& vm, ScriptExecutable* ownerExecutable, Unlink
ConcurrentJSLocker locker(symbolTable->m_lock);
auto iter = symbolTable->find(locker, ident.impl());
ASSERT(iter != symbolTable->end(locker));
if (bytecode.m_getPutInfo.initializationMode() == InitializationMode::ScopedArgumentInitialization) {
ASSERT(bytecode.m_value.isArgument());
unsigned argumentIndex = bytecode.m_value.toArgument() - 1;
symbolTable->prepareToWatchScopedArgument(iter->value, argumentIndex);
} else
iter->value.prepareToWatch();
metadata.m_watchpointSet = iter->value.watchpointSet();
} else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,17 +595,22 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
m_outOfMemoryDuringConstruction = true;
return;
}

unsigned varOrAnonymous = UINT_MAX;

if (UniquedStringImpl* name = visibleNameForParameter(parameters.at(i).first)) {
VarOffset varOffset(offset);
SymbolTableEntry entry(varOffset);
// Stores to these variables via the ScopedArguments object will not do
// notifyWrite(), since that would be cumbersome. Also, watching formal
// parameters when "arguments" is in play is unlikely to be super profitable.
// So, we just disable it.
entry.disableWatching(m_vm);
functionSymbolTable->set(NoLockingNecessary, name, entry);
IGNORE_WARNINGS_BEGIN("dangling-reference")
const Identifier& ident =
static_cast<const BindingNode*>(parameters.at(i).first)->boundProperty();
IGNORE_WARNINGS_END

varOrAnonymous = addConstant(ident);
}
OpPutToScope::emit(this, m_lexicalEnvironmentRegister, UINT_MAX, virtualRegisterForArgumentIncludingThis(1 + i), GetPutInfo(ThrowIfNotFound, ResolvedClosureVar, InitializationMode::NotInitialization, ecmaMode), SymbolTableOrScopeDepth::symbolTable(VirtualRegister { symbolTableConstantIndex }), offset.offset());

OpPutToScope::emit(this, m_lexicalEnvironmentRegister, varOrAnonymous, virtualRegisterForArgumentIncludingThis(1 + i), GetPutInfo(ThrowIfNotFound, ResolvedClosureVar, InitializationMode::ScopedArgumentInitialization, ecmaMode), SymbolTableOrScopeDepth::symbolTable(VirtualRegister { symbolTableConstantIndex }), offset.offset());
}

// This creates a scoped arguments object and copies the overflow arguments into the
Expand Down Expand Up @@ -639,10 +644,10 @@ BytecodeGenerator::BytecodeGenerator(VM& vm, FunctionNode* functionNode, Unlinke
}

ScopeOffset offset = functionSymbolTable->takeNextScopeOffset(NoLockingNecessary);
IGNORE_GCC_WARNINGS_BEGIN("dangling-reference")
IGNORE_WARNINGS_BEGIN("dangling-reference")
const Identifier& ident =
static_cast<const BindingNode*>(parameters.at(i).first)->boundProperty();
IGNORE_GCC_WARNINGS_END
IGNORE_WARNINGS_END
functionSymbolTable->set(NoLockingNecessary, name, SymbolTableEntry(VarOffset(offset)));

OpPutToScope::emit(this, m_lexicalEnvironmentRegister, addConstant(ident), virtualRegisterForArgumentIncludingThis(1 + i), GetPutInfo(ThrowIfNotFound, ResolvedClosureVar, InitializationMode::NotInitialization, ecmaMode), SymbolTableOrScopeDepth::symbolTable(VirtualRegister { symbolTableConstantIndex }), offset.offset());
Expand Down Expand Up @@ -1338,7 +1343,9 @@ void BytecodeGenerator::initializeVarLexicalEnvironment(int symbolTableConstantI
UniquedStringImpl* BytecodeGenerator::visibleNameForParameter(DestructuringPatternNode* pattern)
{
if (pattern->isBindingNode()) {
IGNORE_WARNINGS_BEGIN("dangling-reference")
const Identifier& ident = static_cast<const BindingNode*>(pattern)->boundProperty();
IGNORE_WARNINGS_END
if (!m_functions.contains(ident.impl()))
return ident.impl();
}
Expand Down Expand Up @@ -5584,3 +5591,4 @@ void printInternal(PrintStream& out, JSC::Variable::VariableKind kind)

} // namespace WTF


Original file line number Diff line number Diff line change
Expand Up @@ -2565,9 +2565,10 @@ auto ByteCodeParser::handleIntrinsicCall(Node* callee, Operand resultOperand, Ca
// Add the constant before exit becomes invalid because we may want to insert (redundant) checks on it in Fixup.
Node* kindNode = jsConstant(jsNumber(static_cast<uint32_t>(*kind)));

Node* thisValue = addToGraph(ToThis, OpInfo(ECMAMode::strict()), OpInfo(getPrediction()), get(virtualRegisterForArgumentIncludingThis(0, registerOffset)));
// We don't have an existing error string.
unsigned errorStringIndex = UINT32_MAX;
Node* object = addToGraph(ToObject, OpInfo(errorStringIndex), OpInfo(SpecNone), get(virtualRegisterForArgumentIncludingThis(0, registerOffset)));
Node* object = addToGraph(ToObject, OpInfo(errorStringIndex), OpInfo(SpecNone), thisValue);

Node* iterator = addToGraph(NewInternalFieldObject, OpInfo(m_graph.registerStructure(globalObject->arrayIteratorStructure())));

Expand Down Expand Up @@ -8738,6 +8739,9 @@ void ByteCodeParser::parseBlock(unsigned limit)
// Must happen after the store. See comment for GetGlobalVar.
addToGraph(NotifyWrite, OpInfo(watchpoints));
}

// Keep scope alive until after put.
addToGraph(Phantom, scopeNode);
break;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,11 @@ bool clobbersExitState(Graph& graph, Node* node)
clobberize(
graph, node, NoOpClobberize(),
[&] (const AbstractHeap& heap) {
// There shouldn't be such a thing as a strict subtype of SideState. That's what allows
// us to use a fast != check, below.
ASSERT(!heap.isStrictSubtypeOf(SideState));
// There shouldn't be such a thing as a strict subtype of SideState or HeapObjectCount.
// That's what allows us to use a fast != check, below.
ASSERT(!heap.isStrictSubtypeOf(SideState) && !heap.isStrictSubtypeOf(HeapObjectCount));

if (heap != SideState)
if (heap != SideState && heap != HeapObjectCount)
result = true;
},
NoOpClobberize());
Expand Down