constMethod.hpp 18.7 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29
#ifndef SHARE_VM_OOPS_CONSTMETHODOOP_HPP
#define SHARE_VM_OOPS_CONSTMETHODOOP_HPP

#include "oops/oop.hpp"

30
// An ConstMethod* represents portions of a Java method which
D
duke 已提交
31 32 33 34 35 36 37 38 39 40 41 42
// do not vary.
//
// Memory layout (each line represents a word). Note that most
// applications load thousands of methods, so keeping the size of this
// structure small has a big impact on footprint.
//
// |------------------------------------------------------|
// | header                                               |
// | klass                                                |
// |------------------------------------------------------|
// | fingerprint 1                                        |
// | fingerprint 2                                        |
43
// | constants                      (oop)                 |
D
duke 已提交
44 45 46 47
// | stackmap_data                  (oop)                 |
// | constMethod_size                                     |
// | interp_kind  | flags    | code_size                  |
// | name index              | signature index            |
48
// | method_idnum            | max_stack                  |
49
// | max_locals              | size_of_parameters         |
D
duke 已提交
50 51 52 53 54 55 56 57 58
// |------------------------------------------------------|
// |                                                      |
// | byte codes                                           |
// |                                                      |
// |------------------------------------------------------|
// | compressed linenumber table                          |
// |  (see class CompressedLineNumberReadStream)          |
// |  (note that length is unknown until decompressed)    |
// |  (access flags bit tells whether table is present)   |
59
// |  (indexed from start of ConstMethod*)                |
D
duke 已提交
60 61 62 63 64 65
// |  (elements not necessarily sorted!)                  |
// |------------------------------------------------------|
// | localvariable table elements + length (length last)  |
// |  (length is u2, elements are 6-tuples of u2)         |
// |  (see class LocalVariableTableElement)               |
// |  (access flags bit tells whether table is present)   |
66
// |  (indexed from end of ConstMethod*)                  |
67 68 69 70 71
// |------------------------------------------------------|
// | exception table + length (length last)               |
// |  (length is u2, elements are 4-tuples of u2)         |
// |  (see class ExceptionTableElement)                   |
// |  (access flags bit tells whether table is present)   |
72
// |  (indexed from end of ConstMethod*)                  |
D
duke 已提交
73 74 75 76 77
// |------------------------------------------------------|
// | checked exceptions elements + length (length last)   |
// |  (length is u2, elements are u2)                     |
// |  (see class CheckedExceptionElement)                 |
// |  (access flags bit tells whether table is present)   |
78 79
// |  (indexed from end of ConstMethod*)                  |
// |------------------------------------------------------|
80 81 82 83 84 85
// | method parameters elements + length (length last)    |
// |  (length is u2, elements are u2, u4 structures)      |
// |  (see class MethodParametersElement)                 |
// |  (access flags bit tells whether table is present)   |
// |  (indexed from end of ConstMethod*)                  |
// |------------------------------------------------------|
86 87
// | generic signature index (u2)                         |
// |  (indexed from start of constMethodOop)              |
D
duke 已提交
88
// |------------------------------------------------------|
C
coleenp 已提交
89 90 91
// | annotations arrays - method, parameter, type, default|
// | pointer to Array<u1> if annotation is present        |
// |------------------------------------------------------|
92 93 94
//
// IMPORTANT: If anything gets added here, there need to be changes to
// ensure that ServicabilityAgent doesn't get broken as a result!
D
duke 已提交
95 96


C
coleenp 已提交
97
// Utility class describing elements in checked exceptions table inlined in Method*.
D
duke 已提交
98 99 100 101 102 103
class CheckedExceptionElement VALUE_OBJ_CLASS_SPEC {
 public:
  u2 class_cp_index;
};


C
coleenp 已提交
104
// Utility class describing elements in local variable table inlined in Method*.
D
duke 已提交
105 106 107 108 109 110 111 112 113 114
class LocalVariableTableElement VALUE_OBJ_CLASS_SPEC {
 public:
  u2 start_bci;
  u2 length;
  u2 name_cp_index;
  u2 descriptor_cp_index;
  u2 signature_cp_index;
  u2 slot;
};

