inliner.hpp

Go to the documentation of this file.
00001 /* Copyright 1994, LongView Technologies L.L.C. $Revision: 1.19 $ */
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 # ifdef DELTA_COMPILER
00025 
00026 // The Inliner controls and performs method inlining in the compiler.  It contains 
00027 // all the code to set up the new scopes once a go-ahead decision has been made.
00028 // (Most of) the actual decisions are made by InliningPolicy (further down).
00029 
00030 enum SendKind { NormalSend, SelfSend, SuperSend };
00031 
00032 class Inliner: public PrintableResourceObj {
00033  protected:
00034   InlinedScope* sender;         // scope containing the send
00035   SendKind kind;
00036   InlinedScope* callee;         // scope being inlined (or NULL)
00037   SendInfo* _info;              // send being inlined
00038   Expr* res;                    // result expression
00039   SAPReg* resultPR;             // result PReg
00040   NodeBuilder* gen;             // current generator (sender's or callee's)
00041   MergeNode* merge;             // where multiple versions merge (NULL if only one)
00042   char* _msg;                   // reason for not inlining the send
00043   bool lastLookupFailed;        // last tryLookup failed because no method found
00044  public:
00045   int depth;                    // nesting depth (for debug output)
00046   
00047   Inliner(InlinedScope* s)      { this->sender = s; initialize(); }
00048 
00049   // The inlineXXX generate a non-inlined send if necessary, with the exception
00050   // of inlineBlockInvocation which returns NULL (and does nothing) if the block
00051   // shouldn't be inlined
00052   Expr* inlineNormalSend        (SendInfo* info);
00053   Expr* inlineSuperSend         (SendInfo* info);
00054   Expr* inlineSelfSend          (SendInfo* info);
00055   Expr* inlineBlockInvocation   (SendInfo* info);
00056 
00057   SendInfo* info() const        { return _info; }
00058   char* msg() const             { return _msg; }
00059   void print();
00060 
00061  protected:
00062   void initialize();
00063   void initialize(SendInfo* info, SendKind kind);
00064   Expr* inlineSend();
00065   void tryInlineSend();
00066   Expr* inlineMerge(SendInfo* info);
00067   Expr* picPredict ();
00068   Expr* picPredictUnlikely(SendInfo* info, RUntakenScope* uscope);
00069   Expr* typePredict();
00070   Expr* genRealSend();
00071   InlinedScope* tryLookup(Expr* rcvr);    // try lookup and determine if should inline send
00072   Expr* doInline(Node* start);
00073   char* checkSendInPrimFailure();
00074   InlinedScope* notify(const char* msg);
00075   RScope* makeBlockRScope(const Expr* rcvr, LookupKey* key, const methodOop method);
00076   InlinedScope* makeScope(const Expr* rcvr, const klassOop klass, const LookupKey* key, const methodOop method);
00077   Expr* makeResult(Expr* res);
00078   bool checkSenderPath(Scope* here, ScopeDesc* there) const;
00079 
00080   friend class InliningPolicy;
00081 };
00082 
00083 
00084 class InliningPolicy : public ResourceObj {
00085   // the instance variables only serve as temporary storage during shouldInline()
00086  protected:
00087   methodOop method;             // target method
00088  public:
00089   int calleeCost;               // cost of inlining candidate
00090 
00091   InliningPolicy() { method = NULL; }
00092   char* basic_shouldInline(methodOop method);
00093         // should send be inlined?  returns NULL (--> yes) or rejection msg 
00094         // doesn't rely on compiler-internal information
00095 
00096   static bool isCriticalSmiSelector   (const symbolOop sel);
00097   static bool isCriticalArraySelector (const symbolOop sel);
00098   static bool isCriticalBoolSelector  (const symbolOop sel);
00099 
00100   // predicted by compiler?
00101   static bool isPredictedSmiSelector  (const symbolOop sel);
00102   static bool isPredictedArraySelector(const symbolOop sel);
00103   static bool isPredictedBoolSelector (const symbolOop sel);
00104 
00105   // predicted by interpreter?
00106   static bool isInterpreterPredictedSmiSelector  (const symbolOop sel);
00107   static bool isInterpreterPredictedArraySelector(const symbolOop sel);
00108   static bool isInterpreterPredictedBoolSelector (const symbolOop sel);
00109 
00110  protected:
00111   virtual klassOop receiverKlass() const = 0;           // return receiver klass (NULL if unknown)
00112   virtual klassOop nthArgKlass(int nth) const = 0;      // return nth argument of method (NULL if unknown)
00113   bool shouldNotInline() const;
00114   bool isBuiltinMethod() const;
00115 };
00116 
00117 
00118 // inlining policy of compiler
00119 class CompilerInliningPolicy : public InliningPolicy {
00120  protected:
00121   InlinedScope* sender;         // sending scope
00122   Expr* rcvr;                   // target receiver 
00123 
00124   klassOop receiverKlass() const;
00125   klassOop nthArgKlass(int n) const;
00126  public:
00127   char* shouldInline(InlinedScope* sender, InlinedScope* callee);
00128         // should send be inlined?  returns NULL (--> yes) or rejection msg 
00129 };
00130 
00131 
00132 // "inlining policy" of recompiler (i.e., guesses whether method will be
00133 // inlined or not
00134 class RecompilerInliningPolicy : public InliningPolicy {
00135  protected:
00136   deltaVFrame* _vf;             // top vframe of this method/nmethod; may be NULL
00137   klassOop receiverKlass() const;
00138   klassOop nthArgKlass(int n) const;
00139   char* shouldInline(nmethod* nm);      // should nm be inlined?
00140 
00141  public:
00142   char* shouldInline(RFrame* rf);
00143         // would send be inlined by compiler?  returns NULL (--> yes) or rejection msg 
00144 };
00145 
00146 # endif

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