< prev index next >

src/hotspot/share/compiler/oopMap.hpp

Print this page
*** 26,10 ***
--- 26,11 ---
  #define SHARE_COMPILER_OOPMAP_HPP
  
  #include "code/compressedStream.hpp"
  #include "code/vmreg.hpp"
  #include "memory/allocation.hpp"
+ #include "memory/iterator.hpp"
  #include "oops/oopsHierarchy.hpp"
  #include "utilities/growableArray.hpp"
  
  // Interface for generating the frame map for compiled code.  A frame map
  // describes for a specific pc whether each register and frame stack slot is:

*** 42,10 ***
--- 43,11 ---
  
  enum class DerivedPointerIterationMode;
  class frame;
  class RegisterMap;
  class OopClosure;
+ class CodeBlob;
  
  enum class derived_pointer : intptr_t {};
  
  class OopMapValue: public StackObj {
    friend class VMStructs;

*** 55,11 ***
    void set_value(int value)                         { _value = value; }
    short _content_reg;
  
  public:
    // Constants
!   enum { type_bits                = 2,
           register_bits            = BitsPerShort - type_bits };
  
    enum { type_shift               = 0,
           register_shift           = type_bits };
  
--- 57,11 ---
    void set_value(int value)                         { _value = value; }
    short _content_reg;
  
  public:
    // Constants
!   enum { type_bits                = 2, // 3
           register_bits            = BitsPerShort - type_bits };
  
    enum { type_shift               = 0,
           register_shift           = type_bits };
  

*** 71,10 ***
--- 73,11 ---
    enum oop_types {
           oop_value,
           narrowoop_value,
           callee_saved_value,
           derived_oop_value,
+          // live_value,
           unused_value = -1          // Only used as a sentinel value
    };
  
    // Constructors
    OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }

