Bug 1329019 - Baldr: Split CallSiteAndTarget into CallSite and CallSiteTarget (r=lth)

MozReview-Commit-ID: 8pBMZHnHcIf
This commit is contained in:
Luke Wagner 2017-09-22 11:05:25 -05:00
parent bbe32a26fd
commit 65f6c844dc
3 changed files with 87 additions and 48 deletions

View File

@ -807,7 +807,8 @@ namespace jit {
// The base class of all Assemblers for all archs.
class AssemblerShared
{
wasm::CallSiteAndTargetVector callSites_;
wasm::CallSiteVector callSites_;
wasm::CallSiteTargetVector callSiteTargets_;
wasm::CallFarJumpVector callFarJumps_;
wasm::TrapSiteVector trapSites_;
wasm::TrapFarJumpVector trapFarJumps_;
@ -843,31 +844,48 @@ class AssemblerShared
}
template <typename... Args>
void append(const wasm::CallSiteDesc& desc, CodeOffset retAddr, Args&&... args)
{
wasm::CallSite cs(desc, retAddr.offset());
enoughMemory_ &= callSites_.emplaceBack(cs, mozilla::Forward<Args>(args)...);
void append(const wasm::CallSiteDesc& desc, CodeOffset retAddr, Args&&... args) {
enoughMemory_ &= callSites_.emplaceBack(desc, retAddr.offset());
enoughMemory_ &= callSiteTargets_.emplaceBack(mozilla::Forward<Args>(args)...);
}
const wasm::CallSiteVector& callSites() const {
return callSites_;
}
const wasm::CallSiteTargetVector& callSiteTargets() const {
return callSiteTargets_;
}
wasm::CallSiteVector&& extractCallSites() {
return Move(callSites_);
}
wasm::CallSiteAndTargetVector& callSites() { return callSites_; }
void append(wasm::CallFarJump jmp) {
enoughMemory_ &= callFarJumps_.append(jmp);
}
const wasm::CallFarJumpVector& callFarJumps() const { return callFarJumps_; }
const wasm::CallFarJumpVector& callFarJumps() const {
return callFarJumps_;
}
void append(wasm::TrapSite trapSite) {
enoughMemory_ &= trapSites_.append(trapSite);
}
const wasm::TrapSiteVector& trapSites() const { return trapSites_; }
const wasm::TrapSiteVector& trapSites() const {
return trapSites_;
}
void clearTrapSites() { trapSites_.clear(); }
void append(wasm::TrapFarJump jmp) {
enoughMemory_ &= trapFarJumps_.append(jmp);
}
const wasm::TrapFarJumpVector& trapFarJumps() const { return trapFarJumps_; }
const wasm::TrapFarJumpVector& trapFarJumps() const {
return trapFarJumps_;
}
void append(wasm::MemoryAccess access) { enoughMemory_ &= memoryAccesses_.append(access); }
wasm::MemoryAccessVector&& extractMemoryAccesses() { return Move(memoryAccesses_); }
void append(wasm::MemoryAccess access) {
enoughMemory_ &= memoryAccesses_.append(access);
}
wasm::MemoryAccessVector&& extractMemoryAccesses() {
return Move(memoryAccesses_);
}
void append(const wasm::MemoryAccessDesc& access, size_t codeOffset, size_t framePushed) {
if (access.hasTrap()) {
@ -912,6 +930,9 @@ class AssemblerShared
for (; i < callSites_.length(); i++)
callSites_[i].offsetReturnAddressBy(delta);
enoughMemory_ &= callSiteTargets_.appendAll(other.callSiteTargets_);
// Nothing to offset.
MOZ_ASSERT(other.trapSites_.empty(), "should have been cleared by wasmEmitTrapOutOfLineCode");
i = callFarJumps_.length();

View File

@ -289,17 +289,19 @@ ModuleGenerator::patchCallSites()
EnumeratedArray<Trap, Trap::Limit, Maybe<uint32_t>> existingTrapFarJumps;
for (; lastPatchedCallsite_ < masm_.callSites().length(); lastPatchedCallsite_++) {
const CallSiteAndTarget& cs = masm_.callSites()[lastPatchedCallsite_];
uint32_t callerOffset = cs.returnAddressOffset();
const CallSite& callSite = masm_.callSites()[lastPatchedCallsite_];
const CallSiteTarget& target = masm_.callSiteTargets()[lastPatchedCallsite_];
uint32_t callerOffset = callSite.returnAddressOffset();
MOZ_RELEASE_ASSERT(callerOffset < INT32_MAX);
switch (cs.kind()) {
switch (callSite.kind()) {
case CallSiteDesc::Dynamic:
case CallSiteDesc::Symbolic:
break;
case CallSiteDesc::Func: {
if (funcIsCompiled(cs.funcIndex())) {
uint32_t calleeOffset = funcCodeRange(cs.funcIndex()).funcNormalEntry();
if (funcIsCompiled(target.funcIndex())) {
uint32_t calleeOffset = funcCodeRange(target.funcIndex()).funcNormalEntry();
MOZ_RELEASE_ASSERT(calleeOffset < INT32_MAX);
if (uint32_t(abs(int32_t(calleeOffset) - int32_t(callerOffset))) < JumpRange()) {
@ -308,18 +310,18 @@ ModuleGenerator::patchCallSites()
}
}
OffsetMap::AddPtr p = existingCallFarJumps.lookupForAdd(cs.funcIndex());
OffsetMap::AddPtr p = existingCallFarJumps.lookupForAdd(target.funcIndex());
if (!p) {
Offsets offsets;
offsets.begin = masm_.currentOffset();
masm_.append(CallFarJump(cs.funcIndex(), masm_.farJumpWithPatch()));
masm_.append(CallFarJump(target.funcIndex(), masm_.farJumpWithPatch()));
offsets.end = masm_.currentOffset();
if (masm_.oom())
return false;
if (!metadataTier_->codeRanges.emplaceBack(CodeRange::FarJumpIsland, offsets))
return false;
if (!existingCallFarJumps.add(p, cs.funcIndex(), offsets.begin))
if (!existingCallFarJumps.add(p, target.funcIndex(), offsets.begin))
return false;
}
@ -327,23 +329,23 @@ ModuleGenerator::patchCallSites()
break;
}
case CallSiteDesc::TrapExit: {
if (!existingTrapFarJumps[cs.trap()]) {
if (!existingTrapFarJumps[target.trap()]) {
// See MacroAssembler::wasmEmitTrapOutOfLineCode for why we must
// reload the TLS register on this path.
Offsets offsets;
offsets.begin = masm_.currentOffset();
masm_.loadPtr(Address(FramePointer, offsetof(Frame, tls)), WasmTlsReg);
masm_.append(TrapFarJump(cs.trap(), masm_.farJumpWithPatch()));
masm_.append(TrapFarJump(target.trap(), masm_.farJumpWithPatch()));
offsets.end = masm_.currentOffset();
if (masm_.oom())
return false;
if (!metadataTier_->codeRanges.emplaceBack(CodeRange::FarJumpIsland, offsets))
return false;
existingTrapFarJumps[cs.trap()] = Some(offsets.begin);
existingTrapFarJumps[target.trap()] = Some(offsets.begin);
}
masm_.patchCall(callerOffset, *existingTrapFarJumps[cs.trap()]);
masm_.patchCall(callerOffset, *existingTrapFarJumps[target.trap()]);
break;
}
case CallSiteDesc::Breakpoint:
@ -1113,11 +1115,6 @@ ModuleGenerator::generateBytecodeHash(const ShareableBytes& bytecode)
bool
ModuleGenerator::finishMetadata(const ShareableBytes& bytecode)
{
// Convert the CallSiteAndTargetVector (needed during generation) to a
// CallSiteVector (what is stored in the Module).
if (!metadataTier_->callSites.appendAll(masm_.callSites()))
return false;
// The MacroAssembler has accumulated all the memory accesses during codegen.
metadataTier_->memoryAccesses = masm_.extractMemoryAccesses();
@ -1148,6 +1145,7 @@ ModuleGenerator::finishMetadata(const ShareableBytes& bytecode)
// These Vectors can get large and the excess capacity can be significant,
// so realloc them down to size.
metadataTier_->callSites = masm_.extractCallSites();
metadataTier_->memoryAccesses.podResizeToFit();
metadataTier_->codeRanges.podResizeToFit();
metadataTier_->callSites.podResizeToFit();

View File

@ -1156,33 +1156,53 @@ class CallSite : public CallSiteDesc
WASM_DECLARE_POD_VECTOR(CallSite, CallSiteVector)
class CallSiteAndTarget : public CallSite
// A CallSiteTarget describes the callee of a CallSite, either a function or a
// trap exit. Although checked in debug builds, a CallSiteTarget doesn't
// officially know whether it targets a function or trap, relying on the Kind of
// the CallSite to discriminate.
class CallSiteTarget
{
uint32_t index_;
uint32_t packed_;
#ifdef DEBUG
enum Kind { None, FuncIndex, TrapExit } kind_;
#endif
public:
explicit CallSiteAndTarget(CallSite cs)
: CallSite(cs)
{
MOZ_ASSERT(cs.kind() != Func);
}
CallSiteAndTarget(CallSite cs, uint32_t funcIndex)
: CallSite(cs), index_(funcIndex)
{
MOZ_ASSERT(cs.kind() == Func);
}
CallSiteAndTarget(CallSite cs, Trap trap)
: CallSite(cs),
index_(uint32_t(trap))
{
MOZ_ASSERT(cs.kind() == TrapExit);
explicit CallSiteTarget()
: packed_(UINT32_MAX)
#ifdef DEBUG
, kind_(None)
#endif
{}
explicit CallSiteTarget(uint32_t funcIndex)
: packed_(funcIndex)
#ifdef DEBUG
, kind_(FuncIndex)
#endif
{}
explicit CallSiteTarget(Trap trap)
: packed_(uint32_t(trap))
#ifdef DEBUG
, kind_(TrapExit)
#endif
{}
uint32_t funcIndex() const {
MOZ_ASSERT(kind_ == FuncIndex);
return packed_;
}
uint32_t funcIndex() const { MOZ_ASSERT(kind() == Func); return index_; }
Trap trap() const { MOZ_ASSERT(kind() == TrapExit); return Trap(index_); }
Trap trap() const {
MOZ_ASSERT(kind_ == TrapExit);
MOZ_ASSERT(packed_ < uint32_t(Trap::Limit));
return Trap(packed_);
}
};
typedef Vector<CallSiteAndTarget, 0, SystemAllocPolicy> CallSiteAndTargetVector;
typedef Vector<CallSiteTarget, 0, SystemAllocPolicy> CallSiteTargetVector;
// A wasm::SymbolicAddress represents a pointer to a well-known function that is
// embedded in wasm code. Since wasm code is serialized and later deserialized