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