annotate src/share/vm/interpreter/abstractInterpreter.hpp @ 2346:e1162778c1c8

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
author johnc
date Thu, 07 Apr 2011 09:53:20 -0700
parents 8033953d67ff
children 3d2ab563047a
rev   line source
duke@0 1 /*
jrose@2204 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
duke@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@0 4 *
duke@0 5 * This code is free software; you can redistribute it and/or modify it
duke@0 6 * under the terms of the GNU General Public License version 2 only, as
duke@0 7 * published by the Free Software Foundation.
duke@0 8 *
duke@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@0 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@0 13 * accompanied this code).
duke@0 14 *
duke@0 15 * You should have received a copy of the GNU General Public License version
duke@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@0 18 *
trims@1472 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1472 20 * or visit www.oracle.com if you need additional information or have any
trims@1472 21 * questions.
duke@0 22 *
duke@0 23 */
duke@0 24
stefank@1879 25 #ifndef SHARE_VM_INTERPRETER_ABSTRACTINTERPRETER_HPP
stefank@1879 26 #define SHARE_VM_INTERPRETER_ABSTRACTINTERPRETER_HPP
stefank@1879 27
stefank@1879 28 #include "code/stubs.hpp"
stefank@1879 29 #include "interpreter/bytecodes.hpp"
stefank@1879 30 #include "runtime/vmThread.hpp"
stefank@1879 31 #include "utilities/top.hpp"
stefank@1879 32 #ifdef TARGET_ARCH_MODEL_x86_32
stefank@1879 33 # include "interp_masm_x86_32.hpp"
stefank@1879 34 #endif
stefank@1879 35 #ifdef TARGET_ARCH_MODEL_x86_64
stefank@1879 36 # include "interp_masm_x86_64.hpp"
stefank@1879 37 #endif
stefank@1879 38 #ifdef TARGET_ARCH_MODEL_sparc
stefank@1879 39 # include "interp_masm_sparc.hpp"
stefank@1879 40 #endif
stefank@1879 41 #ifdef TARGET_ARCH_MODEL_zero
stefank@1879 42 # include "interp_masm_zero.hpp"
stefank@1879 43 #endif
bobv@2073 44 #ifdef TARGET_ARCH_MODEL_arm
bobv@2073 45 # include "interp_masm_arm.hpp"
bobv@2073 46 #endif
bobv@2073 47 #ifdef TARGET_ARCH_MODEL_ppc
bobv@2073 48 # include "interp_masm_ppc.hpp"
bobv@2073 49 #endif
stefank@1879 50 #ifdef TARGET_OS_FAMILY_linux
stefank@1879 51 # include "thread_linux.inline.hpp"
stefank@1879 52 #endif
stefank@1879 53 #ifdef TARGET_OS_FAMILY_solaris
stefank@1879 54 # include "thread_solaris.inline.hpp"
stefank@1879 55 #endif
stefank@1879 56 #ifdef TARGET_OS_FAMILY_windows
stefank@1879 57 # include "thread_windows.inline.hpp"
stefank@1879 58 #endif
stefank@1879 59
twisti@605 60 // This file contains the platform-independent parts
duke@0 61 // of the abstract interpreter and the abstract interpreter generator.
duke@0 62
duke@0 63 // Organization of the interpreter(s). There exists two different interpreters in hotpot
duke@0 64 // an assembly language version (aka template interpreter) and a high level language version
duke@0 65 // (aka c++ interpreter). Th division of labor is as follows:
duke@0 66
duke@0 67 // Template Interpreter C++ Interpreter Functionality
duke@0 68 //
duke@0 69 // templateTable* bytecodeInterpreter* actual interpretation of bytecodes
duke@0 70 //
duke@0 71 // templateInterpreter* cppInterpreter* generation of assembly code that creates
duke@0 72 // and manages interpreter runtime frames.
duke@0 73 // Also code for populating interpreter
duke@0 74 // frames created during deoptimization.
duke@0 75 //
duke@0 76 // For both template and c++ interpreter. There are common files for aspects of the interpreter
duke@0 77 // that are generic to both interpreters. This is the layout:
duke@0 78 //
duke@0 79 // abstractInterpreter.hpp: generic description of the interpreter.
duke@0 80 // interpreter*: generic frame creation and handling.
duke@0 81 //
duke@0 82
duke@0 83 //------------------------------------------------------------------------------------------------------------------------
duke@0 84 // The C++ interface to the bytecode interpreter(s).
duke@0 85
duke@0 86 class AbstractInterpreter: AllStatic {
duke@0 87 friend class VMStructs;
duke@0 88 friend class Interpreter;
duke@0 89 friend class CppInterpreterGenerator;
duke@0 90 public:
duke@0 91 enum MethodKind {
duke@0 92 zerolocals, // method needs locals initialization
duke@0 93 zerolocals_synchronized, // method needs locals initialization & is synchronized
duke@0 94 native, // native method
duke@0 95 native_synchronized, // native method & is synchronized
duke@0 96 empty, // empty method (code: _return)
duke@0 97 accessor, // accessor method (code: _aload_0, _getfield, _(a|i)return)
duke@0 98 abstract, // abstract method (throws an AbstractMethodException)
jrose@2204 99 method_handle, // java.lang.invoke.MethodHandles::invoke
duke@0 100 java_lang_math_sin, // implementation of java.lang.Math.sin (x)
duke@0 101 java_lang_math_cos, // implementation of java.lang.Math.cos (x)
duke@0 102 java_lang_math_tan, // implementation of java.lang.Math.tan (x)
duke@0 103 java_lang_math_abs, // implementation of java.lang.Math.abs (x)
duke@0 104 java_lang_math_sqrt, // implementation of java.lang.Math.sqrt (x)
duke@0 105 java_lang_math_log, // implementation of java.lang.Math.log (x)
duke@0 106 java_lang_math_log10, // implementation of java.lang.Math.log10 (x)
johnc@2346 107 java_lang_ref_reference_get, // implementation of java.lang.ref.Reference.get()
duke@0 108 number_of_method_entries,
duke@0 109 invalid = -1
duke@0 110 };
duke@0 111
duke@0 112 enum SomeConstants {
duke@0 113 number_of_result_handlers = 10 // number of result handlers for native calls
duke@0 114 };
duke@0 115
duke@0 116 protected:
duke@0 117 static StubQueue* _code; // the interpreter code (codelets)
duke@0 118
duke@0 119 static bool _notice_safepoints; // true if safepoints are activated
duke@0 120
duke@0 121 static address _native_entry_begin; // Region for native entry code
duke@0 122 static address _native_entry_end;
duke@0 123
duke@0 124 // method entry points
duke@0 125 static address _entry_table[number_of_method_entries]; // entry points for a given method
duke@0 126 static address _native_abi_to_tosca[number_of_result_handlers]; // for native method result handlers
duke@0 127 static address _slow_signature_handler; // the native method generic (slow) signature handler
duke@0 128
duke@0 129 static address _rethrow_exception_entry; // rethrows an activation in previous frame
duke@0 130
duke@0 131 friend class AbstractInterpreterGenerator;
duke@0 132 friend class InterpreterGenerator;
duke@0 133 friend class InterpreterMacroAssembler;
duke@0 134
duke@0 135 public:
duke@0 136 // Initialization/debugging
duke@0 137 static void initialize();
duke@0 138 static StubQueue* code() { return _code; }
duke@0 139
duke@0 140
duke@0 141 // Method activation
duke@0 142 static MethodKind method_kind(methodHandle m);
duke@0 143 static address entry_for_kind(MethodKind k) { assert(0 <= k && k < number_of_method_entries, "illegal kind"); return _entry_table[k]; }
johnc@2346 144 static address entry_for_method(methodHandle m) { return entry_for_kind(method_kind(m)); }
duke@0 145
duke@0 146 static void print_method_kind(MethodKind kind) PRODUCT_RETURN;
duke@0 147
never@1174 148 static bool can_be_compiled(methodHandle m);
never@1174 149
duke@0 150 // Runtime support
duke@0 151
duke@0 152 // length = invoke bytecode length (to advance to next bytecode)
duke@0 153 static address deopt_entry (TosState state, int length) { ShouldNotReachHere(); return NULL; }
duke@0 154 static address return_entry (TosState state, int length) { ShouldNotReachHere(); return NULL; }
duke@0 155
duke@0 156 static address rethrow_exception_entry() { return _rethrow_exception_entry; }
duke@0 157
duke@0 158 // Activation size in words for a method that is just being called.
duke@0 159 // Parameters haven't been pushed so count them too.
duke@0 160 static int size_top_interpreter_activation(methodOop method);
duke@0 161
duke@0 162 // Deoptimization support
cfang@900 163 // Compute the entry address for continuation after
cfang@900 164 static address deopt_continue_after_entry(methodOop method,
cfang@900 165 address bcp,
cfang@900 166 int callee_parameters,
cfang@900 167 bool is_top_frame);
cfang@900 168 // Compute the entry address for reexecution
cfang@900 169 static address deopt_reexecute_entry(methodOop method, address bcp);
cfang@900 170 // Deoptimization should reexecute this bytecode
cfang@900 171 static bool bytecode_should_reexecute(Bytecodes::Code code);
duke@0 172
duke@0 173 // share implementation of size_activation and layout_activation:
duke@0 174 static int size_activation(methodOop method,
duke@0 175 int temps,
duke@0 176 int popframe_args,
duke@0 177 int monitors,
duke@0 178 int callee_params,
duke@0 179 int callee_locals,
duke@0 180 bool is_top_frame);
duke@0 181
duke@0 182 static int layout_activation(methodOop method,
duke@0 183 int temps,
duke@0 184 int popframe_args,
duke@0 185 int monitors,
duke@0 186 int callee_params,
duke@0 187 int callee_locals,
duke@0 188 frame* caller,
duke@0 189 frame* interpreter_frame,
duke@0 190 bool is_top_frame);
duke@0 191
duke@0 192 // Runtime support
duke@0 193 static bool is_not_reached( methodHandle method, int bci);
duke@0 194 // Safepoint support
duke@0 195 static void notice_safepoints() { ShouldNotReachHere(); } // stops the thread when reaching a safepoint
duke@0 196 static void ignore_safepoints() { ShouldNotReachHere(); } // ignores safepoints
duke@0 197
duke@0 198 // Support for native calls
duke@0 199 static address slow_signature_handler() { return _slow_signature_handler; }
duke@0 200 static address result_handler(BasicType type) { return _native_abi_to_tosca[BasicType_as_index(type)]; }
duke@0 201 static int BasicType_as_index(BasicType type); // computes index into result_handler_by_index table
duke@0 202 static bool in_native_entry(address pc) { return _native_entry_begin <= pc && pc < _native_entry_end; }
duke@0 203 // Debugging/printing
duke@0 204 static void print(); // prints the interpreter code
duke@0 205
duke@0 206 public:
twisti@1426 207 // Interpreter helpers
twisti@1426 208 const static int stackElementWords = 1;
twisti@1426 209 const static int stackElementSize = stackElementWords * wordSize;
twisti@1426 210 const static int logStackElementSize = LogBytesPerWord;
duke@0 211
duke@0 212 // Local values relative to locals[n]
duke@0 213 static int local_offset_in_bytes(int n) {
twisti@1426 214 return ((frame::interpreter_frame_expression_stack_direction() * n) * stackElementSize);
duke@0 215 }
duke@0 216
jrose@726 217 // access to stacked values according to type:
jrose@726 218 static oop* oop_addr_in_slot(intptr_t* slot_addr) {
jrose@726 219 return (oop*) slot_addr;
jrose@726 220 }
jrose@726 221 static jint* int_addr_in_slot(intptr_t* slot_addr) {
jrose@726 222 if ((int) sizeof(jint) < wordSize && !Bytes::is_Java_byte_ordering_different())
jrose@726 223 // big-endian LP64
jrose@726 224 return (jint*)(slot_addr + 1) - 1;
jrose@726 225 else
jrose@726 226 return (jint*) slot_addr;
jrose@726 227 }
jrose@726 228 static jlong long_in_slot(intptr_t* slot_addr) {
jrose@726 229 if (sizeof(intptr_t) >= sizeof(jlong)) {
jrose@726 230 return *(jlong*) slot_addr;
twisti@1426 231 } else {
jrose@726 232 return Bytes::get_native_u8((address)slot_addr);
jrose@726 233 }
jrose@726 234 }
jrose@726 235 static void set_long_in_slot(intptr_t* slot_addr, jlong value) {
jrose@726 236 if (sizeof(intptr_t) >= sizeof(jlong)) {
jrose@726 237 *(jlong*) slot_addr = value;
twisti@1426 238 } else {
jrose@726 239 Bytes::put_native_u8((address)slot_addr, value);
jrose@726 240 }
jrose@726 241 }
jrose@726 242 static void get_jvalue_in_slot(intptr_t* slot_addr, BasicType type, jvalue* value) {
jrose@726 243 switch (type) {
jrose@726 244 case T_BOOLEAN: value->z = *int_addr_in_slot(slot_addr); break;
jrose@726 245 case T_CHAR: value->c = *int_addr_in_slot(slot_addr); break;
jrose@726 246 case T_BYTE: value->b = *int_addr_in_slot(slot_addr); break;
jrose@726 247 case T_SHORT: value->s = *int_addr_in_slot(slot_addr); break;
jrose@726 248 case T_INT: value->i = *int_addr_in_slot(slot_addr); break;
jrose@726 249 case T_LONG: value->j = long_in_slot(slot_addr); break;
jrose@726 250 case T_FLOAT: value->f = *(jfloat*)int_addr_in_slot(slot_addr); break;
jrose@726 251 case T_DOUBLE: value->d = jdouble_cast(long_in_slot(slot_addr)); break;
jrose@726 252 case T_OBJECT: value->l = (jobject)*oop_addr_in_slot(slot_addr); break;
jrose@726 253 default: ShouldNotReachHere();
jrose@726 254 }
jrose@726 255 }
jrose@726 256 static void set_jvalue_in_slot(intptr_t* slot_addr, BasicType type, jvalue* value) {
jrose@726 257 switch (type) {
jrose@726 258 case T_BOOLEAN: *int_addr_in_slot(slot_addr) = (value->z != 0); break;
jrose@726 259 case T_CHAR: *int_addr_in_slot(slot_addr) = value->c; break;
jrose@726 260 case T_BYTE: *int_addr_in_slot(slot_addr) = value->b; break;
jrose@726 261 case T_SHORT: *int_addr_in_slot(slot_addr) = value->s; break;
jrose@726 262 case T_INT: *int_addr_in_slot(slot_addr) = value->i; break;
jrose@726 263 case T_LONG: set_long_in_slot(slot_addr, value->j); break;
jrose@726 264 case T_FLOAT: *(jfloat*)int_addr_in_slot(slot_addr) = value->f; break;
jrose@726 265 case T_DOUBLE: set_long_in_slot(slot_addr, jlong_cast(value->d)); break;
jrose@726 266 case T_OBJECT: *oop_addr_in_slot(slot_addr) = (oop) value->l; break;
jrose@726 267 default: ShouldNotReachHere();
jrose@726 268 }
jrose@726 269 }
duke@0 270 };
duke@0 271
duke@0 272 //------------------------------------------------------------------------------------------------------------------------
duke@0 273 // The interpreter generator.
duke@0 274
duke@0 275 class Template;
duke@0 276 class AbstractInterpreterGenerator: public StackObj {
duke@0 277 protected:
duke@0 278 InterpreterMacroAssembler* _masm;
duke@0 279
duke@0 280 // shared code sequences
duke@0 281 // Converter for native abi result to tosca result
duke@0 282 address generate_result_handler_for(BasicType type);
duke@0 283 address generate_slow_signature_handler();
duke@0 284
duke@0 285 // entry point generator
duke@0 286 address generate_method_entry(AbstractInterpreter::MethodKind kind);
duke@0 287
duke@0 288 void bang_stack_shadow_pages(bool native_call);
duke@0 289
duke@0 290 void generate_all();
duke@0 291
duke@0 292 public:
duke@0 293 AbstractInterpreterGenerator(StubQueue* _code);
duke@0 294 };
stefank@1879 295
stefank@1879 296 #endif // SHARE_VM_INTERPRETER_ABSTRACTINTERPRETER_HPP