rscope.hpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996, LongView Technologies L.L.C. $Revision: 1.32 $ */
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 
00025 // RScopes represent the inlined scopes of a nmethod during recompilation.
00026 // Essentially, they are another view of the ScopeDesc information, in a
00027 // format more convenient for the (re)compiler and extended with additional
00028 // info from PICs and uncommon branches.
00029 
00030 # ifdef DELTA_COMPILER
00031 
00032 class RNonDummyScope;
00033 class RInterpretedScope;
00034 
00035 class RScope : public PrintableResourceObj {
00036  protected:
00037   RNonDummyScope* _sender;
00038   const int _senderBCI;
00039  public:
00040   int nsends;           // estimated # of invocations (-1 == unknown)
00041     
00042   RScope(RNonDummyScope* s, int bci);
00043 
00044   // Type tests
00045   virtual bool isInterpretedScope() const                       { return false; }
00046   virtual bool isInlinedScope() const                           { return false; }
00047   virtual bool isNullScope() const                              { return false; }
00048   virtual bool isUninlinableScope() const                       { return false; }
00049   virtual bool isPICScope() const                               { return false; }
00050   virtual bool isUntakenScope() const                           { return false; }
00051   virtual bool isDatabaseScope() const                          { return false; }
00052 
00053   virtual bool isCompiled() const                               { return false; }
00054   RNonDummyScope* sender() const                                { return (RNonDummyScope*)_sender; }
00055   int senderBCI() const                                         { return _senderBCI; }
00056   virtual bool equivalent(InlinedScope* s) const = 0;
00057   virtual bool equivalent(LookupKey* l) const = 0;
00058   virtual RScope* subScope(int bci, LookupKey* l) const         { ShouldNotCallThis(); return NULL;}
00059   virtual GrowableArray<RScope*>* subScopes(int bci) const      { ShouldNotCallThis(); return NULL;}
00060   virtual bool  hasSubScopes(int bci) const                     { ShouldNotCallThis(); return false;}
00061   virtual bool isUncommonAt(int bci) const                      { ShouldNotCallThis(); return false; }
00062           // was send at this bci uncommon (never taken) in recompilee?  (false means "don't know")
00063   virtual bool isNotUncommonAt(int bci) const                   { ShouldNotCallThis(); return false; }
00064           // return true iff the send at this bci *must not* be made uncommon
00065   virtual bool isLite() const                                   { return false; }
00066   virtual nmethod* get_nmethod() const                          { return NULL; }
00067   virtual Expr* receiverExpr(PReg* p) const;
00068   virtual klassOop receiverKlass() const                        = 0;
00069   virtual methodOop method() const                              = 0;
00070   virtual LookupKey* key() const                                = 0;
00071   bool wasNeverExecuted() const;                                // was method never executed?
00072   virtual void print();
00073   virtual void print_short() = 0;
00074   virtual void printTree(int bci, int level) const;
00075 
00076   // Support for inlining database:
00077   // - returns the size of the inlining database tree.
00078   virtual int  inlining_database_size() { return 0; }
00079   // - prints the inlining database tree on a stream.
00080   virtual void print_inlining_database_on(outputStream* st, GrowableArray<PcDesc*>* uncommon, int bci = -1, int level = 0) { }
00081 
00082   virtual void extend() {}
00083   
00084   friend class RNonDummyScope;
00085 };
00086   
00087 class RNullScope : public RScope {
00088   // dummy scope for convenience; e.g. can call subScope() w/o checking for
00089   // this==NULL
00090  public:
00091   RNullScope() : RScope(NULL, 0)                        {}
00092   RNullScope(RNonDummyScope* sender, int bci) : RScope(sender, bci) {}
00093   bool isNullScope() const                              { return true; }
00094   bool equivalent(InlinedScope* s) const                { Unused(s);  return false; }
00095   bool equivalent(LookupKey* l) const                   { Unused(l);  return false; }
00096   RScope* subScope(int bci, LookupKey* l) const         { return (RScope*)this; }
00097   GrowableArray<RScope*>* subScopes(int bci) const;
00098   bool hasSubScopes(int bci) const                      { Unused(bci);  return false; }
00099   bool isUncommonAt(int bci) const                      { return false; }
00100   bool isNotUncommonAt(int bci) const                   { return false; }
00101   klassOop receiverKlass() const                        { ShouldNotCallThis(); return 0; }
00102   methodOop method() const                              { ShouldNotCallThis(); return 0; }
00103   LookupKey* key() const                                { ShouldNotCallThis(); return 0; }
00104   void print()                                          { print_short(); }
00105   void printTree(int bci, int level) const;
00106   void print_short();
00107 };
00108 
00109 class RUninlinableScope : public RNullScope {
00110   // scope marking "callee" of an uninlinable or megamorphic send
00111  public:
00112   RUninlinableScope(RNonDummyScope* sender, int bci);           // for interpreted senders
00113 
00114   bool isUninlinableScope() const                       { return true; }
00115   bool isNullScope() const                              { return false; }
00116   void print_inlining_database_on(outputStream* st, GrowableArray<PcDesc*>* uncommon, int bci, int level);
00117   void print_short();
00118 };
00119 
00120 class RNonDummyScope : public RScope {
00121   // abstract -- a non-dummy scope with subscopes
00122  protected:
00123   const int _level;                             // distance from root
00124   const int ncodes;                             // # byte codes in method
00125   GrowableArray<RScope*>** _subScopes;          // indexed by bci
00126  public:
00127   GrowableArray<RUncommonBranch*> uncommon;     // list of uncommon branches
00128 
00129   RNonDummyScope(RNonDummyScope* s, int bci, methodOop m, int level);
00130   RScope* subScope(int bci, LookupKey* l) const;  
00131         // return the subscope matching the lookup
00132         // return NullScope if no scope
00133   GrowableArray<RScope*>* subScopes(int bci) const;
00134         // return all subscopes at bci
00135   bool hasSubScopes(int bci) const;
00136   int  level() const                                    { return _level; }
00137   bool isUncommonAt(int bci) const;
00138   bool isNotUncommonAt(int bci) const;
00139   void addScope(int bci, RScope* s);
00140   void printTree(int bci, int level) const;
00141 
00142   virtual void unify(RNonDummyScope* s);
00143   static int compare(RNonDummyScope** a, RNonDummyScope** b); // for sorting
00144 
00145  protected:
00146   virtual void constructSubScopes(bool trusted);
00147   virtual int scopeID() const                           { ShouldNotCallThis(); return 0; }
00148   static bool trustPICs(methodOop m);
00149   void printSubScopes() const;
00150   static RNonDummyScope* constructRScopes(const nmethod* nm, bool trusted = true, int level = 0);
00151   friend class Compiler;
00152   friend class nmethod;
00153   friend class InliningDatabase;
00154 };
00155 
00156 class RInterpretedScope : public RNonDummyScope {
00157   // a scope corresponding to an interpreted method
00158   LookupKey* _key;
00159   methodOop _method;
00160   bool trusted;                 // is PIC info trusted?
00161   bool extended;                // subScopes computed?
00162  public:
00163   RInterpretedScope(RNonDummyScope* sender, int bci, LookupKey* key, methodOop m,
00164                     int level, bool trusted);
00165   bool isInterpretedScope() const                       { return true; }
00166   methodOop method() const                              { return _method; }
00167   LookupKey* key() const                                { return _key; }
00168   klassOop receiverKlass() const;
00169   bool equivalent(InlinedScope* s) const;
00170   bool equivalent(LookupKey* l) const;
00171   bool isUncommonAt(int bci) const;
00172   bool isNotUncommonAt(int bci) const                   { return false; }
00173   void extend();
00174   void print()                                          { print_short(); }
00175   void print_short();
00176 };
00177   
00178 class RInlinedScope : public RNonDummyScope {
00179   // an inlined scope in the recompilee
00180  public:
00181   const nmethod* nm;            // containing nmethod
00182   const ScopeDesc* desc;        // scope
00183 
00184   RInlinedScope(RNonDummyScope* s, int bci, const nmethod* nm, ScopeDesc* d, int level);
00185   bool isInlinedScope() const           { return true; }
00186   bool isCompiled() const               { return true; }
00187   methodOop method() const;
00188   nmethod* get_nmethod() const          { return (nmethod*)nm; }
00189   LookupKey* key() const;
00190   klassOop receiverKlass() const;
00191   bool isLite() const;
00192   bool equivalent(LookupKey* l) const;
00193   bool equivalent(InlinedScope* s) const;
00194   void print();
00195   void print_short();
00196   int  inlining_database_size();
00197   void print_inlining_database_on(outputStream* st, GrowableArray<PcDesc*>* uncommon, int bci, int level);
00198  protected:
00199   void constructSubScopes()             { ShouldNotCallThis(); }
00200   int scopeID() const                   { return desc->offset(); }
00201 };
00202 
00203 
00204 // this class should be removed -- it's just a top-level inlined or interpreted scope -- fix this   -Urs
00205 class RPICScope : public RNonDummyScope {
00206   // a scope called by the recompilee via a compiled PIC
00207  protected:
00208   const nmethod* caller;        // calling nmethod
00209   const CompiledIC* _sd;        // calling IC
00210   const PcDesc* pcDesc;         // calling pcDesc
00211   const klassOop klass;         // receiver klass
00212   const nmethod* nm;            // called nmethod (or NULL if interpreted)
00213   const methodOop _method;      // called method
00214   const bool trusted;           // is PIC info trusted?
00215   bool extended;                // subScopes computed?
00216   const ScopeDesc* desc;        // scope (or NULL if interpreted)
00217 
00218  public:    
00219   RPICScope(const nmethod* caller, PcDesc* pc, CompiledIC* s, klassOop k,
00220             ScopeDesc* d, nmethod* n, methodOop m, int nsends, int level, bool trusted);
00221   bool isPICScope() const               { return true; }
00222   bool isCompiled() const               { return nm != NULL; }
00223   methodOop method() const              { return _method; }
00224   nmethod* get_nmethod() const          { return (nmethod*)nm; }
00225   klassOop receiverKlass() const        { return klass; }
00226   CompiledIC* sd() const                { return (CompiledIC*)_sd; }
00227   LookupKey* key() const;
00228   bool isLite() const;
00229   bool equivalent(InlinedScope* s) const;
00230   bool equivalent(LookupKey* l) const;
00231   void unify(RNonDummyScope* s);
00232   void extend();
00233   void print();
00234   void print_short();
00235 
00236  protected:
00237   int scopeID() const                   { return pcDesc->scope; }
00238   static bool trustPICs(const nmethod* nm);
00239   friend RNonDummyScope* RNonDummyScope::constructRScopes(const nmethod* nm, bool trusted, int level);
00240 };
00241 
00242 class RDatabaseScope : public RNonDummyScope {
00243  // a scope created from the inlining database
00244  private:
00245   klassOop             _receiver_klass;
00246   methodOop            _method;
00247   LookupKey*           _key;
00248   GrowableArray<bool>* _uncommon;  // list of uncommon branch
00249  public:
00250   RDatabaseScope(RNonDummyScope* sender, int bci, klassOop receiver_klass, methodOop method, int level);
00251   bool isDatabaseScope()   const { return true; }
00252   methodOop method()       const { return _method; }
00253   LookupKey* key()         const { return _key; }
00254   klassOop receiverKlass() const { return _receiver_klass; }
00255   bool isUncommonAt(int bci) const;
00256   bool isNotUncommonAt(int bci) const;
00257 
00258   // Mark a bci as uncommon (used when constructing database scopes)
00259   void mark_as_uncommon(int bci) { _uncommon->at_put(bci, true); }
00260 
00261   bool equivalent(InlinedScope* s) const;
00262   bool equivalent(LookupKey* l)    const;
00263   void print();
00264   void print_short();
00265 };
00266 
00267 class RUntakenScope : public RNonDummyScope {
00268   //  send/inline cache that was never executed (either an empty ic or an untaken uncommon branch)
00269   const bool isUncommon;                        // true iff untaken uncommon branch
00270   const PcDesc* pc;
00271  public:
00272   RUntakenScope(RNonDummyScope* sender, PcDesc* pc, bool isUnlikely);
00273   bool isUntakenScope() const                   { return true; }
00274   bool isUnlikely() const                       { return isUncommon; }
00275   bool equivalent(InlinedScope* s) const        { Unused(s);  return false; }
00276   bool equivalent(LookupKey* l) const           { Unused(l);  return false; }
00277   Expr* receiverExpr(PReg* p) const;
00278   methodOop method()       const                { ShouldNotCallThis(); return NULL; }
00279   LookupKey* key()         const                { ShouldNotCallThis(); return NULL; }
00280   klassOop receiverKlass() const                { ShouldNotCallThis(); return NULL; }
00281   void extend() {}
00282   void print();
00283   void print_short();
00284  protected:
00285   int scopeID() const                           { return pc->scope; }
00286 };
00287 
00288 
00289 class RUncommonBranch : public PrintableResourceObj {
00290   // represents a taken uncommon branch
00291  public:
00292   RScope* scope;
00293   PcDesc* pcDesc;           // where the trap instruction is
00294 
00295   RUncommonBranch(RScope* r, PcDesc* pc) { scope = r; pcDesc = pc; }
00296 
00297   int bci() const                       { return pcDesc->byteCode; }
00298   void print();
00299 };
00300 
00301 # endif

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