Backed out changeset 03b7d111cc86 (bug 857648)

This commit is contained in:
Carsten "Tomcat" Book 2014-07-04 08:23:17 +02:00
Родитель bc8063b408
Коммит d626e8a402
2 изменённых файлов: 142 добавлений и 0 удалений

Просмотреть файл

@ -37,6 +37,69 @@ JS_GetScriptFilename(JSScript *script);
namespace JS {
class FrameDescription
{
public:
explicit FrameDescription(const js::FrameIter& iter);
FrameDescription(const FrameDescription &rhs);
~FrameDescription();
unsigned lineno() {
if (!linenoComputed_) {
lineno_ = JS_PCToLineNumber(nullptr, script_, pc_);
linenoComputed_ = true;
}
return lineno_;
}
const char *filename() const {
return filename_;
}
JSFlatString *funDisplayName() const {
return funDisplayName_ ? JS_ASSERT_STRING_IS_FLAT(funDisplayName_) : nullptr;
}
// Both these locations should be traced during GC but otherwise not used;
// they are implementation details.
Heap<JSScript*> &markedLocation1() {
return script_;
}
Heap<JSString*> &markedLocation2() {
return funDisplayName_;
}
private:
void operator=(const FrameDescription &) MOZ_DELETE;
// These fields are always initialized:
Heap<JSString*> funDisplayName_;
const char *filename_;
// One of script_ xor scriptSource_ is non-null.
Heap<JSScript*> script_;
js::ScriptSource *scriptSource_;
// For script_-having frames, lineno_ is lazily computed as an optimization.
bool linenoComputed_;
unsigned lineno_;
// pc_ is non-null iff script_ is non-null. If !pc_, linenoComputed_ = true.
jsbytecode *pc_;
};
struct StackDescription
{
unsigned nframes;
FrameDescription *frames;
};
extern JS_PUBLIC_API(StackDescription *)
DescribeStack(JSContext *cx, unsigned maxFrames);
extern JS_PUBLIC_API(void)
FreeStackDescription(JSContext *cx, StackDescription *desc);
extern JS_PUBLIC_API(char *)
FormatStackDump(JSContext *cx, char *buf, bool showArgs, bool showLocals, bool showThisProps);

Просмотреть файл

@ -895,6 +895,85 @@ js_CallContextDebugHandler(JSContext *cx)
}
}
/*
* A contructor that crates a FrameDescription from a ScriptFrameIter, to avoid
* constructing a FrameDescription on the stack just to append it to a vector.
* FrameDescription contains Heap<T> fields that should not live on the stack.
*/
JS::FrameDescription::FrameDescription(const FrameIter& iter)
: scriptSource_(nullptr),
linenoComputed_(false),
pc_(nullptr)
{
if (iter.isNonEvalFunctionFrame())
funDisplayName_ = iter.functionDisplayAtom();
if (iter.hasScript()) {
script_ = iter.script();
pc_ = iter.pc();
filename_ = script_->filename();
} else {
scriptSource_ = iter.scriptSource();
scriptSource_->incref();
filename_ = scriptSource_->filename();
lineno_ = iter.computeLine();
linenoComputed_ = true;
}
}
JS::FrameDescription::FrameDescription(const FrameDescription &rhs)
: funDisplayName_(rhs.funDisplayName_),
filename_(rhs.filename_),
script_(rhs.script_),
scriptSource_(rhs.scriptSource_),
linenoComputed_(rhs.linenoComputed_),
lineno_(rhs.lineno_),
pc_(rhs.pc_)
{
if (scriptSource_)
scriptSource_->incref();
}
JS::FrameDescription::~FrameDescription()
{
if (scriptSource_)
scriptSource_->decref();
}
JS_PUBLIC_API(JS::StackDescription *)
JS::DescribeStack(JSContext *cx, unsigned maxFrames)
{
Vector<FrameDescription> frames(cx);
NonBuiltinFrameIter i(cx, FrameIter::ALL_CONTEXTS,
FrameIter::GO_THROUGH_SAVED,
cx->compartment()->principals);
for ( ; !i.done(); ++i) {
if (!frames.append(i))
return nullptr;
if (frames.length() == maxFrames)
break;
}
JS::StackDescription *desc = js_new<JS::StackDescription>();
if (!desc)
return nullptr;
desc->nframes = frames.length();
desc->frames = frames.extractRawBuffer();
return desc;
}
JS_PUBLIC_API(void)
JS::FreeStackDescription(JSContext *cx, JS::StackDescription *desc)
{
for (size_t i = 0; i < desc->nframes; ++i)
desc->frames[i].~FrameDescription();
js_free(desc->frames);
js_delete(desc);
}
namespace {
class AutoPropertyDescArray