hotspot/src/share/vm/compiler/oopMap.hpp

Print this page
rev 611 : Merge
   1 #ifdef USE_PRAGMA_IDENT_HDR
   2 #pragma ident "@(#)oopMap.hpp   1.81 07/09/28 10:23:19 JVM"
   3 #endif
   4 /*
   5  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  


  32 //   Dead        - Dead; can be Zapped for debugging
  33 //   CalleeXX    - Callee saved; also describes which caller register is saved
  34 //   DerivedXX   - A derived oop; original oop is described.
  35 //
  36 // OopMapValue describes a single OopMap entry
  37 
  38 class frame;
  39 class RegisterMap;
  40 class DerivedPointerEntry;
  41 
  42 class OopMapValue: public StackObj {
  43   friend class VMStructs;
  44 private:
  45   short _value;
  46   int value() const                                 { return _value; }
  47   void set_value(int value)                         { _value = value; }
  48   short _content_reg;
  49 
  50 public:
  51   // Constants
  52   enum { type_bits                = 6,
  53          register_bits            = BitsPerShort - type_bits };
  54  
  55   enum { type_shift               = 0,
  56          register_shift           = type_bits };
  57 
  58   enum { type_mask                = right_n_bits(type_bits),
  59          type_mask_in_place       = type_mask << type_shift,
  60          register_mask            = right_n_bits(register_bits),
  61          register_mask_in_place   = register_mask << register_shift };
  62 
  63   enum oop_types {              // must fit in type_bits
  64          unused_value =0,       // powers of 2, for masking OopMapStream
  65          oop_value = 1,
  66          value_value = 2,
  67          dead_value = 4,
  68          callee_saved_value = 8,
  69          derived_oop_value= 16,
  70          stack_obj = 32 };
  71 
  72   // Constructors
  73   OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
  74   OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg,t); }
  75   OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg,t); set_content_reg(reg2); }
  76   OopMapValue (CompressedReadStream* stream) { read_from(stream); }
  77 
  78   // Archiving
  79   void write_on(CompressedWriteStream* stream) {
  80     stream->write_int(value());
  81     if(is_callee_saved() || is_derived_oop()) {
  82       stream->write_int(content_reg()->value());
  83     }
  84   }
  85 
  86   void read_from(CompressedReadStream* stream) {
  87     set_value(stream->read_int());
  88     if(is_callee_saved() || is_derived_oop()) {
  89       set_content_reg(VMRegImpl::as_VMReg(stream->read_int(), true));
  90     }
  91   }
  92 
  93   // Querying
  94   bool is_oop()               { return mask_bits(value(), type_mask_in_place) == oop_value; } 
  95   bool is_value()             { return mask_bits(value(), type_mask_in_place) == value_value; } 
  96   bool is_dead()              { return mask_bits(value(), type_mask_in_place) == dead_value; } 
  97   bool is_callee_saved()      { return mask_bits(value(), type_mask_in_place) == callee_saved_value; } 
  98   bool is_derived_oop()       { return mask_bits(value(), type_mask_in_place) == derived_oop_value; } 
  99   bool is_stack_obj()         { return mask_bits(value(), type_mask_in_place) == stack_obj; }
 100 
 101   void set_oop()              { set_value((value() & register_mask_in_place) | oop_value); } 
 102   void set_value()            { set_value((value() & register_mask_in_place) | value_value); } 
 103   void set_dead()             { set_value((value() & register_mask_in_place) | dead_value); } 
 104   void set_callee_saved()     { set_value((value() & register_mask_in_place) | callee_saved_value); } 
 105   void set_derived_oop()      { set_value((value() & register_mask_in_place) | derived_oop_value); } 
 106   void set_stack_obj()        { set_value((value() & register_mask_in_place) | stack_obj); }
 107 
 108   VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
 109   oop_types type() const      { return (oop_types)mask_bits(value(), type_mask_in_place); }
 110 
 111   static bool legal_vm_reg_name(VMReg p) {
 112     return (p->value()  == (p->value() & register_mask));
 113   }
 114 
 115   void set_reg_type(VMReg p, oop_types t) { 
 116     set_value((p->value() << register_shift) | t);
 117     assert(reg() == p, "sanity check" );
 118     assert(type() == t, "sanity check" );
 119   }
 120 
 121 
 122   VMReg content_reg() const       { return VMRegImpl::as_VMReg(_content_reg, true); }
 123   void set_content_reg(VMReg r)   { _content_reg = r->value(); }
 124 
 125   // Physical location queries
 126   bool is_register_loc()      { return reg()->is_reg(); }
 127   bool is_stack_loc()         { return reg()->is_stack(); }
 128 
 129   // Returns offset from sp.
 130   int stack_offset() {
 131     assert(is_stack_loc(), "must be stack location");
 132     return reg()->reg2stack();
 133   }
 134 
 135   void print( ) const PRODUCT_RETURN;

 136 };
 137 
 138 
 139 class OopMap: public ResourceObj {
 140   friend class OopMapStream;
 141   friend class VMStructs;
 142  private:
 143   int  _pc_offset; 
 144   int  _omv_count;
 145   int  _omv_data_size;
 146   unsigned char* _omv_data;
 147   CompressedWriteStream* _write_stream;
 148 
 149   debug_only( OopMapValue::oop_types* _locs_used; int _locs_length;)
 150 
 151   // Accessors
 152   unsigned char* omv_data() const             { return _omv_data; }
 153   void set_omv_data(unsigned char* value)     { _omv_data = value; }
 154   int omv_data_size() const                   { return _omv_data_size; }
 155   void set_omv_data_size(int value)           { _omv_data_size = value; }


 161 
 162  private:
 163   enum DeepCopyToken { _deep_copy_token };
 164   OopMap(DeepCopyToken, OopMap* source);  // used only by deep_copy
 165 
 166  public:
 167   OopMap(int frame_size, int arg_count);
 168 
 169   // pc-offset handling
 170   int offset() const     { return _pc_offset; }
 171   void set_offset(int o) { _pc_offset = o; }
 172 
 173   // Check to avoid double insertion
 174   debug_only(OopMapValue::oop_types locs_used( int indx ) { return _locs_used[indx]; })
 175   
 176   // Construction
 177   // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
 178   // slots to hold 4-byte values like ints and floats in the LP64 build.
 179   void set_oop  ( VMReg local);
 180   void set_value( VMReg local);

 181   void set_dead ( VMReg local);
 182   void set_callee_saved( VMReg local, VMReg caller_machine_register );
 183   void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
 184   void set_stack_obj( VMReg local);
 185   void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
 186 
 187   int heap_size() const;
 188   void copy_to(address addr);
 189   OopMap* deep_copy();
 190 
 191   bool has_derived_pointer() const PRODUCT_RETURN0;
 192 
 193   bool legal_vm_reg_name(VMReg local) {
 194      return OopMapValue::legal_vm_reg_name(local);
 195   }
 196 
 197   // Printing
 198   void print_on(outputStream* st) const PRODUCT_RETURN;
 199   void print() const { print_on(tty); }
 200 };
 201 
 202 
 203 class OopMapSet : public ResourceObj {
 204   friend class VMStructs;
 205  private:
 206   int _om_count;
 207   int _om_size;
 208   OopMap** _om_data;
 209 
 210   int om_count() const              { return _om_count; }
 211   void set_om_count(int value)      { _om_count = value; }
 212   void increment_count()            { _om_count++; }
 213   int om_size() const               { return _om_size; }
 214   void set_om_size(int value)       { _om_size = value; }
 215   OopMap** om_data() const          { return _om_data; }
 216   void set_om_data(OopMap** value)  { _om_data = value; }
 217   void grow_om_data();
 218   void set(int index,OopMap* value) { assert((index == 0) || ((index > 0) && (index < om_size())),"bad index"); _om_data[index] = value; }


 230 
 231   // Returns the only oop map. Used for reconstructing 
 232   // Adapter frames during deoptimization
 233   OopMap* singular_oop_map();
 234 
 235   // returns OopMap in that is anchored to the pc
 236   OopMap* find_map_at_offset(int pc_offset) const; 
 237 
 238   int heap_size() const;
 239   void copy_to(address addr);
 240 
 241   // Iterates through frame for a compiled method
 242   static void oops_do            (const frame* fr,
 243                                   const RegisterMap* reg_map, OopClosure* f); 
 244   static void update_register_map(const frame* fr, RegisterMap *reg_map);
 245 
 246   // Iterates through frame for a compiled method for dead ones and values, too
 247   static void all_do(const frame* fr, const RegisterMap* reg_map,
 248                      OopClosure* oop_fn,
 249                      void derived_oop_fn(oop* base, oop* derived),
 250                      OopClosure* value_fn, OopClosure* dead_fn);
 251 
 252   // Printing
 253   void print_on(outputStream* st) const PRODUCT_RETURN;
 254   void print() const { print_on(tty); }
 255 };
 256 
 257 
 258 class OopMapStream : public StackObj {
 259  private:
 260   CompressedReadStream* _stream;
 261   int _mask;
 262   int _size;
 263   int _position;
 264   bool _valid_omv;
 265   OopMapValue _omv;
 266   void find_next();
 267 
 268  public:
 269   OopMapStream(OopMap* oop_map);
 270   OopMapStream(OopMap* oop_map, int oop_types_mask);
 271   bool is_done()                        { if(!_valid_omv) { find_next(); } return !_valid_omv; }
 272   void next()                           { find_next(); }
 273   OopMapValue current()                 { return _omv; }


   1 #ifdef USE_PRAGMA_IDENT_HDR
   2 #pragma ident "@(#)oopMap.hpp   1.81 07/09/28 10:23:19 JVM"
   3 #endif
   4 /*
   5  * Copyright 1998-2008 Sun Microsystems, Inc.  All Rights Reserved.
   6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   7  *
   8  * This code is free software; you can redistribute it and/or modify it
   9  * under the terms of the GNU General Public License version 2 only, as
  10  * published by the Free Software Foundation.
  11  *
  12  * This code is distributed in the hope that it will be useful, but WITHOUT
  13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15  * version 2 for more details (a copy is included in the LICENSE file that
  16  * accompanied this code).
  17  *
  18  * You should have received a copy of the GNU General Public License version
  19  * 2 along with this work; if not, write to the Free Software Foundation,
  20  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  21  *
  22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  23  * CA 95054 USA or visit www.sun.com if you need additional information or
  24  * have any questions.
  25  *  


  32 //   Dead        - Dead; can be Zapped for debugging
  33 //   CalleeXX    - Callee saved; also describes which caller register is saved
  34 //   DerivedXX   - A derived oop; original oop is described.
  35 //
  36 // OopMapValue describes a single OopMap entry
  37 
  38 class frame;
  39 class RegisterMap;
  40 class DerivedPointerEntry;
  41 
  42 class OopMapValue: public StackObj {
  43   friend class VMStructs;
  44 private:
  45   short _value;
  46   int value() const                                 { return _value; }
  47   void set_value(int value)                         { _value = value; }
  48   short _content_reg;
  49 
  50 public:
  51   // Constants
  52   enum { type_bits                = 5,
  53          register_bits            = BitsPerShort - type_bits };
  54  
  55   enum { type_shift               = 0,
  56          register_shift           = type_bits };
  57 
  58   enum { type_mask                = right_n_bits(type_bits),
  59          type_mask_in_place       = type_mask << type_shift,
  60          register_mask            = right_n_bits(register_bits),
  61          register_mask_in_place   = register_mask << register_shift };
  62 
  63   enum oop_types {              // must fit in type_bits
  64          unused_value =0,       // powers of 2, for masking OopMapStream
  65          oop_value = 1,
  66          value_value = 2,
  67          narrowoop_value = 4,
  68          callee_saved_value = 8,
  69          derived_oop_value= 16 };

  70 
  71   // Constructors
  72   OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
  73   OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg,t); }
  74   OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg,t); set_content_reg(reg2); }
  75   OopMapValue (CompressedReadStream* stream) { read_from(stream); }
  76 
  77   // Archiving
  78   void write_on(CompressedWriteStream* stream) {
  79     stream->write_int(value());
  80     if(is_callee_saved() || is_derived_oop()) {
  81       stream->write_int(content_reg()->value());
  82     }
  83   }
  84 
  85   void read_from(CompressedReadStream* stream) {
  86     set_value(stream->read_int());
  87     if(is_callee_saved() || is_derived_oop()) {
  88       set_content_reg(VMRegImpl::as_VMReg(stream->read_int(), true));
  89     }
  90   }
  91 
  92   // Querying
  93   bool is_oop()               { return mask_bits(value(), type_mask_in_place) == oop_value; }
  94   bool is_value()             { return mask_bits(value(), type_mask_in_place) == value_value; }
  95   bool is_narrowoop()           { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
  96   bool is_callee_saved()      { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
  97   bool is_derived_oop()       { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }

  98 
  99   void set_oop()              { set_value((value() & register_mask_in_place) | oop_value); }
 100   void set_value()            { set_value((value() & register_mask_in_place) | value_value); }
 101   void set_narrowoop()          { set_value((value() & register_mask_in_place) | narrowoop_value); }
 102   void set_callee_saved()     { set_value((value() & register_mask_in_place) | callee_saved_value); }
 103   void set_derived_oop()      { set_value((value() & register_mask_in_place) | derived_oop_value); }

 104 
 105   VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
 106   oop_types type() const      { return (oop_types)mask_bits(value(), type_mask_in_place); }
 107 
 108   static bool legal_vm_reg_name(VMReg p) {
 109     return (p->value()  == (p->value() & register_mask));
 110   }
 111 
 112   void set_reg_type(VMReg p, oop_types t) { 
 113     set_value((p->value() << register_shift) | t);
 114     assert(reg() == p, "sanity check" );
 115     assert(type() == t, "sanity check" );
 116   }
 117 
 118 
 119   VMReg content_reg() const       { return VMRegImpl::as_VMReg(_content_reg, true); }
 120   void set_content_reg(VMReg r)   { _content_reg = r->value(); }
 121 
 122   // Physical location queries
 123   bool is_register_loc()      { return reg()->is_reg(); }
 124   bool is_stack_loc()         { return reg()->is_stack(); }
 125 
 126   // Returns offset from sp.
 127   int stack_offset() {
 128     assert(is_stack_loc(), "must be stack location");
 129     return reg()->reg2stack();
 130   }
 131 
 132   void print_on(outputStream* st) const;
 133   void print() const { print_on(tty); }
 134 };
 135 
 136 
 137 class OopMap: public ResourceObj {
 138   friend class OopMapStream;
 139   friend class VMStructs;
 140  private:
 141   int  _pc_offset; 
 142   int  _omv_count;
 143   int  _omv_data_size;
 144   unsigned char* _omv_data;
 145   CompressedWriteStream* _write_stream;
 146 
 147   debug_only( OopMapValue::oop_types* _locs_used; int _locs_length;)
 148 
 149   // Accessors
 150   unsigned char* omv_data() const             { return _omv_data; }
 151   void set_omv_data(unsigned char* value)     { _omv_data = value; }
 152   int omv_data_size() const                   { return _omv_data_size; }
 153   void set_omv_data_size(int value)           { _omv_data_size = value; }


 159 
 160  private:
 161   enum DeepCopyToken { _deep_copy_token };
 162   OopMap(DeepCopyToken, OopMap* source);  // used only by deep_copy
 163 
 164  public:
 165   OopMap(int frame_size, int arg_count);
 166 
 167   // pc-offset handling
 168   int offset() const     { return _pc_offset; }
 169   void set_offset(int o) { _pc_offset = o; }
 170 
 171   // Check to avoid double insertion
 172   debug_only(OopMapValue::oop_types locs_used( int indx ) { return _locs_used[indx]; })
 173   
 174   // Construction
 175   // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
 176   // slots to hold 4-byte values like ints and floats in the LP64 build.
 177   void set_oop  ( VMReg local);
 178   void set_value( VMReg local);
 179   void set_narrowoop(VMReg local);
 180   void set_dead ( VMReg local);
 181   void set_callee_saved( VMReg local, VMReg caller_machine_register );
 182   void set_derived_oop ( VMReg local, VMReg derived_from_local_register );

 183   void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
 184 
 185   int heap_size() const;
 186   void copy_to(address addr);
 187   OopMap* deep_copy();
 188 
 189   bool has_derived_pointer() const PRODUCT_RETURN0;
 190 
 191   bool legal_vm_reg_name(VMReg local) {
 192      return OopMapValue::legal_vm_reg_name(local);
 193   }
 194 
 195   // Printing
 196   void print_on(outputStream* st) const;
 197   void print() const { print_on(tty); }
 198 };
 199 
 200 
 201 class OopMapSet : public ResourceObj {
 202   friend class VMStructs;
 203  private:
 204   int _om_count;
 205   int _om_size;
 206   OopMap** _om_data;
 207 
 208   int om_count() const              { return _om_count; }
 209   void set_om_count(int value)      { _om_count = value; }
 210   void increment_count()            { _om_count++; }
 211   int om_size() const               { return _om_size; }
 212   void set_om_size(int value)       { _om_size = value; }
 213   OopMap** om_data() const          { return _om_data; }
 214   void set_om_data(OopMap** value)  { _om_data = value; }
 215   void grow_om_data();
 216   void set(int index,OopMap* value) { assert((index == 0) || ((index > 0) && (index < om_size())),"bad index"); _om_data[index] = value; }


 228 
 229   // Returns the only oop map. Used for reconstructing 
 230   // Adapter frames during deoptimization
 231   OopMap* singular_oop_map();
 232 
 233   // returns OopMap in that is anchored to the pc
 234   OopMap* find_map_at_offset(int pc_offset) const; 
 235 
 236   int heap_size() const;
 237   void copy_to(address addr);
 238 
 239   // Iterates through frame for a compiled method
 240   static void oops_do            (const frame* fr,
 241                                   const RegisterMap* reg_map, OopClosure* f); 
 242   static void update_register_map(const frame* fr, RegisterMap *reg_map);
 243 
 244   // Iterates through frame for a compiled method for dead ones and values, too
 245   static void all_do(const frame* fr, const RegisterMap* reg_map,
 246                      OopClosure* oop_fn,
 247                      void derived_oop_fn(oop* base, oop* derived),
 248                      OopClosure* value_fn);
 249 
 250   // Printing
 251   void print_on(outputStream* st) const;
 252   void print() const { print_on(tty); }
 253 };
 254 
 255 
 256 class OopMapStream : public StackObj {
 257  private:
 258   CompressedReadStream* _stream;
 259   int _mask;
 260   int _size;
 261   int _position;
 262   bool _valid_omv;
 263   OopMapValue _omv;
 264   void find_next();
 265 
 266  public:
 267   OopMapStream(OopMap* oop_map);
 268   OopMapStream(OopMap* oop_map, int oop_types_mask);
 269   bool is_done()                        { if(!_valid_omv) { find_next(); } return !_valid_omv; }
 270   void next()                           { find_next(); }
 271   OopMapValue current()                 { return _omv; }