Mozilla/mozilla/js/tamarin/core/StackTrace.h
wsharp%adobe.com 039e5a464d bug 375561. stejohns+ review. Various fixes from Flash player codebase
git-svn-id: svn://10.0.0.236/trunk@222472 18797224-902f-48f8-a5cc-f745e15eee43
2007-03-27 18:37:45 +00:00

185 lines
6.3 KiB
C++

/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is [Open Source Virtual Machine.].
*
* The Initial Developer of the Original Code is
* Adobe System Incorporated.
* Portions created by the Initial Developer are Copyright (C) 2004-2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Adobe AS3 Team
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __avmplus_CallStackNode__
#define __avmplus_CallStackNode__
namespace avmplus
{
#ifdef DEBUGGER
class StackTrace : public MMgc::GCObject
{
public:
Stringp format(AvmCore* core);
/**
* The dump and format methods display a human-readable
* version of the stack trace. To avoid thousands of
* lines of output, such as would happen in an infinite
* recursion, no more than kMaxDisplayDepth levels will
* be displayed.
*/
const static int kMaxDisplayDepth = 64;
int depth;
DRCWB(Stringp) stringRep;
struct Element
{
AbstractFunction *info;
Stringp filename; // in the form "C:\path\to\package\root;package/package;filename"
int linenum;
};
bool equals(StackTrace::Element *e, int depth);
static uintptr hashCode(StackTrace::Element *e, int depth);
Element elements[1];
private:
void dumpFilename(Stringp filename, PrintWriter& out) const;
};
/**
* The CallStackNode class tracks the call stack of executing
* ActionScript code. It is used for debugger stack dumps
* and also to keep track of the security contexts of
* running code. There is a master CallStackNode object on
* AvmCore, which is maintained by MethodInfo::enter as
* methods enter and exit.
*
* A single CallStackNode object represents a level of the
* call stack. It tracks the currently executing method,
* and the source file and line number if debug info
* is available.
*
* CallStackNode objects get strung together into linked
* lists to represent a full call stack. Entering a
* method adds a new element to core->stackTrace's
* linked list; exiting a method removes it.
*
* As OP_debugfile and OP_debugline opcodes are encountered,
* the file and line number information in the current
* CallStackNode object is updated.
*
* CallStackNode objects are "semi-immutable." The file
* and line number information can be updated until someone
* wants to snapshot the CallStackNode. To snapshot, the
* "freeze" method is called. This freezes the entire
* linked list. Once a CallStackNode is frozen, it cannot
* be directly modified... a clone must be made of it,
* and then the clone can be modified.
*
* The "semi-immutable" aspect is to support AVM+ heap
* profiling. Every ScriptObject will point to the
* CallStackNode at time of allocation, so that the developer
* can figure out the call stack where an object was
* created. The semi-immutability makes it possible to
* conserve memory, by having many ScriptObjects point to
* the same CallStackNode chain, or chains containing common
* CallStackNode elements.
*/
class CallStackNode
{
public:
/**
* Constructs a new CallStackNode. The method executing and
* the CallStackNode representing the previous call stack
* must be specified. The source file and line number
* will be unset, initially.
* @param info the currently executing method
* @param next the CallStackNode representing the previous
* call stack
*/
CallStackNode(MethodEnv * env,
AbstractFunction *info,
Atom* framep,
Traits** frameTraits,
int argc,
uint32 * ap,
sintptr volatile *eip)
{
initialize(env, info, framep, frameTraits, argc, ap, eip);
}
// WARNING!!!! this method is called by CodegenMIR if you change the signature then change the call there.
void initialize(MethodEnv * env,
AbstractFunction * info,
Atom* framep,
Traits** frameTraits,
int argc,
uint32 * ap,
sintptr volatile * eip);
void exit();
MethodEnv *env;
AbstractFunction* info;
Stringp filename; // in the form "C:\path\to\package\root;package/package;filename"
int linenum;
CallStackNode *next;
int depth;
uint32 * ap;
int argc;
Atom* framep; // pointer to top of AS registers
Traits** traits; // array of traits for AS registers
sintptr volatile * eip; // ptr to where the current pc is stored
void** scopeBase(); // with MIR, array members are (ScriptObject*); with interpreter, they are (Atom).
#ifdef AVMPLUS_INTERP
int* scopeDepth; // Only used by the interpreter! With MIR, look for NULL entires in the scopeBase array.
#endif
protected:
// allow more flexibility to subclasses
CallStackNode(){}
};
// for sampling
class FakeCallStackNode : public CallStackNode
{
public:
FakeCallStackNode(AvmCore *core, const char *name);
~FakeCallStackNode();
void sampleCheck() { if(core) core->sampler()->sampleCheck(); }
private:
AvmCore *core;
};
#endif /* DEBUGGER */
}
#endif /* __avmplus_CallStackNode__ */