Skip to content
Permalink
Browse files
Verify the contents of AssemblerBuffer on arm64e
https://bugs.webkit.org/show_bug.cgi?id=190057
<rdar://problem/38916630>

Reviewed by Mark Lam.

JSTests:

* stress/regress-189132.js:

Source/JavaScriptCore:

* assembler/ARM64Assembler.h:
(JSC::ARM64Assembler::ARM64Assembler):
(JSC::ARM64Assembler::fillNops):
(JSC::ARM64Assembler::link):
(JSC::ARM64Assembler::linkJumpOrCall):
(JSC::ARM64Assembler::linkCompareAndBranch):
(JSC::ARM64Assembler::linkConditionalBranch):
(JSC::ARM64Assembler::linkTestAndBranch):
(JSC::ARM64Assembler::unlinkedCode): Deleted.
* assembler/ARMAssembler.h:
(JSC::ARMAssembler::fillNops):
* assembler/ARMv7Assembler.h:
(JSC::ARMv7Assembler::unlinkedCode): Deleted.
* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::emitNops):
(JSC::AbstractMacroAssembler::AbstractMacroAssembler):
* assembler/AssemblerBuffer.h:
(JSC::ARM64EHash::ARM64EHash):
(JSC::ARM64EHash::update):
(JSC::ARM64EHash::hash const):
(JSC::ARM64EHash::randomSeed const):
(JSC::AssemblerBuffer::AssemblerBuffer):
(JSC::AssemblerBuffer::putShort):
(JSC::AssemblerBuffer::putIntUnchecked):
(JSC::AssemblerBuffer::putInt):
(JSC::AssemblerBuffer::hash const):
(JSC::AssemblerBuffer::data const):
(JSC::AssemblerBuffer::putIntegralUnchecked):
(JSC::AssemblerBuffer::append): Deleted.
* assembler/LinkBuffer.cpp:
(JSC::LinkBuffer::copyCompactAndLinkCode):
* assembler/MIPSAssembler.h:
(JSC::MIPSAssembler::fillNops):
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::jumpsToLink):
(JSC::MacroAssemblerARM64::link):
(JSC::MacroAssemblerARM64::unlinkedCode): Deleted.
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::jumpsToLink):
(JSC::MacroAssemblerARMv7::unlinkedCode): Deleted.
* assembler/X86Assembler.h:
(JSC::X86Assembler::fillNops):

Source/WTF:

* wtf/PtrTag.h:
(WTF::tagInt):


Canonical link: https://commits.webkit.org/205025@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236589 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Saam Barati committed Sep 28, 2018
1 parent d85ae68 commit a190853078db354853acfb767b3ffca16cf4e3ac
@@ -1,3 +1,13 @@
2018-09-27 Saam barati <sbarati@apple.com>

Verify the contents of AssemblerBuffer on arm64e
https://bugs.webkit.org/show_bug.cgi?id=190057
<rdar://problem/38916630>

Reviewed by Mark Lam.

* stress/regress-189132.js:

2018-09-27 Dominik Infuehr <dinfuehr@igalia.com>

Disable test without LLInt on ARMv7
@@ -1,3 +1,5 @@
//@ skip if $memoryLimited

