src/share/vm/oops/constMethodOop.hpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2314
f95d63e2154a
child 3826
2fe087c3e814
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

duke@435 1 /*
stefank@2314 2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #ifndef SHARE_VM_OOPS_CONSTMETHODOOP_HPP
stefank@2314 26 #define SHARE_VM_OOPS_CONSTMETHODOOP_HPP
stefank@2314 27
stefank@2314 28 #include "oops/oop.hpp"
stefank@2314 29 #include "oops/typeArrayOop.hpp"
stefank@2314 30
duke@435 31 // An constMethodOop represents portions of a Java method which
duke@435 32 // do not vary.
duke@435 33 //
duke@435 34 // Memory layout (each line represents a word). Note that most
duke@435 35 // applications load thousands of methods, so keeping the size of this
duke@435 36 // structure small has a big impact on footprint.
duke@435 37 //
duke@435 38 // |------------------------------------------------------|
duke@435 39 // | header |
duke@435 40 // | klass |
duke@435 41 // |------------------------------------------------------|
duke@435 42 // | fingerprint 1 |
duke@435 43 // | fingerprint 2 |
duke@435 44 // | method (oop) |
duke@435 45 // | stackmap_data (oop) |
duke@435 46 // | exception_table (oop) |
duke@435 47 // | constMethod_size |
duke@435 48 // | interp_kind | flags | code_size |
duke@435 49 // | name index | signature index |
duke@435 50 // | method_idnum | generic_signature_index |
duke@435 51 // |------------------------------------------------------|
duke@435 52 // | |
duke@435 53 // | byte codes |
duke@435 54 // | |
duke@435 55 // |------------------------------------------------------|
duke@435 56 // | compressed linenumber table |
duke@435 57 // | (see class CompressedLineNumberReadStream) |
duke@435 58 // | (note that length is unknown until decompressed) |
duke@435 59 // | (access flags bit tells whether table is present) |
duke@435 60 // | (indexed from start of constMethodOop) |
duke@435 61 // | (elements not necessarily sorted!) |
duke@435 62 // |------------------------------------------------------|
duke@435 63 // | localvariable table elements + length (length last) |
duke@435 64 // | (length is u2, elements are 6-tuples of u2) |
duke@435 65 // | (see class LocalVariableTableElement) |
duke@435 66 // | (access flags bit tells whether table is present) |
duke@435 67 // | (indexed from end of contMethodOop) |
duke@435 68 // |------------------------------------------------------|
duke@435 69 // | checked exceptions elements + length (length last) |
duke@435 70 // | (length is u2, elements are u2) |
duke@435 71 // | (see class CheckedExceptionElement) |
duke@435 72 // | (access flags bit tells whether table is present) |
duke@435 73 // | (indexed from end of constMethodOop) |
duke@435 74 // |------------------------------------------------------|
duke@435 75
duke@435 76
duke@435 77 // Utitily class decribing elements in checked exceptions table inlined in methodOop.
duke@435 78 class CheckedExceptionElement VALUE_OBJ_CLASS_SPEC {
duke@435 79 public:
duke@435 80 u2 class_cp_index;
duke@435 81 };
duke@435 82
duke@435 83
duke@435 84 // Utitily class decribing elements in local variable table inlined in methodOop.
duke@435 85 class LocalVariableTableElement VALUE_OBJ_CLASS_SPEC {
duke@435 86 public:
duke@435 87 u2 start_bci;
duke@435 88 u2 length;
duke@435 89 u2 name_cp_index;
duke@435 90 u2 descriptor_cp_index;
duke@435 91 u2 signature_cp_index;
duke@435 92 u2 slot;
duke@435 93 };
duke@435 94
duke@435 95
duke@435 96 class constMethodOopDesc : public oopDesc {
duke@435 97 friend class constMethodKlass;
duke@435 98 friend class VMStructs;
duke@435 99 private:
duke@435 100 enum {
duke@435 101 _has_linenumber_table = 1,
duke@435 102 _has_checked_exceptions = 2,
duke@435 103 _has_localvariable_table = 4
duke@435 104 };
duke@435 105
duke@435 106 // Bit vector of signature
duke@435 107 // Callers interpret 0=not initialized yet and
duke@435 108 // -1=too many args to fix, must parse the slow way.
duke@435 109 // The real initial value is special to account for nonatomicity of 64 bit
duke@435 110 // loads and stores. This value may updated and read without a lock by
duke@435 111 // multiple threads, so is volatile.
duke@435 112 volatile uint64_t _fingerprint;
jmasa@953 113 volatile bool _is_conc_safe; // if true, safe for concurrent GC processing
duke@435 114
duke@435 115 public:
duke@435 116 oop* oop_block_beg() const { return adr_method(); }
duke@435 117 oop* oop_block_end() const { return adr_exception_table() + 1; }
duke@435 118
duke@435 119 private:
duke@435 120 //
duke@435 121 // The oop block. See comment in klass.hpp before making changes.
duke@435 122 //
duke@435 123
duke@435 124 // Backpointer to non-const methodOop (needed for some JVMTI operations)
duke@435 125 methodOop _method;
duke@435 126
duke@435 127 // Raw stackmap data for the method
duke@435 128 typeArrayOop _stackmap_data;
duke@435 129
duke@435 130 // The exception handler table. 4-tuples of ints [start_pc, end_pc,
duke@435 131 // handler_pc, catch_type index] For methods with no exceptions the
duke@435 132 // table is pointing to Universe::the_empty_int_array
duke@435 133 typeArrayOop _exception_table;
duke@435 134
duke@435 135 //
duke@435 136 // End of the oop block.
duke@435 137 //
duke@435 138
duke@435 139 int _constMethod_size;
duke@435 140 jbyte _interpreter_kind;
duke@435 141 jbyte _flags;
duke@435 142
duke@435 143 // Size of Java bytecodes allocated immediately after methodOop.
duke@435 144 u2 _code_size;
duke@435 145 u2 _name_index; // Method name (index in constant pool)
duke@435 146 u2 _signature_index; // Method signature (index in constant pool)
duke@435 147 u2 _method_idnum; // unique identification number for the method within the class
duke@435 148 // initially corresponds to the index into the methods array.
duke@435 149 // but this may change with redefinition
duke@435 150 u2 _generic_signature_index; // Generic signature (index in constant pool, 0 if absent)
duke@435 151
duke@435 152 public:
duke@435 153 // Inlined tables
duke@435 154 void set_inlined_tables_length(int checked_exceptions_len,
duke@435 155 int compressed_line_number_size,
duke@435 156 int localvariable_table_len);
duke@435 157
duke@435 158 bool has_linenumber_table() const
duke@435 159 { return (_flags & _has_linenumber_table) != 0; }
duke@435 160
duke@435 161 bool has_checked_exceptions() const
duke@435 162 { return (_flags & _has_checked_exceptions) != 0; }
duke@435 163
duke@435 164 bool has_localvariable_table() const
duke@435 165 { return (_flags & _has_localvariable_table) != 0; }
duke@435 166
duke@435 167 void set_interpreter_kind(int kind) { _interpreter_kind = kind; }
duke@435 168 int interpreter_kind(void) const { return _interpreter_kind; }
duke@435 169
duke@435 170 // backpointer to non-const methodOop
duke@435 171 methodOop method() const { return _method; }
duke@435 172 void set_method(methodOop m) { oop_store_without_check((oop*)&_method, (oop) m); }
duke@435 173
duke@435 174
duke@435 175 // stackmap table data
duke@435 176 typeArrayOop stackmap_data() const { return _stackmap_data; }
duke@435 177 void set_stackmap_data(typeArrayOop sd) {
duke@435 178 oop_store_without_check((oop*)&_stackmap_data, (oop)sd);
duke@435 179 }
duke@435 180 bool has_stackmap_table() const { return _stackmap_data != NULL; }
duke@435 181
duke@435 182 // exception handler table
duke@435 183 typeArrayOop exception_table() const { return _exception_table; }
duke@435 184 void set_exception_table(typeArrayOop e) { oop_store_without_check((oop*) &_exception_table, (oop) e); }
duke@435 185 bool has_exception_handler() const { return exception_table() != NULL && exception_table()->length() > 0; }
duke@435 186
duke@435 187 void init_fingerprint() {
duke@435 188 const uint64_t initval = CONST64(0x8000000000000000);
duke@435 189 _fingerprint = initval;
duke@435 190 }
duke@435 191
duke@435 192 uint64_t fingerprint() const {
duke@435 193 // Since reads aren't atomic for 64 bits, if any of the high or low order
duke@435 194 // word is the initial value, return 0. See init_fingerprint for initval.
duke@435 195 uint high_fp = (uint)(_fingerprint >> 32);
duke@435 196 if ((int) _fingerprint == 0 || high_fp == 0x80000000) {
duke@435 197 return 0L;
duke@435 198 } else {
duke@435 199 return _fingerprint;
duke@435 200 }
duke@435 201 }
duke@435 202
duke@435 203 uint64_t set_fingerprint(uint64_t new_fingerprint) {
duke@435 204 #ifdef ASSERT
duke@435 205 // Assert only valid if complete/valid 64 bit _fingerprint value is read.
duke@435 206 uint64_t oldfp = fingerprint();
duke@435 207 #endif // ASSERT
duke@435 208 _fingerprint = new_fingerprint;
duke@435 209 assert(oldfp == 0L || new_fingerprint == oldfp,
duke@435 210 "fingerprint cannot change");
duke@435 211 assert(((new_fingerprint >> 32) != 0x80000000) && (int)new_fingerprint !=0,
duke@435 212 "fingerprint should call init to set initial value");
duke@435 213 return new_fingerprint;
duke@435 214 }
duke@435 215
duke@435 216 // name
duke@435 217 int name_index() const { return _name_index; }
duke@435 218 void set_name_index(int index) { _name_index = index; }
duke@435 219
duke@435 220 // signature
duke@435 221 int signature_index() const { return _signature_index; }
duke@435 222 void set_signature_index(int index) { _signature_index = index; }
duke@435 223
duke@435 224 // generics support
duke@435 225 int generic_signature_index() const { return _generic_signature_index; }
duke@435 226 void set_generic_signature_index(int index) { _generic_signature_index = index; }
duke@435 227
duke@435 228 // Sizing
duke@435 229 static int header_size() {
duke@435 230 return sizeof(constMethodOopDesc)/HeapWordSize;
duke@435 231 }
duke@435 232
duke@435 233 // Object size needed
duke@435 234 static int object_size(int code_size, int compressed_line_number_size,
duke@435 235 int local_variable_table_length,
duke@435 236 int checked_exceptions_length);
duke@435 237
duke@435 238 int object_size() const { return _constMethod_size; }
duke@435 239 void set_constMethod_size(int size) { _constMethod_size = size; }
duke@435 240 // Is object parsable by gc
duke@435 241 bool object_is_parsable() { return object_size() > 0; }
duke@435 242
duke@435 243 // code size
duke@435 244 int code_size() const { return _code_size; }
duke@435 245 void set_code_size(int size) {
duke@435 246 assert(max_method_code_size < (1 << 16),
duke@435 247 "u2 is too small to hold method code size in general");
duke@435 248 assert(0 <= size && size <= max_method_code_size, "invalid code size");
duke@435 249 _code_size = size;
duke@435 250 }
duke@435 251
duke@435 252 // linenumber table - note that length is unknown until decompression,
duke@435 253 // see class CompressedLineNumberReadStream.
duke@435 254 u_char* compressed_linenumber_table() const; // not preserved by gc
duke@435 255 u2* checked_exceptions_length_addr() const;
duke@435 256 u2* localvariable_table_length_addr() const;
duke@435 257
duke@435 258 // checked exceptions
duke@435 259 int checked_exceptions_length() const;
duke@435 260 CheckedExceptionElement* checked_exceptions_start() const;
duke@435 261
duke@435 262 // localvariable table
duke@435 263 int localvariable_table_length() const;
duke@435 264 LocalVariableTableElement* localvariable_table_start() const;
duke@435 265
duke@435 266 // byte codes
twisti@1573 267 void set_code(address code) {
twisti@1573 268 if (code_size() > 0) {
twisti@1573 269 memcpy(code_base(), code, code_size());
twisti@1573 270 }
twisti@1573 271 }
duke@435 272 address code_base() const { return (address) (this+1); }
duke@435 273 address code_end() const { return code_base() + code_size(); }
duke@435 274 bool contains(address bcp) const { return code_base() <= bcp
duke@435 275 && bcp < code_end(); }
duke@435 276 // Offset to bytecodes
duke@435 277 static ByteSize codes_offset()
duke@435 278 { return in_ByteSize(sizeof(constMethodOopDesc)); }
duke@435 279
duke@435 280 // interpreter support
duke@435 281 static ByteSize exception_table_offset()
duke@435 282 { return byte_offset_of(constMethodOopDesc, _exception_table); }
duke@435 283
duke@435 284 // Garbage collection support
duke@435 285 oop* adr_method() const { return (oop*)&_method; }
duke@435 286 oop* adr_stackmap_data() const { return (oop*)&_stackmap_data; }
duke@435 287 oop* adr_exception_table() const { return (oop*)&_exception_table; }
jmasa@953 288 bool is_conc_safe() { return _is_conc_safe; }
jmasa@953 289 void set_is_conc_safe(bool v) { _is_conc_safe = v; }
duke@435 290
duke@435 291 // Unique id for the method
duke@435 292 static const u2 MAX_IDNUM;
duke@435 293 static const u2 UNSET_IDNUM;
duke@435 294 u2 method_idnum() const { return _method_idnum; }
duke@435 295 void set_method_idnum(u2 idnum) { _method_idnum = idnum; }
duke@435 296
duke@435 297 private:
duke@435 298 // Since the size of the compressed line number table is unknown, the
duke@435 299 // offsets of the other variable sized sections are computed backwards
duke@435 300 // from the end of the constMethodOop.
duke@435 301
duke@435 302 // First byte after constMethodOop
duke@435 303 address constMethod_end() const
duke@435 304 { return (address)((oop*)this + _constMethod_size); }
duke@435 305
duke@435 306 // Last short in constMethodOop
duke@435 307 u2* last_u2_element() const
duke@435 308 { return (u2*)constMethod_end() - 1; }
duke@435 309 };
stefank@2314 310
stefank@2314 311 #endif // SHARE_VM_OOPS_CONSTMETHODOOP_HPP

mercurial