C
coleenp 已提交
115
// Utility class describing elements in exception table
116 117 118 119 120 121 122 123
class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
 public:
  u2 start_pc;
  u2 end_pc;
  u2 handler_pc;
  u2 catch_type_index;
};

124 125 126 127
// Utility class describing elements in method parameters
class MethodParametersElement VALUE_OBJ_CLASS_SPEC {
 public:
  u2 name_cp_index;
128
  u2 flags;
129 130
};

131
class KlassSizeStats;
132

C
coleenp 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
// Class to collect the sizes of ConstMethod inline tables
#define INLINE_TABLES_DO(do_element)            \
  do_element(localvariable_table_length)        \
  do_element(compressed_linenumber_size)        \
  do_element(exception_table_length)            \
  do_element(checked_exceptions_length)         \
  do_element(method_parameters_length)          \
  do_element(generic_signature_index)           \
  do_element(method_annotations_length)         \
  do_element(parameter_annotations_length)      \
  do_element(type_annotations_length)           \
  do_element(default_annotations_length)

#define INLINE_TABLE_DECLARE(sym)    int _##sym;
#define INLINE_TABLE_PARAM(sym)      int sym,
#define INLINE_TABLE_INIT(sym)       _##sym(sym),
#define INLINE_TABLE_NULL(sym)       _##sym(0),
#define INLINE_TABLE_ACCESSOR(sym)   int sym() const { return _##sym; }

class InlineTableSizes : StackObj {
  // declarations
  INLINE_TABLES_DO(INLINE_TABLE_DECLARE)
  int _end;
 public:
  InlineTableSizes(
      INLINE_TABLES_DO(INLINE_TABLE_PARAM)
      int end) :
      INLINE_TABLES_DO(INLINE_TABLE_INIT)
      _end(end) {}

  // Default constructor for no inlined tables
  InlineTableSizes() :
      INLINE_TABLES_DO(INLINE_TABLE_NULL)
      _end(0) {}

  // Accessors
  INLINE_TABLES_DO(INLINE_TABLE_ACCESSOR)
};
#undef INLINE_TABLE_ACCESSOR
#undef INLINE_TABLE_NULL
#undef INLINE_TABLE_INIT
#undef INLINE_TABLE_PARAM
#undef INLINE_TABLE_DECLARE


178
class ConstMethod : public MetaspaceObj {
D
duke 已提交
179
  friend class VMStructs;
180 181 182 183

public:
  typedef enum { NORMAL, OVERPASS } MethodType;

D
duke 已提交
184 185
private:
  enum {
C
coleenp 已提交
186 187 188 189 190 191 192 193 194 195 196
    _has_linenumber_table = 0x0001,
    _has_checked_exceptions = 0x0002,
    _has_localvariable_table = 0x0004,
    _has_exception_table = 0x0008,
    _has_generic_signature = 0x0010,
    _has_method_parameters = 0x0020,
    _is_overpass = 0x0040,
    _has_method_annotations = 0x0080,
    _has_parameter_annotations = 0x0100,
    _has_type_annotations = 0x0200,
    _has_default_annotations = 0x0400
D
duke 已提交
197 198 199 200 201 202 203 204 205 206
  };

  // Bit vector of signature
  // Callers interpret 0=not initialized yet and
  // -1=too many args to fix, must parse the slow way.
  // The real initial value is special to account for nonatomicity of 64 bit
  // loads and stores.  This value may updated and read without a lock by
  // multiple threads, so is volatile.
  volatile uint64_t _fingerprint;

207
  ConstantPool*     _constants;                  // Constant pool
D
duke 已提交
208 209

  // Raw stackmap data for the method
210
  Array<u1>*        _stackmap_data;
D
duke 已提交
211 212

