primInliner.hpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.36 $ */
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 PrimInliner inlines primitives (if possible) or generates a non-inlined call
00027 // there's one PrimInliner for each primitive call encountered
00028 class PrimInliner: public PrintableResourceObj {
00029  private:
00030   NodeBuilder*          _gen;                           // the active node generator
00031   int                   _bci;                           // bci of primitive call
00032   primitive_desc*       _pdesc;                         // the primitive
00033   MethodInterval*       _failure_block;                 // code in primitive failure block
00034 
00035   InlinedScope*         _scope;                         // the current scope
00036   ExprStack*            _exprStack;                     // the current expression stack
00037   GrowableArray<Expr*>* _params;                        // the copy of the top number_of_parameters() elements of _exprStack
00038                                                         // NB: don't use _params->at(...) -- use parameter() below
00039   bool  _usingUncommonTrap;                             // using uncommon trap for prim. failure?
00040   bool  _cannotFail;                                    // true if primitive can't fail
00041   int   number_of_parameters()  const                   { return _pdesc->number_of_parameters(); }
00042   Expr* parameter(int index)    const                   { return _params->at(index); }          // parameter of primitive call
00043   bool  is_power_of_2(int x) const                      { return x > 0 && (x & (x-1)) == 0; }   // true if there's an n with 2^n = x
00044   int   log2(int x) const;                              // if is_power_of_2(x) then 2^(log2(x)) = x
00045 
00046   inline void assert_failure_block();                   // debugging: asserts that there's a failure block
00047   inline void assert_no_failure_block();                // debugging: asserts that there's no failure block
00048   inline void assert_receiver();                        // debugging: asserts that the first parameter is self
00049 
00050   Expr* tryConstantFold();                              // try constant-folding the primitive
00051   Expr* tryTypeCheck();                                 // try constant-folding primitive failures
00052   Expr* tryInline();                                    // try inlining or special-casing the primitive
00053   Expr* genCall(bool canFail);                          // generate non-inlined primitive call
00054   Expr* primitiveFailure(symbolOop failureCode);        // handle primitive that always fail
00055   Expr* merge_failure_block(Node* ok_exit, Expr* ok_result, Node* failure_exit, Expr* failure_code, bool ok_result_is_read_only = true);
00056   symbolOop failureSymbolForArg(int i);                 // error string for "n.th arg has wrong type"
00057   bool  shouldUseUncommonTrap();                        // use uncommon trap for primitive failure?
00058   inline bool basic_shouldUseUncommonTrap() const;
00059   
00060   Expr* smi_ArithmeticOp(ArithOpCode  op  , Expr* x, Expr* y);
00061   Expr* smi_Comparison  (BranchOpCode cond, Expr* x, Expr* y);
00062   Expr* smi_BitOp       (ArithOpCode  op  , Expr* x, Expr* y);
00063   Expr* smi_Div         (Expr* x, Expr* y);
00064   Expr* smi_Mod         (Expr* x, Expr* y);
00065   Expr* smi_Shift       (Expr* x, Expr* y);
00066 
00067   Expr* array_size();
00068   Expr* array_at_ifFail(ArrayAtNode::AccessType access_type);
00069   Expr* array_at_put_ifFail(ArrayAtPutNode::AccessType access_type);
00070 
00071   Expr* obj_new();
00072   Expr* obj_shallowCopy();
00073   Expr* obj_equal();
00074   Expr* obj_class(bool has_receiver);
00075   Expr* obj_hash(bool has_receiver);
00076   
00077   Expr* proxy_byte_at();
00078   Expr* proxy_byte_at_put();
00079 
00080   Expr* block_primitiveValue();
00081 
00082  public:
00083   PrimInliner(NodeBuilder* gen, primitive_desc* pdesc, MethodInterval* failure_block);
00084   void generate();
00085 
00086   static Expr* generate_cond(BranchOpCode cond, NodeBuilder* gen, PReg* resPReg); 
00087       // generates cond. branch and code to assign true/false to resPReg
00088 
00089   void print();
00090 };
00091 
00092 # endif

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