try {
var a0 = '\ud801';
var a1 = [];
@@ -1,3 +1,54 @@
2018-09-27 Saam barati <sbarati@apple.com>

Verify the contents of AssemblerBuffer on arm64e
https://bugs.webkit.org/show_bug.cgi?id=190057
<rdar://problem/38916630>

Reviewed by Mark Lam.

* assembler/ARM64Assembler.h:
(JSC::ARM64Assembler::ARM64Assembler):
(JSC::ARM64Assembler::fillNops):
(JSC::ARM64Assembler::link):
(JSC::ARM64Assembler::linkJumpOrCall):
(JSC::ARM64Assembler::linkCompareAndBranch):
(JSC::ARM64Assembler::linkConditionalBranch):
(JSC::ARM64Assembler::linkTestAndBranch):
(JSC::ARM64Assembler::unlinkedCode): Deleted.
* assembler/ARMAssembler.h:
(JSC::ARMAssembler::fillNops):
* assembler/ARMv7Assembler.h:
(JSC::ARMv7Assembler::unlinkedCode): Deleted.
* assembler/AbstractMacroAssembler.h:
(JSC::AbstractMacroAssembler::emitNops):
(JSC::AbstractMacroAssembler::AbstractMacroAssembler):
* assembler/AssemblerBuffer.h:
(JSC::ARM64EHash::ARM64EHash):
(JSC::ARM64EHash::update):
(JSC::ARM64EHash::hash const):
(JSC::ARM64EHash::randomSeed const):
(JSC::AssemblerBuffer::AssemblerBuffer):
(JSC::AssemblerBuffer::putShort):
(JSC::AssemblerBuffer::putIntUnchecked):
(JSC::AssemblerBuffer::putInt):
(JSC::AssemblerBuffer::hash const):
(JSC::AssemblerBuffer::data const):
(JSC::AssemblerBuffer::putIntegralUnchecked):
(JSC::AssemblerBuffer::append): Deleted.
* assembler/LinkBuffer.cpp:
(JSC::LinkBuffer::copyCompactAndLinkCode):
* assembler/MIPSAssembler.h:
(JSC::MIPSAssembler::fillNops):
* assembler/MacroAssemblerARM64.h:
(JSC::MacroAssemblerARM64::jumpsToLink):
(JSC::MacroAssemblerARM64::link):
(JSC::MacroAssemblerARM64::unlinkedCode): Deleted.
* assembler/MacroAssemblerARMv7.h:
(JSC::MacroAssemblerARMv7::jumpsToLink):
(JSC::MacroAssemblerARMv7::unlinkedCode): Deleted.
* assembler/X86Assembler.h:
(JSC::X86Assembler::fillNops):

2018-09-27 Mark Lam <mark.lam@apple.com>

ByValInfo should not use integer offsets.
@@ -322,9 +322,17 @@ class ARM64Assembler {
static constexpr bool isZr(RegisterID reg) { return ARM64Registers::isZr(reg); }

public:
ARM64Assembler()
ARM64Assembler(
#if CPU(ARM64E)
unsigned randomNumber
#endif
)
: m_indexOfLastWatchpoint(INT_MIN)
, m_indexOfTailOfLastWatchpoint(INT_MIN)
#if CPU(ARM64E)
, m_buffer(randomNumber)
#endif

{
}

@@ -1558,17 +1566,15 @@ class ARM64Assembler {
insn(nopPseudo());
}

static void fillNops(void* base, size_t size, bool isCopyingToExecutableMemory)
template <typename CopyFunction>
static void fillNops(void* base, size_t size, CopyFunction copy)
{
RELEASE_ASSERT(!(size % sizeof(int32_t)));
size_t n = size / sizeof(int32_t);
for (int32_t* ptr = static_cast<int32_t*>(base); n--;) {
int insn = nopPseudo();
if (isCopyingToExecutableMemory) {
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(ptr) == ptr);
performJITMemcpy(ptr++, &insn, sizeof(int));
} else
memcpy(ptr++, &insn, sizeof(int));
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(ptr) == ptr);
copy(ptr++, &insn, sizeof(int));
}
}

@@ -2573,7 +2579,6 @@ class ARM64Assembler {
return b.m_offset - a.m_offset;
}

void* unlinkedCode() { return m_buffer.data(); }
size_t codeSize() const { return m_buffer.codeSize(); }

static unsigned getCallReturnOffset(AssemblerLabel call)
@@ -2611,13 +2616,6 @@ class ARM64Assembler {
m_jumpsToLink.append(LinkRecord(from.m_offset, to.m_offset, type, condition, bitNumber, compareRegister));
}

void linkJump(AssemblerLabel from, void* executableCode, AssemblerLabel to)
{
ASSERT(from.isSet());
ASSERT(to.isSet());
relinkJumpOrCall<false>(addressOf(from), addressOf(executableCode, from), addressOf(to));
}