  int               _constMethod_size;
C
coleenp 已提交
213
  u2                _flags;
D
duke 已提交
214

215
  // Size of Java bytecodes allocated immediately after Method*.
D
duke 已提交
216 217 218 219 220 221
  u2                _code_size;
  u2                _name_index;                 // Method name (index in constant pool)
  u2                _signature_index;            // Method signature (index in constant pool)
  u2                _method_idnum;               // unique identification number for the method within the class
                                                 // initially corresponds to the index into the methods array.
                                                 // but this may change with redefinition
222
  u2                _max_stack;                  // Maximum number of entries on the expression stack
223 224
  u2                _max_locals;                 // Number of local variables used by this method
  u2                _size_of_parameters;         // size of the parameter block (receiver + arguments) in words
225 226 227

  // Constructor
  ConstMethod(int byte_code_size,
C
coleenp 已提交
228
              InlineTableSizes* sizes,
229 230
              MethodType is_overpass,
              int size);
D
duke 已提交
231
public:
232

233
  static ConstMethod* allocate(ClassLoaderData* loader_data,
234
                               int byte_code_size,
C
coleenp 已提交
235
                               InlineTableSizes* sizes,
236 237
                               MethodType mt,
                               TRAPS);
238 239 240

  bool is_constMethod() const { return true; }

D
duke 已提交
241
  // Inlined tables
C
coleenp 已提交
242
  void set_inlined_tables_length(InlineTableSizes* sizes);
D
duke 已提交
243

244 245 246
  bool has_generic_signature() const
    { return (_flags & _has_generic_signature) != 0; }

D
duke 已提交
247 248 249 250 251 252 253 254 255
  bool has_linenumber_table() const
    { return (_flags & _has_linenumber_table) != 0; }

  bool has_checked_exceptions() const
    { return (_flags & _has_checked_exceptions) != 0; }

  bool has_localvariable_table() const
    { return (_flags & _has_localvariable_table) != 0; }

256 257 258
  bool has_exception_handler() const
    { return (_flags & _has_exception_table) != 0; }

259 260 261
  bool has_method_parameters() const
    { return (_flags & _has_method_parameters) != 0; }

262 263 264 265 266 267 268 269 270 271 272 273
  MethodType method_type() const {
    return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS;
  }

  void set_method_type(MethodType mt) {
    if (mt == NORMAL) {
      _flags &= ~(_is_overpass);
    } else {
      _flags |= _is_overpass;
    }
  }

274
  // constant pool
275 276
  ConstantPool* constants() const        { return _constants; }
  void set_constants(ConstantPool* c)    { _constants = c; }
D
duke 已提交
277

278
  Method* method() const;
D
duke 已提交
279 280

  // stackmap table data
281 282
  Array<u1>* stackmap_data() const { return _stackmap_data; }
  void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; }
283
  void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPS);
D
duke 已提交
284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323
  bool has_stackmap_table() const { return _stackmap_data != NULL; }

  void init_fingerprint() {
    const uint64_t initval = CONST64(0x8000000000000000);
    _fingerprint = initval;
  }

  uint64_t fingerprint() const                   {
    // Since reads aren't atomic for 64 bits, if any of the high or low order
    // word is the initial value, return 0.  See init_fingerprint for initval.
    uint high_fp = (uint)(_fingerprint >> 32);
    if ((int) _fingerprint == 0 || high_fp == 0x80000000) {
      return 0L;
    } else {
      return _fingerprint;
    }
  }

  uint64_t set_fingerprint(uint64_t new_fingerprint) {
#ifdef ASSERT
    // Assert only valid if complete/valid 64 bit _fingerprint value is read.
    uint64_t oldfp = fingerprint();
#endif // ASSERT
    _fingerprint = new_fingerprint;
    assert(oldfp == 0L || new_fingerprint == oldfp,
           "fingerprint cannot change");
    assert(((new_fingerprint >> 32) != 0x80000000) && (int)new_fingerprint !=0,
           "fingerprint should call init to set initial value");
    return new_fingerprint;
  }

  // name
  int name_index() const                         { return _name_index; }
  void set_name_index(int index)                 { _name_index = index; }

  // signature
  int signature_index() const                    { return _signature_index; }
  void set_signature_index(int index)            { _signature_index = index; }

  // generics support
