src/hotspot/share/compiler/oopMap.hpp
changeset 58527 f9cc0141574c
parent 54916 7136c9ac56a7
equal deleted inserted replaced
58524:e84d8379815b 58527:f9cc0141574c
    51   void set_value(int value)                         { _value = value; }
    51   void set_value(int value)                         { _value = value; }
    52   short _content_reg;
    52   short _content_reg;
    53 
    53 
    54 public:
    54 public:
    55   // Constants
    55   // Constants
    56   enum { type_bits                = 4,
    56   enum { type_bits                = 2,
    57          register_bits            = BitsPerShort - type_bits };
    57          register_bits            = BitsPerShort - type_bits };
    58 
    58 
    59   enum { type_shift               = 0,
    59   enum { type_shift               = 0,
    60          register_shift           = type_bits };
    60          register_shift           = type_bits };
    61 
    61 
    62   enum { type_mask                = right_n_bits(type_bits),
    62   enum { type_mask                = right_n_bits(type_bits),
    63          type_mask_in_place       = type_mask << type_shift,
    63          type_mask_in_place       = type_mask << type_shift,
    64          register_mask            = right_n_bits(register_bits),
    64          register_mask            = right_n_bits(register_bits),
    65          register_mask_in_place   = register_mask << register_shift };
    65          register_mask_in_place   = register_mask << register_shift };
    66 
    66 
    67   enum oop_types {              // must fit in type_bits
    67   enum oop_types {
    68          unused_value =0,       // powers of 2, for masking OopMapStream
    68          oop_value,
    69          oop_value = 1,
    69          narrowoop_value,
    70          narrowoop_value = 2,
    70          callee_saved_value,
    71          callee_saved_value = 4,
    71          derived_oop_value,
    72          derived_oop_value= 8 };
    72          unused_value = -1          // Only used as a sentinel value
       
    73   };
    73 
    74 
    74   // Constructors
    75   // Constructors
    75   OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
    76   OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
    76   OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg, t); set_content_reg(VMRegImpl::Bad()); }
    77   OopMapValue (VMReg reg, oop_types t, VMReg reg2) {
    77   OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg, t); set_content_reg(reg2); }
    78     set_reg_type(reg, t);
    78   OopMapValue (CompressedReadStream* stream) { read_from(stream); }
    79     set_content_reg(reg2);
    79 
    80   }
       
    81 
       
    82  private:
       
    83     void set_reg_type(VMReg p, oop_types t) {
       
    84     set_value((p->value() << register_shift) | t);
       
    85     assert(reg() == p, "sanity check" );
       
    86     assert(type() == t, "sanity check" );
       
    87   }
       
    88 
       
    89   void set_content_reg(VMReg r) {
       
    90     if (is_callee_saved()) {
       
    91       // This can never be a stack location, so we don't need to transform it.
       
    92       assert(r->is_reg(), "Trying to callee save a stack location");
       
    93     } else if (is_derived_oop()) {
       
    94       assert (r->is_valid(), "must have a valid VMReg");
       
    95     } else {
       
    96       assert (!r->is_valid(), "valid VMReg not allowed");
       
    97     }
       
    98     _content_reg = r->value();
       
    99   }
       
   100 
       
   101  public:
    80   // Archiving
   102   // Archiving
    81   void write_on(CompressedWriteStream* stream) {
   103   void write_on(CompressedWriteStream* stream) {
    82     stream->write_int(value());
   104     stream->write_int(value());
    83     if(is_callee_saved() || is_derived_oop()) {
   105     if(is_callee_saved() || is_derived_oop()) {
    84       stream->write_int(content_reg()->value());
   106       stream->write_int(content_reg()->value());
    92     }
   114     }
    93   }
   115   }
    94 
   116 
    95   // Querying
   117   // Querying
    96   bool is_oop()               { return mask_bits(value(), type_mask_in_place) == oop_value; }
   118   bool is_oop()               { return mask_bits(value(), type_mask_in_place) == oop_value; }
    97   bool is_narrowoop()           { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
   119   bool is_narrowoop()         { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
    98   bool is_callee_saved()      { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
   120   bool is_callee_saved()      { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
    99   bool is_derived_oop()       { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
   121   bool is_derived_oop()       { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
   100 
   122 
   101   void set_oop()              { set_value((value() & register_mask_in_place) | oop_value); }
       
   102   void set_narrowoop()          { set_value((value() & register_mask_in_place) | narrowoop_value); }
       
   103   void set_callee_saved()     { set_value((value() & register_mask_in_place) | callee_saved_value); }
       
   104   void set_derived_oop()      { set_value((value() & register_mask_in_place) | derived_oop_value); }
       
   105 
       
   106   VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
   123   VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
   107   oop_types type() const      { return (oop_types)mask_bits(value(), type_mask_in_place); }
   124   oop_types type() const      { return (oop_types)mask_bits(value(), type_mask_in_place); }
   108 
   125 
   109   static bool legal_vm_reg_name(VMReg p) {
   126   static bool legal_vm_reg_name(VMReg p) {
   110     return (p->value()  == (p->value() & register_mask));
   127     return (p->value()  == (p->value() & register_mask));
   111   }
   128   }
   112 
   129 
   113   void set_reg_type(VMReg p, oop_types t) {
       
   114     set_value((p->value() << register_shift) | t);
       
   115     assert(reg() == p, "sanity check" );
       
   116     assert(type() == t, "sanity check" );
       
   117   }
       
   118 
       
   119 
       
   120   VMReg content_reg() const       { return VMRegImpl::as_VMReg(_content_reg, true); }
   130   VMReg content_reg() const       { return VMRegImpl::as_VMReg(_content_reg, true); }
   121   void set_content_reg(VMReg r)   { _content_reg = r->value(); }
       
   122 
   131 
   123   // Physical location queries
   132   // Physical location queries
   124   bool is_register_loc()      { return reg()->is_reg(); }
   133   bool is_register_loc()      { return reg()->is_reg(); }
   125   bool is_stack_loc()         { return reg()->is_stack(); }
   134   bool is_stack_loc()         { return reg()->is_stack(); }
   126 
   135 
   154 
   163 
   155  private:
   164  private:
   156   enum DeepCopyToken { _deep_copy_token };
   165   enum DeepCopyToken { _deep_copy_token };
   157   OopMap(DeepCopyToken, OopMap* source);  // used only by deep_copy
   166   OopMap(DeepCopyToken, OopMap* source);  // used only by deep_copy
   158 
   167 
       
   168   void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
       
   169 
   159  public:
   170  public:
   160   OopMap(int frame_size, int arg_count);
   171   OopMap(int frame_size, int arg_count);
   161 
   172 
   162   // pc-offset handling
   173   // pc-offset handling
   163   int offset() const     { return _pc_offset; }
   174   int offset() const     { return _pc_offset; }
   171 
   182 
   172   // Construction
   183   // Construction
   173   // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
   184   // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
   174   // slots to hold 4-byte values like ints and floats in the LP64 build.
   185   // slots to hold 4-byte values like ints and floats in the LP64 build.
   175   void set_oop  ( VMReg local);
   186   void set_oop  ( VMReg local);
   176   void set_value( VMReg local);
       
   177   void set_narrowoop(VMReg local);
   187   void set_narrowoop(VMReg local);
   178   void set_dead ( VMReg local);
       
   179   void set_callee_saved( VMReg local, VMReg caller_machine_register );
   188   void set_callee_saved( VMReg local, VMReg caller_machine_register );
   180   void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
   189   void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
   181   void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
       
   182 
   190 
   183   int heap_size() const;
   191   int heap_size() const;
   184   void copy_data_to(address addr) const;
   192   void copy_data_to(address addr) const;
   185   OopMap* deep_copy();
   193   OopMap* deep_copy();
   186 
       
   187   bool has_derived_pointer() const PRODUCT_RETURN0;
       
   188 
   194 
   189   bool legal_vm_reg_name(VMReg local) {
   195   bool legal_vm_reg_name(VMReg local) {
   190      return OopMapValue::legal_vm_reg_name(local);
   196      return OopMapValue::legal_vm_reg_name(local);
   191   }
   197   }
   192 
   198 
   267 
   273 
   268   address data_addr() const { return (address) this + sizeof(ImmutableOopMap); }
   274   address data_addr() const { return (address) this + sizeof(ImmutableOopMap); }
   269 public:
   275 public:
   270   ImmutableOopMap(const OopMap* oopmap);
   276   ImmutableOopMap(const OopMap* oopmap);
   271 
   277 
   272   bool has_derived_pointer() const PRODUCT_RETURN0;
       
   273   int count() const { return _count; }
   278   int count() const { return _count; }
   274 #ifdef ASSERT
   279 #ifdef ASSERT
   275   int nr_of_bytes() const; // this is an expensive operation, only used in debug builds
   280   int nr_of_bytes() const; // this is an expensive operation, only used in debug builds
   276 #endif
   281 #endif
   277 
   282 
   332 };
   337 };
   333 
   338 
   334 class OopMapStream : public StackObj {
   339 class OopMapStream : public StackObj {
   335  private:
   340  private:
   336   CompressedReadStream* _stream;
   341   CompressedReadStream* _stream;
   337   int _mask;
       
   338   int _size;
   342   int _size;
   339   int _position;
   343   int _position;
   340   bool _valid_omv;
   344   bool _valid_omv;
   341   OopMapValue _omv;
   345   OopMapValue _omv;
   342   void find_next();
   346   void find_next();
   343 
   347 
   344  public:
   348  public:
   345   OopMapStream(OopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
   349   OopMapStream(OopMap* oop_map);
   346   OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
   350   OopMapStream(const ImmutableOopMap* oop_map);
   347   bool is_done()                        { if(!_valid_omv) { find_next(); } return !_valid_omv; }
   351   bool is_done()                        { if(!_valid_omv) { find_next(); } return !_valid_omv; }
   348   void next()                           { find_next(); }
   352   void next()                           { find_next(); }
   349   OopMapValue current()                 { return _omv; }
   353   OopMapValue current()                 { return _omv; }
   350 #ifdef ASSERT
   354 #ifdef ASSERT
   351   int stream_position() const           { return _stream->position(); }
   355   int stream_position() const           { return _stream->position(); }