nmethod* Compiler::compile() { NewBackendGuard guard; if ((PrintProgress > 0) && (nofCompilations % PrintProgress == 0)) std->print("."); const char* compiling; if (DeltaProcess::active()->isUncommon()) { compiling = recompilee ? "Uncommon-Recompiling " : "Uncommon-Compiling "; } else { if (_uses_inlining_database) { compiling = recompilee ? "Recompiling (database)" : "Compiling (database)"; } else { compiling = recompilee ? "Recompiling " : "Compiling "; } } EventMarker em("%s%#lx %#lx", compiling, key->selector(), NULL); // don't use uncommon traps when recompiling because of trap useUncommonTraps = DeferUncommonBranches && !is_uncommon_compile(); if (is_uncommon_compile()) reporter->report_uncommon(false); if (recompilee && recompilee->isUncommonRecompiled()) reporter->report_uncommon(true); // don't use counters when compiling from DB FlagSetting fs(UseRecompilation, UseRecompilation && !is_database_compile()); bool should_trace = _uses_inlining_database ? PrintInliningDatabaseCompilation : PrintCompilation; TraceTime t(compiling, should_trace); if (should_trace || PrintCode) { print_key(std); if (PrintCode || PrintInlining) std->print("\n"); } topScope->genCode(); fixupNLRTestPoints(); buildBBs(); if (PrintCode) print_code(false); if (verifyOften) bbIterator->verify(); // compute escaping blocks and up-level accessed vars bbIterator->computeEscapingBlocks(); bbIterator->computeUplevelAccesses(); if (verifyOften) bbIterator->verify(); //if (PrintCode) print_code(false); // construct def & use information bbIterator->makeUses(); if (verifyOften) bbIterator->verify(); //if (PrintCode) print_code(false); if (LocalCopyPropagate) { bbIterator->localCopyPropagate(); if (verifyOften) bbIterator->verify(); } //if (PrintCode) print_code(false); if (GlobalCopyPropagate) { bbIterator->globalCopyPropagate(); if (verifyOften) bbIterator->verify(); } //if (PrintCode) print_code(false); if (BruteForcePropagate) { bbIterator->bruteForceCopyPropagate(); if (verifyOften) bbIterator->verify(); } //if (PrintCode) print_code(false); if (EliminateUnneededNodes) { bbIterator->eliminateUnneededResults(); if (verifyOften) bbIterator->verify(); } //if (PrintCode) print_code(false); if (OptimizeIntegerLoops) { // run after copy propagation so that loop increment is easier to recognize // also run after eliminateUnneededResults so that cpInfo is set for eliminated PRegs topScope->optimizeLoops(); if (verifyOften) bbIterator->verify(); } //if (PrintCode) print_code(false); // compute existence & format of run-time context objects and blocks computeBlockInfo(); // allocate floats _totalNofFloatTemporaries = topScope->allocateFloatTemporaries(0); // HACK: Fix preallocation // Necessary because a few primitives (allocateContext/Closure) need self or // the previous context after calling a primitive; i.e., self or the previous // context should not be allocated to a register. Currently not working correctly // -> allocated to stack as a temporary fix for the problem. theAllocator->preAllocate(topScope->self()->preg()); bbIterator->localAlloc(); // allocate regs within basic blocks theAllocator->allocate(bbIterator->globals); if (PrintCode) print_code(false); #ifdef ASSERT bbIterator->verify(); #endif if (PrintDebugInfoGeneration) { std->cr(); std->cr(); std->print_cr("Start of debugging info."); } topScope->generateDebugInfo(); // must come before gen to set scopeInfo topScope->generateDebugInfoForNonInlinedBlocks(); // generate machine code theMacroAssm = new MacroAssembler(_code); if (UseNewBackend) { PRegMapping* mapping = new PRegMapping(theMacroAssm, topScope->nofArguments(), 6, topScope->nofTemporaries()); CodeGenerator* cgen = new CodeGenerator(theMacroAssm, mapping); cgen->initialize(topScope); bbIterator->apply(cgen); cgen->finalize(topScope); } else { // use a node visitor to generate code OldCodeGenerator* cgen = new OldCodeGenerator(); bbIterator->apply(cgen); } theMacroAssm->finalize(); theMacroAssm = NULL; #ifndef ASSERT if (verifyOften) { #endif bool ok = bbIterator->verifyLabels(); if (!ok) print_code(false); #ifndef ASSERT } #endif rec->generate(); // write debugging info nmethod* nm = new_nmethod(this); // construct new nmethod em.event.args[1] = nm; if (PrintAssemblyCode) Disassembler::decode(nm); reporter->finish_reporting(); if (should_trace) { lprintf(": %#lx (%d bytes; level %ld v%d)\n", nm, nm->instsLen(), nm->level(), nm->version()); flush_logFile(); } if (verifyOften) nm->verify(); if (PrintDebugInfo) nm->print_inlining(std, true); return nm; }