< prev index next >

src/hotspot/share/oops/generateOopMap.cpp

Print this page




  97 //  To be able to process "ret" bytecodes, we keep track of these return
  98 //  PC's in a 'retAddrs' structure in abstract interpreter context (when
  99 //  processing a "ret" bytecodes, it is not sufficient to know that it gets
 100 //  an argument of the right type 'p'; we need to know which address it
 101 //  returns to).
 102 //
 103 // (Note this comment is borrowed form the original author of the algorithm)
 104 
 105 // ComputeCallStack
 106 //
 107 // Specialization of SignatureIterator - compute the effects of a call
 108 //
 109 class ComputeCallStack : public SignatureIterator {
 110   CellTypeState *_effect;
 111   int _idx;
 112 
 113   void setup();
 114   void set(CellTypeState state)         { _effect[_idx++] = state; }
 115   int  length()                         { return _idx; };
 116 
 117   virtual void do_bool  ()              { set(CellTypeState::value); };
 118   virtual void do_char  ()              { set(CellTypeState::value); };
 119   virtual void do_float ()              { set(CellTypeState::value); };
 120   virtual void do_byte  ()              { set(CellTypeState::value); };
 121   virtual void do_short ()              { set(CellTypeState::value); };
 122   virtual void do_int   ()              { set(CellTypeState::value); };
 123   virtual void do_void  ()              { set(CellTypeState::bottom);};
 124   virtual void do_object(int begin, int end)  { set(CellTypeState::ref); };
 125   virtual void do_array (int begin, int end)  { set(CellTypeState::ref); };
 126 
 127   void do_double()                      { set(CellTypeState::value);
 128                                           set(CellTypeState::value); }
 129   void do_long  ()                      { set(CellTypeState::value);
 130                                            set(CellTypeState::value); }
 131 
 132 public:
 133   ComputeCallStack(Symbol* signature) : SignatureIterator(signature) {};
 134 
 135   // Compute methods
 136   int compute_for_parameters(bool is_static, CellTypeState *effect) {
 137     _idx    = 0;
 138     _effect = effect;
 139 
 140     if (!is_static)
 141       effect[_idx++] = CellTypeState::ref;
 142 
 143     iterate_parameters();
 144 
 145     return length();
 146   };
 147 
 148   int compute_for_returntype(CellTypeState *effect) {
 149     _idx    = 0;
 150     _effect = effect;
 151     iterate_returntype();
 152     set(CellTypeState::bottom);  // Always terminate with a bottom state, so ppush works
 153 
 154     return length();
 155   }
 156 };
 157 
 158 //=========================================================================================
 159 // ComputeEntryStack
 160 //
 161 // Specialization of SignatureIterator - in order to set up first stack frame
 162 //
 163 class ComputeEntryStack : public SignatureIterator {
 164   CellTypeState *_effect;
 165   int _idx;
 166 
 167   void setup();
 168   void set(CellTypeState state)         { _effect[_idx++] = state; }
 169   int  length()                         { return _idx; };
 170 
 171   virtual void do_bool  ()              { set(CellTypeState::value); };
 172   virtual void do_char  ()              { set(CellTypeState::value); };
 173   virtual void do_float ()              { set(CellTypeState::value); };
 174   virtual void do_byte  ()              { set(CellTypeState::value); };
 175   virtual void do_short ()              { set(CellTypeState::value); };
 176   virtual void do_int   ()              { set(CellTypeState::value); };
 177   virtual void do_void  ()              { set(CellTypeState::bottom);};
 178   virtual void do_object(int begin, int end)  { set(CellTypeState::make_slot_ref(_idx)); }
 179   virtual void do_array (int begin, int end)  { set(CellTypeState::make_slot_ref(_idx)); }
 180 
 181   void do_double()                      { set(CellTypeState::value);
 182                                           set(CellTypeState::value); }
 183   void do_long  ()                      { set(CellTypeState::value);
 184                                           set(CellTypeState::value); }
 185 
 186 public:
 187   ComputeEntryStack(Symbol* signature) : SignatureIterator(signature) {};
 188 
 189   // Compute methods
 190   int compute_for_parameters(bool is_static, CellTypeState *effect) {
 191     _idx    = 0;
 192     _effect = effect;
 193 
 194     if (!is_static)
 195       effect[_idx++] = CellTypeState::make_slot_ref(0);
 196 
 197     iterate_parameters();
 198 
 199     return length();
 200   };
 201 
 202   int compute_for_returntype(CellTypeState *effect) {
 203     _idx    = 0;
 204     _effect = effect;
 205     iterate_returntype();
 206     set(CellTypeState::bottom);  // Always terminate with a bottom state, so ppush works
 207 
 208     return length();
 209   }
 210 };
 211 
 212 //=====================================================================================
 213 //
 214 // Implementation of RetTable/RetTableEntry
 215 //
 216 // Contains function to itereate through all bytecodes
 217 // and find all return entry points
 218 //
 219 int RetTable::_init_nof_entries = 10;
 220 int RetTableEntry::_init_nof_jsrs = 5;
 221 
 222 RetTableEntry::RetTableEntry(int target, RetTableEntry *next) {
 223   _target_bci = target;
 224   _jsrs = new GrowableArray<intptr_t>(_init_nof_jsrs);
 225   _next = next;


1913 }
1914 
1915 // Copies bottom/zero terminated CTS string from "src" into "dst".
1916 //   Does NOT terminate with a bottom. Returns the number of cells copied.
1917 int GenerateOopMap::copy_cts(CellTypeState *dst, CellTypeState *src) {
1918   int idx = 0;
1919   while (!src[idx].is_bottom()) {
1920     dst[idx] = src[idx];
1921     idx++;
1922   }
1923   return idx;
1924 }
1925 
1926 void GenerateOopMap::do_field(int is_get, int is_static, int idx, int bci) {
1927   // Dig up signature for field in constant pool
1928   ConstantPool* cp     = method()->constants();
1929   int nameAndTypeIdx     = cp->name_and_type_ref_index_at(idx);
1930   int signatureIdx       = cp->signature_ref_index_at(nameAndTypeIdx);
1931   Symbol* signature      = cp->symbol_at(signatureIdx);
1932 
1933   // Parse signature (espcially simple for fields)
1934   assert(signature->utf8_length() > 0, "field signatures cannot have zero length");
1935   // The signature is UFT8 encoded, but the first char is always ASCII for signatures.
1936   char sigch = (char)*(signature->base());
1937   CellTypeState temp[4];
1938   CellTypeState *eff  = sigchar_to_effect(sigch, bci, temp);
1939 
1940   CellTypeState in[4];
1941   CellTypeState *out;
1942   int i =  0;
1943 
1944   if (is_get) {
1945     out = eff;
1946   } else {
1947     out = epsilonCTS;
1948     i   = copy_cts(in, eff);
1949   }
1950   if (!is_static) in[i++] = CellTypeState::ref;
1951   in[i] = CellTypeState::bottom;
1952   assert(i<=3, "sanity check");
1953   pp(in, out);
1954 }
1955 
1956 void GenerateOopMap::do_method(int is_static, int is_interface, int idx, int bci) {
1957  // Dig up signature for field in constant pool
1958   ConstantPool* cp  = _method->constants();


1974   assert(res_length<=4, "max value should be vv");
1975 
1976   // Compute arguments
1977   int arg_length = cse.compute_for_parameters(is_static != 0, in);
1978   assert(arg_length<=MAXARGSIZE, "too many locals");
1979 
1980   // Pop arguments
1981   for (int i = arg_length - 1; i >= 0; i--) ppop1(in[i]);// Do args in reverse order.
1982 
1983   // Report results
1984   if (_report_result_for_send == true) {
1985      fill_stackmap_for_opcodes(_itr_send, vars(), stack(), _stack_top);
1986      _report_result_for_send = false;
1987   }
1988 
1989   // Push return address
1990   ppush(out);
1991 }
1992 
1993 // This is used to parse the signature for fields, since they are very simple...
1994 CellTypeState *GenerateOopMap::sigchar_to_effect(char sigch, int bci, CellTypeState *out) {
1995   // Object and array
1996   if (sigch==JVM_SIGNATURE_CLASS || sigch==JVM_SIGNATURE_ARRAY) {

1997     out[0] = CellTypeState::make_line_ref(bci);
1998     out[1] = CellTypeState::bottom;
1999     return out;
2000   }
2001   if (sigch == JVM_SIGNATURE_LONG || sigch == JVM_SIGNATURE_DOUBLE) return vvCTS;  // Long and Double
2002   if (sigch == JVM_SIGNATURE_VOID) return epsilonCTS; // Void
2003   return vCTS;                                        // Otherwise
2004 }
2005 
2006 long GenerateOopMap::_total_byte_count = 0;
2007 elapsedTimer GenerateOopMap::_total_oopmap_time;
2008 
2009 // This function assumes "bcs" is at a "ret" instruction and that the vars
2010 // state is valid for that instruction. Furthermore, the ret instruction
2011 // must be the last instruction in "bb" (we store information about the
2012 // "ret" in "bb").
2013 void GenerateOopMap::ret_jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int varNo, int *data) {
2014   CellTypeState ra = vars()[varNo];
2015   if (!ra.is_good_address()) {
2016     verify_error("ret returns from two jsr subroutines?");
2017     return;
2018   }
2019   int target = ra.get_info();
2020 
2021   RetTableEntry* rtEnt = _rt.find_jsrs_for_target(target);
2022   int bci = bcs->bci();




  97 //  To be able to process "ret" bytecodes, we keep track of these return
  98 //  PC's in a 'retAddrs' structure in abstract interpreter context (when
  99 //  processing a "ret" bytecodes, it is not sufficient to know that it gets
 100 //  an argument of the right type 'p'; we need to know which address it
 101 //  returns to).
 102 //
 103 // (Note this comment is borrowed form the original author of the algorithm)
 104 
 105 // ComputeCallStack
 106 //
 107 // Specialization of SignatureIterator - compute the effects of a call
 108 //
 109 class ComputeCallStack : public SignatureIterator {
 110   CellTypeState *_effect;
 111   int _idx;
 112 
 113   void setup();
 114   void set(CellTypeState state)         { _effect[_idx++] = state; }
 115   int  length()                         { return _idx; };
 116 
 117   friend class SignatureIterator;  // so do_parameters_on can call do_type
 118   void do_type(BasicType type, bool for_return = false) {
 119     if (for_return && type == T_VOID) {
 120       set(CellTypeState::bottom);
 121     } else if (is_reference_type(type)) {
 122       set(CellTypeState::ref);
 123     } else {
 124       assert(is_java_primitive(type), "");
 125       set(CellTypeState::value);
 126       if (is_double_word_type(type)) {
 127         set(CellTypeState::value);
 128       }
 129     }
 130   }
 131 
 132  public:
 133   ComputeCallStack(Symbol* signature) : SignatureIterator(signature) {};
 134 
 135   // Compute methods
 136   int compute_for_parameters(bool is_static, CellTypeState *effect) {
 137     _idx    = 0;
 138     _effect = effect;
 139 
 140     if (!is_static)
 141       effect[_idx++] = CellTypeState::ref;
 142 
 143     do_parameters_on(this);
 144 
 145     return length();
 146   };
 147 
 148   int compute_for_returntype(CellTypeState *effect) {
 149     _idx    = 0;
 150     _effect = effect;
 151     do_type(return_type(), true);
 152     set(CellTypeState::bottom);  // Always terminate with a bottom state, so ppush works
 153 
 154     return length();
 155   }
 156 };
 157 
 158 //=========================================================================================
 159 // ComputeEntryStack
 160 //
 161 // Specialization of SignatureIterator - in order to set up first stack frame
 162 //
 163 class ComputeEntryStack : public SignatureIterator {
 164   CellTypeState *_effect;
 165   int _idx;
 166 
 167   void setup();
 168   void set(CellTypeState state)         { _effect[_idx++] = state; }
 169   int  length()                         { return _idx; };
 170 
 171   friend class SignatureIterator;  // so do_parameters_on can call do_type
 172   void do_type(BasicType type, bool for_return = false) {
 173     if (for_return && type == T_VOID) {
 174       set(CellTypeState::bottom);
 175     } else if (is_reference_type(type)) {
 176       set(CellTypeState::make_slot_ref(_idx));
 177     } else {
 178       assert(is_java_primitive(type), "");
 179       set(CellTypeState::value);
 180       if (is_double_word_type(type)) {
 181         set(CellTypeState::value);
 182       }
 183     }
 184   }
 185 
 186  public:
 187   ComputeEntryStack(Symbol* signature) : SignatureIterator(signature) {};
 188 
 189   // Compute methods
 190   int compute_for_parameters(bool is_static, CellTypeState *effect) {
 191     _idx    = 0;
 192     _effect = effect;
 193 
 194     if (!is_static)
 195       effect[_idx++] = CellTypeState::make_slot_ref(0);
 196 
 197     do_parameters_on(this);
 198 
 199     return length();
 200   };
 201 
 202   int compute_for_returntype(CellTypeState *effect) {
 203     _idx    = 0;
 204     _effect = effect;
 205     do_type(return_type(), true);
 206     set(CellTypeState::bottom);  // Always terminate with a bottom state, so ppush works
 207 
 208     return length();
 209   }
 210 };
 211 
 212 //=====================================================================================
 213 //
 214 // Implementation of RetTable/RetTableEntry
 215 //
 216 // Contains function to itereate through all bytecodes
 217 // and find all return entry points
 218 //
 219 int RetTable::_init_nof_entries = 10;
 220 int RetTableEntry::_init_nof_jsrs = 5;
 221 
 222 RetTableEntry::RetTableEntry(int target, RetTableEntry *next) {
 223   _target_bci = target;
 224   _jsrs = new GrowableArray<intptr_t>(_init_nof_jsrs);
 225   _next = next;


1913 }
1914 
1915 // Copies bottom/zero terminated CTS string from "src" into "dst".
1916 //   Does NOT terminate with a bottom. Returns the number of cells copied.
1917 int GenerateOopMap::copy_cts(CellTypeState *dst, CellTypeState *src) {
1918   int idx = 0;
1919   while (!src[idx].is_bottom()) {
1920     dst[idx] = src[idx];
1921     idx++;
1922   }
1923   return idx;
1924 }
1925 
1926 void GenerateOopMap::do_field(int is_get, int is_static, int idx, int bci) {
1927   // Dig up signature for field in constant pool
1928   ConstantPool* cp     = method()->constants();
1929   int nameAndTypeIdx     = cp->name_and_type_ref_index_at(idx);
1930   int signatureIdx       = cp->signature_ref_index_at(nameAndTypeIdx);
1931   Symbol* signature      = cp->symbol_at(signatureIdx);
1932 




1933   CellTypeState temp[4];
1934   CellTypeState *eff  = signature_to_effect(signature, bci, temp);
1935 
1936   CellTypeState in[4];
1937   CellTypeState *out;
1938   int i =  0;
1939 
1940   if (is_get) {
1941     out = eff;
1942   } else {
1943     out = epsilonCTS;
1944     i   = copy_cts(in, eff);
1945   }
1946   if (!is_static) in[i++] = CellTypeState::ref;
1947   in[i] = CellTypeState::bottom;
1948   assert(i<=3, "sanity check");
1949   pp(in, out);
1950 }
1951 
1952 void GenerateOopMap::do_method(int is_static, int is_interface, int idx, int bci) {
1953  // Dig up signature for field in constant pool
1954   ConstantPool* cp  = _method->constants();


1970   assert(res_length<=4, "max value should be vv");
1971 
1972   // Compute arguments
1973   int arg_length = cse.compute_for_parameters(is_static != 0, in);
1974   assert(arg_length<=MAXARGSIZE, "too many locals");
1975 
1976   // Pop arguments
1977   for (int i = arg_length - 1; i >= 0; i--) ppop1(in[i]);// Do args in reverse order.
1978 
1979   // Report results
1980   if (_report_result_for_send == true) {
1981      fill_stackmap_for_opcodes(_itr_send, vars(), stack(), _stack_top);
1982      _report_result_for_send = false;
1983   }
1984 
1985   // Push return address
1986   ppush(out);
1987 }
1988 
1989 // This is used to parse the signature for fields, since they are very simple...
1990 CellTypeState *GenerateOopMap::signature_to_effect(const Symbol* sig, int bci, CellTypeState *out) {
1991   // Object and array
1992   BasicType bt = Signature::basic_type(sig);
1993   if (is_reference_type(bt)) {
1994     out[0] = CellTypeState::make_line_ref(bci);
1995     out[1] = CellTypeState::bottom;
1996     return out;
1997   }
1998   if (is_double_word_type(bt)) return vvCTS; // Long and Double
1999   if (bt == T_VOID) return epsilonCTS;       // Void
2000   return vCTS;                               // Otherwise
2001 }
2002 
2003 long GenerateOopMap::_total_byte_count = 0;
2004 elapsedTimer GenerateOopMap::_total_oopmap_time;
2005 
2006 // This function assumes "bcs" is at a "ret" instruction and that the vars
2007 // state is valid for that instruction. Furthermore, the ret instruction
2008 // must be the last instruction in "bb" (we store information about the
2009 // "ret" in "bb").
2010 void GenerateOopMap::ret_jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int varNo, int *data) {
2011   CellTypeState ra = vars()[varNo];
2012   if (!ra.is_good_address()) {
2013     verify_error("ret returns from two jsr subroutines?");
2014     return;
2015   }
2016   int target = ra.get_info();
2017 
2018   RetTableEntry* rtEnt = _rt.find_jsrs_for_target(target);
2019   int bci = bcs->bci();


< prev index next >