src/share/vm/oops/cpCacheOop.hpp

Tue, 24 Jul 2012 10:51:00 -0700

author
twisti
date
Tue, 24 Jul 2012 10:51:00 -0700
changeset 3969
1d7922586cf6
parent 2982
ddd894528dbc
permissions
-rw-r--r--

7023639: JSR 292 method handle invocation needs a fast path for compiled code
6984705: JSR 292 method handle creation should not go through JNI
Summary: remove assembly code for JDK 7 chained method handles
Reviewed-by: jrose, twisti, kvn, mhaupt
Contributed-by: John Rose <john.r.rose@oracle.com>, Christian Thalinger <christian.thalinger@oracle.com>, Michael Haupt <michael.haupt@oracle.com>

     1 /*
     2  * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #ifndef SHARE_VM_OOPS_CPCACHEOOP_HPP
    26 #define SHARE_VM_OOPS_CPCACHEOOP_HPP
    28 #include "interpreter/bytecodes.hpp"
    29 #include "memory/allocation.hpp"
    30 #include "oops/arrayOop.hpp"
    31 #include "utilities/array.hpp"
    33 // A ConstantPoolCacheEntry describes an individual entry of the constant
    34 // pool cache. There's 2 principal kinds of entries: field entries for in-
    35 // stance & static field access, and method entries for invokes. Some of
    36 // the entry layout is shared and looks as follows:
    37 //
    38 // bit number |31                0|
    39 // bit length |-8--|-8--|---16----|
    40 // --------------------------------
    41 // _indices   [ b2 | b1 |  index  ]  index = constant_pool_index (!= 0, normal entries only)
    42 // _indices   [  index  |  00000  ]  index = main_entry_index (secondary entries only)
    43 // _f1        [  entry specific   ]  method, klass, or oop (MethodType or CallSite)
    44 // _f2        [  entry specific   ]  vtable index or vfinal method
    45 // _flags     [tos|0|00|00|00|f|v|f2|unused|field_index] (for field entries)
    46 // bit length [ 4 |1|1 |1 | 1|1|1| 1|---5--|----16-----]
    47 // _flags     [tos|M|vf|fv|ea|f|0|f2|unused|00000|psize] (for method entries)
    48 // bit length [ 4 |1|1 |1 | 1|1|1| 1|---5--|--8--|--8--]
    50 // --------------------------------
    51 //
    52 // with:
    53 // index  = original constant pool index
    54 // b1     = bytecode 1
    55 // b2     = bytecode 2
    56 // psize  = parameters size (method entries only)
    57 // field_index = index into field information in holder instanceKlass
    58 //          The index max is 0xffff (max number of fields in constant pool)
    59 //          and is multiplied by (instanceKlass::next_offset) when accessing.
    60 // t      = TosState (see below)
    61 // f      = field is marked final (see below)
    62 // f2     = virtual but final (method entries only: is_vfinal())
    63 // v      = field is volatile (see below)
    64 // m      = invokeinterface used for method in class Object (see below)
    65 // h      = RedefineClasses/Hotswap bit (see below)
    66 //
    67 // The flags after TosState have the following interpretation:
    68 // bit 27: 0 for fields, 1 for methods
    69 // f  flag true if field is marked final
    70 // v  flag true if field is volatile (only for fields)
    71 // f2 flag true if f2 contains an oop (e.g., virtual final method)
    72 // fv flag true if invokeinterface used for method in class Object
    73 //
    74 // The flags 31, 30, 29, 28 together build a 4 bit number 0 to 8 with the
    75 // following mapping to the TosState states:
    76 //
    77 // btos: 0
    78 // ctos: 1
    79 // stos: 2
    80 // itos: 3
    81 // ltos: 4
    82 // ftos: 5
    83 // dtos: 6
    84 // atos: 7
    85 // vtos: 8
    86 //
    87 // Entry specific: field entries:
    88 // _indices = get (b1 section) and put (b2 section) bytecodes, original constant pool index
    89 // _f1      = field holder (as a java.lang.Class, not a klassOop)
    90 // _f2      = field offset in bytes
    91 // _flags   = field type information, original FieldInfo index in field holder
    92 //            (field_index section)
    93 //
    94 // Entry specific: method entries:
    95 // _indices = invoke code for f1 (b1 section), invoke code for f2 (b2 section),
    96 //            original constant pool index
    97 // _f1      = methodOop for non-virtual calls, unused by virtual calls.
    98 //            for interface calls, which are essentially virtual but need a klass,
    99 //            contains klassOop for the corresponding interface.
   100 //            for invokedynamic, f1 contains a site-specific CallSite object (as an appendix)
   101 //            for invokehandle, f1 contains a site-specific MethodType object (as an appendix)
   102 //            (upcoming metadata changes will move the appendix to a separate array)
   103 // _f2      = vtable/itable index (or final methodOop) for virtual calls only,
   104 //            unused by non-virtual.  The is_vfinal flag indicates this is a
   105 //            method pointer for a final method, not an index.
   106 // _flags   = method type info (t section),
   107 //            virtual final bit (vfinal),
   108 //            parameter size (psize section)
   109 //
   110 // Note: invokevirtual & invokespecial bytecodes can share the same constant
   111 //       pool entry and thus the same constant pool cache entry. All invoke
   112 //       bytecodes but invokevirtual use only _f1 and the corresponding b1
   113 //       bytecode, while invokevirtual uses only _f2 and the corresponding
   114 //       b2 bytecode.  The value of _flags is shared for both types of entries.
   115 //
   116 // The fields are volatile so that they are stored in the order written in the
   117 // source code.  The _indices field with the bytecode must be written last.
   119 class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC {
   120   friend class VMStructs;
   121   friend class constantPoolCacheKlass;
   122   friend class constantPoolOopDesc;  //resolve_constant_at_impl => set_f1
   124  private:
   125   volatile intx     _indices;  // constant pool index & rewrite bytecodes
   126   volatile oop      _f1;       // entry specific oop field
   127   volatile intx     _f2;       // entry specific int/oop field
   128   volatile intx     _flags;    // flags
   131 #ifdef ASSERT
   132   bool same_methodOop(oop cur_f1, oop f1);
   133 #endif
   135   void set_bytecode_1(Bytecodes::Code code);
   136   void set_bytecode_2(Bytecodes::Code code);
   137   void set_f1(oop f1)                            {
   138     oop existing_f1 = _f1; // read once
   139     assert(existing_f1 == NULL || existing_f1 == f1, "illegal field change");
   140     oop_store(&_f1, f1);
   141   }
   142   void release_set_f1(oop f1);
   143   void set_f2(intx f2)                           { assert(_f2 == 0 || _f2 == f2,            "illegal field change"); _f2 = f2; }
   144   void set_f2_as_vfinal_method(methodOop f2)     { assert(_f2 == 0 || _f2 == (intptr_t) f2, "illegal field change"); assert(is_vfinal(), "flags must be set"); _f2 = (intptr_t) f2; }
   145   int make_flags(TosState state, int option_bits, int field_index_or_method_params);
   146   void set_flags(intx flags)                     { _flags = flags; }
   147   bool init_flags_atomic(intx flags);
   148   void set_field_flags(TosState field_type, int option_bits, int field_index) {
   149     assert((field_index & field_index_mask) == field_index, "field_index in range");
   150     set_flags(make_flags(field_type, option_bits | (1 << is_field_entry_shift), field_index));
   151   }
   152   void set_method_flags(TosState return_type, int option_bits, int method_params) {
   153     assert((method_params & parameter_size_mask) == method_params, "method_params in range");
   154     set_flags(make_flags(return_type, option_bits, method_params));
   155   }
   156   bool init_method_flags_atomic(TosState return_type, int option_bits, int method_params) {
   157     assert((method_params & parameter_size_mask) == method_params, "method_params in range");
   158     return init_flags_atomic(make_flags(return_type, option_bits, method_params));
   159   }
   161  public:
   162   // specific bit definitions for the flags field:
   163   // (Note: the interpreter must use these definitions to access the CP cache.)
   164   enum {
   165     // high order bits are the TosState corresponding to field type or method return type
   166     tos_state_bits             = 4,
   167     tos_state_mask             = right_n_bits(tos_state_bits),
   168     tos_state_shift            = BitsPerInt - tos_state_bits,  // see verify_tos_state_shift below
   169     // misc. option bits; can be any bit position in [16..27]
   170     is_vfinal_shift            = 21,
   171     is_volatile_shift          = 22,
   172     is_final_shift             = 23,
   173     has_appendix_shift         = 24,
   174     is_forced_virtual_shift    = 25,
   175     is_field_entry_shift       = 26,
   176     // low order bits give field index (for FieldInfo) or method parameter size:
   177     field_index_bits           = 16,
   178     field_index_mask           = right_n_bits(field_index_bits),
   179     parameter_size_bits        = 8,  // subset of field_index_mask, range is 0..255
   180     parameter_size_mask        = right_n_bits(parameter_size_bits),
   181     option_bits_mask           = ~(((-1) << tos_state_shift) | (field_index_mask | parameter_size_mask))
   182   };
   184   // specific bit definitions for the indices field:
   185   enum {
   186     main_cp_index_bits         = 2*BitsPerByte,
   187     main_cp_index_mask         = right_n_bits(main_cp_index_bits),
   188     bytecode_1_shift           = main_cp_index_bits,
   189     bytecode_1_mask            = right_n_bits(BitsPerByte), // == (u1)0xFF
   190     bytecode_2_shift           = main_cp_index_bits + BitsPerByte,
   191     bytecode_2_mask            = right_n_bits(BitsPerByte), // == (u1)0xFF
   192     // the secondary cp index overlaps with bytecodes 1 and 2:
   193     secondary_cp_index_shift   = bytecode_1_shift,
   194     secondary_cp_index_bits    = BitsPerInt - main_cp_index_bits
   195   };
   198   // Initialization
   199   void initialize_entry(int original_index);     // initialize primary entry
   200   void initialize_secondary_entry(int main_index); // initialize secondary entry
   202   void set_field(                                // sets entry to resolved field state
   203     Bytecodes::Code get_code,                    // the bytecode used for reading the field
   204     Bytecodes::Code put_code,                    // the bytecode used for writing the field
   205     KlassHandle     field_holder,                // the object/klass holding the field
   206     int             orig_field_index,            // the original field index in the field holder
   207     int             field_offset,                // the field offset in words in the field holder
   208     TosState        field_type,                  // the (machine) field type
   209     bool            is_final,                     // the field is final
   210     bool            is_volatile                  // the field is volatile
   211   );
   213   void set_method(                               // sets entry to resolved method entry
   214     Bytecodes::Code invoke_code,                 // the bytecode used for invoking the method
   215     methodHandle    method,                      // the method/prototype if any (NULL, otherwise)
   216     int             vtable_index                 // the vtable index if any, else negative
   217   );
   219   void set_interface_call(
   220     methodHandle method,                         // Resolved method
   221     int index                                    // Method index into interface
   222   );
   224   void set_method_handle(
   225     methodHandle method,                         // adapter for invokeExact, etc.
   226     Handle appendix                              // stored in f1; could be a java.lang.invoke.MethodType
   227   );
   229   void set_dynamic_call(
   230     methodHandle method,                         // adapter for this call site
   231     Handle appendix                              // stored in f1; could be a java.lang.invoke.CallSite
   232   );
   234   // Common code for invokedynamic and MH invocations.
   236   // The "appendix" is an optional call-site-specific parameter which is
   237   // pushed by the JVM at the end of the argument list.  This argument may
   238   // be a MethodType for the MH.invokes and a CallSite for an invokedynamic
   239   // instruction.  However, its exact type and use depends on the Java upcall,
   240   // which simply returns a compiled LambdaForm along with any reference
   241   // that LambdaForm needs to complete the call.  If the upcall returns a
   242   // null appendix, the argument is not passed at all.
   243   //
   244   // The appendix is *not* represented in the signature of the symbolic
   245   // reference for the call site, but (if present) it *is* represented in
   246   // the methodOop bound to the site.  This means that static and dynamic
   247   // resolution logic needs to make slightly different assessments about the
   248   // number and types of arguments.
   249   void set_method_handle_common(
   250     Bytecodes::Code invoke_code,                 // _invokehandle or _invokedynamic
   251     methodHandle adapter,                        // invoker method (f2)
   252     Handle appendix                              // appendix such as CallSite, MethodType, etc. (f1)
   253   );
   255   methodOop method_if_resolved(constantPoolHandle cpool);
   257   void set_parameter_size(int value);
   259   // Which bytecode number (1 or 2) in the index field is valid for this bytecode?
   260   // Returns -1 if neither is valid.
   261   static int bytecode_number(Bytecodes::Code code) {
   262     switch (code) {
   263       case Bytecodes::_getstatic       :    // fall through
   264       case Bytecodes::_getfield        :    // fall through
   265       case Bytecodes::_invokespecial   :    // fall through
   266       case Bytecodes::_invokestatic    :    // fall through
   267       case Bytecodes::_invokeinterface : return 1;
   268       case Bytecodes::_putstatic       :    // fall through
   269       case Bytecodes::_putfield        :    // fall through
   270       case Bytecodes::_invokehandle    :    // fall through
   271       case Bytecodes::_invokedynamic   :    // fall through
   272       case Bytecodes::_invokevirtual   : return 2;
   273       default                          : break;
   274     }
   275     return -1;
   276   }
   278   // Has this bytecode been resolved? Only valid for invokes and get/put field/static.
   279   bool is_resolved(Bytecodes::Code code) const {
   280     switch (bytecode_number(code)) {
   281       case 1:  return (bytecode_1() == code);
   282       case 2:  return (bytecode_2() == code);
   283     }
   284     return false;      // default: not resolved
   285   }
   287   // Accessors
   288   bool is_secondary_entry() const                { return (_indices & main_cp_index_mask) == 0; }
   289   int main_entry_index() const                   { assert(is_secondary_entry(), "must be secondary entry");
   290                                                    return ((uintx)_indices >> secondary_cp_index_shift); }
   291   int primary_entry_indices() const              { assert(!is_secondary_entry(), "must be main entry");
   292                                                    return _indices; }
   293   int constant_pool_index() const                { return (primary_entry_indices() & main_cp_index_mask); }
   294   Bytecodes::Code bytecode_1() const             { return Bytecodes::cast((primary_entry_indices() >> bytecode_1_shift)
   295                                                                           & bytecode_1_mask); }
   296   Bytecodes::Code bytecode_2() const             { return Bytecodes::cast((primary_entry_indices() >> bytecode_2_shift)
   297                                                                           & bytecode_2_mask); }
   298   methodOop f1_as_method() const                 { oop f1 = _f1; assert(f1 == NULL || f1->is_method(), ""); return methodOop(f1); }
   299   klassOop  f1_as_klass() const                  { oop f1 = _f1; assert(f1 == NULL || f1->is_klass(), ""); return klassOop(f1); }
   300   oop       f1_as_klass_mirror() const           { oop f1 = f1_as_instance(); return f1; }  // i.e., return a java_mirror
   301   oop       f1_as_instance() const               { oop f1 = _f1; assert(f1 == NULL || f1->is_instance() || f1->is_array(), ""); return f1; }
   302   oop       f1_appendix() const                  { assert(has_appendix(), ""); return f1_as_instance(); }
   303   bool      is_f1_null() const                   { oop f1 = _f1; return f1 == NULL; }  // classifies a CPC entry as unbound
   304   int       f2_as_index() const                  { assert(!is_vfinal(), ""); return (int) _f2; }
   305   methodOop f2_as_vfinal_method() const          { assert(is_vfinal(), ""); return methodOop(_f2); }
   306   int  field_index() const                       { assert(is_field_entry(),  ""); return (_flags & field_index_mask); }
   307   int  parameter_size() const                    { assert(is_method_entry(), ""); return (_flags & parameter_size_mask); }
   308   bool is_volatile() const                       { return (_flags & (1 << is_volatile_shift))       != 0; }
   309   bool is_final() const                          { return (_flags & (1 << is_final_shift))          != 0; }
   310   bool has_appendix() const                      { return (_flags & (1 << has_appendix_shift))     != 0; }
   311   bool is_forced_virtual() const                 { return (_flags & (1 << is_forced_virtual_shift)) != 0; }
   312   bool is_vfinal() const                         { return (_flags & (1 << is_vfinal_shift))         != 0; }
   313   bool is_method_entry() const                   { return (_flags & (1 << is_field_entry_shift))    == 0; }
   314   bool is_field_entry() const                    { return (_flags & (1 << is_field_entry_shift))    != 0; }
   315   bool is_byte() const                           { return flag_state() == btos; }
   316   bool is_char() const                           { return flag_state() == ctos; }
   317   bool is_short() const                          { return flag_state() == stos; }
   318   bool is_int() const                            { return flag_state() == itos; }
   319   bool is_long() const                           { return flag_state() == ltos; }
   320   bool is_float() const                          { return flag_state() == ftos; }
   321   bool is_double() const                         { return flag_state() == dtos; }
   322   bool is_object() const                         { return flag_state() == atos; }
   323   TosState flag_state() const                    { assert((uint)number_of_states <= (uint)tos_state_mask+1, "");
   324                                                    return (TosState)((_flags >> tos_state_shift) & tos_state_mask); }
   326   // Code generation support
   327   static WordSize size()                         { return in_WordSize(sizeof(ConstantPoolCacheEntry) / HeapWordSize); }
   328   static ByteSize size_in_bytes()                { return in_ByteSize(sizeof(ConstantPoolCacheEntry)); }
   329   static ByteSize indices_offset()               { return byte_offset_of(ConstantPoolCacheEntry, _indices); }
   330   static ByteSize f1_offset()                    { return byte_offset_of(ConstantPoolCacheEntry, _f1); }
   331   static ByteSize f2_offset()                    { return byte_offset_of(ConstantPoolCacheEntry, _f2); }
   332   static ByteSize flags_offset()                 { return byte_offset_of(ConstantPoolCacheEntry, _flags); }
   334   // GC Support
   335   void oops_do(void f(oop*));
   336   void oop_iterate(OopClosure* blk);
   337   void oop_iterate_m(OopClosure* blk, MemRegion mr);
   338   void follow_contents();
   339   void adjust_pointers();
   341 #ifndef SERIALGC
   342   // Parallel Old
   343   void follow_contents(ParCompactionManager* cm);
   344 #endif // SERIALGC
   346   void update_pointers();
   348   // RedefineClasses() API support:
   349   // If this constantPoolCacheEntry refers to old_method then update it
   350   // to refer to new_method.
   351   // trace_name_printed is set to true if the current call has
   352   // printed the klass name so that other routines in the adjust_*
   353   // group don't print the klass name.
   354   bool adjust_method_entry(methodOop old_method, methodOop new_method,
   355          bool * trace_name_printed);
   356   bool is_interesting_method_entry(klassOop k);
   358   // Debugging & Printing
   359   void print (outputStream* st, int index) const;
   360   void verify(outputStream* st) const;
   362   static void verify_tos_state_shift() {
   363     // When shifting flags as a 32-bit int, make sure we don't need an extra mask for tos_state:
   364     assert((((u4)-1 >> tos_state_shift) & ~tos_state_mask) == 0, "no need for tos_state mask");
   365   }
   366 };
   369 // A constant pool cache is a runtime data structure set aside to a constant pool. The cache
   370 // holds interpreter runtime information for all field access and invoke bytecodes. The cache
   371 // is created and initialized before a class is actively used (i.e., initialized), the indivi-
   372 // dual cache entries are filled at resolution (i.e., "link") time (see also: rewriter.*).
   374 class constantPoolCacheOopDesc: public oopDesc {
   375   friend class VMStructs;
   376  private:
   377   int             _length;
   378   constantPoolOop _constant_pool;                // the corresponding constant pool
   380   // Sizing
   381   debug_only(friend class ClassVerifier;)
   382  public:
   383   int length() const                             { return _length; }
   384  private:
   385   void set_length(int length)                    { _length = length; }
   387   static int header_size()                       { return sizeof(constantPoolCacheOopDesc) / HeapWordSize; }
   388   static int object_size(int length)             { return align_object_size(header_size() + length * in_words(ConstantPoolCacheEntry::size())); }
   389   int object_size()                              { return object_size(length()); }
   391   // Helpers
   392   constantPoolOop*        constant_pool_addr()   { return &_constant_pool; }
   393   ConstantPoolCacheEntry* base() const           { return (ConstantPoolCacheEntry*)((address)this + in_bytes(base_offset())); }
   395   friend class constantPoolCacheKlass;
   396   friend class ConstantPoolCacheEntry;
   398  public:
   399   // Initialization
   400   void initialize(intArray& inverse_index_map);
   402   // Secondary indexes.
   403   // They must look completely different from normal indexes.
   404   // The main reason is that byte swapping is sometimes done on normal indexes.
   405   // Also, some of the CP accessors do different things for secondary indexes.
   406   // Finally, it is helpful for debugging to tell the two apart.
   407   static bool is_secondary_index(int i) { return (i < 0); }
   408   static int  decode_secondary_index(int i) { assert(is_secondary_index(i),  ""); return ~i; }
   409   static int  encode_secondary_index(int i) { assert(!is_secondary_index(i), ""); return ~i; }
   411   // Accessors
   412   void set_constant_pool(constantPoolOop pool)   { oop_store_without_check((oop*)&_constant_pool, (oop)pool); }
   413   constantPoolOop constant_pool() const          { return _constant_pool; }
   414   // Fetches the entry at the given index.
   415   // The entry may be either primary or secondary.
   416   // In either case the index must not be encoded or byte-swapped in any way.
   417   ConstantPoolCacheEntry* entry_at(int i) const {
   418     assert(0 <= i && i < length(), "index out of bounds");
   419     return base() + i;
   420   }
   421   // Fetches the secondary entry referred to by index.
   422   // The index may be a secondary index, and must not be byte-swapped.
   423   ConstantPoolCacheEntry* secondary_entry_at(int i) const {
   424     int raw_index = i;
   425     if (is_secondary_index(i)) {  // correct these on the fly
   426       raw_index = decode_secondary_index(i);
   427     }
   428     assert(entry_at(raw_index)->is_secondary_entry(), "not a secondary entry");
   429     return entry_at(raw_index);
   430   }
   431   // Given a primary or secondary index, fetch the corresponding primary entry.
   432   // Indirect through the secondary entry, if the index is encoded as a secondary index.
   433   // The index must not be byte-swapped.
   434   ConstantPoolCacheEntry* main_entry_at(int i) const {
   435     int primary_index = i;
   436     if (is_secondary_index(i)) {
   437       // run through an extra level of indirection:
   438       int raw_index = decode_secondary_index(i);
   439       primary_index = entry_at(raw_index)->main_entry_index();
   440     }
   441     assert(!entry_at(primary_index)->is_secondary_entry(), "only one level of indirection");
   442     return entry_at(primary_index);
   443   }
   445   // Code generation
   446   static ByteSize base_offset()                  { return in_ByteSize(sizeof(constantPoolCacheOopDesc)); }
   447   static ByteSize entry_offset(int raw_index) {
   448     int index = raw_index;
   449     if (is_secondary_index(raw_index))
   450       index = decode_secondary_index(raw_index);
   451     return (base_offset() + ConstantPoolCacheEntry::size_in_bytes() * index);
   452   }
   454   // RedefineClasses() API support:
   455   // If any entry of this constantPoolCache points to any of
   456   // old_methods, replace it with the corresponding new_method.
   457   // trace_name_printed is set to true if the current call has
   458   // printed the klass name so that other routines in the adjust_*
   459   // group don't print the klass name.
   460   void adjust_method_entries(methodOop* old_methods, methodOop* new_methods,
   461                              int methods_length, bool * trace_name_printed);
   462 };
   464 #endif // SHARE_VM_OOPS_CPCACHEOOP_HPP

mercurial