< prev index next >

src/hotspot/share/oops/methodData.hpp

Print this page

        

@@ -81,20 +81,21 @@
   friend class JVMCIVMStructs;
 
 private:
   // Every data layout begins with a header.  This header
   // contains a tag, which is used to indicate the size/layout
-  // of the data, 4 bits of flags, which can be used in any way,
-  // 4 bits of trap history (none/one reason/many reasons),
+  // of the data, 8 bits of flags, which can be used in any way,
+  // 32 bits of trap history (none/one reason/many reasons),
   // and a bci, which is used to tie this piece of data to a
   // specific bci in the bytecodes.
   union {
-    intptr_t _bits;
+    u8 _bits;
     struct {
       u1 _tag;
       u1 _flags;
       u2 _bci;
+      u4 _traps;
     } _struct;
   } _header;
 
   // The data layout has an arbitrary number of cells, each sized
   // to accomodate a pointer or an integer.

@@ -129,32 +130,27 @@
     parameters_type_data_tag,
     speculative_trap_data_tag
   };
 
   enum {
-    // The _struct._flags word is formatted as [trap_state:4 | flags:4].
-    // The trap state breaks down further as [recompile:1 | reason:3].
+    // The trap state breaks down as [recompile:1 | reason:31].
     // This further breakdown is defined in deoptimization.cpp.
     // See Deoptimization::trap_state_reason for an assert that
     // trap_bits is big enough to hold reasons < Reason_RECORDED_LIMIT.
     //
     // The trap_state is collected only if ProfileTraps is true.
-    trap_bits = 1+3,  // 3: enough to distinguish [0..Reason_RECORDED_LIMIT].
-    trap_shift = BitsPerByte - trap_bits,
+    trap_bits = 1+31,  // 31: enough to distinguish [0..Reason_RECORDED_LIMIT].
     trap_mask = right_n_bits(trap_bits),
-    trap_mask_in_place = (trap_mask << trap_shift),
-    flag_limit = trap_shift,
-    flag_mask = right_n_bits(flag_limit),
     first_flag = 0
   };
 
   // Size computation
   static int header_size_in_bytes() {
-    return cell_size;
+    return header_size_in_cells() * cell_size;
   }
   static int header_size_in_cells() {
-    return 1;
+    return LP64_ONLY(1) NOT_LP64(2);
   }
 
   static int compute_size_in_bytes(int cell_count) {
     return header_size_in_bytes() + cell_count * cell_size;
   }

@@ -165,56 +161,54 @@
   // Accessors
   u1 tag() {
     return _header._struct._tag;
   }
 
-  // Return a few bits of trap state.  Range is [0..trap_mask].
+  // Return 32 bits of trap state.
   // The state tells if traps with zero, one, or many reasons have occurred.
   // It also tells whether zero or many recompilations have occurred.
   // The associated trap histogram in the MDO itself tells whether
   // traps are common or not.  If a BCI shows that a trap X has
   // occurred, and the MDO shows N occurrences of X, we make the
   // simplifying assumption that all N occurrences can be blamed
   // on that BCI.
