mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge.
This commit is contained in:
commit
5137a68ca5
@ -1,5 +1,5 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99:
|
||||
* vim: set ts=4 sw=4 et tw=99:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
@ -94,7 +94,7 @@ static struct {
|
||||
#define AUDIT(x) (stat.x++)
|
||||
#else
|
||||
#define AUDIT(x) ((void)0)
|
||||
#endif DEBUG
|
||||
#endif
|
||||
|
||||
#define INS_CONST(c) addName(lir->insImm(c), #c)
|
||||
|
||||
@ -102,7 +102,8 @@ using namespace avmplus;
|
||||
using namespace nanojit;
|
||||
|
||||
static GC gc = GC();
|
||||
static avmplus::AvmCore* core = new (&gc) avmplus::AvmCore();
|
||||
static avmplus::AvmCore s_core = avmplus::AvmCore();
|
||||
static avmplus::AvmCore* core = &s_core;
|
||||
|
||||
/* We really need a better way to configure the JIT. Shaver, where is my fancy JIT object? */
|
||||
static bool nesting_enabled = getenv("TRACEMONKEY") && strstr(getenv("TRACEMONKEY"), "nesting");
|
||||
@ -1287,6 +1288,7 @@ TraceRecorder::closeLoop(Fragmento* fragmento)
|
||||
sprintf(label, "%s:%u", cx->fp->script->filename,
|
||||
js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc));
|
||||
fragmento->labels->add(fragment, sizeof(Fragment), 0, label);
|
||||
free(label);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1369,6 +1371,16 @@ nanojit::Assembler::asm_bailout(LIns *guard, Register state)
|
||||
/* we adjust ip/sp/rp when exiting from the tree in the recovery code */
|
||||
}
|
||||
|
||||
void
|
||||
nanojit::Fragment::onDestroy()
|
||||
{
|
||||
if (root == this) {
|
||||
delete mergeCounts;
|
||||
delete lirbuf;
|
||||
}
|
||||
delete (TreeInfo *)vmprivate;
|
||||
}
|
||||
|
||||
void
|
||||
js_DeleteRecorder(JSContext* cx)
|
||||
{
|
||||
@ -1509,7 +1521,7 @@ js_RecordTree(JSContext* cx, JSTraceMonitor* tm, Fragment* f)
|
||||
JS_ASSERT(!f->vmprivate);
|
||||
|
||||
/* setup the VM-private treeInfo structure for this fragment */
|
||||
TreeInfo* ti = new TreeInfo(f); // TODO: deallocate when fragment dies
|
||||
TreeInfo* ti = new (&gc) TreeInfo(f); // TODO: deallocate when fragment dies
|
||||
f->vmprivate = ti;
|
||||
|
||||
/* we shouldn't have any interned globals for a new tree */
|
||||
@ -1800,7 +1812,7 @@ js_InitJIT(JSContext* cx)
|
||||
extern void
|
||||
js_DestroyJIT(JSContext* cx)
|
||||
{
|
||||
// TODO: figure out how to properly free fragmento and a potentially pending trace recorder
|
||||
JSTraceMonitor* tm = &JS_TRACE_MONITOR(cx);
|
||||
#ifdef DEBUG
|
||||
printf("recorder: started(%llu), aborted(%llu), completed(%llu), different header(%llu), "
|
||||
"trees trashed(%llu), slot promoted(%llu), "
|
||||
@ -1811,6 +1823,8 @@ js_DestroyJIT(JSContext* cx)
|
||||
"global mismatch(%llu)\n", stat.traceTriggered, stat.sideExitIntoInterpreter,
|
||||
stat.typeMapMismatchAtEntry, stat.globalShapeMismatchAtEntry);
|
||||
#endif
|
||||
verbose_only(delete tm->fragmento->labels;)
|
||||
delete tm->fragmento;
|
||||
}
|
||||
|
||||
extern void
|
||||
@ -1824,7 +1838,6 @@ js_FlushJITCache(JSContext* cx)
|
||||
js_AbortRecording(cx, NULL, "flush cache");
|
||||
Fragmento* fragmento = tm->fragmento;
|
||||
if (fragmento) {
|
||||
// TODO: deallocate vmprivate -> TreeInfo for root fragments
|
||||
fragmento->clearFrags();
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(fragmento->labels);
|
||||
@ -3925,22 +3938,32 @@ TraceRecorder::record_JSOP_FORLOCAL()
|
||||
if (stateval == JSVAL_ZERO)
|
||||
goto done;
|
||||
|
||||
LIns* state_ins = lir->ins2(LIR_and, stateval_ins, lir->insImmPtr((void*) ~jsval(3)));
|
||||
LIns* cursor_ins = lir->insLoadi(state_ins, offsetof(JSNativeEnumerator, cursor));
|
||||
LIns* state_ins;
|
||||
LIns* cursor_ins;
|
||||
|
||||
state_ins = lir->ins2(LIR_and, stateval_ins, lir->insImmPtr((void*) ~jsval(3)));
|
||||
cursor_ins = lir->insLoadi(state_ins, offsetof(JSNativeEnumerator, cursor));
|
||||
guard(false, addName(lir->ins_eq0(cursor_ins), "guard(ne->cursor != 0)"), MISMATCH_EXIT);
|
||||
|
||||
JSNativeEnumerator* ne = (JSNativeEnumerator*) (stateval & ~jsval(3));
|
||||
JSNativeEnumerator* ne;
|
||||
|
||||
ne = (JSNativeEnumerator*) (stateval & ~jsval(3));
|
||||
if (ne->cursor == 0)
|
||||
goto done;
|
||||
|
||||
cursor_ins = lir->ins2i(LIR_sub, cursor_ins, 1);
|
||||
lir->insStorei(cursor_ins, state_ins, offsetof(JSNativeEnumerator, cursor));
|
||||
|
||||
LIns* ids_ins = lir->ins2i(LIR_add, state_ins, offsetof(JSNativeEnumerator, ids));
|
||||
LIns* id_addr_ins = lir->ins2(LIR_add, ids_ins,
|
||||
LIns* ids_ins;
|
||||
LIns* id_addr_ins;
|
||||
|
||||
ids_ins = lir->ins2i(LIR_add, state_ins, offsetof(JSNativeEnumerator, ids));
|
||||
id_addr_ins = lir->ins2(LIR_add, ids_ins,
|
||||
lir->ins2i(LIR_lsh, cursor_ins, (sizeof(jsid) == 4) ? 2 : 3));
|
||||
|
||||
LIns* id_ins = lir->insLoadi(id_addr_ins, 0);
|
||||
LIns* id_ins;
|
||||
|
||||
id_ins = lir->insLoadi(id_addr_ins, 0);
|
||||
var(GET_SLOTNO(cx->fp->regs->pc), id_ins);
|
||||
|
||||
// Stack an unboxed true to make JSOP_IFEQ loop.
|
||||
|
@ -174,7 +174,7 @@ public:
|
||||
bool matches(TypeMap& other);
|
||||
};
|
||||
|
||||
class TreeInfo {
|
||||
class TreeInfo MMGC_SUBCLASS_DECL {
|
||||
nanojit::Fragment* fragment;
|
||||
public:
|
||||
unsigned entryNativeStackSlots;
|
||||
|
@ -1240,7 +1240,12 @@ namespace nanojit
|
||||
case LIR_loop:
|
||||
{
|
||||
JMP_long_placeholder(); // jump to SOT
|
||||
verbose_only( if (_verbose && _outputCache) { _outputCache->removeLast(); outputf(" jmp SOT"); } );
|
||||
#if defined(NJ_VERBOSE)
|
||||
if (_verbose && _outputCache) {
|
||||
delete _outputCache->removeLast();
|
||||
outputf(" jmp SOT");
|
||||
}
|
||||
#endif
|
||||
|
||||
loopJumps.add(_nIns);
|
||||
|
||||
|
@ -71,7 +71,7 @@ namespace nanojit
|
||||
|
||||
Fragmento::~Fragmento()
|
||||
{
|
||||
debug_only( clearFrags() );
|
||||
clearFrags();
|
||||
_frags->clear();
|
||||
while( _allocList.size() > 0 )
|
||||
{
|
||||
@ -81,6 +81,12 @@ namespace nanojit
|
||||
#endif
|
||||
_gcHeap->Free( _allocList.removeLast() );
|
||||
}
|
||||
delete _frags;
|
||||
delete _assm;
|
||||
#if defined(NJ_VERBOSE)
|
||||
delete enterCounts;
|
||||
delete mergeCounts;
|
||||
#endif
|
||||
NanoAssert(_stats.freePages == _stats.pages );
|
||||
}
|
||||
|
||||
@ -168,6 +174,7 @@ namespace nanojit
|
||||
while (!_frags->isEmpty()) {
|
||||
Fragment *f = _frags->removeLast();
|
||||
f->releaseTreeMem(this);
|
||||
delete f;
|
||||
}
|
||||
|
||||
verbose_only( enterCounts->clear();)
|
||||
@ -454,6 +461,7 @@ namespace nanojit
|
||||
|
||||
Fragment::~Fragment()
|
||||
{
|
||||
onDestroy();
|
||||
NanoAssert(_pages == 0);
|
||||
}
|
||||
|
||||
@ -627,10 +635,6 @@ namespace nanojit
|
||||
|
||||
void Fragment::releaseLirBuffer()
|
||||
{
|
||||
if (lirbuf) {
|
||||
lirbuf->clear();
|
||||
lirbuf = 0;
|
||||
}
|
||||
lastIns = 0;
|
||||
}
|
||||
|
||||
@ -656,6 +660,7 @@ namespace nanojit
|
||||
{
|
||||
Fragment* next = branch->nextbranch;
|
||||
branch->releaseTreeMem(frago); // @todo safer here to recurse in case we support nested trees
|
||||
delete branch;
|
||||
branch = next;
|
||||
}
|
||||
}
|
||||
|
@ -184,6 +184,7 @@ namespace nanojit
|
||||
void releaseTreeMem(Fragmento* frago);
|
||||
bool isAnchor() { return anchor == this; }
|
||||
bool isRoot() { return root == this; }
|
||||
void onDestroy();
|
||||
|
||||
verbose_only( uint32_t _called; )
|
||||
verbose_only( uint32_t _native; )
|
||||
|
@ -114,6 +114,9 @@ namespace nanojit
|
||||
//buffer_count--;
|
||||
//fprintf(stderr, "~LirBuffer %x start %x\n", (int)this, (int)_start);
|
||||
clear();
|
||||
#ifdef DEBUG
|
||||
delete names;
|
||||
#endif
|
||||
_frago = 0;
|
||||
}
|
||||
|
||||
@ -1315,6 +1318,13 @@ namespace nanojit
|
||||
List<RetiredEntry*, LIST_GCObjects> retired;
|
||||
int maxlive;
|
||||
LiveTable(GC *gc) : live(gc), retired(gc), maxlive(0) {}
|
||||
~LiveTable()
|
||||
{
|
||||
for (size_t i = 0; i < retired.size(); i++) {
|
||||
delete retired.get(i);
|
||||
}
|
||||
|
||||
}
|
||||
void add(LInsp i, LInsp use) {
|
||||
if (!i->isconst() && !i->isconstq() && !live.containsKey(i)) {
|
||||
live.put(i,use);
|
||||
@ -1417,6 +1427,25 @@ namespace nanojit
|
||||
}
|
||||
}
|
||||
|
||||
LabelMap::Entry::~Entry()
|
||||
{
|
||||
delete name;
|
||||
}
|
||||
|
||||
LirNameMap::Entry::~Entry()
|
||||
{
|
||||
delete name;
|
||||
}
|
||||
|
||||
LirNameMap::~LirNameMap()
|
||||
{
|
||||
Entry *e;
|
||||
|
||||
while ((e = names.removeLast()) != NULL) {
|
||||
delete e;
|
||||
}
|
||||
}
|
||||
|
||||
void LirNameMap::addName(LInsp i, Stringp name) {
|
||||
if (!names.containsKey(i)) {
|
||||
Entry *e = new (labels->core->gc) Entry(name);
|
||||
@ -1787,6 +1816,12 @@ namespace nanojit
|
||||
root->link(assm);
|
||||
if (treeCompile) root->linkBranches(assm);
|
||||
}
|
||||
|
||||
#if defined(NJ_VERBOSE)
|
||||
for (size_t i = 0; i < asmOutput.size(); i++) {
|
||||
gc->Free(asmOutput.get(i));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* FEATURE_NANOJIT */
|
||||
@ -1796,6 +1831,15 @@ namespace nanojit
|
||||
: parent(parent), names(core->gc), addrs(core->config.verbose_addrs), end(buf), core(core)
|
||||
{}
|
||||
|
||||
LabelMap::~LabelMap()
|
||||
{
|
||||
Entry *e;
|
||||
|
||||
while ((e = names.removeLast()) != NULL) {
|
||||
delete e;
|
||||
}
|
||||
}
|
||||
|
||||
void LabelMap::add(const void *p, size_t size, size_t align, const char *name)
|
||||
{
|
||||
if (!this || names.containsKey(p))
|
||||
|
@ -419,6 +419,7 @@ namespace nanojit
|
||||
public:
|
||||
Entry(int) : name(0), size(0), align(0) {}
|
||||
Entry(avmplus::String *n, size_t s, size_t a) : name(n),size(s),align(a) {}
|
||||
~Entry();
|
||||
DRCWB(avmplus::String*) name;
|
||||
size_t size:29, align:3;
|
||||
};
|
||||
@ -429,6 +430,7 @@ namespace nanojit
|
||||
public:
|
||||
AvmCore *core;
|
||||
LabelMap(AvmCore *, LabelMap* parent);
|
||||
~LabelMap();
|
||||
void add(const void *p, size_t size, size_t align, const char *name);
|
||||
void add(const void *p, size_t size, size_t align, avmplus::String*);
|
||||
const char *dup(const char *);
|
||||
@ -455,6 +457,7 @@ namespace nanojit
|
||||
public:
|
||||
Entry(int) : name(0) {}
|
||||
Entry(avmplus::String *n) : name(n) {}
|
||||
~Entry();
|
||||
DRCWB(avmplus::String*) name;
|
||||
};
|
||||
avmplus::SortedMap<LInsp, Entry*, avmplus::LIST_GCObjects> names;
|
||||
@ -470,6 +473,7 @@ namespace nanojit
|
||||
_functions(_functions),
|
||||
labels(r)
|
||||
{}
|
||||
~LirNameMap();
|
||||
|
||||
void addName(LInsp i, const char *s);
|
||||
void addName(LInsp i, avmplus::String *s);
|
||||
|
@ -190,12 +190,22 @@ namespace nanojit
|
||||
|
||||
class GCObject
|
||||
{
|
||||
public:
|
||||
static void operator delete (void *gcObject)
|
||||
{
|
||||
free(gcObject);
|
||||
}
|
||||
};
|
||||
|
||||
#define MMGC_SUBCLASS_DECL
|
||||
#define MMGC_SUBCLASS_DECL : public GCObject
|
||||
|
||||
class GCFinalizedObject
|
||||
class GCFinalizedObject : public GCObject
|
||||
{
|
||||
public:
|
||||
static void operator delete (void *gcObject)
|
||||
{
|
||||
free(gcObject);
|
||||
}
|
||||
};
|
||||
|
||||
class GCHeap
|
||||
|
Loading…
Reference in New Issue
Block a user