Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8272329: Cherry pick GTK WebKit 2.32.3 changes #603

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -34,7 +34,25 @@

#if OS(LINUX)
#include <asm/hwcap.h>
#if __has_include(<sys/auxv.h>)
#include <sys/auxv.h>
#else
#include <linux/auxvec.h>
// Provide an implementation for C libraries which do not ship one.
static unsigned long getauxval(unsigned long type)
{
char** env = environ;
while (*env++) { /* no-op */ }

for (auto* auxv = reinterpret_cast<unsigned long*>(env); *auxv != AT_NULL; auxv += 2) {
if (*auxv == type)
return auxv[1];
}

errno = ENOENT;
return 0;
}
#endif
#endif

namespace JSC {
@@ -28,6 +28,8 @@

#if ENABLE(ASSEMBLER)

#include <initializer_list>

#include "ARMv7Assembler.h"
#include "AbstractMacroAssembler.h"

@@ -43,9 +45,10 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler<Assembler> {
inline ARMRegisters::FPSingleRegisterID fpTempRegisterAsSingle() { return ARMRegisters::asSingle(fpTempRegister); }

public:
static constexpr unsigned numGPRs = 16;
static constexpr unsigned numFPRs = 16;

#define DUMMY_REGISTER_VALUE(id, name, r, cs) 0,
static constexpr unsigned numGPRs = std::initializer_list<int>({ FOR_EACH_GP_REGISTER(DUMMY_REGISTER_VALUE) }).size();
static constexpr unsigned numFPRs = std::initializer_list<int>({ FOR_EACH_FP_REGISTER(DUMMY_REGISTER_VALUE) }).size();
#undef DUMMY_REGISTER_VALUE
RegisterID scratchRegister() { return dataTempRegister; }

MacroAssemblerARMv7()
@@ -240,10 +240,11 @@ class IntRange {
T newMin = static_cast<T>(m_min) << static_cast<T>(shiftAmount);
T newMax = static_cast<T>(m_max) << static_cast<T>(shiftAmount);

if ((newMin >> shiftAmount) != static_cast<T>(m_min))
if (((newMin >> shiftAmount) != static_cast<T>(m_min))
|| ((newMax >> shiftAmount) != static_cast<T>(m_max))) {
newMin = std::numeric_limits<T>::min();
if ((newMax >> shiftAmount) != static_cast<T>(m_max))
newMax = std::numeric_limits<T>::max();
}

return IntRange(newMin, newMax);
}
@@ -277,12 +277,30 @@ void CodeBlockBytecodeDumper<Block>::dumpGraph(Block* block, const InstructionSt

out.printf("\n");

Vector<Vector<unsigned>> predecessors;
predecessors.resize(graph.size());
for (auto& block : graph) {
if (block.isEntryBlock() || block.isExitBlock())
continue;
for (auto successorIndex : block.successors()) {
if (!predecessors[successorIndex].contains(block.index()))
predecessors[successorIndex].append(block.index());
}
}

for (BytecodeBasicBlock& block : graph) {
if (block.isEntryBlock() || block.isExitBlock())
continue;

out.print("bb#", block.index(), "\n");

out.print("Predecessors: [");
for (unsigned predecessor : predecessors[block.index()]) {
if (!graph[predecessor].isEntryBlock())
out.print(" #", predecessor);
}
out.print(" ]\n");

for (unsigned i = 0; i < block.totalLength(); ) {
auto& currentInstruction = instructions.at(i + block.leaderOffset());
dumper.dumpBytecode(currentInstruction, icStatusMap);
@@ -945,7 +945,7 @@ void CodeBlock::setAlternative(VM& vm, CodeBlock* alternative)
m_alternative.set(vm, this, alternative);
}

void CodeBlock::setNumParameters(int newValue)
void CodeBlock::setNumParameters(unsigned newValue)
{
m_numParameters = newValue;

@@ -2051,7 +2051,7 @@ void CodeBlock::ensureCatchLivenessIsComputedForBytecodeIndexSlow(const OpCatch&
liveOperands.append(virtualRegisterForLocal(liveLocal));
});

for (int i = 0; i < numParameters(); ++i)
for (unsigned i = 0; i < numParameters(); ++i)
liveOperands.append(virtualRegisterForArgumentIncludingThis(i));

auto profiles = makeUnique<ValueProfileAndVirtualRegisterBuffer>(liveOperands.size());
@@ -156,17 +156,17 @@ class CodeBlock : public JSCell {

MetadataTable* metadataTable() const { return m_metadata.get(); }

int numParameters() const { return m_numParameters; }
void setNumParameters(int newValue);
unsigned numParameters() const { return m_numParameters; }
void setNumParameters(unsigned newValue);

int numberOfArgumentsToSkip() const { return m_numberOfArgumentsToSkip; }
unsigned numberOfArgumentsToSkip() const { return m_numberOfArgumentsToSkip; }

int numCalleeLocals() const { return m_numCalleeLocals; }
unsigned numCalleeLocals() const { return m_numCalleeLocals; }

int numVars() const { return m_numVars; }
int numTmps() const { return m_unlinkedCode->hasCheckpoints() * maxNumCheckpointTmps; }
unsigned numVars() const { return m_numVars; }
unsigned numTmps() const { return m_unlinkedCode->hasCheckpoints() * maxNumCheckpointTmps; }

int* addressOfNumParameters() { return &m_numParameters; }
unsigned* addressOfNumParameters() { return &m_numParameters; }
static ptrdiff_t offsetOfNumParameters() { return OBJECT_OFFSETOF(CodeBlock, m_numParameters); }

CodeBlock* alternative() const { return static_cast<CodeBlock*>(m_alternative.get()); }
@@ -243,7 +243,7 @@ class CodeBlock : public JSCell {

ALWAYS_INLINE bool isTemporaryRegister(VirtualRegister reg)
{
return reg.offset() >= m_numVars;
return reg.offset() >= static_cast<int>(m_numVars);
}

HandlerInfo* handlerForBytecodeIndex(BytecodeIndex, RequiredHandler = RequiredHandler::AnyHandler);
@@ -996,10 +996,10 @@ class CodeBlock : public JSCell {
void insertBasicBlockBoundariesForControlFlowProfiler();
void ensureCatchLivenessIsComputedForBytecodeIndexSlow(const OpCatch&, BytecodeIndex);

int m_numCalleeLocals;
int m_numVars;
int m_numParameters;
int m_numberOfArgumentsToSkip { 0 };
unsigned m_numCalleeLocals;
unsigned m_numVars;
unsigned m_numParameters;
unsigned m_numberOfArgumentsToSkip { 0 };
unsigned m_numberOfNonArgumentValueProfiles { 0 };
union {
unsigned m_debuggerRequests;
@@ -179,8 +179,8 @@ class UnlinkedCodeBlock : public JSCell {

const InstructionStream& instructions() const;

int numCalleeLocals() const { return m_numCalleeLocals; }
int numVars() const { return m_numVars; }
unsigned numCalleeLocals() const { return m_numCalleeLocals; }
unsigned numVars() const { return m_numVars; }

// Jump Tables

@@ -366,9 +366,9 @@ class UnlinkedCodeBlock : public JSCell {
unsigned m_lineCount { 0 };
unsigned m_endColumn { UINT_MAX };

int m_numVars { 0 };
int m_numCalleeLocals { 0 };
int m_numParameters { 0 };
unsigned m_numVars { 0 };
unsigned m_numCalleeLocals { 0 };
unsigned m_numParameters { 0 };

PackedRefPtr<StringImpl> m_sourceURLDirective;
PackedRefPtr<StringImpl> m_sourceMappingURLDirective;
@@ -58,8 +58,8 @@ class UnlinkedCodeBlockGenerator {
EvalContextType evalContextType() const { return m_codeBlock->evalContextType(); }
bool isArrowFunctionContext() const { return m_codeBlock->isArrowFunctionContext(); }
bool isClassContext() const { return m_codeBlock->isClassContext(); }
int numCalleeLocals() const { return m_codeBlock->m_numCalleeLocals; }
int numVars() const { return m_codeBlock->m_numVars; }
unsigned numCalleeLocals() const { return m_codeBlock->m_numCalleeLocals; }
unsigned numVars() const { return m_codeBlock->m_numVars; }
unsigned numParameters() const { return m_codeBlock->numParameters(); }
VirtualRegister thisRegister() const { return m_codeBlock->thisRegister(); }
VirtualRegister scopeRegister() const { return m_codeBlock->scopeRegister(); }
@@ -70,11 +70,11 @@ class UnlinkedCodeBlockGenerator {
// Updating UnlinkedCodeBlock.
void setHasCheckpoints() { m_codeBlock->setHasCheckpoints(); }
void setHasTailCalls() { m_codeBlock->setHasTailCalls(); }
void setNumCalleeLocals(int numCalleeLocals) { m_codeBlock->m_numCalleeLocals = numCalleeLocals; }
void setNumVars(int numVars) { m_codeBlock->m_numVars = numVars; }
void setNumCalleeLocals(unsigned numCalleeLocals) { m_codeBlock->m_numCalleeLocals = numCalleeLocals; }
void setNumVars(unsigned numVars) { m_codeBlock->m_numVars = numVars; }
void setThisRegister(VirtualRegister thisRegister) { m_codeBlock->setThisRegister(thisRegister); }
void setScopeRegister(VirtualRegister thisRegister) { m_codeBlock->setScopeRegister(thisRegister); }
void setNumParameters(int newValue) { m_codeBlock->setNumParameters(newValue); }
void setNumParameters(unsigned newValue) { m_codeBlock->setNumParameters(newValue); }

UnlinkedMetadataTable& metadata() { return m_codeBlock->metadata(); }
void addExpressionInfo(unsigned instructionOffset, int divot, int startOffset, int endOffset, unsigned line, unsigned column);
@@ -283,7 +283,7 @@ ParserError BytecodeGenerator::generate()
if (m_isAsync)
performGeneratorification(*this, m_codeBlock.get(), m_writer, m_generatorFrameSymbolTable.get(), m_generatorFrameSymbolTableIndex);

RELEASE_ASSERT(static_cast<unsigned>(m_codeBlock->numCalleeLocals()) < static_cast<unsigned>(FirstConstantRegisterIndex));
RELEASE_ASSERT(m_codeBlock->numCalleeLocals() < static_cast<unsigned>(FirstConstantRegisterIndex));
m_codeBlock->finalize(m_writer.finalize());
if (m_expressionTooDeep)
return ParserError(ParserError::OutOfMemory);
@@ -4000,7 +4000,7 @@ void BytecodeGenerator::emitPushFunctionNameScope(const Identifier& property, Re
addResult.iterator->value.setIsConst(); // The function name scope name acts like a const variable.
unsigned numVars = m_codeBlock->numVars();
pushLexicalScopeInternal(nameScopeEnvironment, TDZCheckOptimization::Optimize, NestedScopeType::IsNotNested, nullptr, TDZRequirement::NotUnderTDZ, ScopeType::FunctionNameScope, ScopeRegisterType::Var);
ASSERT_UNUSED(numVars, m_codeBlock->numVars() == static_cast<int>(numVars + 1)); // Should have only created one new "var" for the function name scope.
ASSERT_UNUSED(numVars, m_codeBlock->numVars() == numVars + 1); // Should have only created one new "var" for the function name scope.
bool shouldTreatAsLexicalVariable = ecmaMode().isStrict();
Variable functionVar = variableForLocalEntry(property, m_lexicalScopeStack.last().m_symbolTable->get(NoLockingNecessary, property.impl()), m_lexicalScopeStack.last().m_symbolTableConstantIndex, shouldTreatAsLexicalVariable);
emitPutToScope(m_lexicalScopeStack.last().m_scope, functionVar, callee, ThrowIfNotFound, InitializationMode::NotInitialization);
@@ -161,9 +161,10 @@ template<typename Traits>
RegisterID* BytecodeGeneratorBase<Traits>::newRegister()
{
m_calleeLocals.append(virtualRegisterForLocal(m_calleeLocals.size()));
int numCalleeLocals = std::max<int>(m_codeBlock->numCalleeLocals(), m_calleeLocals.size());
size_t numCalleeLocals = std::max<size_t>(m_codeBlock->numCalleeLocals(), m_calleeLocals.size());
numCalleeLocals = WTF::roundUpToMultipleOf(stackAlignmentRegisters(), numCalleeLocals);
m_codeBlock->setNumCalleeLocals(numCalleeLocals);
m_codeBlock->setNumCalleeLocals(static_cast<unsigned>(numCalleeLocals));
RELEASE_ASSERT(numCalleeLocals == m_codeBlock->numCalleeLocals());
return &m_calleeLocals.last();
}

@@ -3469,7 +3469,7 @@ RegisterID* ShortCircuitReadModifyResolveNode::emitBytecode(BytecodeGenerator& g
Ref<Label> afterAssignment = generator.newLabel();
emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());

result = generator.emitNode(result.get(), m_right); // Execute side effects first.
generator.emitNode(result.get(), m_right); // Execute side effects first.
bool threwException = generator.emitReadOnlyExceptionIfNeeded(var);

if (!threwException)
@@ -3486,7 +3486,7 @@ RegisterID* ShortCircuitReadModifyResolveNode::emitBytecode(BytecodeGenerator& g
Ref<Label> afterAssignment = generator.newLabel();
emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());

result = generator.emitNode(result.get(), m_right);
generator.emitNode(result.get(), m_right);
generator.move(local.get(), result.get());
generator.emitProfileType(result.get(), var, divotStart(), divotEnd());

@@ -3499,7 +3499,7 @@ RegisterID* ShortCircuitReadModifyResolveNode::emitBytecode(BytecodeGenerator& g
Ref<Label> afterAssignment = generator.newLabel();
emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());

result = generator.emitNode(result.get(), m_right);
generator.emitNode(result.get(), m_right);
generator.emitProfileType(result.get(), var, divotStart(), divotEnd());

generator.emitLabel(afterAssignment.get());
@@ -3509,26 +3509,28 @@ RegisterID* ShortCircuitReadModifyResolveNode::emitBytecode(BytecodeGenerator& g
generator.emitExpressionInfo(newDivot, divotStart(), newDivot);
RefPtr<RegisterID> scope = generator.emitResolveScope(nullptr, var);

RefPtr<RegisterID> result = generator.emitGetFromScope(generator.tempDestination(dst), scope.get(), var, ThrowIfNotFound);
generator.emitTDZCheckIfNecessary(var, result.get(), nullptr);
RefPtr<RegisterID> uncheckedResult = generator.newTemporary();

generator.emitGetFromScope(uncheckedResult.get(), scope.get(), var, ThrowIfNotFound);
generator.emitTDZCheckIfNecessary(var, uncheckedResult.get(), nullptr);

Ref<Label> afterAssignment = generator.newLabel();
emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());
emitShortCircuitAssignment(generator, uncheckedResult.get(), m_operator, afterAssignment.get());

generator.emitNode(result.get(), m_right); // Execute side effects first.
generator.emitNode(uncheckedResult.get(), m_right); // Execute side effects first.

bool threwException = isReadOnly ? generator.emitReadOnlyExceptionIfNeeded(var) : false;

if (!threwException)
generator.emitExpressionInfo(divot(), divotStart(), divotEnd());

if (!isReadOnly) {
result = generator.emitPutToScope(scope.get(), var, result.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
generator.emitProfileType(result.get(), var, divotStart(), divotEnd());
generator.emitPutToScope(scope.get(), var, uncheckedResult.get(), ThrowIfNotFound, InitializationMode::NotInitialization);
generator.emitProfileType(uncheckedResult.get(), var, divotStart(), divotEnd());
}

generator.emitLabel(afterAssignment.get());
return generator.move(dst, result.get());
return generator.move(generator.finalDestination(dst, uncheckedResult.get()), uncheckedResult.get());
}

// ------------------------------ AssignResolveNode -----------------------------------
@@ -3642,24 +3644,24 @@ RegisterID* ShortCircuitReadModifyDotNode::emitBytecode(BytecodeGenerator& gener
RefPtr<RegisterID> base = generator.emitNodeForLeftHandSide(m_base, m_rightHasAssignments, m_right->isPure(generator));
RefPtr<RegisterID> thisValue;

RefPtr<RegisterID> result;
RefPtr<RegisterID> result = generator.tempDestination(dst);

generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
if (m_base->isSuperNode()) {
thisValue = generator.ensureThis();
result = generator.emitGetById(generator.tempDestination(dst), base.get(), thisValue.get(), m_ident);
generator.emitGetById(result.get(), base.get(), thisValue.get(), m_ident);
} else
result = generator.emitGetById(generator.tempDestination(dst), base.get(), m_ident);
generator.emitGetById(result.get(), base.get(), m_ident);

Ref<Label> afterAssignment = generator.newLabel();
emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());

result = generator.emitNode(result.get(), m_right);
generator.emitNode(result.get(), m_right);
generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
if (m_base->isSuperNode())
result = generator.emitPutById(base.get(), thisValue.get(), m_ident, result.get());
generator.emitPutById(base.get(), thisValue.get(), m_ident, result.get());
else
result = generator.emitPutById(base.get(), m_ident, result.get());
generator.emitPutById(base.get(), m_ident, result.get());
generator.emitProfileType(result.get(), divotStart(), divotEnd());

generator.emitLabel(afterAssignment.get());
@@ -3738,24 +3740,24 @@ RegisterID* ShortCircuitReadModifyBracketNode::emitBytecode(BytecodeGenerator& g
RefPtr<RegisterID> property = generator.emitNodeForLeftHandSideForProperty(m_subscript, m_rightHasAssignments, m_right->isPure(generator));
RefPtr<RegisterID> thisValue;

RefPtr<RegisterID> result;
RefPtr<RegisterID> result = generator.tempDestination(dst);

generator.emitExpressionInfo(subexpressionDivot(), subexpressionStart(), subexpressionEnd());
if (m_base->isSuperNode()) {
thisValue = generator.ensureThis();
result = generator.emitGetByVal(generator.tempDestination(dst), base.get(), thisValue.get(), property.get());
generator.emitGetByVal(result.get(), base.get(), thisValue.get(), property.get());
} else
result = generator.emitGetByVal(generator.tempDestination(dst), base.get(), property.get());
generator.emitGetByVal(result.get(), base.get(), property.get());

Ref<Label> afterAssignment = generator.newLabel();
emitShortCircuitAssignment(generator, result.get(), m_operator, afterAssignment.get());

result = generator.emitNode(result.get(), m_right);
generator.emitNode(result.get(), m_right);
generator.emitExpressionInfo(divot(), divotStart(), divotEnd());
if (m_base->isSuperNode())
result = generator.emitPutByVal(base.get(), thisValue.get(), property.get(), result.get());
generator.emitPutByVal(base.get(), thisValue.get(), property.get(), result.get());
else
result = generator.emitPutByVal(base.get(), property.get(), result.get());
generator.emitPutByVal(base.get(), property.get(), result.get());
generator.emitProfileType(result.get(), divotStart(), divotEnd());

generator.emitLabel(afterAssignment.get());