src/share/vm/oops/methodData.hpp

changeset 5921
ce0cc25bc5e2
parent 5914
d13d7aba8c12
child 5987
5ccbab1c69f3
     1.1 --- a/src/share/vm/oops/methodData.hpp	Fri Oct 11 19:51:31 2013 -0700
     1.2 +++ b/src/share/vm/oops/methodData.hpp	Sat Oct 12 12:12:59 2013 +0200
     1.3 @@ -271,6 +271,7 @@
     1.4  // data in a structured way.
     1.5  class ProfileData : public ResourceObj {
     1.6    friend class TypeEntries;
     1.7 +  friend class ReturnTypeEntry;
     1.8    friend class TypeStackSlotEntries;
     1.9  private:
    1.10  #ifndef PRODUCT
    1.11 @@ -748,119 +749,60 @@
    1.12      per_arg_cell_count
    1.13    };
    1.14  
    1.15 -  // Start with a header if needed. It stores the number of cells used
    1.16 -  // for this call type information. Unless we collect only profiling
    1.17 -  // for a single argument the number of cells is unknown statically.
    1.18 -  static int header_cell_count() {
    1.19 -    return (TypeProfileArgsLimit > 1) ? 1 : 0;
    1.20 -  }
    1.21 -
    1.22 -  static int cell_count_local_offset() {
    1.23 -     assert(arguments_profiling_enabled() && TypeProfileArgsLimit > 1, "no cell count");
    1.24 -     return 0;
    1.25 -   }
    1.26 -
    1.27 -  int cell_count_global_offset() const {
    1.28 -    return _base_off + cell_count_local_offset();
    1.29 -  }
    1.30 -
    1.31    // offset of cell for stack slot for entry i within ProfileData object
    1.32 -  int stack_slot_global_offset(int i) const {
    1.33 +  int stack_slot_offset(int i) const {
    1.34      return _base_off + stack_slot_local_offset(i);
    1.35    }
    1.36  
    1.37 -  void check_number_of_arguments(int total) {
    1.38 -    assert(number_of_arguments() == total, "should be set in DataLayout::initialize");
    1.39 -  }
    1.40 -
    1.41 -  // number of cells not counting the header
    1.42 -  int cell_count_no_header() const {
    1.43 -    return _pd->uint_at(cell_count_global_offset());
    1.44 -  }
    1.45 -
    1.46 -  static bool arguments_profiling_enabled();
    1.47 -  static void assert_arguments_profiling_enabled() {
    1.48 -    assert(arguments_profiling_enabled(), "args profiling should be on");
    1.49 -  }
    1.50 -
    1.51  protected:
    1.52 +  const int _number_of_entries;
    1.53  
    1.54    // offset of cell for type for entry i within ProfileData object
    1.55 -  int type_global_offset(int i) const {
    1.56 +  int type_offset(int i) const {
    1.57      return _base_off + type_local_offset(i);
    1.58    }
    1.59  
    1.60  public:
    1.61  
    1.62 -  TypeStackSlotEntries(int base_off)
    1.63 -    : TypeEntries(base_off) {}
    1.64 +  TypeStackSlotEntries(int base_off, int nb_entries)
    1.65 +    : TypeEntries(base_off), _number_of_entries(nb_entries) {}
    1.66  
    1.67 -  static int compute_cell_count(BytecodeStream* stream);
    1.68 +  static int compute_cell_count(Symbol* signature, int max);
    1.69  
    1.70 -  static void initialize(DataLayout* dl, int base, int cell_count) {
    1.71 -    if (TypeProfileArgsLimit > 1) {
    1.72 -      int off = base + cell_count_local_offset();
    1.73 -      dl->set_cell_at(off, cell_count - base - header_cell_count());
    1.74 -    }
    1.75 -  }
    1.76 -
    1.77 -  void post_initialize(BytecodeStream* stream);
    1.78 -
    1.79 -  int number_of_arguments() const {
    1.80 -    assert_arguments_profiling_enabled();
    1.81 -    if (TypeProfileArgsLimit > 1) {
    1.82 -      int cell_count = cell_count_no_header();
    1.83 -      int nb = cell_count / TypeStackSlotEntries::per_arg_count();
    1.84 -      assert(nb > 0 && nb <= TypeProfileArgsLimit , "only when we profile args");
    1.85 -      return nb;
    1.86 -    } else {
    1.87 -      assert(TypeProfileArgsLimit == 1, "at least one arg");
    1.88 -      return 1;
    1.89 -    }
    1.90 -  }
    1.91 -
    1.92 -  int cell_count() const {
    1.93 -    assert_arguments_profiling_enabled();
    1.94 -    if (TypeProfileArgsLimit > 1) {
    1.95 -      return _base_off + header_cell_count() + _pd->int_at_unchecked(cell_count_global_offset());
    1.96 -    } else {
    1.97 -      return _base_off + TypeStackSlotEntries::per_arg_count();
    1.98 -    }
    1.99 -  }
   1.100 +  void post_initialize(Symbol* signature, bool has_receiver);
   1.101  
   1.102    // offset of cell for stack slot for entry i within this block of cells for a TypeStackSlotEntries
   1.103    static int stack_slot_local_offset(int i) {
   1.104 -    assert_arguments_profiling_enabled();
   1.105 -    return header_cell_count() + i * per_arg_cell_count + stack_slot_entry;
   1.106 +    return i * per_arg_cell_count + stack_slot_entry;
   1.107    }
   1.108  
   1.109    // offset of cell for type for entry i within this block of cells for a TypeStackSlotEntries
   1.110    static int type_local_offset(int i) {
   1.111 -    return header_cell_count() + i * per_arg_cell_count + type_entry;
   1.112 +    return i * per_arg_cell_count + type_entry;
   1.113    }
   1.114  
   1.115    // stack slot for entry i
   1.116    uint stack_slot(int i) const {
   1.117 -    assert(i >= 0 && i < number_of_arguments(), "oob");
   1.118 -    return _pd->uint_at(stack_slot_global_offset(i));
   1.119 +    assert(i >= 0 && i < _number_of_entries, "oob");
   1.120 +    return _pd->uint_at(stack_slot_offset(i));
   1.121    }
   1.122  
   1.123    // set stack slot for entry i
   1.124    void set_stack_slot(int i, uint num) {
   1.125 -    assert(i >= 0 && i < number_of_arguments(), "oob");
   1.126 -    _pd->set_uint_at(stack_slot_global_offset(i), num);
   1.127 +    assert(i >= 0 && i < _number_of_entries, "oob");
   1.128 +    _pd->set_uint_at(stack_slot_offset(i), num);
   1.129    }
   1.130  
   1.131    // type for entry i
   1.132    intptr_t type(int i) const {
   1.133 -    assert(i >= 0 && i < number_of_arguments(), "oob");
   1.134 -    return _pd->intptr_at(type_global_offset(i));
   1.135 +    assert(i >= 0 && i < _number_of_entries, "oob");
   1.136 +    return _pd->intptr_at(type_offset(i));
   1.137    }
   1.138  
   1.139    // set type for entry i
   1.140    void set_type(int i, intptr_t k) {
   1.141 -    assert(i >= 0 && i < number_of_arguments(), "oob");
   1.142 -    _pd->set_intptr_at(type_global_offset(i), k);
   1.143 +    assert(i >= 0 && i < _number_of_entries, "oob");
   1.144 +    _pd->set_intptr_at(type_offset(i), k);
   1.145    }
   1.146  
   1.147    static ByteSize per_arg_size() {
   1.148 @@ -871,22 +813,50 @@
   1.149      return per_arg_cell_count ;
   1.150    }
   1.151  
   1.152 -  // Code generation support
   1.153 -   static ByteSize cell_count_offset() {
   1.154 -     return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size);
   1.155 -   }
   1.156 +  // GC support
   1.157 +  void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
   1.158  
   1.159 -   static ByteSize args_data_offset() {
   1.160 -     return in_ByteSize(header_cell_count() * DataLayout::cell_size);
   1.161 -   }
   1.162 +#ifndef PRODUCT
   1.163 +  void print_data_on(outputStream* st) const;
   1.164 +#endif
   1.165 +};
   1.166  
   1.167 -   static ByteSize stack_slot_offset(int i) {
   1.168 -     return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size);
   1.169 -   }
   1.170 +// Type entry used for return from a call. A single cell to record the
   1.171 +// type.
   1.172 +class ReturnTypeEntry : public TypeEntries {
   1.173  
   1.174 -   static ByteSize type_offset(int i) {
   1.175 -     return in_ByteSize(type_local_offset(i) * DataLayout::cell_size);
   1.176 -   }
   1.177 +private:
   1.178 +  enum {
   1.179 +    cell_count = 1
   1.180 +  };
   1.181 +
   1.182 +public:
   1.183 +  ReturnTypeEntry(int base_off)
   1.184 +    : TypeEntries(base_off) {}
   1.185 +
   1.186 +  void post_initialize() {
   1.187 +    set_type(type_none());
   1.188 +  }
   1.189 +
   1.190 +  intptr_t type() const {
   1.191 +    return _pd->intptr_at(_base_off);
   1.192 +  }
   1.193 +
   1.194 +  void set_type(intptr_t k) {
   1.195 +    _pd->set_intptr_at(_base_off, k);
   1.196 +  }
   1.197 +
   1.198 +  static int static_cell_count() {
   1.199 +    return cell_count;
   1.200 +  }
   1.201 +
   1.202 +  static ByteSize size() {
   1.203 +    return in_ByteSize(cell_count * DataLayout::cell_size);
   1.204 +  }
   1.205 +
   1.206 +  ByteSize type_offset() {
   1.207 +    return DataLayout::cell_offset(_base_off);
   1.208 +  }
   1.209  
   1.210    // GC support
   1.211    void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
   1.212 @@ -896,23 +866,118 @@
   1.213  #endif
   1.214  };
   1.215  
   1.216 +// Entries to collect type information at a call: contains arguments
   1.217 +// (TypeStackSlotEntries), a return type (ReturnTypeEntry) and a
   1.218 +// number of cells. Because the number of cells for the return type is
   1.219 +// smaller than the number of cells for the type of an arguments, the
   1.220 +// number of cells is used to tell how many arguments are profiled and
   1.221 +// whether a return value is profiled. See has_arguments() and
   1.222 +// has_return().
   1.223 +class TypeEntriesAtCall {
   1.224 +private:
   1.225 +  static int stack_slot_local_offset(int i) {
   1.226 +    return header_cell_count() + TypeStackSlotEntries::stack_slot_local_offset(i);
   1.227 +  }
   1.228 +
   1.229 +  static int argument_type_local_offset(int i) {
   1.230 +    return header_cell_count() + TypeStackSlotEntries::type_local_offset(i);;
   1.231 +  }
   1.232 +
   1.233 +public:
   1.234 +
   1.235 +  static int header_cell_count() {
   1.236 +    return 1;
   1.237 +  }
   1.238 +
   1.239 +  static int cell_count_local_offset() {
   1.240 +    return 0;
   1.241 +  }
   1.242 +
   1.243 +  static int compute_cell_count(BytecodeStream* stream);
   1.244 +
   1.245 +  static void initialize(DataLayout* dl, int base, int cell_count) {
   1.246 +    int off = base + cell_count_local_offset();
   1.247 +    dl->set_cell_at(off, cell_count - base - header_cell_count());
   1.248 +  }
   1.249 +
   1.250 +  static bool arguments_profiling_enabled();
   1.251 +  static bool return_profiling_enabled();
   1.252 +
   1.253 +  // Code generation support
   1.254 +  static ByteSize cell_count_offset() {
   1.255 +    return in_ByteSize(cell_count_local_offset() * DataLayout::cell_size);
   1.256 +  }
   1.257 +
   1.258 +  static ByteSize args_data_offset() {
   1.259 +    return in_ByteSize(header_cell_count() * DataLayout::cell_size);
   1.260 +  }
   1.261 +
   1.262 +  static ByteSize stack_slot_offset(int i) {
   1.263 +    return in_ByteSize(stack_slot_local_offset(i) * DataLayout::cell_size);
   1.264 +  }
   1.265 +
   1.266 +  static ByteSize argument_type_offset(int i) {
   1.267 +    return in_ByteSize(argument_type_local_offset(i) * DataLayout::cell_size);
   1.268 +  }
   1.269 +};
   1.270 +
   1.271  // CallTypeData
   1.272  //
   1.273  // A CallTypeData is used to access profiling information about a non
   1.274 -// virtual call for which we collect type information about arguments.
   1.275 +// virtual call for which we collect type information about arguments
   1.276 +// and return value.
   1.277  class CallTypeData : public CounterData {
   1.278  private:
   1.279 +  // entries for arguments if any
   1.280    TypeStackSlotEntries _args;
   1.281 +  // entry for return type if any
   1.282 +  ReturnTypeEntry _ret;
   1.283 +
   1.284 +  int cell_count_global_offset() const {
   1.285 +    return CounterData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset();
   1.286 +  }
   1.287 +
   1.288 +  // number of cells not counting the header
   1.289 +  int cell_count_no_header() const {
   1.290 +    return uint_at(cell_count_global_offset());
   1.291 +  }
   1.292 +
   1.293 +  void check_number_of_arguments(int total) {
   1.294 +    assert(number_of_arguments() == total, "should be set in DataLayout::initialize");
   1.295 +  }
   1.296 +
   1.297 +protected:
   1.298 +  // An entry for a return value takes less space than an entry for an
   1.299 +  // argument so if the number of cells exceeds the number of cells
   1.300 +  // needed for an argument, this object contains type information for
   1.301 +  // at least one argument.
   1.302 +  bool has_arguments() const {
   1.303 +    bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();
   1.304 +    assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");
   1.305 +    return res;
   1.306 +  }
   1.307  
   1.308  public:
   1.309    CallTypeData(DataLayout* layout) :
   1.310 -    CounterData(layout), _args(CounterData::static_cell_count())  {
   1.311 +    CounterData(layout),
   1.312 +    _args(CounterData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()),
   1.313 +    _ret(cell_count() - ReturnTypeEntry::static_cell_count())
   1.314 +  {
   1.315      assert(layout->tag() == DataLayout::call_type_data_tag, "wrong type");
   1.316      // Some compilers (VC++) don't want this passed in member initialization list
   1.317      _args.set_profile_data(this);
   1.318 +    _ret.set_profile_data(this);
   1.319    }
   1.320  
   1.321 -  const TypeStackSlotEntries* args() const { return &_args; }
   1.322 +  const TypeStackSlotEntries* args() const {
   1.323 +    assert(has_arguments(), "no profiling of arguments");
   1.324 +    return &_args;
   1.325 +  }
   1.326 +
   1.327 +  const ReturnTypeEntry* ret() const {
   1.328 +    assert(has_return(), "no profiling of return value");
   1.329 +    return &_ret;
   1.330 +  }
   1.331  
   1.332    virtual bool is_CallTypeData() const { return true; }
   1.333  
   1.334 @@ -921,38 +986,60 @@
   1.335    }
   1.336  
   1.337    static int compute_cell_count(BytecodeStream* stream) {
   1.338 -    return CounterData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream);
   1.339 +    return CounterData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream);
   1.340    }
   1.341  
   1.342    static void initialize(DataLayout* dl, int cell_count) {
   1.343 -    TypeStackSlotEntries::initialize(dl, CounterData::static_cell_count(), cell_count);
   1.344 +    TypeEntriesAtCall::initialize(dl, CounterData::static_cell_count(), cell_count);
   1.345    }
   1.346  
   1.347 -  virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {
   1.348 -    _args.post_initialize(stream);
   1.349 +  virtual void post_initialize(BytecodeStream* stream, MethodData* mdo);
   1.350 +
   1.351 +  virtual int cell_count() const {
   1.352 +    return CounterData::static_cell_count() +
   1.353 +      TypeEntriesAtCall::header_cell_count() +
   1.354 +      int_at_unchecked(cell_count_global_offset());
   1.355    }
   1.356  
   1.357 -  virtual int cell_count() const {
   1.358 -    return _args.cell_count();
   1.359 -  }
   1.360 -
   1.361 -  uint number_of_arguments() const {
   1.362 -    return args()->number_of_arguments();
   1.363 +  int number_of_arguments() const {
   1.364 +    return cell_count_no_header() / TypeStackSlotEntries::per_arg_count();
   1.365    }
   1.366  
   1.367    void set_argument_type(int i, Klass* k) {
   1.368 +    assert(has_arguments(), "no arguments!");
   1.369      intptr_t current = _args.type(i);
   1.370      _args.set_type(i, TypeEntries::with_status(k, current));
   1.371    }
   1.372  
   1.373 +  void set_return_type(Klass* k) {
   1.374 +    assert(has_return(), "no return!");
   1.375 +    intptr_t current = _ret.type();
   1.376 +    _ret.set_type(TypeEntries::with_status(k, current));
   1.377 +  }
   1.378 +
   1.379 +  // An entry for a return value takes less space than an entry for an
   1.380 +  // argument, so if the remainder of the number of cells divided by
   1.381 +  // the number of cells for an argument is not null, a return value
   1.382 +  // is profiled in this object.
   1.383 +  bool has_return() const {
   1.384 +    bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0;
   1.385 +    assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values");
   1.386 +    return res;
   1.387 +  }
   1.388 +
   1.389    // Code generation support
   1.390    static ByteSize args_data_offset() {
   1.391 -    return cell_offset(CounterData::static_cell_count()) + TypeStackSlotEntries::args_data_offset();
   1.392 +    return cell_offset(CounterData::static_cell_count()) + TypeEntriesAtCall::args_data_offset();
   1.393    }
   1.394  
   1.395    // GC support
   1.396    virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
   1.397 -    _args.clean_weak_klass_links(is_alive_closure);
   1.398 +    if (has_arguments()) {
   1.399 +      _args.clean_weak_klass_links(is_alive_closure);
   1.400 +    }
   1.401 +    if (has_return()) {
   1.402 +      _ret.clean_weak_klass_links(is_alive_closure);
   1.403 +    }
   1.404    }
   1.405  
   1.406  #ifndef PRODUCT
   1.407 @@ -1105,20 +1192,59 @@
   1.408  //
   1.409  // A VirtualCallTypeData is used to access profiling information about
   1.410  // a virtual call for which we collect type information about
   1.411 -// arguments.
   1.412 +// arguments and return value.
   1.413  class VirtualCallTypeData : public VirtualCallData {
   1.414  private:
   1.415 +  // entries for arguments if any
   1.416    TypeStackSlotEntries _args;
   1.417 +  // entry for return type if any
   1.418 +  ReturnTypeEntry _ret;
   1.419 +
   1.420 +  int cell_count_global_offset() const {
   1.421 +    return VirtualCallData::static_cell_count() + TypeEntriesAtCall::cell_count_local_offset();
   1.422 +  }
   1.423 +
   1.424 +  // number of cells not counting the header
   1.425 +  int cell_count_no_header() const {
   1.426 +    return uint_at(cell_count_global_offset());
   1.427 +  }
   1.428 +
   1.429 +  void check_number_of_arguments(int total) {
   1.430 +    assert(number_of_arguments() == total, "should be set in DataLayout::initialize");
   1.431 +  }
   1.432 +
   1.433 +protected:
   1.434 +  // An entry for a return value takes less space than an entry for an
   1.435 +  // argument so if the number of cells exceeds the number of cells
   1.436 +  // needed for an argument, this object contains type information for
   1.437 +  // at least one argument.
   1.438 +  bool has_arguments() const {
   1.439 +    bool res = cell_count_no_header() >= TypeStackSlotEntries::per_arg_count();
   1.440 +    assert (!res || TypeEntriesAtCall::arguments_profiling_enabled(), "no profiling of arguments");
   1.441 +    return res;
   1.442 +  }
   1.443  
   1.444  public:
   1.445    VirtualCallTypeData(DataLayout* layout) :
   1.446 -    VirtualCallData(layout), _args(VirtualCallData::static_cell_count())  {
   1.447 +    VirtualCallData(layout),
   1.448 +    _args(VirtualCallData::static_cell_count()+TypeEntriesAtCall::header_cell_count(), number_of_arguments()),
   1.449 +    _ret(cell_count() - ReturnTypeEntry::static_cell_count())
   1.450 +  {
   1.451      assert(layout->tag() == DataLayout::virtual_call_type_data_tag, "wrong type");
   1.452      // Some compilers (VC++) don't want this passed in member initialization list
   1.453      _args.set_profile_data(this);
   1.454 +    _ret.set_profile_data(this);
   1.455    }
   1.456  
   1.457 -  const TypeStackSlotEntries* args() const { return &_args; }
   1.458 +  const TypeStackSlotEntries* args() const {
   1.459 +    assert(has_arguments(), "no profiling of arguments");
   1.460 +    return &_args;
   1.461 +  }
   1.462 +
   1.463 +  const ReturnTypeEntry* ret() const {
   1.464 +    assert(has_return(), "no profiling of return value");
   1.465 +    return &_ret;
   1.466 +  }
   1.467  
   1.468    virtual bool is_VirtualCallTypeData() const { return true; }
   1.469  
   1.470 @@ -1127,39 +1253,61 @@
   1.471    }
   1.472  
   1.473    static int compute_cell_count(BytecodeStream* stream) {
   1.474 -    return VirtualCallData::static_cell_count() + TypeStackSlotEntries::compute_cell_count(stream);
   1.475 +    return VirtualCallData::static_cell_count() + TypeEntriesAtCall::compute_cell_count(stream);
   1.476    }
   1.477  
   1.478    static void initialize(DataLayout* dl, int cell_count) {
   1.479 -    TypeStackSlotEntries::initialize(dl, VirtualCallData::static_cell_count(), cell_count);
   1.480 +    TypeEntriesAtCall::initialize(dl, VirtualCallData::static_cell_count(), cell_count);
   1.481    }
   1.482  
   1.483 -  virtual void post_initialize(BytecodeStream* stream, MethodData* mdo) {
   1.484 -    _args.post_initialize(stream);
   1.485 +  virtual void post_initialize(BytecodeStream* stream, MethodData* mdo);
   1.486 +
   1.487 +  virtual int cell_count() const {
   1.488 +    return VirtualCallData::static_cell_count() +
   1.489 +      TypeEntriesAtCall::header_cell_count() +
   1.490 +      int_at_unchecked(cell_count_global_offset());
   1.491    }
   1.492  
   1.493 -  virtual int cell_count() const {
   1.494 -    return _args.cell_count();
   1.495 -  }
   1.496 -
   1.497 -  uint number_of_arguments() const {
   1.498 -    return args()->number_of_arguments();
   1.499 +  int number_of_arguments() const {
   1.500 +    return cell_count_no_header() / TypeStackSlotEntries::per_arg_count();
   1.501    }
   1.502  
   1.503    void set_argument_type(int i, Klass* k) {
   1.504 +    assert(has_arguments(), "no arguments!");
   1.505      intptr_t current = _args.type(i);
   1.506      _args.set_type(i, TypeEntries::with_status(k, current));
   1.507    }
   1.508  
   1.509 +  void set_return_type(Klass* k) {
   1.510 +    assert(has_return(), "no return!");
   1.511 +    intptr_t current = _ret.type();
   1.512 +    _ret.set_type(TypeEntries::with_status(k, current));
   1.513 +  }
   1.514 +
   1.515 +  // An entry for a return value takes less space than an entry for an
   1.516 +  // argument, so if the remainder of the number of cells divided by
   1.517 +  // the number of cells for an argument is not null, a return value
   1.518 +  // is profiled in this object.
   1.519 +  bool has_return() const {
   1.520 +    bool res = (cell_count_no_header() % TypeStackSlotEntries::per_arg_count()) != 0;
   1.521 +    assert (!res || TypeEntriesAtCall::return_profiling_enabled(), "no profiling of return values");
   1.522 +    return res;
   1.523 +  }
   1.524 +
   1.525    // Code generation support
   1.526    static ByteSize args_data_offset() {
   1.527 -    return cell_offset(VirtualCallData::static_cell_count()) + TypeStackSlotEntries::args_data_offset();
   1.528 +    return cell_offset(VirtualCallData::static_cell_count()) + TypeEntriesAtCall::args_data_offset();
   1.529    }
   1.530  
   1.531    // GC support
   1.532    virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure) {
   1.533      ReceiverTypeData::clean_weak_klass_links(is_alive_closure);
   1.534 -    _args.clean_weak_klass_links(is_alive_closure);
   1.535 +    if (has_arguments()) {
   1.536 +      _args.clean_weak_klass_links(is_alive_closure);
   1.537 +    }
   1.538 +    if (has_return()) {
   1.539 +      _ret.clean_weak_klass_links(is_alive_closure);
   1.540 +    }
   1.541    }
   1.542  
   1.543  #ifndef PRODUCT
   1.544 @@ -1691,6 +1839,9 @@
   1.545    static bool profile_arguments_jsr292_only();
   1.546    static bool profile_all_arguments();
   1.547    static bool profile_arguments_for_invoke(methodHandle m, int bci);
   1.548 +  static int profile_return_flag();
   1.549 +  static bool profile_all_return();
   1.550 +  static bool profile_return_for_invoke(methodHandle m, int bci);
   1.551  
   1.552  public:
   1.553    static int header_size() {
   1.554 @@ -1933,6 +2084,8 @@
   1.555    void verify_data_on(outputStream* st);
   1.556  
   1.557    static bool profile_arguments();
   1.558 +  static bool profile_return();
   1.559 +  static bool profile_return_jsr292_only();
   1.560  };
   1.561  
   1.562  #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP

mercurial