324 325 326 327 328 329 330 331 332 333 334 335
  int generic_signature_index() const            {
    if (has_generic_signature()) {
      return *generic_signature_index_addr();
    } else {
      return 0;
    }
  }
  void set_generic_signature_index(u2 index)    {
    assert(has_generic_signature(), "");
    u2* addr = generic_signature_index_addr();
    *addr = index;
  }
D
duke 已提交
336 337 338

  // Sizing
  static int header_size() {
339
    return sizeof(ConstMethod)/HeapWordSize;
D
duke 已提交
340 341
  }

342
  // Size needed
C
coleenp 已提交
343
  static int size(int code_size, InlineTableSizes* sizes);
D
duke 已提交
344

345
  int size() const                    { return _constMethod_size;}
D
duke 已提交
346
  void set_constMethod_size(int size)     { _constMethod_size = size; }
347 348 349
#if INCLUDE_SERVICES
  void collect_statistics(KlassSizeStats *sz) const;
#endif
D
duke 已提交
350 351 352 353 354 355 356 357 358 359 360 361 362

  // code size
  int code_size() const                          { return _code_size; }
  void set_code_size(int size) {
    assert(max_method_code_size < (1 << 16),
           "u2 is too small to hold method code size in general");
    assert(0 <= size && size <= max_method_code_size, "invalid code size");
    _code_size = size;
  }

  // linenumber table - note that length is unknown until decompression,
  // see class CompressedLineNumberReadStream.
  u_char* compressed_linenumber_table() const;         // not preserved by gc
363
  u2* generic_signature_index_addr() const;
D
duke 已提交
364 365
  u2* checked_exceptions_length_addr() const;
  u2* localvariable_table_length_addr() const;
366
  u2* exception_table_length_addr() const;
367
  u2* method_parameters_length_addr() const;
D
duke 已提交
368 369 370 371 372 373 374 375 376

  // checked exceptions
  int checked_exceptions_length() const;
  CheckedExceptionElement* checked_exceptions_start() const;

  // localvariable table
  int localvariable_table_length() const;
  LocalVariableTableElement* localvariable_table_start() const;

377 378 379 380
  // exception table
  int exception_table_length() const;
  ExceptionTableElement* exception_table_start() const;

381 382 383 384
  // method parameters table
  int method_parameters_length() const;
  MethodParametersElement* method_parameters_start() const;

C
coleenp 已提交
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443
  // method annotations
  bool has_method_annotations() const
    { return (_flags & _has_method_annotations) != 0; }

  bool has_parameter_annotations() const
    { return (_flags & _has_parameter_annotations) != 0; }

  bool has_type_annotations() const
    { return (_flags & _has_type_annotations) != 0; }

  bool has_default_annotations() const
    { return (_flags & _has_default_annotations) != 0; }


  AnnotationArray** method_annotations_addr() const;
  AnnotationArray* method_annotations() const  {
    return has_method_annotations() ? *(method_annotations_addr()) : NULL;
  }
  void set_method_annotations(AnnotationArray* anno) {
    *(method_annotations_addr()) = anno;
  }

  AnnotationArray** parameter_annotations_addr() const;
  AnnotationArray* parameter_annotations() const {
    return has_parameter_annotations() ? *(parameter_annotations_addr()) : NULL;
  }
  void set_parameter_annotations(AnnotationArray* anno) {
    *(parameter_annotations_addr()) = anno;
  }

  AnnotationArray** type_annotations_addr() const;
  AnnotationArray* type_annotations() const {
    return has_type_annotations() ? *(type_annotations_addr()) : NULL;
  }
  void set_type_annotations(AnnotationArray* anno) {
    *(type_annotations_addr()) = anno;
  }

  AnnotationArray** default_annotations_addr() const;
  AnnotationArray* default_annotations() const {
    return has_default_annotations() ? *(default_annotations_addr()) : NULL;
  }
  void set_default_annotations(AnnotationArray* anno) {
    *(default_annotations_addr()) = anno;
  }

  int method_annotations_length() const {
    return has_method_annotations() ? method_annotations()->length() : 0;
  }
  int parameter_annotations_length() const {
    return has_parameter_annotations() ? parameter_annotations()->length() : 0;
  }
  int type_annotations_length() const {
    return has_type_annotations() ? type_annotations()->length() : 0;
  }
  int default_annotations_length() const {
    return has_default_annotations() ? default_annotations()->length() : 0;
  }