-  int trap_state() const {
-    return ((_header._struct._flags >> trap_shift) & trap_mask);
+  uint trap_state() const {
+    return _header._struct._traps;
   }
 
-  void set_trap_state(int new_state) {
+  void set_trap_state(uint new_state) {
     assert(ProfileTraps, "used only under +ProfileTraps");
-    uint old_flags = (_header._struct._flags & flag_mask);
-    _header._struct._flags = (new_state << trap_shift) | old_flags;
+    uint old_flags = _header._struct._traps;
+    _header._struct._traps = new_state | old_flags;
   }
 
   u1 flags() const {
     return _header._struct._flags;
   }
 
   u2 bci() const {
     return _header._struct._bci;
   }
 
-  void set_header(intptr_t value) {
+  void set_header(u8 value) {
     _header._bits = value;
   }
-  intptr_t header() {
+  u8 header() {
     return _header._bits;
   }
   void set_cell_at(int index, intptr_t value) {
     _cells[index] = value;
   }
   void release_set_cell_at(int index, intptr_t value);
   intptr_t cell_at(int index) const {
     return _cells[index];
   }
 
-  void set_flag_at(int flag_number) {
-    assert(flag_number < flag_limit, "oob");
+  void set_flag_at(u1 flag_number) {
     _header._struct._flags |= (0x1 << flag_number);
   }
-  bool flag_at(int flag_number) const {
-    assert(flag_number < flag_limit, "oob");
+  bool flag_at(u1 flag_number) const {
     return (_header._struct._flags & (0x1 << flag_number)) != 0;
   }
 
   // Low-level support for code generation.
   static ByteSize header_offset() {

@@ -236,18 +230,17 @@
   static int cell_offset_in_bytes(int index) {
     return (int)offset_of(DataLayout, _cells[index]);
   }
 #endif // CC_INTERP
   // Return a value which, when or-ed as a byte into _flags, sets the flag.
-  static int flag_number_to_byte_constant(int flag_number) {
-    assert(0 <= flag_number && flag_number < flag_limit, "oob");
+  static u1 flag_number_to_constant(u1 flag_number) {
     DataLayout temp; temp.set_header(0);
     temp.set_flag_at(flag_number);
     return temp._header._struct._flags;
   }
   // Return a value which, when or-ed as a word into _header, sets the flag.
-  static intptr_t flag_mask_to_header_mask(int byte_constant) {
+  static u8 flag_mask_to_header_mask(uint byte_constant) {
     DataLayout temp; temp.set_header(0);
     temp._header._struct._flags = byte_constant;
     return temp._header._bits;
   }
 

@@ -362,12 +355,12 @@
 
   // two convenient imports for use by subclasses:
   static ByteSize cell_offset(int index) {
     return DataLayout::cell_offset(index);
   }
-  static int flag_number_to_byte_constant(int flag_number) {
-    return DataLayout::flag_number_to_byte_constant(flag_number);
+  static int flag_number_to_constant(int flag_number) {
+    return DataLayout::flag_number_to_constant(flag_number);
   }
 
   ProfileData(DataLayout* data) {
     _data = data;
   }

@@ -572,11 +565,11 @@
   void set_exception_seen() { set_flag_at(exception_seen_flag); }
 #endif
 
   // Code generation support
   static int null_seen_byte_constant() {
-    return flag_number_to_byte_constant(null_seen_flag);
+    return flag_number_to_constant(null_seen_flag);
   }
 
   static ByteSize bit_data_size() {
     return cell_offset(bit_cell_count);
   }

@@ -2048,10 +2041,13 @@
 // the ProfileData at that bci is updated.
 class SpeculativeTrapData : public ProfileData {
 protected:
   enum {
     speculative_trap_method,
+#ifndef _LP64
+    speculative_trap_padding,
+#endif
     speculative_trap_cell_count
   };
 public:
   SpeculativeTrapData(DataLayout* layout) : ProfileData(layout) {
     assert(layout->tag() == DataLayout::speculative_trap_data_tag, "wrong type");

@@ -2160,11 +2156,11 @@
   bool is_methodData() const volatile { return true; }
   void initialize();
 
   // Whole-method sticky bits and flags
   enum {
-    _trap_hist_limit    = 23 JVMCI_ONLY(+5),   // decoupled from Deoptimization::Reason_LIMIT
+    _trap_hist_limit    = 24 JVMCI_ONLY(+5),   // decoupled from Deoptimization::Reason_LIMIT
     _trap_hist_mask     = max_jubyte,
     _extra_data_count   = 4     // extra DataLayout headers, for trap history
   }; // Public flag values
 private:
   uint _nof_decompiles;             // count of all nmethod removals
< prev index next >