00001 /* Copyright 1994, 1995, LongView Technologies, L.L.C. $Revision: 1.10 $ */ 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 // IC_Shape describes the (logical) shape in which an IC at a particular 00025 // call site apears; i.e. how many receivers have been registered in that 00026 // IC. 00027 // 00028 // Note: IC_Shape is the LOGICAL shape and it does not necessarily 00029 // correspond with the physical implementation of a call site; e.g. 00030 // a call site may contain a pic but nevertheless hold only one 00031 // receiver and therefore be monomorphic! 00032 00033 enum IC_Shape { 00034 anamorphic, // send has never been executed => no type information (size = 0) 00035 monomorphic, // only one receiver type available (size = 1) 00036 polymorphic, // more than one receiver type available (size > 1) 00037 megamorphic // many receiver types, only last one is available (size = 1) 00038 }; 00039 00040 00041 // IC_Iterator is the abstract superclass of all IC iterators in the system. 00042 // It SHOULD BE USED whenever iteration over an inline cache is required. 00043 00044 class IC_Iterator: public PrintableResourceObj { 00045 public: 00046 // IC information 00047 virtual int number_of_targets() const = 0; 00048 virtual IC_Shape shape() const = 0; 00049 virtual symbolOop selector() const = 0; 00050 00051 virtual InterpretedIC* interpreted_ic() const { ShouldNotCallThis(); return NULL; } 00052 virtual CompiledIC* compiled_ic() const { ShouldNotCallThis(); return NULL; } 00053 00054 virtual bool is_interpreted_ic() const { return false; } // is sender interpreted? 00055 virtual bool is_compiled_ic() const { return false; } // is sender compiled? 00056 virtual bool is_super_send() const = 0; // is super send? 00057 00058 // Iterating through entries 00059 virtual void init_iteration() = 0; 00060 virtual void advance() = 0; 00061 virtual bool at_end() const = 0; 00062 00063 // Accessing entries 00064 virtual klassOop klass() const = 0; 00065 00066 virtual bool is_interpreted() const = 0; // is current target interpreted? 00067 virtual bool is_compiled() const = 0; // is current target compiled? 00068 00069 virtual methodOop interpreted_method() const = 0; // target methodOop (always non-NULL) 00070 virtual nmethod* compiled_method() const = 0; // target nmethod; NULL if interpreted 00071 00072 // methods for direct access to ith element (will set iteration state to i) 00073 void goto_elem(int i); 00074 methodOop interpreted_method(int i); 00075 nmethod* compiled_method(int i); 00076 klassOop klass(int i); 00077 00078 }; 00079 00080 00081 // IC is the implementation independent representation for ICs. It allows manipulation 00082 // of ICs without dealing with concrete interpreted or compiled ICs and it SHOULD BE 00083 // USED instead whenever possible. 00084 // 00085 // Class hierarchy: 00086 // 00087 // IC ---- uses ----> IC_Iterator 00088 // InterpretedIC_Iterator --- uses ---> InterpretedIC 00089 // CompiledIC_Iterator --- uses ---> CompiledIC & PIC_Iterator 00090 // 00091 // (Note: One could also imagine IC being the abstract super class of InterpretedIC 00092 // and CompiledIC, which in turn are using InterpretedIC_Iterator and CompiledIC_Iterator. 00093 // However, right now, CompiledIC shares a common super class with PrimitiveIC, and 00094 // furthermore, the real ICs are composed out of at least 2 classes, one for the 00095 // monormorphic case and one for the polymorphic case. Having IC based on the 00096 // iterator seems to simplify this.) 00097 00098 class IC: public PrintableResourceObj { 00099 private: 00100 const IC_Iterator* _iter; 00101 00102 public: 00103 IC(IC_Iterator* iter) : _iter(iter) { } 00104 IC(CompiledIC* ic); 00105 IC(InterpretedIC* ic); 00106 00107 IC_Iterator* iterator() const { return (IC_Iterator*)_iter; } 00108 00109 // IC information 00110 int number_of_targets() const { return _iter->number_of_targets(); } 00111 IC_Shape shape() const { return _iter->shape(); } 00112 symbolOop selector() const { return _iter->selector(); } 00113 00114 InterpretedIC* interpreted_ic() const { return _iter->interpreted_ic(); } 00115 CompiledIC* compiled_ic() const { return _iter->compiled_ic(); } 00116 00117 bool is_interpreted_ic() const { return _iter->is_interpreted_ic(); } 00118 bool is_compiled_ic() const { return _iter->is_compiled_ic(); } 00119 bool is_super_send() const { return _iter->is_super_send(); } 00120 00121 GrowableArray<klassOop>* receiver_klasses() const; 00122 00123 // IC manipulation 00124 void replace(nmethod* nm); // replace entry matching nm's key with nm 00125 00126 // Debugging 00127 void print(); 00128 };