444 445 446
  // Copy annotations from other ConstMethod
  void copy_annotations_from(ConstMethod* cm);

D
duke 已提交
447
  // byte codes
448 449 450 451 452
  void    set_code(address code) {
    if (code_size() > 0) {
      memcpy(code_base(), code, code_size());
    }
  }
D
duke 已提交
453 454 455 456 457 458
  address code_base() const            { return (address) (this+1); }
  address code_end() const             { return code_base() + code_size(); }
  bool    contains(address bcp) const  { return code_base() <= bcp
                                                     && bcp < code_end(); }
  // Offset to bytecodes
  static ByteSize codes_offset()
459
                            { return in_ByteSize(sizeof(ConstMethod)); }
D
duke 已提交
460

461
  static ByteSize constants_offset()
462
                            { return byte_offset_of(ConstMethod, _constants); }
D
duke 已提交
463

464 465
  static ByteSize max_stack_offset()
                            { return byte_offset_of(ConstMethod, _max_stack); }
466 467 468 469 470
  static ByteSize size_of_locals_offset()
                            { return byte_offset_of(ConstMethod, _max_locals); }
  static ByteSize size_of_parameters_offset()
                            { return byte_offset_of(ConstMethod, _size_of_parameters); }

471

D
duke 已提交
472 473 474 475 476 477
  // Unique id for the method
  static const u2 MAX_IDNUM;
  static const u2 UNSET_IDNUM;
  u2 method_idnum() const                        { return _method_idnum; }
  void set_method_idnum(u2 idnum)                { _method_idnum = idnum; }

478 479 480 481
  // max stack
  int  max_stack() const                         { return _max_stack; }
  void set_max_stack(int size)                   { _max_stack = size; }

482 483 484 485 486 487 488 489
  // max locals
  int  max_locals() const                        { return _max_locals; }
  void set_max_locals(int size)                  { _max_locals = size; }

  // size of parameters
  int  size_of_parameters() const                { return _size_of_parameters; }
  void set_size_of_parameters(int size)          { _size_of_parameters = size; }

490 491 492 493 494
  // Deallocation for RedefineClasses
  void deallocate_contents(ClassLoaderData* loader_data);
  bool is_klass() const { return false; }
  DEBUG_ONLY(bool on_stack() { return false; })

D
duke 已提交
495 496 497
private:
  // Since the size of the compressed line number table is unknown, the
  // offsets of the other variable sized sections are computed backwards
498
  // from the end of the ConstMethod*.
D
duke 已提交
499

500
  // First byte after ConstMethod*
D
duke 已提交
501
  address constMethod_end() const
C
coleenp 已提交
502
                          { return (address)((intptr_t*)this + _constMethod_size); }
D
duke 已提交
503

504
  // Last short in ConstMethod*
C
coleenp 已提交
505
  u2* last_u2_element() const;
506 507 508 509 510 511 512 513 514 515

 public:
  // Printing
  void print_on      (outputStream* st) const;
  void print_value_on(outputStream* st) const;

  const char* internal_name() const { return "{constMethod}"; }

  // Verify
  void verify_on(outputStream* st);
D
duke 已提交
516
};
517 518

#endif // SHARE_VM_OOPS_CONSTMETHODOOP_HPP