compUtils.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, LongView Technologies L.L.C. $Revision: 1.9 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 # include "incls/_precompiled.incl"
00025 
00026 #ifdef DELTA_COMPILER
00027 
00028 # include "incls/_compUtils.cpp.incl"
00029 
00030 PerformanceDebugger::PerformanceDebugger(Compiler* c) {
00031   this->c = c; compileReported = false;
00032   blocks = new GrowableArray<BlockPReg*>(5);
00033   reports = new GrowableArray<char*>(5);
00034   str = NULL;
00035   notInlinedBecauseNmethodTooBig = NULL;
00036 }
00037 
00038 void PerformanceDebugger::start_report() {
00039   str = new stringStream(256);
00040   report_compile();
00041 }
00042 
00043 void PerformanceDebugger::stop_report() {
00044   char* report = str->as_string();
00045   for (int i = reports->length() - 1; i >= 0; i--) {
00046     if (strcmp(reports->at(i), report) == 0) return;  // already printed identical msg
00047   }
00048   std->print(report);
00049   reports->append(report);
00050   str = NULL;
00051 }
00052 
00053 void PerformanceDebugger::report_compile() {
00054   if (!compileReported) {
00055     compileReported = true;
00056     std->print("\n*while compiling nmethod for %s:\n", c->key->print_string());
00057   }
00058 }
00059 
00060 // always put one of these in your top_level reporting method
00061 // see PerformanceDebugger::report_context for an example
00062 class Reporter {
00063   PerformanceDebugger* d;
00064 public:
00065   Reporter(PerformanceDebugger* d) { this->d = d; d->start_report(); }
00066   ~Reporter() { d->stop_report(); }
00067 };
00068 
00069 void PerformanceDebugger::finish_reporting() {
00070   // output messages about non-inlined sends
00071   if (DebugPerformance && notInlinedBecauseNmethodTooBig) {
00072     Reporter r(this);
00073     str->print("  did not inline the following sends because the nmethod was getting too big:");
00074     int len = notInlinedBecauseNmethodTooBig->length();
00075     for (int i = 0; i < min(9, len); i++) {
00076       if (i % 3 == 0) str->print("\n    ");
00077       InlinedScope* s = notInlinedBecauseNmethodTooBig->at(i);
00078       str->print("%s  ", s->key()->print_string());
00079     }
00080     if (i < len) str->print("\n    (%d more sends omitted)\n", len);
00081     str->put('\n');
00082   }
00083 }
00084 
00085 void PerformanceDebugger::report_context(InlinedScope* s) {
00086   if (!DebugPerformance) return;
00087   Reporter r(this);
00088   GrowableArray<Expr*>* temps = s->contextTemporaries();
00089   const int len = temps->length();
00090   int nused = 0;
00091   for (int i = 0; i < len; i++) {
00092     PReg* r = temps->at(i)->preg();
00093     if (r->uplevelR() || r->uplevelW() || (r->isBlockPReg() && !r->isUnused())) nused++;
00094   }
00095   if (nused == 0) {
00096     str->print("  could not eliminate context of scope %s (fixable compiler restriction; should be eliminated)\n", s->key()->print_string());
00097   } else {
00098     str->print("  could not eliminate context of scope %s; temp(s) still used: ", s->key()->print_string());
00099     for (int j = 0; j < len; j++) {
00100       PReg* r = temps->at(j)->preg();
00101       if (r->uplevelR() || r->uplevelW()) {
00102         str->print("%d ", j);
00103       } else if (r->isBlockPReg() && !r->isUnused()) {
00104         str->print("%d (non-inlined block)", j);
00105       }
00106     }
00107     str->print("\n");
00108   } 
00109 }
00110 
00111 void PerformanceDebugger::report_toobig(InlinedScope* s) {
00112   if (!DebugPerformance) return;
00113   report_compile();
00114   if (!notInlinedBecauseNmethodTooBig) notInlinedBecauseNmethodTooBig = new GrowableArray<InlinedScope*>(20);
00115   notInlinedBecauseNmethodTooBig->append(s);
00116 }
00117 
00118 void PerformanceDebugger::report_uncommon(bool reoptimizing) {
00119   if (!DebugPerformance) return;
00120   Reporter r(this);
00121   if (reoptimizing) {
00122     str->print(" -- reoptimizing previously compiled 'uncommon' version of nmethod\n");
00123   } else {
00124     str->print(" -- creating 'uncommon' version of nmethod\n");
00125   }
00126 }
00127 
00128 void PerformanceDebugger::report_prim_failure(primitive_desc* pd) {
00129   // suppress methods for uncommon compiles -- too many (and not interesting)
00130   if (!DebugPerformance || theCompiler->is_uncommon_compile()) return;
00131   Reporter r(this);
00132   str->print(" primitive failure of %s not uncommon\n", pd->name());
00133 }
00134 
00135 void PerformanceDebugger::report_block(Node* n, BlockPReg* blk, char* what) {
00136   if (!DebugPerformance) return;
00137   if (blocks->contains(blk)) return;
00138   if (blk->method()->is_clean_block()) return;
00139   Reporter r(this);
00140   str->print(" could not eliminate block in ");
00141   blk->method()->home()->selector()->print_symbol_on(str);
00142   str->print(" because it is %s in scope %s at bytecode %d", 
00143              what, n->scope()->key()->print_string(), n->bci());
00144   InterpretedIC* ic = n->scope()->method()->ic_at(n->bci());
00145   if (ic) str->print(" (send of %s)", ic->selector()->copy_null_terminated());
00146   str->print("\n");
00147   blocks->append(blk);
00148 }
00149 
00150 #endif

Generated on Mon Oct 9 13:37:07 2006 for Strongtalk VM by  doxygen 1.4.7