*** 121,10 ***
--- 124,12 ---
    // Querying
    bool is_oop()               { return mask_bits(value(), type_mask_in_place) == oop_value; }
    bool is_narrowoop()         { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
    bool is_callee_saved()      { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
    bool is_derived_oop()       { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
+   // bool is_live()              { return mask_bits(value(), type_mask_in_place) == live_value; }
+   bool is_oop_or_narrow()     { return is_oop() || is_narrowoop(); }
  
    VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
    oop_types type() const      { return (oop_types)mask_bits(value(), type_mask_in_place); }
  
    static bool legal_vm_reg_name(VMReg p) {

*** 145,21 ***
--- 150,28 ---
  
  
  class OopMap: public ResourceObj {
    friend class OopMapStream;
    friend class VMStructs;
+   friend class OopMapSet;
+   friend class OopMapSort;
   private:
    int  _pc_offset; // offset in the code that this OopMap corresponds to
    int  _omv_count; // number of OopMapValues in the stream
+   int  _num_oops;  // number of oops
+   int  _index;     // index in OopMapSet
+   bool _has_derived_oops;
    CompressedWriteStream* _write_stream;
  
    debug_only( OopMapValue::oop_types* _locs_used; int _locs_length;)
  
    // Accessors
    int omv_count() const                       { return _omv_count; }
    void set_omv_count(int value)               { _omv_count = value; }
    void increment_count()                      { _omv_count++; }
+   void increment_num_oops()                   { _num_oops++; }
+   void set_has_derived_oops(bool value)       { _has_derived_oops = value; }
    CompressedWriteStream* write_stream() const { return _write_stream; }
    void set_write_stream(CompressedWriteStream* value) { _write_stream = value; }
  
   private:
    enum DeepCopyToken { _deep_copy_token };

*** 174,10 ***
--- 186,13 ---
    int offset() const     { return _pc_offset; }
    void set_offset(int o) { _pc_offset = o; }
    int count() const { return _omv_count; }
    int data_size() const  { return write_stream()->position(); }
    address data() const { return write_stream()->buffer(); }
+   int num_oops() const { return _num_oops; }
+   bool has_derived_oops() const { return _has_derived_oops; }
+   int index() const { return _index; }
  
    // Construction
    // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
    // slots to hold 4-byte values like ints and floats in the LP64 build.
    void set_oop  ( VMReg local);

*** 185,10 ***
--- 200,11 ---
    void set_callee_saved( VMReg local, VMReg caller_machine_register );
    void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
  
    int heap_size() const;
    void copy_data_to(address addr) const;
+   void copy_and_sort_data_to(address addr) const;
    OopMap* deep_copy();
  
    bool legal_vm_reg_name(VMReg local) {
       return OopMapValue::legal_vm_reg_name(local);
    }

*** 197,69 ***
    void print_on(outputStream* st) const;
    void print() const;
    bool equals(const OopMap* other) const;
  };
  
  class OopMapSet : public ResourceObj {
    friend class VMStructs;
   private:
    GrowableArray<OopMap*> _list;
  
!   void add(OopMap* value) { _list.append(value); }
  
   public:
    OopMapSet();
  
    // returns the number of OopMaps in this OopMapSet
    int size() const            { return _list.length(); }
    // returns the OopMap at a given index
    OopMap* at(int index) const { return _list.at(index); }
  
    // Collect OopMaps.
!   void add_gc_map(int pc, OopMap* map);
  
    // Methods oops_do() and all_do() filter out NULL oops and
    // oop == CompressedOops::base() before passing oops
    // to closures.
  
    // Iterates through frame for a compiled method
!   static void oops_do            (const frame* fr,
!                                   const RegisterMap* reg_map,
!                                   OopClosure* f,
!                                   DerivedPointerIterationMode mode);
    static void update_register_map(const frame* fr, RegisterMap *reg_map);
  
!   // Iterates through frame for a compiled method for dead ones and values, too
!   static void all_do(const frame* fr, const RegisterMap* reg_map,
!                      OopClosure* oop_fn,
!                      void derived_oop_fn(oop* base, derived_pointer* derived, OopClosure* oop_fn));
  
    // Printing
    void print_on(outputStream* st) const;
    void print() const;
  };
  
  class ImmutableOopMapBuilder;
  
  class ImmutableOopMap {
    friend class OopMapStream;
    friend class VMStructs;
  #ifdef ASSERT
    friend class ImmutableOopMapBuilder;
  #endif
  private:
    int _count; // contains the number of entries in this OopMap
  
    address data_addr() const { return (address) this + sizeof(ImmutableOopMap); }
  public:
    ImmutableOopMap(const OopMap* oopmap);
  
    int count() const { return _count; }
  #ifdef ASSERT
    int nr_of_bytes() const; // this is an expensive operation, only used in debug builds
  #endif
  
    // Printing
    void print_on(outputStream* st) const;
    void print() const;
  };
  
--- 213,102 ---
    void print_on(outputStream* st) const;
    void print() const;
    bool equals(const OopMap* other) const;
  };
  
+ class ImmutableOopMap;
+ 
  class OopMapSet : public ResourceObj {
    friend class VMStructs;
   private:
    GrowableArray<OopMap*> _list;
  
!   int add(OopMap* value) { return _list.append(value); }
  
   public:
    OopMapSet();
  
    // returns the number of OopMaps in this OopMapSet
    int size() const            { return _list.length(); }
    // returns the OopMap at a given index
    OopMap* at(int index) const { return _list.at(index); }
  
    // Collect OopMaps.
!   int add_gc_map(int pc, OopMap* map);
  
    // Methods oops_do() and all_do() filter out NULL oops and
    // oop == CompressedOops::base() before passing oops
    // to closures.
  
+   static const ImmutableOopMap* find_map(const CodeBlob* cb, address pc);
+   static const ImmutableOopMap* find_map(const frame *fr);
+ 
    // Iterates through frame for a compiled method
!   static void oops_do            (const frame* fr, const RegisterMap* reg_map,
!                                   OopClosure* f, DerivedOopClosure* df);
!   static void oops_do            (const frame* fr, const RegisterMap* reg_map,
!                                   OopClosure* f, DerivedPointerIterationMode mode);
    static void update_register_map(const frame* fr, RegisterMap *reg_map);
  
! #ifndef PRODUCT
!   static void trace_codeblob_maps(const frame *fr, const RegisterMap *reg_map);
! #endif
! 
+   // // Iterates through frame for a compiled method for dead ones and values, too
+   // static void all_do(const frame* fr, const RegisterMap* reg_map,
+   //                    OopClosure* oop_fn,
+   //                    DerivedOopClosure* derived_oop_fn,
+   //                    OopClosure* value_fn);
  
    // Printing
    void print_on(outputStream* st) const;
    void print() const;
  };
  
  class ImmutableOopMapBuilder;
  
+ class OopMapClosure : public Closure {
+  public:
+   virtual bool handle_type(OopMapValue::oop_types type) { return true; }
+   virtual void do_value(VMReg reg, OopMapValue::oop_types type) = 0;
+ };
+ 
+ template <typename OopFnT, typename DerivedOopFnT, typename ValueFilterT>
+ class OopMapDo;
+ 
  class ImmutableOopMap {
    friend class OopMapStream;
    friend class VMStructs;
+   template <typename OopFnT, typename DerivedOopFnT, typename ValueFilterT>
+   friend class OopMapDo;
  #ifdef ASSERT
    friend class ImmutableOopMapBuilder;
  #endif
  private:
    int _count; // contains the number of entries in this OopMap
+   int _num_oops;
+   bool _has_derived_oops;
  
    address data_addr() const { return (address) this + sizeof(ImmutableOopMap); }
  public:
    ImmutableOopMap(const OopMap* oopmap);
  
    int count() const { return _count; }
+   int num_oops() const { return _num_oops; }
+   bool has_derived_oops() const { return _has_derived_oops; }
+   bool has_any(OopMapValue::oop_types type) const;
+ 
  #ifdef ASSERT
    int nr_of_bytes() const; // this is an expensive operation, only used in debug builds
  #endif
  
+   void oops_do(const frame* fr, const RegisterMap* reg_map, OopClosure* f, DerivedOopClosure* df) const;
+   void oops_do(const frame* fr, const RegisterMap* reg_map, OopClosure* f, DerivedPointerIterationMode derived_mode) const;
+   void all_type_do(const frame *fr, OopMapValue::oop_types type, OopMapClosure* fn) const;
+   void all_type_do(const frame *fr, OopMapClosure* fn) const;
+   void update_register_map(const frame* fr, RegisterMap *reg_map) const;
+ 
    // Printing
    void print_on(outputStream* st) const;
    void print() const;
  };
  

*** 301,11 ***
--- 350,13 ---
  
    ImmutableOopMapPair* get_pairs() const { return (ImmutableOopMapPair*) ((address) this + sizeof(*this)); }
  
    static ImmutableOopMapSet* build_from(const OopMapSet* oopmap_set);
  
+   int find_slot_for_offset(int pc_offset) const;
    const ImmutableOopMap* find_map_at_offset(int pc_offset) const;
+   const ImmutableOopMap* find_map_at_slot(int slot, int pc_offset) const;
  
    const ImmutableOopMapPair* pair_at(int index) const { assert(index >= 0 && index < _count, "check"); return &get_pairs()[index]; }
  
    int count() const { return _count; }
    int nr_of_bytes() const { return _size; }

*** 314,28 ***
    void print() const;
  };
  
  class OopMapStream : public StackObj {
   private:
!   CompressedReadStream* _stream;
    int _size;
    int _position;
    bool _valid_omv;
    OopMapValue _omv;
    void find_next();
  
   public:
!   OopMapStream(OopMap* oop_map);
    OopMapStream(const ImmutableOopMap* oop_map);
    bool is_done()                        { if(!_valid_omv) { find_next(); } return !_valid_omv; }
    void next()                           { find_next(); }
    OopMapValue current()                 { return _omv; }
  #ifdef ASSERT
!   int stream_position() const           { return _stream->position(); }
  #endif
  };
  
  class ImmutableOopMapBuilder {
  private:
    class Mapping;
  
  private:
--- 365,29 ---
    void print() const;
  };
  
  class OopMapStream : public StackObj {
   private:
!   CompressedReadStream _stream;
    int _size;
    int _position;
    bool _valid_omv;
    OopMapValue _omv;
    void find_next();
  
   public:
!   OopMapStream(const OopMap* oop_map);
    OopMapStream(const ImmutableOopMap* oop_map);
    bool is_done()                        { if(!_valid_omv) { find_next(); } return !_valid_omv; }
    void next()                           { find_next(); }
    OopMapValue current()                 { return _omv; }
  #ifdef ASSERT
!   int stream_position() const           { return _stream.position(); }
  #endif
  };
  
+ 
  class ImmutableOopMapBuilder {
  private:
    class Mapping;
  
  private:

*** 401,10 ***
--- 453,33 ---
    void fill_pair(ImmutableOopMapPair* pair, const OopMap* map, int offset, const ImmutableOopMapSet* set);
    int fill_map(ImmutableOopMapPair* pair, const OopMap* map, int offset, const ImmutableOopMapSet* set);
    void fill(ImmutableOopMapSet* set, int size);
  };
  
+ class SkipNullValue {
+ public:
+   static inline bool should_skip(oop val);
+ };
+ 
+ class IncludeAllValues {
+ public:
+   static bool should_skip(oop value) { return false; }
+ };
+ 
+ template <typename OopFnT, typename DerivedOopFnT, typename ValueFilterT>
+ class OopMapDo {
+ private:
+   OopFnT* _oop_fn;
+   DerivedOopFnT* _derived_oop_fn;
+ public:
+   OopMapDo(OopFnT* oop_fn, DerivedOopFnT* derived_oop_fn) : _oop_fn(oop_fn), _derived_oop_fn(derived_oop_fn) {}
+   template <typename RegisterMapT>
+   void oops_do(const frame* fr, const RegisterMapT* reg_map, const ImmutableOopMap* oopmap);
+ private:
+   template <typename RegisterMapT>
+   void iterate_oops_do(const frame *fr, const RegisterMapT *reg_map, const ImmutableOopMap* oopmap);
+ };
  
  // Derived pointer support. This table keeps track of all derived points on a
  // stack.  It is cleared before each scavenge/GC.  During the traversal of all
  // oops, it is filled in with references to all locations that contains a
  // derived oop (assumed to be very few).  When the GC is complete, the derived
< prev index next >