mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1447244 Part 2 - Track source ID in saved frames, r=jimb.
--HG-- extra : rebase_source : 6d585a37588dae528e0d37d53d0629f9b509e82d
This commit is contained in:
parent
8e9fd6140b
commit
e2c9ceed8d
@ -287,6 +287,10 @@ class ConcreteStackFrame<DeserializedStackFrame> : public BaseStackFrame {
|
||||
AtomOrTwoByteChars source() const override {
|
||||
return AtomOrTwoByteChars(get().source);
|
||||
}
|
||||
uint32_t sourceId() const override {
|
||||
// Source IDs are local to their host process and are not serialized.
|
||||
return 0;
|
||||
}
|
||||
AtomOrTwoByteChars functionDisplayName() const override {
|
||||
return AtomOrTwoByteChars(get().functionDisplayName);
|
||||
}
|
||||
|
@ -65,6 +65,15 @@ extern JS_PUBLIC_API SavedFrameResult GetSavedFrameSource(
|
||||
MutableHandle<JSString*> sourcep,
|
||||
SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
|
||||
|
||||
/**
|
||||
* Given a SavedFrame JSObject, get an ID identifying its ScriptSource.
|
||||
* Defaults to 0.
|
||||
*/
|
||||
extern JS_PUBLIC_API SavedFrameResult GetSavedFrameSourceId(
|
||||
JSContext* cx, JSPrincipals* principals, Handle<JSObject*> savedFrame,
|
||||
uint32_t* sourceIdp,
|
||||
SavedFrameSelfHosted selfHosted = SavedFrameSelfHosted::Include);
|
||||
|
||||
/**
|
||||
* Given a SavedFrame JSObject, get its line property. Defaults to 0.
|
||||
*/
|
||||
|
@ -247,6 +247,9 @@ class BaseStackFrame {
|
||||
// Get this frame's source name. Never null.
|
||||
virtual AtomOrTwoByteChars source() const = 0;
|
||||
|
||||
// Get a unique per-process ID for this frame's source. Defaults to zero.
|
||||
virtual uint32_t sourceId() const = 0;
|
||||
|
||||
// Return this frame's function name if named, otherwise the inferred
|
||||
// display name. Can be null.
|
||||
virtual AtomOrTwoByteChars functionDisplayName() const = 0;
|
||||
@ -414,6 +417,7 @@ class StackFrame {
|
||||
uint32_t line() const { return base()->line(); }
|
||||
uint32_t column() const { return base()->column(); }
|
||||
AtomOrTwoByteChars source() const { return base()->source(); }
|
||||
uint32_t sourceId() const { return base()->sourceId(); }
|
||||
AtomOrTwoByteChars functionDisplayName() const {
|
||||
return base()->functionDisplayName();
|
||||
}
|
||||
@ -464,6 +468,7 @@ class ConcreteStackFrame<void> : public BaseStackFrame {
|
||||
AtomOrTwoByteChars source() const override {
|
||||
MOZ_CRASH("null JS::ubi::StackFrame");
|
||||
}
|
||||
uint32_t sourceId() const override { MOZ_CRASH("null JS::ubi::StackFrame"); }
|
||||
AtomOrTwoByteChars functionDisplayName() const override {
|
||||
MOZ_CRASH("null JS::ubi::StackFrame");
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ class SavedFrame : public NativeObject {
|
||||
// Prototype methods and properties to be exposed to JS.
|
||||
static bool construct(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool sourceProperty(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool sourceIdProperty(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool lineProperty(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool columnProperty(JSContext* cx, unsigned argc, Value* vp);
|
||||
static bool functionDisplayNameProperty(JSContext* cx, unsigned argc,
|
||||
@ -44,6 +45,7 @@ class SavedFrame : public NativeObject {
|
||||
|
||||
// Convenient getters for SavedFrame's reserved slots for use from C++.
|
||||
JSAtom* getSource();
|
||||
uint32_t getSourceId();
|
||||
uint32_t getLine();
|
||||
uint32_t getColumn();
|
||||
JSAtom* getFunctionDisplayName();
|
||||
@ -129,6 +131,7 @@ class SavedFrame : public NativeObject {
|
||||
HandleObject proto);
|
||||
void initFromLookup(JSContext* cx, HandleLookup lookup);
|
||||
void initSource(JSAtom* source);
|
||||
void initSourceId(uint32_t id);
|
||||
void initLine(uint32_t line);
|
||||
void initColumn(uint32_t column);
|
||||
void initFunctionDisplayName(JSAtom* maybeName);
|
||||
@ -140,6 +143,7 @@ class SavedFrame : public NativeObject {
|
||||
enum {
|
||||
// The reserved slots in the SavedFrame class.
|
||||
JSSLOT_SOURCE,
|
||||
JSSLOT_SOURCEID,
|
||||
JSSLOT_LINE,
|
||||
JSSLOT_COLUMN,
|
||||
JSSLOT_FUNCTIONDISPLAYNAME,
|
||||
@ -260,6 +264,8 @@ class ConcreteStackFrame<SavedFrame> : public BaseStackFrame {
|
||||
return AtomOrTwoByteChars(source);
|
||||
}
|
||||
|
||||
uint32_t sourceId() const override { return get().getSourceId(); }
|
||||
|
||||
AtomOrTwoByteChars functionDisplayName() const override {
|
||||
auto name = get().getFunctionDisplayName();
|
||||
return AtomOrTwoByteChars(name);
|
||||
|
@ -173,12 +173,13 @@ void LiveSavedFrameCache::findWithoutInvalidation(
|
||||
}
|
||||
|
||||
struct SavedFrame::Lookup {
|
||||
Lookup(JSAtom* source, uint32_t line, uint32_t column,
|
||||
Lookup(JSAtom* source, uint32_t sourceId, uint32_t line, uint32_t column,
|
||||
JSAtom* functionDisplayName, JSAtom* asyncCause, SavedFrame* parent,
|
||||
JSPrincipals* principals,
|
||||
const Maybe<LiveSavedFrameCache::FramePtr>& framePtr = Nothing(),
|
||||
jsbytecode* pc = nullptr, Activation* activation = nullptr)
|
||||
: source(source),
|
||||
sourceId(sourceId),
|
||||
line(line),
|
||||
column(column),
|
||||
functionDisplayName(functionDisplayName),
|
||||
@ -197,6 +198,7 @@ struct SavedFrame::Lookup {
|
||||
|
||||
explicit Lookup(SavedFrame& savedFrame)
|
||||
: source(savedFrame.getSource()),
|
||||
sourceId(savedFrame.getSourceId()),
|
||||
line(savedFrame.getLine()),
|
||||
column(savedFrame.getColumn()),
|
||||
functionDisplayName(savedFrame.getFunctionDisplayName()),
|
||||
@ -210,6 +212,7 @@ struct SavedFrame::Lookup {
|
||||
}
|
||||
|
||||
JSAtom* source;
|
||||
uint32_t sourceId;
|
||||
uint32_t line;
|
||||
uint32_t column;
|
||||
JSAtom* functionDisplayName;
|
||||
@ -370,6 +373,7 @@ const Class SavedFrame::protoClass_ = {
|
||||
|
||||
/* static */ const JSPropertySpec SavedFrame::protoAccessors[] = {
|
||||
JS_PSG("source", SavedFrame::sourceProperty, 0),
|
||||
JS_PSG("sourceId", SavedFrame::sourceIdProperty, 0),
|
||||
JS_PSG("line", SavedFrame::lineProperty, 0),
|
||||
JS_PSG("column", SavedFrame::columnProperty, 0),
|
||||
JS_PSG("functionDisplayName", SavedFrame::functionDisplayNameProperty, 0),
|
||||
@ -393,6 +397,11 @@ JSAtom* SavedFrame::getSource() {
|
||||
return &s->asAtom();
|
||||
}
|
||||
|
||||
uint32_t SavedFrame::getSourceId() {
|
||||
const Value& v = getReservedSlot(JSSLOT_SOURCEID);
|
||||
return v.toPrivateUint32();
|
||||
}
|
||||
|
||||
uint32_t SavedFrame::getLine() {
|
||||
const Value& v = getReservedSlot(JSSLOT_LINE);
|
||||
return v.toPrivateUint32();
|
||||
@ -439,6 +448,10 @@ void SavedFrame::initSource(JSAtom* source) {
|
||||
initReservedSlot(JSSLOT_SOURCE, StringValue(source));
|
||||
}
|
||||
|
||||
void SavedFrame::initSourceId(uint32_t sourceId) {
|
||||
initReservedSlot(JSSLOT_SOURCEID, PrivateUint32Value(sourceId));
|
||||
}
|
||||
|
||||
void SavedFrame::initLine(uint32_t line) {
|
||||
initReservedSlot(JSSLOT_LINE, PrivateUint32Value(line));
|
||||
}
|
||||
@ -494,6 +507,7 @@ void SavedFrame::initFromLookup(JSContext* cx,
|
||||
}
|
||||
|
||||
initSource(lookup->source);
|
||||
initSourceId(lookup->sourceId);
|
||||
initLine(lookup->line);
|
||||
initColumn(lookup->column);
|
||||
initFunctionDisplayName(lookup->functionDisplayName);
|
||||
@ -728,6 +742,25 @@ JS_PUBLIC_API SavedFrameResult GetSavedFrameSource(
|
||||
return SavedFrameResult::Ok;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API SavedFrameResult GetSavedFrameSourceId(
|
||||
JSContext* cx, JSPrincipals* principals, HandleObject savedFrame,
|
||||
uint32_t* sourceIdp,
|
||||
SavedFrameSelfHosted selfHosted /* = SavedFrameSelfHosted::Include */) {
|
||||
js::AssertHeapIsIdle();
|
||||
CHECK_THREAD(cx);
|
||||
MOZ_RELEASE_ASSERT(cx->realm());
|
||||
|
||||
bool skippedAsync;
|
||||
js::RootedSavedFrame frame(cx, UnwrapSavedFrame(cx, principals, savedFrame,
|
||||
selfHosted, skippedAsync));
|
||||
if (!frame) {
|
||||
*sourceIdp = 0;
|
||||
return SavedFrameResult::AccessDenied;
|
||||
}
|
||||
*sourceIdp = frame->getSourceId();
|
||||
return SavedFrameResult::Ok;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API SavedFrameResult GetSavedFrameLine(
|
||||
JSContext* cx, JSPrincipals* principals, HandleObject savedFrame,
|
||||
uint32_t* linep,
|
||||
@ -1058,6 +1091,20 @@ namespace js {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool SavedFrame::sourceIdProperty(JSContext* cx, unsigned argc,
|
||||
Value* vp) {
|
||||
THIS_SAVEDFRAME(cx, argc, vp, "(get sourceId)", args, frame);
|
||||
JSPrincipals* principals = cx->realm()->principals();
|
||||
uint32_t sourceId;
|
||||
if (JS::GetSavedFrameSourceId(cx, principals, frame, &sourceId) ==
|
||||
JS::SavedFrameResult::Ok) {
|
||||
args.rval().setNumber(sourceId);
|
||||
} else {
|
||||
args.rval().setNull();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */ bool SavedFrame::lineProperty(JSContext* cx, unsigned argc,
|
||||
Value* vp) {
|
||||
THIS_SAVEDFRAME(cx, argc, vp, "(get line)", args, frame);
|
||||
@ -1346,7 +1393,8 @@ bool SavedStacks::insertFrames(JSContext* cx, MutableHandleSavedFrame frame,
|
||||
MOZ_ASSERT_IF(framePtr && !iter.isWasm(), iter.pc());
|
||||
|
||||
if (!stackChain->emplaceBack(
|
||||
location.source(), location.line(), location.column(), displayAtom,
|
||||
location.source(), location.sourceId(),
|
||||
location.line(), location.column(), displayAtom,
|
||||
nullptr, // asyncCause
|
||||
nullptr, // parent (not known yet)
|
||||
principals, framePtr, iter.pc(), &activation)) {
|
||||
@ -1656,11 +1704,12 @@ bool SavedStacks::getLocation(JSContext* cx, const FrameIter& iter,
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t sourceId = script->scriptSource()->id();
|
||||
uint32_t column;
|
||||
uint32_t line = PCToLineNumber(script, pc, &column);
|
||||
|
||||
// Make the column 1-based. See comment above.
|
||||
LocationValue value(source, line, column + 1);
|
||||
LocationValue value(source, sourceId, line, column + 1);
|
||||
if (!pcLocationMap.add(p, key, value)) {
|
||||
ReportOutOfMemory(cx);
|
||||
return false;
|
||||
@ -1842,7 +1891,8 @@ JS_PUBLIC_API bool ConstructSavedFrameStackSlow(
|
||||
auto principals =
|
||||
js::ReconstructedSavedFramePrincipals::getSingleton(ubiFrame.get());
|
||||
|
||||
if (!stackChain->emplaceBack(source, ubiFrame.get().line(),
|
||||
if (!stackChain->emplaceBack(source, ubiFrame.get().sourceId(),
|
||||
ubiFrame.get().line(),
|
||||
ubiFrame.get().column(), functionDisplayName,
|
||||
/* asyncCause */ nullptr,
|
||||
/* parent */ nullptr, principals)) {
|
||||
|
@ -243,9 +243,9 @@ class SavedStacks {
|
||||
|
||||
public:
|
||||
struct LocationValue {
|
||||
LocationValue() : source(nullptr), line(0), column(0) {}
|
||||
LocationValue(JSAtom* source, size_t line, uint32_t column)
|
||||
: source(source), line(line), column(column) {}
|
||||
LocationValue() : source(nullptr), sourceId(0), line(0), column(0) {}
|
||||
LocationValue(JSAtom* source, uint32_t sourceId, size_t line, uint32_t column)
|
||||
: source(source), sourceId(sourceId), line(line), column(column) {}
|
||||
|
||||
void trace(JSTracer* trc) {
|
||||
TraceNullableEdge(trc, &source, "SavedStacks::LocationValue::source");
|
||||
@ -261,6 +261,7 @@ class SavedStacks {
|
||||
}
|
||||
|
||||
HeapPtr<JSAtom*> source;
|
||||
uint32_t sourceId;
|
||||
size_t line;
|
||||
uint32_t column;
|
||||
};
|
||||
@ -299,6 +300,7 @@ class SavedStacks {
|
||||
template <typename Wrapper>
|
||||
struct WrappedPtrOperations<SavedStacks::LocationValue, Wrapper> {
|
||||
JSAtom* source() const { return loc().source; }
|
||||
uint32_t sourceId() const { return loc().sourceId; }
|
||||
size_t line() const { return loc().line; }
|
||||
uint32_t column() const { return loc().column; }
|
||||
|
||||
@ -312,6 +314,7 @@ template <typename Wrapper>
|
||||
struct MutableWrappedPtrOperations<SavedStacks::LocationValue, Wrapper>
|
||||
: public WrappedPtrOperations<SavedStacks::LocationValue, Wrapper> {
|
||||
void setSource(JSAtom* v) { loc().source = v; }
|
||||
void setSourceId(uint32_t v) { loc().sourceId = v; }
|
||||
void setLine(size_t v) { loc().line = v; }
|
||||
void setColumn(uint32_t v) { loc().column = v; }
|
||||
|
||||
|
@ -2820,6 +2820,10 @@ JSObject* JSStructuredCloneReader::readSavedFrame(uint32_t principalsTag) {
|
||||
}
|
||||
savedFrame->initColumn(column);
|
||||
|
||||
// Don't specify a source ID when reading a cloned saved frame, as these IDs
|
||||
// are only valid within a specific process.
|
||||
savedFrame->initSourceId(0);
|
||||
|
||||
RootedValue name(context());
|
||||
if (!startRead(&name) || !(name.isString() || name.isNull())) {
|
||||
return nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user