Bug 541886 - nanojit: move compile() into class Assembler. r=rreitmai.

--HG--
extra : convert_revision : f3506c693a7e8b7af089367313cbe960d7e2607f
This commit is contained in:
Nicholas Nethercote 2010-01-26 13:38:15 +11:00
parent 1f13f206c4
commit 09e7e8d0a8
5 changed files with 159 additions and 162 deletions

View File

@ -760,7 +760,7 @@ FragmentAssembler::endFragment()
mFragment->lastIns =
mLir->insGuard(LIR_x, NULL, createGuardRecord(createSideExit()));
::compile(&mParent.mAssm, mFragment, mParent.mAlloc, optimize
mParent.mAssm.compile(mFragment, mParent.mAlloc, optimize
verbose_only(, mParent.mLabelMap));
if (mParent.mAssm.error() != nanojit::None) {

View File

@ -825,6 +825,155 @@ namespace nanojit
return jmpTarget;
}
void Assembler::compile(Fragment* frag, Allocator& alloc, bool optimize verbose_only(, LabelMap* labels))
{
verbose_only(
bool anyVerb = (_logc->lcbits & 0xFFFF & ~LC_FragProfile) > 0;
bool asmVerb = (_logc->lcbits & 0xFFFF & LC_Assembly) > 0;
bool liveVerb = (_logc->lcbits & 0xFFFF & LC_Liveness) > 0;
)
/* BEGIN decorative preamble */
verbose_only(
if (anyVerb) {
_logc->printf("========================================"
"========================================\n");
_logc->printf("=== BEGIN LIR::compile(%p, %p)\n",
(void*)this, (void*)frag);
_logc->printf("===\n");
})
/* END decorative preamble */
verbose_only( if (liveVerb) {
_logc->printf("\n");
_logc->printf("=== Results of liveness analysis:\n");
_logc->printf("===\n");
LirReader br(frag->lastIns);
LirFilter* lir = &br;
if (optimize) {
StackFilter* sf = new (alloc) StackFilter(lir, alloc, frag->lirbuf->sp, frag->lirbuf->rp);
lir = sf;
}
live(lir, alloc, frag, _logc);
})
/* Set up the generic text output cache for the assembler */
verbose_only( StringList asmOutput(alloc); )
verbose_only( _outputCache = &asmOutput; )
beginAssembly(frag);
if (error())
return;
//_logc->printf("recompile trigger %X kind %d\n", (int)frag, frag->kind);
verbose_only( if (anyVerb) {
_logc->printf("=== Translating LIR fragments into assembly:\n");
})
// now the the main trunk
verbose_only( if (anyVerb) {
_logc->printf("=== -- Compile trunk %s: begin\n",
labels->format(frag));
})
// Used for debug printing, if needed
debug_only(ValidateReader *validate = NULL;)
verbose_only(
ReverseLister *pp_init = NULL;
ReverseLister *pp_after_sf = NULL;
)
// The LIR passes through these filters as listed in this
// function, viz, top to bottom.
// set up backwards pipeline: assembler <- StackFilter <- LirReader
LirFilter* lir = new (alloc) LirReader(frag->lastIns);
#ifdef DEBUG
// VALIDATION
validate = new (alloc) ValidateReader(lir);
lir = validate;
#endif
// INITIAL PRINTING
verbose_only( if (_logc->lcbits & LC_ReadLIR) {
pp_init = new (alloc) ReverseLister(lir, alloc, frag->lirbuf->names, _logc,
"Initial LIR");
lir = pp_init;
})
// STACKFILTER
if (optimize) {
StackFilter* stackfilter =
new (alloc) StackFilter(lir, alloc, frag->lirbuf->sp, frag->lirbuf->rp);
lir = stackfilter;
}
verbose_only( if (_logc->lcbits & LC_AfterSF) {
pp_after_sf = new (alloc) ReverseLister(lir, alloc, frag->lirbuf->names, _logc,
"After StackFilter");
lir = pp_after_sf;
})
assemble(frag, lir);
// If we were accumulating debug info in the various ReverseListers,
// call finish() to emit whatever contents they have accumulated.
verbose_only(
if (pp_init) pp_init->finish();
if (pp_after_sf) pp_after_sf->finish();
)
verbose_only( if (anyVerb) {
_logc->printf("=== -- Compile trunk %s: end\n",
labels->format(frag));
})
verbose_only(
if (asmVerb)
outputf("## compiling trunk %s", labels->format(frag));
)
endAssembly(frag);
// Reverse output so that assembly is displayed low-to-high.
// Up to this point, _outputCache has been non-NULL, and so has been
// accumulating output. Now we set it to NULL, traverse the entire
// list of stored strings, and hand them a second time to output.
// Since _outputCache is now NULL, outputf just hands these strings
// directly onwards to _logc->printf.
verbose_only( if (anyVerb) {
_logc->printf("\n");
_logc->printf("=== Aggregated assembly output: BEGIN\n");
_logc->printf("===\n");
_outputCache = 0;
for (Seq<char*>* p = asmOutput.get(); p != NULL; p = p->tail) {
char *str = p->head;
outputf(" %s", str);
}
_logc->printf("===\n");
_logc->printf("=== Aggregated assembly output: END\n");
});
if (error())
frag->fragEntry = 0;
verbose_only( frag->nCodeBytes += codeBytes; )
verbose_only( frag->nExitBytes += exitBytes; )
/* BEGIN decorative postamble */
verbose_only( if (anyVerb) {
_logc->printf("\n");
_logc->printf("===\n");
_logc->printf("=== END LIR::compile(%p, %p)\n",
(void*)this, (void*)frag);
_logc->printf("========================================"
"========================================\n");
_logc->printf("\n");
});
/* END decorative postamble */
}
void Assembler::beginAssembly(Fragment *frag)
{
verbose_only( codeBytes = 0; )

View File

@ -241,11 +241,8 @@ namespace nanojit
class Assembler
{
friend class VerboseBlockReader;
public:
#ifdef NJ_VERBOSE
// Log controller object. Contains what-stuff-should-we-print
// bits, and a sink function for debug printing.
LogControl* _logc;
public:
// Buffer for holding text as we generate it in reverse order.
StringList* _outputCache;
@ -254,6 +251,10 @@ namespace nanojit
void outputf(const char* format, ...);
private:
// Log controller object. Contains what-stuff-should-we-print
// bits, and a sink function for debug printing.
LogControl* _logc;
// Buffer used in most of the output function. It must big enough
// to hold both the output line and the 'outlineEOL' buffer, which
// is concatenated onto 'outline' just before it is printed.
@ -281,6 +282,9 @@ namespace nanojit
Assembler(CodeAlloc& codeAlloc, Allocator& dataAlloc, Allocator& alloc, AvmCore* core, LogControl* logc);
void compile(Fragment *frag, Allocator& alloc, bool optimize
verbose_only(, LabelMap*));
void endAssembly(Fragment* frag);
void assemble(Fragment* frag, LirFilter* reader);
void beginAssembly(Fragment *frag);
@ -302,10 +306,10 @@ namespace nanojit
debug_only( void resourceConsistencyCheck(); )
debug_only( void registerConsistencyCheck(); )
Stats _stats;
CodeList* codeList; // finished blocks of code.
private:
Stats _stats;
void gen(LirFilter* toCompile);
NIns* genPrologue();
@ -387,12 +391,10 @@ namespace nanojit
NIns* _nExitIns; // current instruction in current exit code chunk
// note: _nExitIns == NULL until the first side exit is seen.
#ifdef NJ_VERBOSE
public:
size_t codeBytes; // bytes allocated in normal code chunks
size_t exitBytes; // bytes allocated in exit code chunks
#endif
private:
#define SWAP(t, a, b) do { t tmp = a; a = b; b = tmp; } while (0)
void swapCodeChunks();

View File

@ -2129,157 +2129,6 @@ namespace nanojit
return out->insCall(ci, args);
}
void compile(Assembler* assm, Fragment* frag, Allocator& alloc, bool optimize verbose_only(, LabelMap* labels))
{
verbose_only(
LogControl *logc = assm->_logc;
bool anyVerb = (logc->lcbits & 0xFFFF & ~LC_FragProfile) > 0;
bool asmVerb = (logc->lcbits & 0xFFFF & LC_Assembly) > 0;
bool liveVerb = (logc->lcbits & 0xFFFF & LC_Liveness) > 0;
)
/* BEGIN decorative preamble */
verbose_only(
if (anyVerb) {
logc->printf("========================================"
"========================================\n");
logc->printf("=== BEGIN LIR::compile(%p, %p)\n",
(void*)assm, (void*)frag);
logc->printf("===\n");
})
/* END decorative preamble */
verbose_only( if (liveVerb) {
logc->printf("\n");
logc->printf("=== Results of liveness analysis:\n");
logc->printf("===\n");
LirReader br(frag->lastIns);
LirFilter* lir = &br;
if (optimize) {
StackFilter* sf = new (alloc) StackFilter(lir, alloc, frag->lirbuf->sp, frag->lirbuf->rp);
lir = sf;
}
live(lir, alloc, frag, logc);
})
/* Set up the generic text output cache for the assembler */
verbose_only( StringList asmOutput(alloc); )
verbose_only( assm->_outputCache = &asmOutput; )
assm->beginAssembly(frag);
if (assm->error())
return;
//logc->printf("recompile trigger %X kind %d\n", (int)frag, frag->kind);
verbose_only( if (anyVerb) {
logc->printf("=== Translating LIR fragments into assembly:\n");
})
// now the the main trunk
verbose_only( if (anyVerb) {
logc->printf("=== -- Compile trunk %s: begin\n",
labels->format(frag));
})
// Used for debug printing, if needed
debug_only(ValidateReader *validate = NULL;)
verbose_only(
ReverseLister *pp_init = NULL;
ReverseLister *pp_after_sf = NULL;
)
// The LIR passes through these filters as listed in this
// function, viz, top to bottom.
// set up backwards pipeline: assembler <- StackFilter <- LirReader
LirFilter* lir = new (alloc) LirReader(frag->lastIns);
#ifdef DEBUG
// VALIDATION
validate = new (alloc) ValidateReader(lir);
lir = validate;
#endif
// INITIAL PRINTING
verbose_only( if (assm->_logc->lcbits & LC_ReadLIR) {
pp_init = new (alloc) ReverseLister(lir, alloc, frag->lirbuf->names, assm->_logc,
"Initial LIR");
lir = pp_init;
})
// STACKFILTER
if (optimize) {
StackFilter* stackfilter =
new (alloc) StackFilter(lir, alloc, frag->lirbuf->sp, frag->lirbuf->rp);
lir = stackfilter;
}
verbose_only( if (assm->_logc->lcbits & LC_AfterSF) {
pp_after_sf = new (alloc) ReverseLister(lir, alloc, frag->lirbuf->names, assm->_logc,
"After StackFilter");
lir = pp_after_sf;
})
assm->assemble(frag, lir);
// If we were accumulating debug info in the various ReverseListers,
// call finish() to emit whatever contents they have accumulated.
verbose_only(
if (pp_init) pp_init->finish();
if (pp_after_sf) pp_after_sf->finish();
)
verbose_only( if (anyVerb) {
logc->printf("=== -- Compile trunk %s: end\n",
labels->format(frag));
})
verbose_only(
if (asmVerb)
assm->outputf("## compiling trunk %s",
labels->format(frag));
)
assm->endAssembly(frag);
// Reverse output so that assembly is displayed low-to-high.
// Up to this point, assm->_outputCache has been non-NULL, and so
// has been accumulating output. Now we set it to NULL, traverse
// the entire list of stored strings, and hand them a second time
// to assm->output. Since _outputCache is now NULL, outputf just
// hands these strings directly onwards to logc->printf.
verbose_only( if (anyVerb) {
logc->printf("\n");
logc->printf("=== Aggregated assembly output: BEGIN\n");
logc->printf("===\n");
assm->_outputCache = 0;
for (Seq<char*>* p = asmOutput.get(); p != NULL; p = p->tail) {
char *str = p->head;
assm->outputf(" %s", str);
}
logc->printf("===\n");
logc->printf("=== Aggregated assembly output: END\n");
});
if (assm->error())
frag->fragEntry = 0;
verbose_only( frag->nCodeBytes += assm->codeBytes; )
verbose_only( frag->nExitBytes += assm->exitBytes; )
/* BEGIN decorative postamble */
verbose_only( if (anyVerb) {
logc->printf("\n");
logc->printf("===\n");
logc->printf("=== END LIR::compile(%p, %p)\n",
(void*)assm, (void*)frag);
logc->printf("========================================"
"========================================\n");
logc->printf("\n");
});
/* END decorative postamble */
}
LInsp LoadFilter::insLoad(LOpcode v, LInsp base, int32_t disp)
{
if (base != sp && base != rp)

View File

@ -1545,9 +1545,6 @@ namespace nanojit
}
};
class Assembler;
void compile(Assembler *assm, Fragment *frag, Allocator& alloc, bool optimize verbose_only(, LabelMap*));
verbose_only(void live(LirFilter* in, Allocator& alloc, Fragment* frag, LogControl*);)
class StackFilter: public LirFilter