mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-16 23:05:42 +00:00
Bug 1329019 - Baldr: Split CallSiteAndTarget into CallSite and CallSiteTarget (r=lth)
MozReview-Commit-ID: 8pBMZHnHcIf
This commit is contained in:
parent
bbe32a26fd
commit
65f6c844dc
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user