< prev index next >

src/hotspot/share/oops/methodData.hpp

Print this page
@@ -123,11 +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
+     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 +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 ReturnTypeEntry;
+   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 +618,12 @@
    }
  
  public:
    JumpData(DataLayout* layout) : ProfileData(layout) {
      assert(layout->tag() == DataLayout::jump_data_tag ||
-       layout->tag() == DataLayout::branch_data_tag, "wrong type");
+       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 +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 ReturnTypeEntry : public TypeEntries {
+ class SingleTypeEntry : public TypeEntries {
  
  private:
    enum {
      cell_count = 1
    };
  
  public:
-   ReturnTypeEntry(int base_off)
+   SingleTypeEntry(int base_off)
      : TypeEntries(base_off) {}
  
    void post_initialize() {
      set_type(type_none());
    }

@@ -882,11 +897,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
+ // (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 +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 ReturnTypeEntry::size() + in_ByteSize(header_cell_count() * DataLayout::cell_size);
+     return SingleTypeEntry::size() + in_ByteSize(header_cell_count() * DataLayout::cell_size);
    }
  
  };
  
  // CallTypeData

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

@@ -970,11 +985,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())
+     _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 +998,11 @@
    const TypeStackSlotEntries* args() const {
      assert(has_arguments(), "no profiling of arguments");
      return &_args;
    }
  
-   const ReturnTypeEntry* ret() const {
+   const SingleTypeEntry* ret() const {
      assert(has_return(), "no profiling of return value");
      return &_ret;
    }
  
    virtual bool is_CallTypeData() const { return true; }

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

@@ -1273,11 +1288,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())
+     _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 +1301,11 @@
    const TypeStackSlotEntries* args() const {
      assert(has_arguments(), "no profiling of arguments");
      return &_args;
    }
  
-   const ReturnTypeEntry* ret() const {
+   const SingleTypeEntry* ret() const {
      assert(has_return(), "no profiling of return value");
      return &_ret;
    }
  
    virtual bool is_VirtualCallTypeData() const { return true; }

@@ -1488,11 +1503,11 @@
      set_int_at(displacement_off_set, displacement);
    }
  
  public:
    BranchData(DataLayout* layout) : JumpData(layout) {
-     assert(layout->tag() == DataLayout::branch_data_tag, "wrong type");
+     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 >