import changes from `dev' branch of rmottola/Arctic-Fox:

- bug 1191326 - always initialize ProxyAccessible::mOuterDoc r=lsocks (74ed8d596)
- Bug 1156062 part 1a - New nsEditor::SplitNodeDeep variant; r=ehsan (a80d26ece)
- minor fix (c1e5c74e3)
- Bug 1172216 - Move nsStackwalk to mozglue. r=glandium (971014ffb)
- Bug 1156903: Add quirk flag that causes NPN_GetValue(NPNVdocumentOrigin) to return an empty string even when it fails; r=jimm (9508b57b1)
- Bug 554178 - Remove unused member variable PluginModuleChild::mUserAgent. r=jimm (a6fda391a)
- Bug 1203428 - E10S for device storage API r=cyu (da575f819)
- Bug 1150642 - Make mozilla_sampler_save_profile_to_file callable from lldb in Nightly builds. r=jrmuizel (bb98fafd6)
- Bug 1136834 - Stop leaking markers in ProfileBuffer. (r=mstange) (b2f5f813a)
- Bug 1148069 - Ensure synchronous sampling does not set JitcodeGlobalEntry's generation. (r=djvj) (f5a4dd6a4)
- Bug 1181348 - Fix ARM64 toggledCall() under debug mode. r=djvj (4bbbe51a4)
- Bug 1181354 - Account for initaliasedlexical in this one weird const cutout in jit::SetProperty. (r=jandem) (472179ea2)
- Bug 1181558 part 0 - Remove unused SnapshotIterator constructor. r=jandem (cae21907a)
- Bug 1181558 part 1 - Share the machine state between all SnapshotIterators of the same InlineFrameIterator. r=jandem (49e53a014)
- Bug 1177922 - Fix a bogus assert on OOM in markSafepointAt. r=nbp (cf26143e7)
- Bug 1182060 - IsObjectEscaped: Handle UnboxedPlainObject in guard shape. r=bhackett (35b6c285a)
- Bug 1183051: Fix register allocations of Atomics callouts on arm vfp; r=h4writer (42d708374)
- Bug 1138693 - Add comments and test. r=jandem (9619e8053)
- Bug 1138693 - Add an early quit to the test if TypedObject isn't enabled. r=nbp (f6b04026e)
- Bug 1180184 - Support JSOP_TOSTRING used by template strings in baseline JIT. r=jandem (8215c953b)
This commit is contained in:
2021-09-28 21:57:21 +08:00
parent 5313db75c9
commit 83aaad87df
48 changed files with 383 additions and 312 deletions
+1 -1
View File
@@ -306,7 +306,7 @@ public:
protected:
explicit ProxyAccessible(DocAccessibleParent* aThisAsDoc) :
mParent(nullptr), mDoc(aThisAsDoc), mWrapper(0), mID(0),
mRole(roles::DOCUMENT)
mRole(roles::DOCUMENT), mOuterDoc(false)
{ MOZ_COUNT_CTOR(ProxyAccessible); }
protected:
+1 -1
View File
@@ -147,7 +147,7 @@ nsCOMPtr<T>::operator=(const mozilla::dom::OwningNonNull<U>& aOther)
return operator=(aOther.get());
}
// Declared in nsRefPtr.h
// Declared in mozilla/nsRefPtr.h
template<class T> template<class U>
nsRefPtr<T>::nsRefPtr(const mozilla::dom::OwningNonNull<U>& aOther)
: nsRefPtr(aOther.get())
+11
View File
@@ -5105,6 +5105,17 @@ ContentParent::RecvEndDriverCrashGuard(const uint32_t& aGuardType)
return true;
}
bool
ContentParent::RecvGetDeviceStorageLocation(const nsString& aType,
nsString* aPath) {
#ifdef MOZ_WIDGET_ANDROID
mozilla::AndroidBridge::GetExternalPublicDirectory(aType, *aPath);
return true;
#else
return false;
#endif
}
} // namespace dom
} // namespace mozilla
+2
View File
@@ -855,6 +855,8 @@ private:
virtual bool RecvProfile(const nsCString& aProfile) override;
virtual bool RecvGetGraphicsDeviceInitData(DeviceInitData* aOut) override;
virtual bool RecvGetDeviceStorageLocation(const nsString& aType,
nsString* aPath) override;
// If you add strong pointers to cycle collected objects here, be sure to
// release these objects in ShutDownProcess. See the comment there for more
// details.
+3
View File
@@ -1068,6 +1068,9 @@ parent:
sync GetGraphicsDeviceInitData()
returns (DeviceInitData aData);
sync GetDeviceStorageLocation(nsString type)
returns (nsString path);
both:
AsyncMessage(nsString aMessage, ClonedMessageData aData,
CpowEntry[] aCpows, Principal aPrincipal);
+3 -1
View File
@@ -403,7 +403,9 @@ PluginInstanceChild::NPN_GetValue(NPNVariable aVar,
if (!CallNPN_GetValue_NPNVdocumentOrigin(&v, &result)) {
return NPERR_GENERIC_ERROR;
}
if (result == NPERR_NO_ERROR) {
if (result == NPERR_NO_ERROR ||
(GetQuirks() &
PluginModuleChild::QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN)) {
*static_cast<char**>(aValue) = ToNewCString(v);
}
return result;
+5 -2
View File
@@ -149,7 +149,7 @@ PluginModuleChild::PluginModuleChild(bool aIsChrome)
MOZ_ASSERT(!gChromeInstance);
gChromeInstance = this;
}
mUserAgent.SetIsVoid(true);
#ifdef XP_MACOSX
if (aIsChrome) {
mac_plugin_interposing::child::SetUpCocoaInterposing();
@@ -2095,15 +2095,18 @@ PluginModuleChild::InitQuirksModes(const nsCString& aMimeType)
#endif
}
#ifdef OS_WIN
if (specialType == nsPluginHost::eSpecialType_Flash) {
mQuirks |= QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN;
#ifdef OS_WIN
mQuirks |= QUIRK_WINLESS_TRACKPOPUP_HOOK;
mQuirks |= QUIRK_FLASH_THROTTLE_WMUSER_EVENTS;
mQuirks |= QUIRK_FLASH_HOOK_SETLONGPTR;
mQuirks |= QUIRK_FLASH_HOOK_GETWINDOWINFO;
mQuirks |= QUIRK_FLASH_FIXUP_MOUSE_CAPTURE;
#endif
}
#ifdef OS_WIN
// QuickTime plugin usually loaded with audio/mpeg mimetype
NS_NAMED_LITERAL_CSTRING(quicktime, "npqtplugin");
if (FindInReadable(quicktime, mPluginFilename)) {
+5 -2
View File
@@ -266,8 +266,12 @@ public:
// CGContextRef we pass to it in NPP_HandleEvent(NPCocoaEventDrawRect)
// outside of that call. See bug 804606.
QUIRK_FLASH_AVOID_CGMODE_CRASHES = 1 << 10,
// Work around a Flash bug where it fails to check the error code of a
// NPN_GetValue(NPNVdocumentOrigin) call before trying to dereference
// its char* output.
QUIRK_FLASH_RETURN_EMPTY_DOCUMENT_ORIGIN = 1 << 11,
// Win: Addresses a Unity bug with mouse capture.
QUIRK_UNITY_FIXUP_MOUSE_CAPTURE = 1 << 11,
QUIRK_UNITY_FIXUP_MOUSE_CAPTURE = 1 << 12,
};
int GetQuirks() { return mQuirks; }
@@ -303,7 +307,6 @@ private:
PRLibrary* mLibrary;
nsCString mPluginFilename; // UTF8
nsCString mUserAgent;
int mQuirks;
bool mIsChrome;
+27
View File
@@ -3802,6 +3802,33 @@ nsEditor::IsPreformatted(nsIDOMNode *aNode, bool *aResult)
// a new element, for instance, if that's why you were splitting
// the node.
//
int32_t
nsEditor::SplitNodeDeep(nsIContent& aNode, nsIContent& aSplitPointParent,
int32_t aSplitPointOffset,
EmptyContainers aEmptyContainers,
nsIContent** outLeftNode,
nsIContent** outRightNode)
{
int32_t offset;
nsCOMPtr<nsIDOMNode> leftNodeDOM, rightNodeDOM;
nsresult res = SplitNodeDeep(aNode.AsDOMNode(),
aSplitPointParent.AsDOMNode(), aSplitPointOffset, &offset,
aEmptyContainers == EmptyContainers::no, address_of(leftNodeDOM),
address_of(rightNodeDOM));
NS_ENSURE_SUCCESS(res, -1);
if (outLeftNode) {
nsCOMPtr<nsIContent> leftNode = do_QueryInterface(leftNodeDOM);
MOZ_ASSERT(!leftNodeDOM || leftNode);
leftNode.forget(outLeftNode);
}
if (outRightNode) {
nsCOMPtr<nsIContent> rightNode = do_QueryInterface(rightNodeDOM);
MOZ_ASSERT(!rightNodeDOM || rightNode);
rightNode.forget(outRightNode);
}
return offset;
}
nsresult
nsEditor::SplitNodeDeep(nsIDOMNode *aNode,
nsIDOMNode *aSplitPointParent,
+11 -7
View File
@@ -638,13 +638,17 @@ public:
nsresult IsPreformatted(nsIDOMNode *aNode, bool *aResult);
nsresult SplitNodeDeep(nsIDOMNode *aNode,
nsIDOMNode *aSplitPointParent,
int32_t aSplitPointOffset,
int32_t *outOffset,
bool aNoEmptyContainers = false,
nsCOMPtr<nsIDOMNode> *outLeftNode = 0,
nsCOMPtr<nsIDOMNode> *outRightNode = 0);
enum class EmptyContainers { no, yes };
int32_t SplitNodeDeep(nsIContent& aNode, nsIContent& aSplitPointParent,
int32_t aSplitPointOffset,
EmptyContainers aEmptyContainers =
EmptyContainers::yes,
nsIContent** outLeftNode = nullptr,
nsIContent** outRightNode = nullptr);
nsresult SplitNodeDeep(nsIDOMNode* aNode, nsIDOMNode* aSplitPointParent,
int32_t aSplitPointOffset, int32_t* outOffset, bool aNoEmptyContainers =
false, nsCOMPtr<nsIDOMNode>* outLeftNode = nullptr, nsCOMPtr<nsIDOMNode>*
outRightNode = nullptr);
::DOMPoint JoinNodeDeep(nsIContent& aLeftNode, nsIContent& aRightNode);
nsresult GetString(const nsAString& name, nsAString& value);
+9
View File
@@ -0,0 +1,9 @@
for (a of []) {}
var log = "";
(function() {
for (a of [,0]) {}
const y = "FOO";
log += y;
function inner() { log += y; }
})()
assertEq(log, "FOO");
@@ -0,0 +1,22 @@
if (!this.hasOwnProperty("TypedObject"))
quit();
var T = TypedObject;
var ST = new T.StructType({x:T.int32});
function check(v) {
return v.toSource();
}
function test() {
var fake = { toSource: ST.toSource };
try {
check(fake);
} catch (e) {}
}
test();
var uint8 = TypedObject.uint8;
function runTests() {
uint8.toSource();
}
runTests();
test();
+2 -2
View File
@@ -137,8 +137,8 @@ class BailoutFrameInfo
SnapshotOffset snapshotOffset() const {
return snapshotOffset_;
}
const MachineState machineState() const {
return machine_;
const MachineState* machineState() const {
return &machine_;
}
size_t topFrameSize() const {
return topFrameSize_;
+1 -1
View File
@@ -412,7 +412,7 @@ class SnapshotIteratorForBailout : public SnapshotIterator
public:
SnapshotIteratorForBailout(JitActivation* activation, JitFrameIterator& iter)
: SnapshotIterator(iter),
: SnapshotIterator(iter, activation->bailoutData()->machineState()),
activation_(activation),
iter_(iter)
{
+28
View File
@@ -3340,6 +3340,34 @@ BaselineCompiler::emit_JSOP_TOID()
return true;
}
typedef JSString* (*ToStringFn)(JSContext*, HandleValue);
static const VMFunction ToStringInfo = FunctionInfo<ToStringFn>(ToStringSlow);
bool
BaselineCompiler::emit_JSOP_TOSTRING()
{
// Keep top stack value in R0.
frame.popRegsAndSync(1);
// Inline path for string.
Label done;
masm.branchTestString(Assembler::Equal, R0, &done);
prepareVMCall();
pushArg(R0);
// Call ToStringSlow which doesn't handle string inputs.
if (!callVM(ToStringInfo))
return false;
masm.tagValue(JSVAL_TYPE_STRING, ReturnReg, R0);
masm.bind(&done);
frame.push(R0);
return true;
}
bool
BaselineCompiler::emit_JSOP_TABLESWITCH()
{
+1
View File
@@ -184,6 +184,7 @@ namespace jit {
_(JSOP_RUNONCE) \
_(JSOP_REST) \
_(JSOP_TOID) \
_(JSOP_TOSTRING) \
_(JSOP_TABLESWITCH) \
_(JSOP_ITER) \
_(JSOP_MOREITER) \
+9 -8
View File
@@ -410,7 +410,7 @@ class SnapshotIterator
SnapshotReader snapshot_;
RecoverReader recover_;
JitFrameLayout* fp_;
MachineState machine_;
const MachineState* machine_;
IonScript* ionScript_;
RInstructionResults* instructionResults_;
@@ -429,17 +429,17 @@ class SnapshotIterator
private:
// Read a spilled register from the machine state.
bool hasRegister(Register reg) const {
return machine_.has(reg);
return machine_->has(reg);
}
uintptr_t fromRegister(Register reg) const {
return machine_.read(reg);
return machine_->read(reg);
}
bool hasRegister(FloatRegister reg) const {
return machine_.has(reg);
return machine_->has(reg);
}
double fromRegister(FloatRegister reg) const {
return machine_.read(reg);
return machine_->read(reg);
}
// Read an uintptr_t from the stack.
@@ -550,9 +550,7 @@ class SnapshotIterator
// Connect all informations about the current script in order to recover the
// content of baseline frames.
SnapshotIterator(IonScript* ionScript, SnapshotOffset snapshotOffset,
JitFrameLayout* fp, const MachineState& machine);
explicit SnapshotIterator(const JitFrameIterator& iter);
SnapshotIterator(const JitFrameIterator& iter, const MachineState* machineState);
SnapshotIterator();
Value read() {
@@ -657,6 +655,9 @@ class InlineFrameIterator
jsbytecode* pc_;
uint32_t numActualArgs_;
// Register state, used by all snapshot iterators.
MachineState machine_;
struct Nop {
void operator()(const Value& v) { }
};
+15 -29
View File
@@ -353,12 +353,12 @@ JitFrameIterator::machineState() const
// The MachineState is used by GCs for marking call-sites.
if (MOZ_UNLIKELY(isBailoutJS()))
return activation_->bailoutData()->machineState();
return *activation_->bailoutData()->machineState();
SafepointReader reader(ionScript(), safepoint());
uintptr_t* spill = spillBase();
MachineState machine;
for (GeneralRegisterBackwardIterator iter(reader.allGprSpills()); iter.more(); iter++)
machine.setRegisterLocation(*iter, --spill);
@@ -1163,7 +1163,7 @@ MarkBailoutFrame(JSTracer* trc, const JitFrameIterator& frame)
// The vector of recover instructions is already traced as part of the
// JitActivation.
SnapshotIterator snapIter(frame);
SnapshotIterator snapIter(frame, frame.activation()->bailoutData()->machineState());
// For each instruction, we read the allocations without evaluating the
// recover instruction, nor reconstructing the frame. We are only looking at
@@ -1754,24 +1754,7 @@ RInstructionResults::trace(JSTracer* trc)
}
SnapshotIterator::SnapshotIterator(IonScript* ionScript, SnapshotOffset snapshotOffset,
JitFrameLayout* fp, const MachineState& machine)
: snapshot_(ionScript->snapshots(),
snapshotOffset,
ionScript->snapshotsRVATableSize(),
ionScript->snapshotsListSize()),
recover_(snapshot_,
ionScript->recovers(),
ionScript->recoversSize()),
fp_(fp),
machine_(machine),
ionScript_(ionScript),
instructionResults_(nullptr)
{
MOZ_ASSERT(snapshotOffset < ionScript->snapshotsListSize());
}
SnapshotIterator::SnapshotIterator(const JitFrameIterator& iter)
SnapshotIterator::SnapshotIterator(const JitFrameIterator& iter, const MachineState* machineState)
: snapshot_(iter.ionScript()->snapshots(),
iter.snapshotOffset(),
iter.ionScript()->snapshotsRVATableSize(),
@@ -1780,7 +1763,7 @@ SnapshotIterator::SnapshotIterator(const JitFrameIterator& iter)
iter.ionScript()->recovers(),
iter.ionScript()->recoversSize()),
fp_(iter.jsFrame()),
machine_(iter.machineState()),
machine_(machineState),
ionScript_(iter.ionScript()),
instructionResults_(nullptr)
{
@@ -2012,7 +1995,7 @@ SnapshotIterator::floatAllocationPointer(const RValueAllocation& alloc) const
{
switch (alloc.mode()) {
case RValueAllocation::ANY_FLOAT_REG:
return machine_.address(alloc.fpuReg());
return machine_->address(alloc.fpuReg());
case RValueAllocation::ANY_FLOAT_STACK:
return (FloatRegisters::RegisterContent*) AddressOfFrameSlot(fp_, alloc.stackOffset());
@@ -2065,7 +2048,7 @@ SnapshotIterator::writeAllocationValuePayload(const RValueAllocation& alloc, Val
break;
case RValueAllocation::TYPED_REG:
machine_.write(alloc.reg2(), payload);
machine_->write(alloc.reg2(), payload);
break;
case RValueAllocation::TYPED_STACK:
@@ -2084,7 +2067,7 @@ SnapshotIterator::writeAllocationValuePayload(const RValueAllocation& alloc, Val
#if defined(JS_NUNBOX32)
case RValueAllocation::UNTYPED_REG_REG:
case RValueAllocation::UNTYPED_STACK_REG:
machine_.write(alloc.reg2(), payload);
machine_->write(alloc.reg2(), payload);
break;
case RValueAllocation::UNTYPED_REG_STACK:
@@ -2093,7 +2076,7 @@ SnapshotIterator::writeAllocationValuePayload(const RValueAllocation& alloc, Val
break;
#elif defined(JS_PUNBOX64)
case RValueAllocation::UNTYPED_REG:
machine_.write(alloc.reg(), v.asRawBits());
machine_->write(alloc.reg(), v.asRawBits());
break;
case RValueAllocation::UNTYPED_STACK:
@@ -2203,7 +2186,8 @@ SnapshotIterator::initInstructionResults(MaybeReadFallback& fallback)
// Start a new snapshot at the beginning of the JitFrameIterator. This
// SnapshotIterator is used for evaluating the content of all recover
// instructions. The result is then saved on the JitActivation.
SnapshotIterator s(*fallback.frame);
MachineState machine = fallback.frame->machineState();
SnapshotIterator s(*fallback.frame, &machine);
if (!s.computeInstructionResults(cx, results)) {
// If the evaluation failed because of OOMs, then we discard the
@@ -2395,7 +2379,8 @@ InlineFrameIterator::InlineFrameIterator(JSContext* cx, const InlineFrameIterato
script_(cx)
{
if (frame_) {
start_ = SnapshotIterator(*frame_);
machine_ = iter->machine_;
start_ = SnapshotIterator(*frame_, &machine_);
// findNextFrame will iterate to the next frame and init. everything.
// Therefore to settle on the same frame, we report one frame less readed.
@@ -2412,7 +2397,8 @@ InlineFrameIterator::resetOn(const JitFrameIterator* iter)
frameCount_ = UINT32_MAX;
if (iter) {
start_ = SnapshotIterator(*iter);
machine_ = iter->machineState();
start_ = SnapshotIterator(*iter, &machine_);
findNextFrame();
}
}
+6 -1
View File
@@ -112,7 +112,10 @@ class RegisterDump
}
};
// Information needed to recover machine register state.
// Information needed to recover machine register state. This records the
// location of spilled register and not the content of the spilled
// registers. Thus we can safely assume that this structure is unchanged, even
// if the GC pointers mapped by this structure are relocated.
class MachineState
{
mozilla::Array<Registers::RegisterContent*, Registers::Total> regs_;
@@ -120,10 +123,12 @@ class MachineState
public:
MachineState() {
#ifndef JS_CODEGEN_NONE
for (unsigned i = 0; i < Registers::Total; i++)
regs_[i] = reinterpret_cast<Registers::RegisterContent*>(i + 0x100);
for (unsigned i = 0; i < FloatRegisters::Total; i++)
fpregs_[i] = reinterpret_cast<FloatRegisters::RegisterContent*>(i + 0x200);
#endif
}
static MachineState FromBailout(RegisterDump::GPRArray& regs, RegisterDump::FPUArray& fpregs);
+9 -1
View File
@@ -224,7 +224,7 @@ IsObjectEscaped(MInstruction* ins, JSObject* objDefault)
case MDefinition::Op_GuardShape: {
MGuardShape* guard = def->toGuardShape();
MOZ_ASSERT(!ins->isGuardShape());
if (obj->as<NativeObject>().lastProperty() != guard->shape()) {
if (obj->maybeShape() != guard->shape()) {
JitSpewDef(JitSpew_Escape, "has a non-matching guard shape\n", guard);
return true;
}
@@ -511,6 +511,8 @@ ObjectMemoryView::visitStoreFixedSlot(MStoreFixedSlot* ins)
state_->setFixedSlot(ins->slot(), ins->value());
ins->block()->insertBefore(ins->toInstruction(), state_);
} else {
// UnsafeSetReserveSlot can access baked-in slots which are guarded by
// conditions, which are not seen by the escape analysis.
MBail* bailout = MBail::New(alloc_, Bailout_Inevitable);
ins->block()->insertBefore(ins, bailout);
}
@@ -530,6 +532,8 @@ ObjectMemoryView::visitLoadFixedSlot(MLoadFixedSlot* ins)
if (state_->hasFixedSlot(ins->slot())) {
ins->replaceAllUsesWith(state_->getFixedSlot(ins->slot()));
} else {
// UnsafeGetReserveSlot can access baked-in slots which are guarded by
// conditions, which are not seen by the escape analysis.
MBail* bailout = MBail::New(alloc_, Bailout_Inevitable);
ins->block()->insertBefore(ins, bailout);
ins->replaceAllUsesWith(undefinedVal_);
@@ -572,6 +576,8 @@ ObjectMemoryView::visitStoreSlot(MStoreSlot* ins)
state_->setDynamicSlot(ins->slot(), ins->value());
ins->block()->insertBefore(ins->toInstruction(), state_);
} else {
// UnsafeSetReserveSlot can access baked-in slots which are guarded by
// conditions, which are not seen by the escape analysis.
MBail* bailout = MBail::New(alloc_, Bailout_Inevitable);
ins->block()->insertBefore(ins, bailout);
}
@@ -595,6 +601,8 @@ ObjectMemoryView::visitLoadSlot(MLoadSlot* ins)
if (state_->hasDynamicSlot(ins->slot())) {
ins->replaceAllUsesWith(state_->getDynamicSlot(ins->slot()));
} else {
// UnsafeGetReserveSlot can access baked-in slots which are guarded by
// conditions, which are not seen by the escape analysis.
MBail* bailout = MBail::New(alloc_, Bailout_Inevitable);
ins->block()->insertBefore(ins, bailout);
ins->replaceAllUsesWith(undefinedVal_);
+1 -1
View File
@@ -435,7 +435,7 @@ SetProperty(JSContext* cx, HandleObject obj, HandlePropertyName name, HandleValu
JSOp op = JSOp(*pc);
if (op == JSOP_SETALIASEDVAR) {
if (op == JSOP_SETALIASEDVAR || op == JSOP_INITALIASEDLEXICAL) {
// Aliased var assigns ignore readonly attributes on the property, as
// required for initializing 'const' closure variables.
Shape* shape = obj->as<NativeObject>().lookup(cx, name);
+10 -11
View File
@@ -659,10 +659,10 @@ LIRGeneratorARM::visitAsmJSCompareExchangeHeap(MAsmJSCompareExchangeHeap* ins)
if (byteSize(ins->accessType()) != 4 && !HasLDSTREXBHD()) {
LAsmJSCompareExchangeCallout* lir =
new(alloc()) LAsmJSCompareExchangeCallout(useRegister(ptr),
useRegister(ins->oldValue()),
useRegister(ins->newValue()));
defineFixed(lir, ins, LAllocation(AnyRegister(ReturnReg)));
new(alloc()) LAsmJSCompareExchangeCallout(useRegisterAtStart(ptr),
useRegisterAtStart(ins->oldValue()),
useRegisterAtStart(ins->newValue()));
defineReturn(lir, ins);
return;
}
@@ -680,14 +680,12 @@ LIRGeneratorARM::visitAsmJSAtomicExchangeHeap(MAsmJSAtomicExchangeHeap* ins)
MOZ_ASSERT(ins->ptr()->type() == MIRType_Int32);
MOZ_ASSERT(ins->accessType() < Scalar::Float32);
const LAllocation ptr = useRegister(ins->ptr());
const LAllocation value = useRegister(ins->value());
const LAllocation ptr = useRegisterAtStart(ins->ptr());
const LAllocation value = useRegisterAtStart(ins->value());
if (byteSize(ins->accessType()) < 4 && !HasLDSTREXBHD()) {
// Call out on ARMv6.
defineFixed(new(alloc()) LAsmJSAtomicExchangeCallout(ptr, value),
ins,
LAllocation(AnyRegister(ReturnReg)));
defineReturn(new(alloc()) LAsmJSAtomicExchangeCallout(ptr, value), ins);
return;
}
@@ -704,8 +702,9 @@ LIRGeneratorARM::visitAsmJSAtomicBinopHeap(MAsmJSAtomicBinopHeap* ins)
if (byteSize(ins->accessType()) != 4 && !HasLDSTREXBHD()) {
LAsmJSAtomicBinopCallout* lir =
new(alloc()) LAsmJSAtomicBinopCallout(useRegister(ptr), useRegister(ins->value()));
defineFixed(lir, ins, LAllocation(AnyRegister(ReturnReg)));
new(alloc()) LAsmJSAtomicBinopCallout(useRegisterAtStart(ptr),
useRegisterAtStart(ins->value()));
defineReturn(lir, ins);
return;
}
+4 -1
View File
@@ -2870,6 +2870,10 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
// Emit a BLR or NOP instruction. ToggleCall can be used to patch
// this instruction.
CodeOffsetLabel toggledCall(JitCode* target, bool enabled) {
// The returned offset must be to the first instruction generated,
// for the debugger to match offset with Baseline's pcMappingEntries_.
BufferOffset offset = nextOffset();
// TODO: Random pool insertion between instructions below is terrible.
// Unfortunately, we can't forbid pool prevention, because we're trying
// to add an entry to a pool. So as a temporary fix, just flush the pool
@@ -2879,7 +2883,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
syncStackPtr();
BufferOffset offset = nextOffset();
BufferOffset loadOffset;
{
vixl::UseScratchRegisterScope temps(this);
+1 -1
View File
@@ -1052,7 +1052,7 @@ CodeGeneratorShared::markSafepoint(LInstruction* ins)
void
CodeGeneratorShared::markSafepointAt(uint32_t offset, LInstruction* ins)
{
MOZ_ASSERT_IF(!safepointIndices_.empty(),
MOZ_ASSERT_IF(!safepointIndices_.empty() && !masm.oom(),
offset - safepointIndices_.back().displacement() >= sizeof(uint32_t));
masm.propagateOOM(safepointIndices_.append(SafepointIndex(offset, ins->safepoint())));
}
+14 -31
View File
@@ -27,7 +27,7 @@
#endif
#include "nscore.h"
#include "nsStackWalk.h"
#include "mozilla/StackWalk.h"
#include "js/HashTable.h"
#include "js/Vector.h"
@@ -117,7 +117,7 @@ static bool gIsDMDInitialized = false;
// - Indirect allocations in js::{Vector,HashSet,HashMap} -- this class serves
// as their AllocPolicy.
//
// - Other indirect allocations (e.g. NS_StackWalk) -- see the comments on
// - Other indirect allocations (e.g. MozStackWalk) -- see the comments on
// Thread::mBlockIntercepts and in replace_malloc for how these work.
//
// It would be nice if we could use the InfallibleAllocPolicy from mozalloc,
@@ -504,7 +504,7 @@ class Thread
// When true, this blocks intercepts, which allows malloc interception
// functions to themselves call malloc. (Nb: for direct calls to malloc we
// can just use InfallibleAllocPolicy::{malloc_,new_}, but we sometimes
// indirectly call vanilla malloc via functions like NS_StackWalk.)
// indirectly call vanilla malloc via functions like MozStackWalk.)
bool mBlockIntercepts;
Thread()
@@ -727,40 +727,23 @@ StackTrace::Get(Thread* aT)
MOZ_ASSERT(gStateLock->IsLocked());
MOZ_ASSERT(aT->InterceptsAreBlocked());
// On Windows, NS_StackWalk can acquire a lock from the shared library
// On Windows, MozStackWalk can acquire a lock from the shared library
// loader. Another thread might call malloc while holding that lock (when
// loading a shared library). So we can't be in gStateLock during the call
// to NS_StackWalk. For details, see
// to MozStackWalk. For details, see
// https://bugzilla.mozilla.org/show_bug.cgi?id=374829#c8
// On Linux, something similar can happen; see bug 824340.
// So let's just release it on all platforms.
nsresult rv;
StackTrace tmp;
{
AutoUnlockState unlock;
uint32_t skipFrames = 2;
rv = NS_StackWalk(StackWalkCallback, skipFrames,
gOptions->MaxFrames(), &tmp, 0, nullptr);
}
if (rv == NS_OK) {
// Handle the common case first. All is ok. Nothing to do.
} else if (rv == NS_ERROR_NOT_IMPLEMENTED || rv == NS_ERROR_FAILURE) {
tmp.mLength = 0;
} else if (rv == NS_ERROR_UNEXPECTED) {
// XXX: This |rv| only happens on Mac, and it indicates that we're handling
// a call to malloc that happened inside a mutex-handling function. Any
// attempt to create a semaphore (which can happen in printf) could
// deadlock.
//
// However, the most complex thing DMD does after Get() returns is to put
// something in a hash table, which might call
// InfallibleAllocPolicy::malloc_. I'm not yet sure if this needs special
// handling, hence the forced abort. Sorry. If you hit this, please file
// a bug and CC nnethercote.
MOZ_CRASH("unexpected case in StackTrace::Get()");
} else {
MOZ_CRASH("impossible case in StackTrace::Get()");
if (MozStackWalk(StackWalkCallback, skipFrames,
gOptions->MaxFrames(), &tmp, 0, nullptr)) {
// Handle the common case first. All is ok. Nothing to do.
} else {
tmp.mLength = 0;
}
}
StackTraceTable::AddPtr p = gStackTraceTable->lookupForAdd(&tmp);
@@ -1224,7 +1207,7 @@ replace_malloc(size_t aSize)
Thread* t = Thread::Fetch();
if (t->InterceptsAreBlocked()) {
// Intercepts are blocked, which means this must be a call to malloc
// triggered indirectly by DMD (e.g. via NS_StackWalk). Be infallible.
// triggered indirectly by DMD (e.g. via MozStackWalk). Be infallible.
return InfallibleAllocPolicy::malloc_(aSize);
}
@@ -1530,9 +1513,9 @@ Init(const malloc_table_t* aMallocTable)
// (prior to the creation of any mutexes, apparently) otherwise we can get
// hangs when getting stack traces (bug 821577). But
// StackWalkInitCriticalAddress() isn't exported from xpcom/, so instead we
// just call NS_StackWalk, because that calls StackWalkInitCriticalAddress().
// just call MozStackWalk, because that calls StackWalkInitCriticalAddress().
// See the comment above StackWalkInitCriticalAddress() for more details.
(void)NS_StackWalk(NopStackWalkCallback, /* skipFrames */ 0,
(void)MozStackWalk(NopStackWalkCallback, /* skipFrames */ 0,
/* maxFrames */ 1, nullptr, 0, nullptr);
#endif
+1 -1
View File
@@ -13,7 +13,7 @@ EXPORTS += [
SOURCES += [
'../../../mfbt/HashFunctions.cpp',
'../../../mfbt/JSONWriter.cpp',
'../../../xpcom/base/nsStackWalk.cpp',
'../../../mozglue/misc/StackWalk.cpp',
'DMD.cpp',
]
@@ -9,9 +9,6 @@
#include "mozilla/Assertions.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/StackWalk.h"
#include "nsStackWalkPrivate.h"
#include "nsStackWalk.h"
#if defined(_MSC_VER) && _MSC_VER < 1900
#define snprintf _snprintf
@@ -38,16 +35,16 @@ static CriticalAddress gCriticalAddress;
#include <dlfcn.h>
#endif
#define NSSTACKWALK_SUPPORTS_MACOSX \
#define MOZ_STACKWALK_SUPPORTS_MACOSX \
(defined(XP_DARWIN) && \
(defined(__i386) || defined(__ppc__) || defined(HAVE__UNWIND_BACKTRACE)))
#define NSSTACKWALK_SUPPORTS_LINUX \
#define MOZ_STACKWALK_SUPPORTS_LINUX \
(defined(linux) && \
((defined(__GNUC__) && (defined(__i386) || defined(PPC))) || \
defined(HAVE__UNWIND_BACKTRACE)))
#if NSSTACKWALK_SUPPORTS_MACOSX
#if MOZ_STACKWALK_SUPPORTS_MACOSX
#include <pthread.h>
#include <sys/errno.h>
#ifdef MOZ_WIDGET_COCOA
@@ -110,7 +107,7 @@ my_malloc_logger(uint32_t aType,
// On Leopard dladdr returns the wrong value for "new_sem_from_pool". The
// stack shows up as having two pthread_cond_wait$UNIX2003 frames.
const char* name = "new_sem_from_pool";
NS_StackWalk(stack_callback, /* skipFrames */ 0, /* maxFrames */ 0,
MozStackWalk(stack_callback, /* skipFrames */ 0, /* maxFrames */ 0,
const_cast<char*>(name), 0, nullptr);
}
@@ -121,7 +118,7 @@ my_malloc_logger(uint32_t aType,
// function during NS_LogInit() ensures that we meet the first criterion, and
// running this function during the stack walking functions ensures we meet the
// second criterion.
void
MFBT_API void
StackWalkInitCriticalAddress()
{
if (gCriticalAddress.mInit) {
@@ -181,7 +178,7 @@ IsCriticalAddress(void* aPC)
// We still initialize gCriticalAddress.mInit so that this code behaves
// the same on all platforms. Otherwise a failure to init would be visible
// only on OS X.
void
MFBT_API void
StackWalkInitCriticalAddress()
{
gCriticalAddress.mInit = true;
@@ -190,15 +187,12 @@ StackWalkInitCriticalAddress()
#if defined(_WIN32) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64)) // WIN32 x86 stack walking code
#include "nscore.h"
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <malloc.h>
#include "plstr.h"
#include "mozilla/ArrayUtils.h"
#include "nspr.h"
#include <imagehlp.h>
// We need a way to know if we are building for WXP (or later), as if we are, we
// need to use the newer 64-bit APIs. API_VERSION_NUMBER seems to fit the bill.
@@ -512,8 +506,8 @@ WalkStackThread(void* aData)
* whose in memory address doesn't match its in-file address.
*/
XPCOM_API(nsresult)
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
MFBT_API bool
MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
void* aPlatformData)
{
@@ -524,7 +518,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
struct WalkStackData data;
if (!EnsureWalkThreadReady()) {
return NS_ERROR_FAILURE;
return false;
}
HANDLE currentThread = ::GetCurrentThread();
@@ -542,7 +536,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
if (data.walkCallingThread) {
PrintError("DuplicateHandle (process)");
}
return NS_ERROR_FAILURE;
return false;
}
}
if (!::DuplicateHandle(::GetCurrentProcess(),
@@ -553,7 +547,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
if (data.walkCallingThread) {
PrintError("DuplicateHandle (thread)");
}
return NS_ERROR_FAILURE;
return false;
}
data.skipFrames = aSkipFrames;
@@ -622,7 +616,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
(*aCallback)(i + 1, data.pcs[i], data.sps[i], aClosure);
}
return data.pc_count == 0 ? NS_ERROR_FAILURE : NS_OK;
return data.pc_count != 0;
}
@@ -772,8 +766,8 @@ EnsureSymInitialized()
}
XPCOM_API(nsresult)
NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
MFBT_API bool
MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails)
{
aDetails->library[0] = '\0';
aDetails->loffset = 0;
@@ -783,7 +777,7 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
aDetails->foffset = 0;
if (!EnsureSymInitialized()) {
return NS_ERROR_FAILURE;
return false;
}
HANDLE myProcess = ::GetCurrentProcess();
@@ -804,12 +798,12 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
modInfoRes = SymGetModuleInfoEspecial64(myProcess, addr, &modInfo, &lineInfo);
if (modInfoRes) {
PL_strncpyz(aDetails->library, modInfo.ModuleName,
strncpy(aDetails->library, modInfo.ModuleName,
sizeof(aDetails->library));
aDetails->loffset = (char*)aPC - (char*)modInfo.BaseOfImage;
if (lineInfo.FileName) {
PL_strncpyz(aDetails->filename, lineInfo.FileName,
strncpy(aDetails->filename, lineInfo.FileName,
sizeof(aDetails->filename));
aDetails->lineno = lineInfo.LineNumber;
}
@@ -825,23 +819,21 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
ok = SymFromAddr(myProcess, addr, &displacement, pSymbol);
if (ok) {
PL_strncpyz(aDetails->function, pSymbol->Name,
strncpy(aDetails->function, pSymbol->Name,
sizeof(aDetails->function));
aDetails->foffset = static_cast<ptrdiff_t>(displacement);
}
LeaveCriticalSection(&gDbgHelpCS); // release our lock
return NS_OK;
return true;
}
// i386 or PPC Linux stackwalking code
#elif HAVE_DLADDR && (HAVE__UNWIND_BACKTRACE || NSSTACKWALK_SUPPORTS_LINUX || NSSTACKWALK_SUPPORTS_MACOSX)
#elif HAVE_DLADDR && (HAVE__UNWIND_BACKTRACE || MOZ_STACKWALK_SUPPORTS_LINUX || MOZ_STACKWALK_SUPPORTS_MACOSX)
#include <stdlib.h>
#include <string.h>
#include "nscore.h"
#include <stdio.h>
#include "plstr.h"
// On glibc 2.1, the Dl_info api defined in <dlfcn.h> is only exposed
// if __USE_GNU is defined. I suppose its some kind of standards
@@ -868,7 +860,7 @@ void DemangleSymbol(const char* aSymbol,
char* demangled = abi::__cxa_demangle(aSymbol, 0, 0, 0);
if (demangled) {
PL_strncpyz(aBuffer, demangled, aBufLen);
strncpy(aBuffer, demangled, aBufLen);
free(demangled);
}
#endif // MOZ_DEMANGLE_SYMBOLS
@@ -884,8 +876,8 @@ void DemangleSymbol(const char* aSymbol,
extern MOZ_EXPORT void* __libc_stack_end; // from ld-linux.so
#endif
namespace mozilla {
nsresult
FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
bool
FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
uint32_t aMaxFrames, void* aClosure, void** bp,
void* aStackEnd)
{
@@ -915,7 +907,7 @@ FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
bp += 2;
#endif
if (IsCriticalAddress(pc)) {
return NS_ERROR_UNEXPECTED;
return false;
}
if (--skip < 0) {
// Assume that the SP points to the BP of the function
@@ -930,16 +922,16 @@ FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
}
bp = next;
}
return numFrames == 0 ? NS_ERROR_FAILURE : NS_OK;
return numFrames != 0;
}
}
#define X86_OR_PPC (defined(__i386) || defined(PPC) || defined(__ppc__))
#if X86_OR_PPC && (NSSTACKWALK_SUPPORTS_MACOSX || NSSTACKWALK_SUPPORTS_LINUX) // i386 or PPC Linux or Mac stackwalking code
#if X86_OR_PPC && (MOZ_STACKWALK_SUPPORTS_MACOSX || MOZ_STACKWALK_SUPPORTS_LINUX) // i386 or PPC Linux or Mac stackwalking code
XPCOM_API(nsresult)
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
MFBT_API bool
MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
void* aPlatformData)
{
@@ -975,7 +967,7 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
struct unwind_info
{
NS_WalkStackCallback callback;
MozWalkStackCallback callback;
int skip;
int maxFrames;
int numFrames;
@@ -1007,8 +999,8 @@ unwind_callback(struct _Unwind_Context* context, void* closure)
return _URC_NO_REASON;
}
XPCOM_API(nsresult)
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
MFBT_API bool
MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
void* aPlatformData)
{
@@ -1034,15 +1026,15 @@ NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
// is to make unwind_callback return something other than _URC_NO_REASON,
// which causes _Unwind_Backtrace to return a non-success code.
if (info.isCriticalAbort) {
return NS_ERROR_UNEXPECTED;
return false;
}
return info.numFrames == 0 ? NS_ERROR_FAILURE : NS_OK;
return info.numFrames != 0;
}
#endif
XPCOM_API(nsresult)
NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
bool MFBT_API
MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails)
{
aDetails->library[0] = '\0';
aDetails->loffset = 0;
@@ -1054,51 +1046,51 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
Dl_info info;
int ok = dladdr(aPC, &info);
if (!ok) {
return NS_OK;
return true;
}
PL_strncpyz(aDetails->library, info.dli_fname, sizeof(aDetails->library));
strncpy(aDetails->library, info.dli_fname, sizeof(aDetails->library));
aDetails->loffset = (char*)aPC - (char*)info.dli_fbase;
const char* symbol = info.dli_sname;
if (!symbol || symbol[0] == '\0') {
return NS_OK;
return true;
}
DemangleSymbol(symbol, aDetails->function, sizeof(aDetails->function));
if (aDetails->function[0] == '\0') {
// Just use the mangled symbol if demangling failed.
PL_strncpyz(aDetails->function, symbol, sizeof(aDetails->function));
strncpy(aDetails->function, symbol, sizeof(aDetails->function));
}
aDetails->foffset = (char*)aPC - (char*)info.dli_saddr;
return NS_OK;
return true;
}
#else // unsupported platform.
XPCOM_API(nsresult)
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
MFBT_API bool
MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
void* aPlatformData)
{
MOZ_ASSERT(!aThread);
MOZ_ASSERT(!aPlatformData);
return NS_ERROR_NOT_IMPLEMENTED;
return false;
}
namespace mozilla {
nsresult
FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
MFBT_API bool
FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
void* aClosure, void** aBp)
{
return NS_ERROR_NOT_IMPLEMENTED;
return false;
}
}
XPCOM_API(nsresult)
NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
MFBT_API bool
MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails)
{
aDetails->library[0] = '\0';
aDetails->loffset = 0;
@@ -1106,24 +1098,24 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails)
aDetails->lineno = 0;
aDetails->function[0] = '\0';
aDetails->foffset = 0;
return NS_ERROR_NOT_IMPLEMENTED;
return false;
}
#endif
XPCOM_API(void)
NS_FormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
MFBT_API void
MozFormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
uint32_t aFrameNumber, void* aPC,
const nsCodeAddressDetails* aDetails)
const MozCodeAddressDetails* aDetails)
{
NS_FormatCodeAddress(aBuffer, aBufferSize,
MozFormatCodeAddress(aBuffer, aBufferSize,
aFrameNumber, aPC, aDetails->function,
aDetails->library, aDetails->loffset,
aDetails->filename, aDetails->lineno);
}
XPCOM_API(void)
NS_FormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
MFBT_API void
MozFormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
const void* aPC, const char* aFunction,
const char* aLibrary, ptrdiff_t aLOffset,
const char* aFileName, uint32_t aLineNo)
@@ -6,20 +6,16 @@
/* API for getting a stack trace of the C/C++ stack on the current thread */
#ifndef nsStackWalk_h_
#define nsStackWalk_h_
#ifndef mozilla_StackWalk_h
#define mozilla_StackWalk_h
/* WARNING: This file is intended to be included from C or C++ files. */
#include "nscore.h"
#include "mozilla/Types.h"
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* The callback for NS_StackWalk.
* The callback for MozStackWalk.
*
* @param aFrameNumber The frame number (starts at 1, not 0).
* @param aPC The program counter value.
@@ -27,20 +23,20 @@ extern "C" {
* pointer will be pointing to when the execution returns
* to executing that at aPC. If no approximation can
* be made it will be nullptr.
* @param aClosure Extra data passed in via NS_StackWalk().
* @param aClosure Extra data passed in via MozStackWalk().
*/
typedef void
(*NS_WalkStackCallback)(uint32_t aFrameNumber, void* aPC, void* aSP,
(*MozWalkStackCallback)(uint32_t aFrameNumber, void* aPC, void* aSP,
void* aClosure);
/**
* Call aCallback for the C/C++ stack frames on the current thread, from
* the caller of NS_StackWalk to main (or above).
* the caller of MozStackWalk to main (or above).
*
* @param aCallback Callback function, called once per frame.
* @param aSkipFrames Number of initial frames to skip. 0 means that
* the first callback will be for the caller of
* NS_StackWalk.
* MozStackWalk.
* @param aMaxFrames Maximum number of frames to trace. 0 means no limit.
* @param aClosure Caller-supplied data passed through to aCallback.
* @param aThread The thread for which the stack is to be retrieved.
@@ -53,27 +49,14 @@ typedef void
* CONTEXT on Windows and should not be passed on other
* platforms.
*
* Return values:
* - NS_ERROR_NOT_IMPLEMENTED. Occurs on platforms where it is unimplemented.
*
* - NS_ERROR_UNEXPECTED. Occurs when the stack indicates that the thread
* is in a very dangerous situation (e.g., holding sem_pool_lock in Mac OS X
* pthreads code). Callers should then bail out immediately.
*
* - NS_ERROR_FAILURE. Occurs when stack walking completely failed, i.e.
* aCallback was never called.
*
* - NS_OK. Occurs when stack walking succeeded, i.e. aCallback was called at
* least once (and there was no need to exit with NS_ERROR_UNEXPECTED).
*
* May skip some stack frames due to compiler optimizations or code
* generation.
*
* Note: this (and other helper methods) will only be available when
* MOZ_STACKWALKING is defined, so any new consumers must #if based on that.
*/
XPCOM_API(nsresult)
NS_StackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
MFBT_API bool
MozStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
uint32_t aMaxFrames, void* aClosure, uintptr_t aThread,
void* aPlatformData);
@@ -99,7 +82,7 @@ typedef struct
*/
char function[256];
ptrdiff_t foffset;
} nsCodeAddressDetails;
} MozCodeAddressDetails;
/**
* For a given pointer to code, fill in the pieces of information used
@@ -108,8 +91,8 @@ typedef struct
* @param aPC The code address.
* @param aDetails A structure to be filled in with the result.
*/
XPCOM_API(nsresult)
NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails);
MFBT_API bool
MozDescribeCodeAddress(void* aPC, MozCodeAddressDetails* aDetails);
/**
* Format the information about a code address in a format suitable for
@@ -137,15 +120,15 @@ NS_DescribeCodeAddress(void* aPC, nsCodeAddressDetails* aDetails);
* @param aFileName The filename. Possibly null or the empty string.
* @param aLineNo The line number. Possibly zero.
*/
XPCOM_API(void)
NS_FormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
MFBT_API void
MozFormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
const void* aPC, const char* aFunction,
const char* aLibrary, ptrdiff_t aLOffset,
const char* aFileName, uint32_t aLineNo);
/**
* Format the information about a code address in the same fashion as
* NS_FormatCodeAddress.
* MozFormatCodeAddress.
*
* @param aBuffer A string to be filled in with the description.
* The string will always be null-terminated.
@@ -156,15 +139,27 @@ NS_FormatCodeAddress(char* aBuffer, uint32_t aBufferSize, uint32_t aFrameNumber,
* is the terminating null.
* @param aFrameNumber The frame number.
* @param aPC The code address.
* @param aDetails The value filled in by NS_DescribeCodeAddress(aPC).
* @param aDetails The value filled in by MozDescribeCodeAddress(aPC).
*/
XPCOM_API(void)
NS_FormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
MFBT_API void
MozFormatCodeAddressDetails(char* aBuffer, uint32_t aBufferSize,
uint32_t aFrameNumber, void* aPC,
const nsCodeAddressDetails* aDetails);
const MozCodeAddressDetails* aDetails);
namespace mozilla {
MFBT_API bool
FramePointerStackWalk(MozWalkStackCallback aCallback, uint32_t aSkipFrames,
uint32_t aMaxFrames, void* aClosure, void** aBp,
void* aStackEnd);
#ifdef __cplusplus
}
#endif
#endif /* !defined(nsStackWalk_h_) */
/**
* Initialize the critical sections for this platform so that we can
* abort stack walks when needed.
*/
MFBT_API void
StackWalkInitCriticalAddress(void);
#endif
+12
View File
@@ -1,6 +1,7 @@
FINAL_LIBRARY = 'mozglue'
EXPORTS.mozilla += [
'StackWalk.h',
'TimeStamp.h',
]
@@ -26,6 +27,7 @@ if CONFIG['OS_ARCH'] == 'WINNT':
SOURCES += [
'TimeStamp_windows.cpp',
]
OS_LIBS += ['dbghelp']
elif CONFIG['HAVE_CLOCK_MONOTONIC']:
SOURCES += [
'TimeStamp_posix.cpp',
@@ -37,4 +39,14 @@ elif CONFIG['OS_ARCH'] == 'Darwin':
elif CONFIG['COMPILE_ENVIRONMENT']:
error('No TimeStamp implementation on this platform. Build will not succeed')
# MOZ_STACKWALKING is defined in configure.in when the build configuration meets
# the conditions for GeckoStackWalk to work correctly.
# We exclude this file from other build configurations so that if somebody adds a
# new usage of NS_StackWalk it will cause a link error, which is better than having
# GeckoStackWalk silently return garbage at runtime.
if CONFIG['MOZ_STACKWALKING']:
SOURCES += [
'StackWalk.cpp',
]
FAIL_ON_WARNINGS = True
@@ -18,7 +18,7 @@
#include "nsContentUtils.h"
#ifdef MOZ_STACKWALKING
#include "nsStackWalk.h"
#include "mozilla/StackWalk.h"
#endif
#define TARGET_SANDBOX_EXPORT __declspec(dllexport)
@@ -63,10 +63,10 @@ StackFrameToOStringStream(uint32_t aFrameNumber, void* aPC, void* aSP,
void* aClosure)
{
std::ostringstream* stream = static_cast<std::ostringstream*>(aClosure);
nsCodeAddressDetails details;
MozCodeAddressDetails details;
char buf[1024];
NS_DescribeCodeAddress(aPC, &details);
NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
MozDescribeCodeAddress(aPC, &details);
MozFormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
*stream << std::endl << "--" << buf;
stream->flush();
}
@@ -90,7 +90,7 @@ Log(const char* aMessageType,
if (aShouldLogStackTrace) {
if (sStackTraceDepth) {
msgStream << std::endl << "Stack Trace:";
NS_StackWalk(StackFrameToOStringStream, aFramesToSkip, sStackTraceDepth,
MozStackWalk(StackFrameToOStringStream, aFramesToSkip, sStackTraceDepth,
&msgStream, 0, nullptr);
}
}
+6 -6
View File
@@ -18,7 +18,7 @@
#include "mozilla/unused.h"
#include "mozilla/dom/Exceptions.h"
#include "nsContentUtils.h"
#include "nsStackWalk.h"
#include "mozilla/StackWalk.h"
#include "nsString.h"
#include "nsThreadUtils.h"
@@ -74,10 +74,10 @@ static void SandboxPrintStackFrame(uint32_t aFrameNumber, void *aPC, void *aSP,
void *aClosure)
{
char buf[1024];
nsCodeAddressDetails details;
MozCodeAddressDetails details;
NS_DescribeCodeAddress(aPC, &details);
NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
MozDescribeCodeAddress(aPC, &details);
MozFormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
SANDBOX_LOG_ERROR("frame %s", buf);
}
@@ -87,11 +87,11 @@ SandboxLogCStack()
// Skip 3 frames: one for this module, one for the signal handler in
// libmozsandbox, and one for the signal trampoline.
//
// Warning: this might not print any stack frames. NS_StackWalk
// Warning: this might not print any stack frames. MozStackWalk
// can't walk past the signal trampoline on ARM (bug 968531), and
// x86 frame pointer walking may or may not work (bug 1082276).
NS_StackWalk(SandboxPrintStackFrame, /* skip */ 3, /* max */ 0,
MozStackWalk(SandboxPrintStackFrame, /* skip */ 3, /* max */ 0,
nullptr, 0, nullptr);
SANDBOX_LOG_ERROR("end of stack.");
}
+5 -5
View File
@@ -58,7 +58,7 @@ unsigned int _gdb_sleep_duration = 300;
#include <unistd.h>
#include "nsISupportsUtils.h"
#include "nsStackWalk.h"
#include "mozilla/StackWalk.h"
// NB: keep me up to date with the same variable in
// ipc/chromium/chrome/common/ipc_channel_posix.cc
@@ -70,10 +70,10 @@ static void PrintStackFrame(uint32_t aFrameNumber, void *aPC, void *aSP,
void *aClosure)
{
char buf[1024];
nsCodeAddressDetails details;
MozCodeAddressDetails details;
NS_DescribeCodeAddress(aPC, &details);
NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
MozDescribeCodeAddress(aPC, &details);
MozFormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
fprintf(stdout, "%s\n", buf);
fflush(stdout);
}
@@ -89,7 +89,7 @@ ah_crap_handler(int signum)
signum);
printf("Stack:\n");
NS_StackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0,
MozStackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0,
nullptr, 0, nullptr);
printf("Sleeping for %d seconds.\n",_gdb_sleep_duration);
+7
View File
@@ -38,6 +38,7 @@ bool mozilla_sampler_is_active();
void mozilla_sampler_responsiveness(TimeStamp time);
void mozilla_sampler_frame_number(int frameNumber);
const double* mozilla_sampler_get_responsiveness();
void mozilla_sampler_save();
mozilla::UniquePtr<char[]> mozilla_sampler_get_profile(float aSinceTime);
@@ -46,6 +47,12 @@ JSObject *mozilla_sampler_get_profile_data(JSContext *aCx, float aSinceTime);
void mozilla_sampler_get_profile_data_async(float aSinceTime,
mozilla::dom::Promise* aPromise);
// Make this function easily callable from a debugger in a build without
// debugging information (work around http://llvm.org/bugs/show_bug.cgi?id=22211)
extern "C" {
void mozilla_sampler_save_profile_to_file(const char* aFilename);
}
const char** mozilla_sampler_get_features();
void mozilla_sampler_get_buffer_info(uint32_t *aCurrentPosition, uint32_t *aTotalSize,
+11 -1
View File
@@ -111,11 +111,21 @@ ProfileBuffer::ProfileBuffer(int aEntrySize)
{
}
ProfileBuffer::~ProfileBuffer()
{
while (mStoredMarkers.peek()) {
delete mStoredMarkers.popHead();
}
}
// Called from signal, call only reentrant functions
void ProfileBuffer::addTag(const ProfileEntry& aTag)
{
mEntries[mWritePos++] = aTag;
if (mWritePos == mEntrySize) {
// Wrapping around may result in things referenced in the buffer (e.g.,
// JIT code addresses and markers) being incorrectly collected.
MOZ_ASSERT(mGeneration != UINT32_MAX);
mGeneration++;
mWritePos = 0;
}
@@ -134,7 +144,7 @@ void ProfileBuffer::addStoredMarker(ProfilerMarker *aStoredMarker) {
void ProfileBuffer::deleteExpiredStoredMarkers() {
// Delete markers of samples that have been overwritten due to circular
// buffer wraparound.
int generation = mGeneration;
uint32_t generation = mGeneration;
while (mStoredMarkers.peek() &&
mStoredMarkers.peek()->HasExpired(generation)) {
delete mStoredMarkers.popHead();
+2 -3
View File
@@ -250,7 +250,7 @@ protected:
char* processDynamicTag(int readPos, int* tagsConsumed, char* tagBuff);
int FindLastSampleOfThread(int aThreadId);
~ProfileBuffer() {}
~ProfileBuffer();
public:
// Circular buffer 'Keep One Slot Open' implementation for simplicity
@@ -267,7 +267,7 @@ public:
int mEntrySize;
// How many times mWritePos has wrapped around.
int mGeneration;
uint32_t mGeneration;
// Markers that marker entries in the buffer might refer to.
ProfilerMarkerLinkedList mStoredMarkers;
@@ -410,7 +410,6 @@ public:
}
uint32_t bufferGeneration() const {
MOZ_ASSERT(mBuffer->mGeneration >= 0);
return mBuffer->mGeneration;
}
+3 -3
View File
@@ -92,9 +92,9 @@ public:
void StreamJSON(SpliceableJSONWriter& aWriter, UniqueStacks& aUniqueStacks) const;
void SetGeneration(int aGenID);
void SetGeneration(uint32_t aGenID);
bool HasExpired(int aGenID) const {
bool HasExpired(uint32_t aGenID) const {
return mGenID + 2 <= aGenID;
}
@@ -105,7 +105,7 @@ private:
ProfilerMarkerPayload* mPayload;
ProfilerMarker* mNext;
float mTime;
int mGenID;
uint32_t mGenID;
};
template<typename T>
+17 -12
View File
@@ -47,9 +47,6 @@
#if defined(MOZ_PROFILING) && (defined(XP_MACOSX) || defined(XP_WIN))
#define USE_NS_STACKWALK
#endif
#ifdef USE_NS_STACKWALK
#include "nsStackWalk.h"
#endif
#if defined(XP_WIN)
typedef CONTEXT tickcontext_t;
@@ -635,7 +632,16 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
// like the native stack, the JS stack is iterated youngest-to-oldest and we
// need to iterate oldest-to-youngest when adding entries to aProfile.
uint32_t startBufferGen = aProfile.bufferGeneration();
// Synchronous sampling reports an invalid buffer generation to
// ProfilingFrameIterator to avoid incorrectly resetting the generation of
// sampled JIT entries inside the JS engine. See note below concerning 'J'
// entries.
uint32_t startBufferGen;
if (aSample->isSamplingCurrentThread) {
startBufferGen = UINT32_MAX;
} else {
startBufferGen = aProfile.bufferGeneration();
}
uint32_t jsCount = 0;
JS::ProfilingFrameIterator::Frame jsFrames[1000];
// Only walk jit stack if profiling frame iterator is turned on.
@@ -781,14 +787,13 @@ void mergeStacksIntoProfile(ThreadProfile& aProfile, TickSample* aSample, Native
}
}
MOZ_ASSERT(aProfile.bufferGeneration() >= startBufferGen);
uint32_t lapCount = aProfile.bufferGeneration() - startBufferGen;
// Update the JS runtime with the current profile sample buffer generation.
//
// Do not do this for synchronous sampling, which create their own
// ProfileBuffers.
if (!aSample->isSamplingCurrentThread && pseudoStack->mRuntime) {
MOZ_ASSERT(aProfile.bufferGeneration() >= startBufferGen);
uint32_t lapCount = aProfile.bufferGeneration() - startBufferGen;
JS::UpdateJSRuntimeProfilerSampleBufferGen(pseudoStack->mRuntime,
aProfile.bufferGeneration(),
lapCount);
@@ -823,7 +828,7 @@ void TableTicker::doNativeBacktrace(ThreadProfile &aProfile, TickSample* aSample
};
// Start with the current function. We use 0 as the frame number here because
// the FramePointerStackWalk() and NS_StackWalk() calls below will use 1..N.
// the FramePointerStackWalk() and MozStackWalk() calls below will use 1..N.
// This is a bit weird but it doesn't matter because StackWalkCallback()
// doesn't use the frame number argument.
StackWalkCallback(/* frameNumber */ 0, aSample->pc, aSample->sp, &nativeStack);
@@ -834,7 +839,7 @@ void TableTicker::doNativeBacktrace(ThreadProfile &aProfile, TickSample* aSample
void *stackEnd = reinterpret_cast<void*>(-1);
if (pt)
stackEnd = static_cast<char*>(pthread_get_stackaddr_np(pt));
nsresult rv = NS_OK;
bool rv = true;
if (aSample->fp >= aSample->sp && aSample->fp <= stackEnd)
rv = FramePointerStackWalk(StackWalkCallback, /* skipFrames */ 0,
maxFrames, &nativeStack,
@@ -843,17 +848,17 @@ void TableTicker::doNativeBacktrace(ThreadProfile &aProfile, TickSample* aSample
void *platformData = nullptr;
#ifdef XP_WIN
if (aSample->isSamplingCurrentThread) {
// In this case we want NS_StackWalk to know that it's walking the
// In this case we want MozStackWalk to know that it's walking the
// current thread's stack, so we pass 0 as the thread handle.
thread = 0;
}
platformData = aSample->context;
#endif // XP_WIN
nsresult rv = NS_StackWalk(StackWalkCallback, /* skipFrames */ 0, maxFrames,
bool rv = MozStackWalk(StackWalkCallback, /* skipFrames */ 0, maxFrames,
&nativeStack, thread, platformData);
#endif
if (NS_SUCCEEDED(rv))
if (rv)
mergeStacksIntoProfile(aProfile, aSample, nativeStack);
}
#endif
+1 -1
View File
@@ -197,7 +197,7 @@ ProfilerMarker::~ProfilerMarker() {
}
void
ProfilerMarker::SetGeneration(int aGenID) {
ProfilerMarker::SetGeneration(uint32_t aGenID) {
mGenID = aGenID;
}
+8 -8
View File
@@ -13,7 +13,7 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/Types.h"
#include "nsStackWalk.h"
#include "mozilla/StackWalk.h"
namespace mozilla {
@@ -27,7 +27,7 @@ namespace mozilla {
// while |free| is used to free strings created by |copy|.
//
// |DescribeCodeAddressLock| is needed when the callers may be holding a lock
// used by NS_DescribeCodeAddress. |DescribeCodeAddressLock| must implement
// used by MozDescribeCodeAddress. |DescribeCodeAddressLock| must implement
// static methods IsLocked(), Unlock() and Lock().
template <class StringTable,
class StringAlloc,
@@ -35,9 +35,9 @@ template <class StringTable,
class CodeAddressService
{
// GetLocation() is the key function in this class. It's basically a wrapper
// around NS_DescribeCodeAddress.
// around MozDescribeCodeAddress.
//
// However, NS_DescribeCodeAddress is very slow on some platforms, and we
// However, MozDescribeCodeAddress is very slow on some platforms, and we
// have lots of repeated (i.e. same PC) calls to it. So we do some caching
// of results. Each cached result includes two strings (|mFunction| and
// |mLibrary|), so we also optimize them for space in the following ways.
@@ -137,15 +137,15 @@ public:
if (!entry.mInUse || entry.mPc != aPc) {
mNumCacheMisses++;
// NS_DescribeCodeAddress can (on Linux) acquire a lock inside
// MozDescribeCodeAddress can (on Linux) acquire a lock inside
// the shared library loader. Another thread might call malloc
// while holding that lock (when loading a shared library). So
// we have to exit the lock around this call. For details, see
// https://bugzilla.mozilla.org/show_bug.cgi?id=363334#c3
nsCodeAddressDetails details;
MozCodeAddressDetails details;
{
DescribeCodeAddressLock::Unlock();
(void)NS_DescribeCodeAddress(const_cast<void*>(aPc), &details);
(void)MozDescribeCodeAddress(const_cast<void*>(aPc), &details);
DescribeCodeAddressLock::Lock();
}
@@ -159,7 +159,7 @@ public:
MOZ_ASSERT(entry.mPc == aPc);
NS_FormatCodeAddress(aBuf, aBufLen, aFrameNumber, entry.mPc,
MozFormatCodeAddress(aBuf, aBufLen, aFrameNumber, entry.mPc,
entry.mFunction, entry.mLibrary, entry.mLOffset,
entry.mFileName, entry.mLineNo);
}
-24
View File
@@ -1,24 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* API for getting a stack trace of the C/C++ */
#ifndef StackWalk_h_
#define StackWalk_h_
// XXX: it would be nice to eventually remove this header dependency on nsStackWalk.h
#include "nsStackWalk.h"
namespace mozilla {
nsresult
FramePointerStackWalk(NS_WalkStackCallback aCallback, uint32_t aSkipFrames,
uint32_t aMaxFrames, void* aClosure, void** aBp,
void* aStackEnd);
}
#endif /* !defined(StackWalk_h_) */
-12
View File
@@ -57,7 +57,6 @@ EXPORTS += [
'nsISupportsBase.h',
'nsObjCExceptions.h',
'nsQueryObject.h',
'nsStackWalk.h',
'nsTraceRefcnt.h',
'nsWeakPtr.h',
]
@@ -79,7 +78,6 @@ EXPORTS.mozilla += [
'HoldDropJSObjects.h',
'LinuxUtils.h',
'nsMemoryInfoDumper.h',
'StackWalk.h',
'StaticMutex.h',
'StaticPtr.h',
'SystemMemoryReporter.h',
@@ -120,16 +118,6 @@ UNIFIED_SOURCES += [
'nsVersionComparatorImpl.cpp',
]
# MOZ_STACKWALKING is defined in configure.in when the build configuration meets
# the conditions for NS_StackWalk to work correctly.
# We exclude this file from other build configurations so that if somebody adds a
# new usage of NS_StackWalk it will cause a link error, which is better than having
# NS_StackWalk silently return garbage at runtime.
if CONFIG['MOZ_STACKWALKING']:
SOURCES += [
'nsStackWalk.cpp',
]
if CONFIG['OS_ARCH'] == 'Linux':
SOURCES += [
'LinuxUtils.cpp',
-12
View File
@@ -1,12 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* Initialize the critical sections for this platform so that we can
* abort stack walks when needed.
*/
void
StackWalkInitCriticalAddress(void);
+7 -8
View File
@@ -18,8 +18,7 @@
#include "nsCRT.h"
#include <math.h>
#include "nsHashKeys.h"
#include "nsStackWalkPrivate.h"
#include "nsStackWalk.h"
#include "mozilla/StackWalk.h"
#include "nsString.h"
#include "nsThreadUtils.h"
#include "CodeAddressService.h"
@@ -210,7 +209,7 @@ struct CodeAddressServiceStringAlloc final
static void free(char* aPtr) { ::free(aPtr); }
};
// WalkTheStack does not hold any locks needed by NS_DescribeCodeAddress, so
// WalkTheStack does not hold any locks needed by MozDescribeCodeAddress, so
// this class does not need to do anything.
struct CodeAddressServiceLock final
{
@@ -829,11 +828,11 @@ static void
PrintStackFrame(uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure)
{
FILE* stream = (FILE*)aClosure;
nsCodeAddressDetails details;
MozCodeAddressDetails details;
char buf[1024];
NS_DescribeCodeAddress(aPC, &details);
NS_FormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
MozDescribeCodeAddress(aPC, &details);
MozFormatCodeAddressDetails(buf, sizeof(buf), aFrameNumber, aPC, &details);
fprintf(stream, "%s\n", buf);
fflush(stream);
}
@@ -857,7 +856,7 @@ void
nsTraceRefcnt::WalkTheStack(FILE* aStream)
{
#ifdef MOZ_STACKWALKING
NS_StackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0, aStream,
MozStackWalk(PrintStackFrame, /* skipFrames */ 2, /* maxFrames */ 0, aStream,
0, nullptr);
#endif
}
@@ -869,7 +868,7 @@ nsTraceRefcnt::WalkTheStackCached(FILE* aStream)
if (!gCodeAddressService) {
gCodeAddressService = new WalkTheStackCodeAddressService();
}
NS_StackWalk(PrintStackFrameCached, /* skipFrames */ 2, /* maxFrames */ 0,
MozStackWalk(PrintStackFrameCached, /* skipFrames */ 2, /* maxFrames */ 0,
aStream, 0, nullptr);
#endif
}
+2 -2
View File
@@ -15,7 +15,7 @@
#include "nsAppDirectoryServiceDefs.h"
#include "nsDirectoryServiceUtils.h"
#include "nsPrintfCString.h"
#include "nsStackWalk.h"
#include "mozilla/StackWalk.h"
#include "plstr.h"
#include "prio.h"
@@ -128,7 +128,7 @@ LateWriteObserver::Observe(IOInterposeObserver::Observation& aOb)
// concurrently from many writes, so we use multiple temporary files.
std::vector<uintptr_t> rawStack;
NS_StackWalk(RecordStackWalker, /* skipFrames */ 0, /* maxFrames */ 0,
MozStackWalk(RecordStackWalker, /* skipFrames */ 0, /* maxFrames */ 0,
reinterpret_cast<void*>(&rawStack), 0, nullptr);
nsPrintfCString nameAux("%s%s%s", mProfileDirectory,
+1 -1
View File
@@ -15,7 +15,7 @@
#include "mozilla/ProcessedStack.h"
#include "mozilla/Scoped.h"
#include "nsPrintfCString.h"
#include "nsStackWalk.h"
#include "mozilla/StackWalk.h"
#include "nsTraceRefcnt.h"
#include "plstr.h"
#include "prio.h"
+2 -2
View File
@@ -14,7 +14,7 @@
#ifndef MOZ_CALLSTACK_DISABLED
#include "CodeAddressService.h"
#include "nsHashKeys.h"
#include "nsStackWalk.h"
#include "mozilla/StackWalk.h"
#include "nsTHashtable.h"
#endif
@@ -68,7 +68,7 @@ BlockingResourceBase::GetStackTrace(AcquisitionState& aState)
// NB: Ignore the return value, there's nothing useful we can do if this
// this fails.
NS_StackWalk(StackWalkCallback, kSkipFrames, 24, &aState, 0, nullptr);
MozStackWalk(StackWalkCallback, kSkipFrames, 24, &aState, 0, nullptr);
#endif
}
+1 -1
View File
@@ -14,7 +14,7 @@
#include "mozilla/StaticPtr.h"
#include "mozilla/UniquePtr.h"
#include "nsReadableUtils.h"
#include "nsStackWalk.h"
#include "mozilla/StackWalk.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
+1 -1
View File
@@ -60,7 +60,7 @@
#if defined(NS_FUNCTION_TIMER) && defined(_MSC_VER)
#include "nsTimerImpl.h"
#include "nsStackWalk.h"
#include "mozilla/StackWalk.h"
#endif
#ifdef NS_FUNCTION_TIMER
#include "nsCRT.h"