static void linkJump(void* code, AssemblerLabel from, void* to)
{
ASSERT(from.isSet());
@@ -2977,30 +2975,32 @@ class ARM64Assembler {
return m_jumpsToLink;
}

static void ALWAYS_INLINE link(LinkRecord& record, uint8_t* from, const uint8_t* fromInstruction8, uint8_t* to)
typedef void* (*CopyFunction)(void*, const void*, size_t);

static void ALWAYS_INLINE link(LinkRecord& record, uint8_t* from, const uint8_t* fromInstruction8, uint8_t* to, CopyFunction copy)
{
const int* fromInstruction = reinterpret_cast<const int*>(fromInstruction8);
switch (record.linkType()) {
case LinkJumpNoCondition:
linkJumpOrCall<false>(reinterpret_cast<int*>(from), fromInstruction, to);
linkJumpOrCall<false>(reinterpret_cast<int*>(from), fromInstruction, to, copy);
break;
case LinkJumpConditionDirect:
linkConditionalBranch<true>(record.condition(), reinterpret_cast<int*>(from), fromInstruction, to);
linkConditionalBranch<true>(record.condition(), reinterpret_cast<int*>(from), fromInstruction, to, copy);
break;
case LinkJumpCondition:
linkConditionalBranch<false>(record.condition(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to);
linkConditionalBranch<false>(record.condition(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to, copy);
break;
case LinkJumpCompareAndBranchDirect:
linkCompareAndBranch<true>(record.condition(), record.is64Bit(), record.compareRegister(), reinterpret_cast<int*>(from), fromInstruction, to);
linkCompareAndBranch<true>(record.condition(), record.is64Bit(), record.compareRegister(), reinterpret_cast<int*>(from), fromInstruction, to, copy);
break;
case LinkJumpCompareAndBranch:
linkCompareAndBranch<false>(record.condition(), record.is64Bit(), record.compareRegister(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to);
linkCompareAndBranch<false>(record.condition(), record.is64Bit(), record.compareRegister(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to, copy);
break;
case LinkJumpTestBitDirect:
linkTestAndBranch<true>(record.condition(), record.bitNumber(), record.compareRegister(), reinterpret_cast<int*>(from), fromInstruction, to);
linkTestAndBranch<true>(record.condition(), record.bitNumber(), record.compareRegister(), reinterpret_cast<int*>(from), fromInstruction, to, copy);
break;
case LinkJumpTestBit:
linkTestAndBranch<false>(record.condition(), record.bitNumber(), record.compareRegister(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to);
linkTestAndBranch<false>(record.condition(), record.bitNumber(), record.compareRegister(), reinterpret_cast<int*>(from) - 1, fromInstruction - 1, to, copy);
break;
default:
ASSERT_NOT_REACHED();
@@ -3042,7 +3042,7 @@ class ARM64Assembler {
}

template<bool isCall>
static void linkJumpOrCall(int* from, const int* fromInstruction, void* to)
static void linkJumpOrCall(int* from, const int* fromInstruction, void* to, CopyFunction copy = performJITMemcpy)
{
bool link;
int imm26;
@@ -3059,11 +3059,11 @@ class ARM64Assembler {

int insn = unconditionalBranchImmediate(isCall, static_cast<int>(offset));
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
performJITMemcpy(from, &insn, sizeof(int));
copy(from, &insn, sizeof(int));
}

template<bool isDirect>
static void linkCompareAndBranch(Condition condition, bool is64Bit, RegisterID rt, int* from, const int* fromInstruction, void* to)
static void linkCompareAndBranch(Condition condition, bool is64Bit, RegisterID rt, int* from, const int* fromInstruction, void* to, CopyFunction copy = performJITMemcpy)
{
ASSERT(!(reinterpret_cast<intptr_t>(from) & 3));
ASSERT(!(reinterpret_cast<intptr_t>(to) & 3));
@@ -3076,22 +3076,22 @@ class ARM64Assembler {
if (useDirect || isDirect) {
int insn = compareAndBranchImmediate(is64Bit ? Datasize_64 : Datasize_32, condition == ConditionNE, static_cast<int>(offset), rt);
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
performJITMemcpy(from, &insn, sizeof(int));
copy(from, &insn, sizeof(int));
if (!isDirect) {
insn = nopPseudo();
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from + 1) == (from + 1));
performJITMemcpy(from + 1, &insn, sizeof(int));
copy(from + 1, &insn, sizeof(int));
}
} else {
int insn = compareAndBranchImmediate(is64Bit ? Datasize_64 : Datasize_32, invert(condition) == ConditionNE, 2, rt);
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
performJITMemcpy(from, &insn, sizeof(int));
linkJumpOrCall<false>(from + 1, fromInstruction + 1, to);
copy(from, &insn, sizeof(int));
linkJumpOrCall<false>(from + 1, fromInstruction + 1, to, copy);
}
}

template<bool isDirect>
static void linkConditionalBranch(Condition condition, int* from, const int* fromInstruction, void* to)
static void linkConditionalBranch(Condition condition, int* from, const int* fromInstruction, void* to, CopyFunction copy = performJITMemcpy)
{
ASSERT(!(reinterpret_cast<intptr_t>(from) & 3));
ASSERT(!(reinterpret_cast<intptr_t>(to) & 3));
@@ -3104,22 +3104,22 @@ class ARM64Assembler {
if (useDirect || isDirect) {
int insn = conditionalBranchImmediate(static_cast<int>(offset), condition);
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
performJITMemcpy(from, &insn, sizeof(int));
copy(from, &insn, sizeof(int));
if (!isDirect) {
insn = nopPseudo();
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from + 1) == (from + 1));
performJITMemcpy(from + 1, &insn, sizeof(int));
copy(from + 1, &insn, sizeof(int));
}
} else {
int insn = conditionalBranchImmediate(2, invert(condition));
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
performJITMemcpy(from, &insn, sizeof(int));
linkJumpOrCall<false>(from + 1, fromInstruction + 1, to);
copy(from, &insn, sizeof(int));
linkJumpOrCall<false>(from + 1, fromInstruction + 1, to, copy);
}
}

template<bool isDirect>
static void linkTestAndBranch(Condition condition, unsigned bitNumber, RegisterID rt, int* from, const int* fromInstruction, void* to)
static void linkTestAndBranch(Condition condition, unsigned bitNumber, RegisterID rt, int* from, const int* fromInstruction, void* to, CopyFunction copy = performJITMemcpy)
{
ASSERT(!(reinterpret_cast<intptr_t>(from) & 3));
ASSERT(!(reinterpret_cast<intptr_t>(to) & 3));
@@ -3133,17 +3133,17 @@ class ARM64Assembler {
if (useDirect || isDirect) {
int insn = testAndBranchImmediate(condition == ConditionNE, static_cast<int>(bitNumber), static_cast<int>(offset), rt);
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
performJITMemcpy(from, &insn, sizeof(int));
copy(from, &insn, sizeof(int));
if (!isDirect) {
insn = nopPseudo();
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from + 1) == (from + 1));
performJITMemcpy(from + 1, &insn, sizeof(int));
copy(from + 1, &insn, sizeof(int));
}
} else {
int insn = testAndBranchImmediate(invert(condition) == ConditionNE, static_cast<int>(bitNumber), 2, rt);
RELEASE_ASSERT(roundUpToMultipleOf<instructionSize>(from) == from);
performJITMemcpy(from, &insn, sizeof(int));
linkJumpOrCall<false>(from + 1, fromInstruction + 1, to);
copy(from, &insn, sizeof(int));
linkJumpOrCall<false>(from + 1, fromInstruction + 1, to, copy);
}
}

@@ -3201,11 +3201,6 @@ class ARM64Assembler {
return reinterpret_cast<int*>(static_cast<char*>(code) + label.m_offset);
}

int* addressOf(AssemblerLabel label)
{
return addressOf(m_buffer.data(), label);
}

static RegisterID disassembleXOrSp(int reg) { return reg == 31 ? ARM64Registers::sp : static_cast<RegisterID>(reg); }
static RegisterID disassembleXOrZr(int reg) { return reg == 31 ? ARM64Registers::zr : static_cast<RegisterID>(reg); }
static RegisterID disassembleXOrZrOrSp(bool useZr, int reg) { return reg == 31 ? (useZr ? ARM64Registers::zr : ARM64Registers::sp) : static_cast<RegisterID>(reg); }
@@ -3781,10 +3776,10 @@ class ARM64Assembler {
#endif
}

AssemblerBuffer m_buffer;
Vector<LinkRecord, 0, UnsafeVectorOverflow> m_jumpsToLink;
int m_indexOfLastWatchpoint;
int m_indexOfTailOfLastWatchpoint;
AssemblerBuffer m_buffer;

public:
static constexpr ptrdiff_t MAX_POINTER_BITS = 48;
@@ -752,9 +752,10 @@ namespace JSC {
m_buffer.putInt(NOP);
}

static void fillNops(void* base, size_t size, bool isCopyingToExecutableMemory)
template <typename CopyFunction>
static void fillNops(void* base, size_t size, CopyFunction copy)
{
UNUSED_PARAM(isCopyingToExecutableMemory);
UNUSED_PARAM(copy);
RELEASE_ASSERT(!(size % sizeof(int32_t)));

int32_t* ptr = static_cast<int32_t*>(base);
@@ -2057,18 +2057,16 @@ class ARMv7Assembler {
return OP_NOP_T2a | (OP_NOP_T2b << 16);
}

static void fillNops(void* base, size_t size, bool isCopyingToExecutableMemory)
template <typename CopyFunction>
static void fillNops(void* base, size_t size, CopyFunction copy)
{
RELEASE_ASSERT(!(size % sizeof(int16_t)));

char* ptr = static_cast<char*>(base);
const size_t num32s = size / sizeof(int32_t);
for (size_t i = 0; i < num32s; i++) {
const int32_t insn = nopPseudo32();
if (isCopyingToExecutableMemory)
performJITMemcpy(ptr, &insn, sizeof(int32_t));
else
memcpy(ptr, &insn, sizeof(int32_t));
copy(ptr, &insn, sizeof(int32_t));
ptr += sizeof(int32_t);
}

@@ -2077,10 +2075,7 @@ class ARMv7Assembler {
ASSERT(num16s * sizeof(int16_t) + num32s * sizeof(int32_t) == size);
if (num16s) {
const int16_t insn = nopPseudo16();
if (isCopyingToExecutableMemory)
performJITMemcpy(ptr, &insn, sizeof(int16_t));
else
memcpy(ptr, &insn, sizeof(int16_t));
copy(ptr, &insn, sizeof(int16_t));
}
}

@@ -2247,7 +2242,6 @@ class ARMv7Assembler {
}
}

void* unlinkedCode() { return m_formatter.data(); }
size_t codeSize() const { return m_formatter.codeSize(); }

static unsigned getCallReturnOffset(AssemblerLabel call)

0 comments on commit a190853

Please sign in to comment.