< prev index next >

src/hotspot/share/oops/methodData.hpp

Print this page
*** 123,11 ***
      multi_branch_data_tag,
      arg_info_data_tag,
      call_type_data_tag,
      virtual_call_type_data_tag,
      parameters_type_data_tag,
!     speculative_trap_data_tag
    };
  
    enum {
      // The trap state breaks down as [recompile:1 | reason:31].
      // This further breakdown is defined in deoptimization.cpp.
--- 123,13 ---
      multi_branch_data_tag,
      arg_info_data_tag,
      call_type_data_tag,
      virtual_call_type_data_tag,
      parameters_type_data_tag,
!     speculative_trap_data_tag,
+     array_load_store_data_tag,
+     acmp_data_tag
    };
  
    enum {
      // The trap state breaks down as [recompile:1 | reason:31].
      // This further breakdown is defined in deoptimization.cpp.

*** 259,23 ***
  class           VirtualCallTypeData;
  class       RetData;
  class       CallTypeData;
  class   JumpData;
  class     BranchData;
  class   ArrayData;
  class     MultiBranchData;
  class     ArgInfoData;
  class     ParametersTypeData;
  class   SpeculativeTrapData;
  
  // ProfileData
  //
  // A ProfileData object is created to refer to a section of profiling
  // data in a structured way.
  class ProfileData : public ResourceObj {
    friend class TypeEntries;
!   friend class ReturnTypeEntry;
    friend class TypeStackSlotEntries;
  private:
    enum {
      tab_width_one = 16,
      tab_width_two = 36
--- 261,25 ---
  class           VirtualCallTypeData;
  class       RetData;
  class       CallTypeData;
  class   JumpData;
  class     BranchData;
+ class       ACmpData;
  class   ArrayData;
  class     MultiBranchData;
  class     ArgInfoData;
  class     ParametersTypeData;
  class   SpeculativeTrapData;
+ class   ArrayLoadStoreData;
  
  // ProfileData
  //
  // A ProfileData object is created to refer to a section of profiling
  // data in a structured way.
  class ProfileData : public ResourceObj {
    friend class TypeEntries;
!   friend class SingleTypeEntry;
    friend class TypeStackSlotEntries;
  private:
    enum {
      tab_width_one = 16,
      tab_width_two = 36

*** 392,10 ***
--- 396,12 ---
    virtual bool is_ArgInfoData()     const { return false; }
    virtual bool is_CallTypeData()    const { return false; }
    virtual bool is_VirtualCallTypeData()const { return false; }
    virtual bool is_ParametersTypeData() const { return false; }
    virtual bool is_SpeculativeTrapData()const { return false; }
+   virtual bool is_ArrayLoadStoreData() const { return false; }
+   virtual bool is_ACmpData()           const { return false; }
  
  
    BitData* as_BitData() const {
      assert(is_BitData(), "wrong type");
      return is_BitData()         ? (BitData*)        this : NULL;

*** 450,10 ***
--- 456,18 ---
    }
    SpeculativeTrapData* as_SpeculativeTrapData() const {
      assert(is_SpeculativeTrapData(), "wrong type");
      return is_SpeculativeTrapData() ? (SpeculativeTrapData*)this : NULL;
    }
+   ArrayLoadStoreData* as_ArrayLoadStoreData() const {
+     assert(is_ArrayLoadStoreData(), "wrong type");
+     return is_ArrayLoadStoreData() ? (ArrayLoadStoreData*)this : NULL;
+   }
+   ACmpData* as_ACmpData() const {
+     assert(is_ACmpData(), "wrong type");
+     return is_ACmpData() ? (ACmpData*)this : NULL;
+   }
  
  
    // Subclass specific initialization
    virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {}
  

*** 604,11 ***
    }
  
  public:
    JumpData(DataLayout* layout) : ProfileData(layout) {
      assert(layout->tag() == DataLayout::jump_data_tag ||
!       layout->tag() == DataLayout::branch_data_tag, "wrong type");
    }
  
    virtual bool is_JumpData() const { return true; }
  
    static int static_cell_count() {
--- 618,12 ---
    }
  
  public:
    JumpData(DataLayout* layout) : ProfileData(layout) {
      assert(layout->tag() == DataLayout::jump_data_tag ||
!       layout->tag() == DataLayout::branch_data_tag ||
+       layout->tag() == DataLayout::acmp_data_tag, "wrong type");
    }
  
    virtual bool is_JumpData() const { return true; }
  
    static int static_cell_count() {

*** 840,19 ***
    void print_data_on(outputStream* st) const;
  };
  
  // Type entry used for return from a call. A single cell to record the
  // type.
! class ReturnTypeEntry : public TypeEntries {
  
  private:
    enum {
      cell_count = 1
    };
  
  public:
!   ReturnTypeEntry(int base_off)
      : TypeEntries(base_off) {}
  
    void post_initialize() {
      set_type(type_none());
    }
--- 855,19 ---
    void print_data_on(outputStream* st) const;
  };
  
  // Type entry used for return from a call. A single cell to record the
  // type.
! class SingleTypeEntry : public TypeEntries {
  
  private:
    enum {
      cell_count = 1
    };
  
  public:
!   SingleTypeEntry(int base_off)
      : TypeEntries(base_off) {}
  
    void post_initialize() {
      set_type(type_none());
    }

*** 882,11 ***
  
    void print_data_on(outputStream* st) const;
  };
  
  // Entries to collect type information at a call: contains arguments
! // (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a
  // number of cells. Because the number of cells for the return type is
  // smaller than the number of cells for the type of an arguments, the
  // number of cells is used to tell how many arguments are profiled and
  // whether a return value is profiled. See has_arguments() and
  // has_return().
--- 897,11 ---
  
    void print_data_on(outputStream* st) const;
  };
  
  // Entries to collect type information at a call: contains arguments
! // (TypeStackSlotEntries), a return type (SingleTypeEntry) and a
  // number of cells. Because the number of cells for the return type is
  // smaller than the number of cells for the type of an arguments, the
  // number of cells is used to tell how many arguments are profiled and
  // whether a return value is profiled. See has_arguments() and
  // has_return().

*** 936,11 ***
    static ByteSize argument_type_offset(int i) {
      return in_ByteSize(argument_type_local_offset(i) * DataLayout::cell_size);
    }
  
    static ByteSize return_only_size() {
!     return ReturnTypeEntry::size() + in_ByteSize(header_cell_count() * DataLayout::cell_size);
    }
  
  };
  
  // CallTypeData
--- 951,11 ---
    static ByteSize argument_type_offset(int i) {
      return in_ByteSize(argument_type_local_offset(i) * DataLayout::cell_size);
    }
  
    static ByteSize return_only_size() {
!     return SingleTypeEntry::size() + in_ByteSize(header_cell_count() * DataLayout::cell_size);
    }
  
  };
  
  // CallTypeData

*** 951,11 ***
  class CallTypeData : public CounterData {
  private:
    // entries for arguments if any
    TypeStackSlotEntries _args;
    // entry for return type if any
!   ReturnTypeEntry _ret;
  
    int cell_count_global_offset() const {
      return CounterData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset();
    }
  
--- 966,11 ---
  class CallTypeData : public CounterData {
  private:
    // entries for arguments if any
    TypeStackSlotEntries _args;
    // entry for return type if any
!   SingleTypeEntry _ret;
  
    int cell_count_global_offset() const {
      return CounterData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset();
    }
  

*** 970,11 ***
  
  public:
    CallTypeData(DataLayout* layout) :
      CounterData(layout),
      _args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()),
!     _ret(cell_count() - ReturnTypeEntry::static_cell_count())
    {
      assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type");
      // Some compilers (VC++) don't want this passed in member initialization list
      _args.set_profile_data(this);
      _ret.set_profile_data(this);
--- 985,11 ---
  
  public:
    CallTypeData(DataLayout* layout) :
      CounterData(layout),
      _args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()),
!     _ret(cell_count() - SingleTypeEntry::static_cell_count())
    {
      assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type");
      // Some compilers (VC++) don't want this passed in member initialization list
      _args.set_profile_data(this);
      _ret.set_profile_data(this);

*** 983,11 ***
    const TypeStackSlotEntries* args() const {
      assert(has_arguments(), "no profiling of arguments");
      return &_args;
    }
  
!   const ReturnTypeEntry* ret() const {
      assert(has_return(), "no profiling of return value");
      return &_ret;
    }
  
    virtual bool is_CallTypeData() const { return true; }
--- 998,11 ---
    const TypeStackSlotEntries* args() const {
      assert(has_arguments(), "no profiling of arguments");
      return &_args;
    }
  
!   const SingleTypeEntry* ret() const {
      assert(has_return(), "no profiling of return value");
      return &_ret;
    }
  
    virtual bool is_CallTypeData() const { return true; }

*** 1254,11 ***
  class VirtualCallTypeData : public VirtualCallData {
  private:
    // entries for arguments if any
    TypeStackSlotEntries _args;
    // entry for return type if any
!   ReturnTypeEntry _ret;
  
    int cell_count_global_offset() const {
      return VirtualCallData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset();
    }
  
--- 1269,11 ---
  class VirtualCallTypeData : public VirtualCallData {
  private:
    // entries for arguments if any
    TypeStackSlotEntries _args;
    // entry for return type if any
!   SingleTypeEntry _ret;
  
    int cell_count_global_offset() const {
      return VirtualCallData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset();
    }
  

*** 1273,11 ***
  
  public:
    VirtualCallTypeData(DataLayout* layout) :
      VirtualCallData(layout),
      _args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()),
!     _ret(cell_count() - ReturnTypeEntry::static_cell_count())
    {
      assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type");
      // Some compilers (VC++) don't want this passed in member initialization list
      _args.set_profile_data(this);
      _ret.set_profile_data(this);
--- 1288,11 ---
  
  public:
    VirtualCallTypeData(DataLayout* layout) :
      VirtualCallData(layout),
      _args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()),
!     _ret(cell_count() - SingleTypeEntry::static_cell_count())
    {
      assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type");
      // Some compilers (VC++) don't want this passed in member initialization list
      _args.set_profile_data(this);
      _ret.set_profile_data(this);

*** 1286,11 ***
    const TypeStackSlotEntries* args() const {
      assert(has_arguments(), "no profiling of arguments");
      return &_args;
    }
  
!   const ReturnTypeEntry* ret() const {
      assert(has_return(), "no profiling of return value");
      return &_ret;
    }
  
    virtual bool is_VirtualCallTypeData() const { return true; }
--- 1301,11 ---
    const TypeStackSlotEntries* args() const {
      assert(has_arguments(), "no profiling of arguments");
      return &_args;
    }
  
!   const SingleTypeEntry* ret() const {
      assert(has_return(), "no profiling of return value");
      return &_ret;
    }
  
    virtual bool is_VirtualCallTypeData() const { return true; }

*** 1488,11 ***
      set_int_at(displacement_off_set, displacement);
    }
  
  public:
    BranchData(DataLayout* layout) : JumpData(layout) {
!     assert(layout->tag() == DataLayout::branch_data_tag, "wrong type");
    }
  
    virtual bool is_BranchData() const { return true; }
  
    static int static_cell_count() {
--- 1503,11 ---
      set_int_at(displacement_off_set, displacement);
    }
  
  public:
    BranchData(DataLayout* layout) : JumpData(layout) {
!     assert(layout->tag() == DataLayout::branch_data_tag || layout->tag() == DataLayout::acmp_data_tag, "wrong type");
    }
  
    virtual bool is_BranchData() const { return true; }
  
    static int static_cell_count() {

*** 1845,10 ***
--- 1860,156 ---
    }
  
    virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
  };
  
+ class ArrayLoadStoreData : public ProfileData {
+ private:
+   enum {
+     flat_array_flag = DataLayout::first_flag,
+     null_free_array_flag = flat_array_flag + 1,
+   };
+ 
+   SingleTypeEntry _array;
+   SingleTypeEntry _element;
+ 
+ public:
+   ArrayLoadStoreData(DataLayout* layout) :
+     ProfileData(layout),
+     _array(0),
+     _element(SingleTypeEntry::static_cell_count()) {
+     assert(layout->tag() == DataLayout::array_load_store_data_tag, "wrong type");
+     _array.set_profile_data(this);
+     _element.set_profile_data(this);
+   }
+ 
+   const SingleTypeEntry* array() const {
+     return &_array;
+   }
+ 
+   const SingleTypeEntry* element() const {
+     return &_element;
+   }
+ 
+   virtual bool is_ArrayLoadStoreData() const { return true; }
+ 
+   static int static_cell_count() {
+     return SingleTypeEntry::static_cell_count() * 2;
+   }
+ 
+   virtual int cell_count() const {
+     return static_cell_count();
+   }
+ 
+   void set_flat_array() { set_flag_at(flat_array_flag); }
+   bool flat_array() const { return flag_at(flat_array_flag); }
+ 
+   void set_null_free_array() { set_flag_at(null_free_array_flag); }
+   bool null_free_array() const { return flag_at(null_free_array_flag); }
+ 
+   // Code generation support
+   static int flat_array_byte_constant() {
+     return flag_number_to_constant(flat_array_flag);
+   }
+ 
+   static int null_free_array_byte_constant() {
+     return flag_number_to_constant(null_free_array_flag);
+   }
+ 
+   static ByteSize array_offset() {
+     return cell_offset(0);
+   }
+ 
+   static ByteSize element_offset() {
+     return cell_offset(SingleTypeEntry::static_cell_count());
+   }
+ 
+   virtual void clean_weak_klass_links(bool always_clean) {
+     _array.clean_weak_klass_links(always_clean);
+     _element.clean_weak_klass_links(always_clean);
+   }
+ 
+   static ByteSize array_load_store_data_size() {
+     return cell_offset(static_cell_count());
+   }
+ 
+   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
+ };
+ 
+ class ACmpData : public BranchData {
+ private:
+   enum {
+     left_inline_type_flag = DataLayout::first_flag,
+     right_inline_type_flag
+   };
+ 
+   SingleTypeEntry _left;
+   SingleTypeEntry _right;
+ 
+ public:
+   ACmpData(DataLayout* layout) :
+     BranchData(layout),
+     _left(BranchData::static_cell_count()),
+     _right(BranchData::static_cell_count() + SingleTypeEntry::static_cell_count()) {
+     assert(layout->tag() == DataLayout::acmp_data_tag, "wrong type");
+     _left.set_profile_data(this);
+     _right.set_profile_data(this);
+   }
+ 
+   const SingleTypeEntry* left() const {
+     return &_left;
+   }
+ 
+   const SingleTypeEntry* right() const {
+     return &_right;
+   }
+ 
+   virtual bool is_ACmpData() const { return true; }
+ 
+   static int static_cell_count() {
+     return BranchData::static_cell_count() + SingleTypeEntry::static_cell_count() * 2;
+   }
+ 
+   virtual int cell_count() const {
+     return static_cell_count();
+   }
+ 
+   void set_left_inline_type() { set_flag_at(left_inline_type_flag); }
+   bool left_inline_type() const { return flag_at(left_inline_type_flag); }
+ 
+   void set_right_inline_type() { set_flag_at(right_inline_type_flag); }
+   bool right_inline_type() const { return flag_at(right_inline_type_flag); }
+ 
+   // Code generation support
+   static int left_inline_type_byte_constant() {
+     return flag_number_to_constant(left_inline_type_flag);
+   }
+ 
+   static int right_inline_type_byte_constant() {
+     return flag_number_to_constant(right_inline_type_flag);
+   }
+ 
+   static ByteSize left_offset() {
+     return cell_offset(BranchData::static_cell_count());
+   }
+ 
+   static ByteSize right_offset() {
+     return cell_offset(BranchData::static_cell_count() + SingleTypeEntry::static_cell_count());
+   }
+ 
+   virtual void clean_weak_klass_links(bool always_clean) {
+     _left.clean_weak_klass_links(always_clean);
+     _right.clean_weak_klass_links(always_clean);
+   }
+ 
+   static ByteSize acmp_data_size() {
+     return cell_offset(static_cell_count());
+   }
+ 
+   virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
+ };
+ 
  // MethodData*
  //
  // A MethodData* holds information which has been collected about
  // a method.  Its layout looks like this:
  //
< prev index next >