This commit is contained in:
Jesper Wilhelmsson 2016-01-14 17:36:29 +01:00
commit 54d0181916
1018 changed files with 30713 additions and 7018 deletions

View file

@ -133,7 +133,8 @@ bool AdvancedThresholdPolicy::is_old(Method* method) {
}
double AdvancedThresholdPolicy::weight(Method* method) {
return (method->rate() + 1) * ((method->invocation_count() + 1) * (method->backedge_count() + 1));
return (double)(method->rate() + 1) *
(method->invocation_count() + 1) * (method->backedge_count() + 1);
}
// Apply heuristics and return true if x should be compiled before y

View file

@ -3374,12 +3374,6 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req
const char* fileSep = os::file_separator();
sprintf(path, "%s%slib%sendorsed", Arguments::get_java_home(), fileSep, fileSep);
#if INCLUDE_JVMCI
if (EnableJVMCI) {
JVMCIRuntime::save_options(_system_properties);
}
#endif // INCLUDE_JVMCI
if (CheckEndorsedAndExtDirs) {
int nonEmptyDirs = 0;
// check endorsed directory

View file

@ -31,6 +31,7 @@
class BasicLock VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
friend class JVMCIVMStructs;
private:
volatile markOop _displaced_header;
public:

View file

@ -168,6 +168,7 @@ JVMCI_ONLY(public:)
// This is only a CheapObj to ease debugging after a deopt failure
class UnrollBlock : public CHeapObj<mtCompiler> {
friend class VMStructs;
friend class JVMCIVMStructs;
private:
int _size_of_deoptimized_frame; // Size, in bytes, of current deoptimized frame
int _caller_adjustment; // Adjustment, in bytes, to caller's SP by initial interpreted frame

View file

@ -832,6 +832,9 @@ public:
product(bool, UseAESIntrinsics, false, \
"Use intrinsics for AES versions of crypto") \
\
product(bool, UseAESCTRIntrinsics, false, \
"Use intrinsics for the paralleled version of AES/CTR crypto") \
\
product(bool, UseSHA1Intrinsics, false, \
"Use intrinsics for SHA-1 crypto hash function. " \
"Requires that UseSHA is enabled.") \
@ -853,6 +856,9 @@ public:
product(bool, UseAdler32Intrinsics, false, \
"use intrinsics for java.util.zip.Adler32") \
\
product(bool, UseVectorizedMismatchIntrinsic, false, \
"Enables intrinsification of ArraysSupport.vectorizedMismatch()") \
\
diagnostic(ccstrlist, DisableIntrinsic, "", \
"do not expand intrinsics whose (internal) names appear here") \
\
@ -4162,8 +4168,11 @@ public:
diagnostic(bool, CompilerDirectivesIgnoreCompileCommands, false, \
"Disable backwards compatibility for compile commands.") \
\
diagnostic(bool, PrintCompilerDirectives, false, \
"Print compiler directives on installation.")
diagnostic(bool, CompilerDirectivesPrint, false, \
"Print compiler directives on installation.") \
diagnostic(int, CompilerDirectivesLimit, 50, \
"Limit on number of compiler directives.")
/*
* Macros for factoring of globals

View file

@ -398,7 +398,7 @@ void print_statistics() {
// Note: before_exit() can be executed only once, if more than one threads
// are trying to shutdown the VM at the same time, only one thread
// can run before_exit() and all other threads must wait.
void before_exit(JavaThread * thread) {
void before_exit(JavaThread* thread) {
#define BEFORE_EXIT_NOT_RUN 0
#define BEFORE_EXIT_RUNNING 1
#define BEFORE_EXIT_DONE 2
@ -426,7 +426,15 @@ void before_exit(JavaThread * thread) {
}
#if INCLUDE_JVMCI
JVMCIRuntime::shutdown();
// We are not using CATCH here because we want the exit to continue normally.
Thread* THREAD = thread;
JVMCIRuntime::shutdown(THREAD);
if (HAS_PENDING_EXCEPTION) {
Handle exception(THREAD, PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
ttyLocker ttyl;
java_lang_Throwable::print_stack_trace(exception, tty);
}
#endif
// Hang forever on exit if we're reporting an error.
@ -612,9 +620,7 @@ void vm_exit_during_initialization(Handle exception) {
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
}
java_lang_Throwable::print(exception, tty);
tty->cr();
java_lang_Throwable::print_stack_trace(exception(), tty);
java_lang_Throwable::print_stack_trace(exception, tty);
tty->cr();
vm_notify_during_shutdown(NULL, NULL);

View file

@ -47,6 +47,7 @@ friend class StubGenerator;
friend class JavaThread;
friend class frame;
friend class VMStructs;
friend class JVMCIVMStructs;
friend class BytecodeInterpreter;
friend class JavaCallWrapper;

View file

@ -827,7 +827,7 @@ void os::print_cpu_info(outputStream* st, char* buf, size_t buflen) {
st->print("total %d", os::processor_count());
// It's not safe to query number of active processors after crash
// st->print("(active %d)", os::active_processor_count());
st->print(" %s", VM_Version::cpu_features());
st->print(" %s", VM_Version::features_string());
st->cr();
pd_print_cpu_info(st, buf, buflen);
}

View file

@ -102,6 +102,7 @@ class MallocTracker;
class os: AllStatic {
friend class VMStructs;
friend class JVMCIVMStructs;
friend class MallocTracker;
public:
enum { page_sizes_max = 9 }; // Size of _page_sizes array (8 plus a sentinel)

View file

@ -60,6 +60,7 @@ enum ThreadState {
class OSThread: public CHeapObj<mtThread> {
friend class VMStructs;
friend class JVMCIVMStructs;
private:
OSThreadStartFunc _start_proc; // Thread start routine
void* _start_parm; // Thread start routine parameter

View file

@ -1091,6 +1091,18 @@ Handle SharedRuntime::find_callee_info(JavaThread* thread, Bytecodes::Code& bc,
return find_callee_info_helper(thread, vfst, bc, callinfo, THREAD);
}
methodHandle SharedRuntime::extract_attached_method(vframeStream& vfst) {
nmethod* caller_nm = vfst.nm();
nmethodLocker caller_lock(caller_nm);
address pc = vfst.frame_pc();
{ // Get call instruction under lock because another thread may be busy patching it.
MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag);
return caller_nm->attached_method_before_pc(pc);
}
return NULL;
}
// Finds receiver, CallInfo (i.e. receiver method), and calling bytecode
// for a call current in progress, i.e., arguments has been pushed on stack
@ -1108,15 +1120,37 @@ Handle SharedRuntime::find_callee_info_helper(JavaThread* thread,
methodHandle caller(THREAD, vfst.method());
int bci = vfst.bci();
// Find bytecode
Bytecode_invoke bytecode(caller, bci);
bc = bytecode.invoke_code();
int bytecode_index = bytecode.index();
methodHandle attached_method = extract_attached_method(vfst);
if (attached_method.not_null()) {
methodHandle callee = bytecode.static_target(CHECK_NH);
vmIntrinsics::ID id = callee->intrinsic_id();
// When VM replaces MH.invokeBasic/linkTo* call with a direct/virtual call,
// it attaches statically resolved method to the call site.
if (MethodHandles::is_signature_polymorphic(id) &&
MethodHandles::is_signature_polymorphic_intrinsic(id)) {
bc = MethodHandles::signature_polymorphic_intrinsic_bytecode(id);
// Need to adjust invokehandle since inlining through signature-polymorphic
// method happened.
if (bc == Bytecodes::_invokehandle &&
!MethodHandles::is_signature_polymorphic_method(attached_method())) {
bc = attached_method->is_static() ? Bytecodes::_invokestatic
: Bytecodes::_invokevirtual;
}
}
} else {
bc = bytecode.invoke_code();
}
bool has_receiver = bc != Bytecodes::_invokestatic &&
bc != Bytecodes::_invokedynamic &&
bc != Bytecodes::_invokehandle;
// Find receiver for non-static call
if (bc != Bytecodes::_invokestatic &&
bc != Bytecodes::_invokedynamic &&
bc != Bytecodes::_invokehandle) {
if (has_receiver) {
// This register map must be update since we need to find the receiver for
// compiled frames. The receiver might be in a register.
RegisterMap reg_map2(thread);
@ -1124,10 +1158,13 @@ Handle SharedRuntime::find_callee_info_helper(JavaThread* thread,
// Caller-frame is a compiled frame
frame callerFrame = stubFrame.sender(&reg_map2);
methodHandle callee = bytecode.static_target(CHECK_(nullHandle));
if (callee.is_null()) {
THROW_(vmSymbols::java_lang_NoSuchMethodException(), nullHandle);
if (attached_method.is_null()) {
methodHandle callee = bytecode.static_target(CHECK_NH);
if (callee.is_null()) {
THROW_(vmSymbols::java_lang_NoSuchMethodException(), nullHandle);
}
}
// Retrieve from a compiled argument list
receiver = Handle(THREAD, callerFrame.retrieve_receiver(&reg_map2));
@ -1136,26 +1173,35 @@ Handle SharedRuntime::find_callee_info_helper(JavaThread* thread,
}
}
// Resolve method. This is parameterized by bytecode.
constantPoolHandle constants(THREAD, caller->constants());
assert(receiver.is_null() || receiver->is_oop(), "wrong receiver");
LinkResolver::resolve_invoke(callinfo, receiver, constants, bytecode_index, bc, CHECK_(nullHandle));
// Resolve method
if (attached_method.not_null()) {
// Parameterized by attached method.
LinkResolver::resolve_invoke(callinfo, receiver, attached_method, bc, CHECK_NH);
} else {
// Parameterized by bytecode.
constantPoolHandle constants(THREAD, caller->constants());
LinkResolver::resolve_invoke(callinfo, receiver, constants, bytecode_index, bc, CHECK_NH);
}
#ifdef ASSERT
// Check that the receiver klass is of the right subtype and that it is initialized for virtual calls
if (bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic && bc != Bytecodes::_invokehandle) {
if (has_receiver) {
assert(receiver.not_null(), "should have thrown exception");
KlassHandle receiver_klass(THREAD, receiver->klass());
Klass* rk = constants->klass_ref_at(bytecode_index, CHECK_(nullHandle));
// klass is already loaded
Klass* rk = NULL;
if (attached_method.not_null()) {
// In case there's resolved method attached, use its holder during the check.
rk = attached_method->method_holder();
} else {
// Klass is already loaded.
constantPoolHandle constants(THREAD, caller->constants());
rk = constants->klass_ref_at(bytecode_index, CHECK_NH);
}
KlassHandle static_receiver_klass(THREAD, rk);
// Method handle invokes might have been optimized to a direct call
// so don't check for the receiver class.
// FIXME this weakens the assert too much
methodHandle callee = callinfo.selected_method();
assert(receiver_klass->is_subtype_of(static_receiver_klass()) ||
callee->is_method_handle_intrinsic() ||
callee->is_compiled_lambda_form(),
assert(receiver_klass->is_subtype_of(static_receiver_klass()),
"actual receiver must be subclass of static receiver klass");
if (receiver_klass->is_instance_klass()) {
if (InstanceKlass::cast(receiver_klass())->is_not_initialized()) {
@ -1691,7 +1737,6 @@ methodHandle SharedRuntime::reresolve_call_site(JavaThread *thread, TRAPS) {
inline_cache->set_to_clean();
}
}
}
methodHandle callee_method = find_callee_method(thread, CHECK_(methodHandle()));

View file

@ -353,6 +353,8 @@ class SharedRuntime: AllStatic {
Bytecodes::Code& bc,
CallInfo& callinfo, TRAPS);
static methodHandle extract_attached_method(vframeStream& vfst);
static address clean_virtual_call_entry();
static address clean_opt_virtual_call_entry();
static address clean_static_call_entry();

View file

@ -127,6 +127,7 @@ address StubRoutines::_aescrypt_encryptBlock = NULL;
address StubRoutines::_aescrypt_decryptBlock = NULL;
address StubRoutines::_cipherBlockChaining_encryptAESCrypt = NULL;
address StubRoutines::_cipherBlockChaining_decryptAESCrypt = NULL;
address StubRoutines::_counterMode_AESCrypt = NULL;
address StubRoutines::_ghash_processBlocks = NULL;
address StubRoutines::_sha1_implCompress = NULL;
@ -149,11 +150,13 @@ address StubRoutines::_mulAdd = NULL;
address StubRoutines::_montgomeryMultiply = NULL;
address StubRoutines::_montgomerySquare = NULL;
address StubRoutines::_vectorizedMismatch = NULL;
address StubRoutines::_dexp = NULL;
address StubRoutines::_dlog = NULL;
address StubRoutines::_dpow = NULL;
double (* StubRoutines::_intrinsic_log10 )(double) = NULL;
double (* StubRoutines::_intrinsic_pow )(double, double) = NULL;
double (* StubRoutines::_intrinsic_sin )(double) = NULL;
double (* StubRoutines::_intrinsic_cos )(double) = NULL;
double (* StubRoutines::_intrinsic_tan )(double) = NULL;

View file

@ -186,6 +186,7 @@ class StubRoutines: AllStatic {
static address _aescrypt_decryptBlock;
static address _cipherBlockChaining_encryptAESCrypt;
static address _cipherBlockChaining_decryptAESCrypt;
static address _counterMode_AESCrypt;
static address _ghash_processBlocks;
static address _sha1_implCompress;
@ -208,8 +209,11 @@ class StubRoutines: AllStatic {
static address _montgomeryMultiply;
static address _montgomerySquare;
static address _vectorizedMismatch;
static address _dexp;
static address _dlog;
static address _dpow;
// These are versions of the java.lang.Math methods which perform
// the same operations as the intrinsic version. They are used for
@ -356,6 +360,7 @@ class StubRoutines: AllStatic {
static address aescrypt_decryptBlock() { return _aescrypt_decryptBlock; }
static address cipherBlockChaining_encryptAESCrypt() { return _cipherBlockChaining_encryptAESCrypt; }
static address cipherBlockChaining_decryptAESCrypt() { return _cipherBlockChaining_decryptAESCrypt; }
static address counterMode_AESCrypt() { return _counterMode_AESCrypt; }
static address ghash_processBlocks() { return _ghash_processBlocks; }
static address sha1_implCompress() { return _sha1_implCompress; }
@ -378,8 +383,11 @@ class StubRoutines: AllStatic {
static address montgomeryMultiply() { return _montgomeryMultiply; }
static address montgomerySquare() { return _montgomerySquare; }
static address vectorizedMismatch() { return _vectorizedMismatch; }
static address dexp() { return _dexp; }
static address dlog() { return _dlog; }
static address dpow() { return _dpow; }
static address select_fill_function(BasicType t, bool aligned, const char* &name);

View file

@ -3658,13 +3658,12 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
if (jvmciCompiler != NULL) {
JVMCIRuntime::save_compiler(jvmciCompiler);
}
JVMCIRuntime::maybe_print_flags(CHECK_JNI_ERR);
}
#endif // INCLUDE_JVMCI
// initialize compiler(s)
#if defined(COMPILER1) || defined(COMPILER2) || defined(SHARK) || INCLUDE_JVMCI
CompileBroker::compilation_init();
CompileBroker::compilation_init(CHECK_JNI_ERR);
#endif
// Pre-initialize some JSR292 core classes to avoid deadlock during class loading.

View file

@ -101,6 +101,7 @@ class WorkerThread;
class Thread: public ThreadShadow {
friend class VMStructs;
friend class JVMCIVMStructs;
private:
#ifndef USE_LIBRARY_BASED_TLS_ONLY
@ -783,6 +784,7 @@ typedef void (*ThreadFunction)(JavaThread*, TRAPS);
class JavaThread: public Thread {
friend class VMStructs;
friend class JVMCIVMStructs;
friend class WhiteBox;
private:
JavaThread* _next; // The next thread in the Threads list

View file

@ -849,6 +849,7 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
static_field(StubRoutines, _aescrypt_decryptBlock, address) \
static_field(StubRoutines, _cipherBlockChaining_encryptAESCrypt, address) \
static_field(StubRoutines, _cipherBlockChaining_decryptAESCrypt, address) \
static_field(StubRoutines, _counterMode_AESCrypt, address) \
static_field(StubRoutines, _ghash_processBlocks, address) \
static_field(StubRoutines, _updateBytesCRC32, address) \
static_field(StubRoutines, _crc_table_adr, address) \
@ -859,6 +860,8 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
static_field(StubRoutines, _mulAdd, address) \
static_field(StubRoutines, _dexp, address) \
static_field(StubRoutines, _dlog, address) \
static_field(StubRoutines, _dpow, address) \
static_field(StubRoutines, _vectorizedMismatch, address) \
static_field(StubRoutines, _jbyte_arraycopy, address) \
static_field(StubRoutines, _jshort_arraycopy, address) \
static_field(StubRoutines, _jint_arraycopy, address) \
@ -1307,6 +1310,8 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
\
static_field(Abstract_VM_Version, _s_vm_release, const char*) \
static_field(Abstract_VM_Version, _s_internal_vm_info_string, const char*) \
static_field(Abstract_VM_Version, _features, uint64_t) \
static_field(Abstract_VM_Version, _features_string, const char*) \
static_field(Abstract_VM_Version, _vm_major_version, int) \
static_field(Abstract_VM_Version, _vm_minor_version, int) \
static_field(Abstract_VM_Version, _vm_security_version, int) \
@ -2056,7 +2061,6 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
declare_c2_type(AtanDNode, Node) \
declare_c2_type(SqrtDNode, Node) \
declare_c2_type(Log10DNode, Node) \
declare_c2_type(PowDNode, Node) \
declare_c2_type(ReverseBytesINode, Node) \
declare_c2_type(ReverseBytesLNode, Node) \
declare_c2_type(ReductionNode, Node) \
@ -2843,104 +2847,6 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
//--------------------------------------------------------------------------------
// VM_ADDRESSES
//
#define VM_ADDRESSES(declare_address, declare_preprocessor_address, declare_function) \
\
declare_function(SharedRuntime::register_finalizer) \
declare_function(SharedRuntime::exception_handler_for_return_address) \
declare_function(SharedRuntime::OSR_migration_end) \
declare_function(SharedRuntime::dsin) \
declare_function(SharedRuntime::dcos) \
declare_function(SharedRuntime::dtan) \
declare_function(SharedRuntime::dexp) \
declare_function(SharedRuntime::dlog) \
declare_function(SharedRuntime::dlog10) \
declare_function(SharedRuntime::dpow) \
\
declare_function(os::dll_load) \
declare_function(os::dll_lookup) \
declare_function(os::javaTimeMillis) \
declare_function(os::javaTimeNanos) \
\
declare_function(Deoptimization::fetch_unroll_info) \
COMPILER2_PRESENT(declare_function(Deoptimization::uncommon_trap)) \
declare_function(Deoptimization::unpack_frames)
//--------------------------------------------------------------------------------
// Macros operating on the above lists
//--------------------------------------------------------------------------------
// This utility macro quotes the passed string
#define QUOTE(x) #x
//--------------------------------------------------------------------------------
// VMStructEntry macros
//
// This macro generates a VMStructEntry line for a nonstatic field
#define GENERATE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 0, offset_of(typeName, fieldName), NULL },
// This macro generates a VMStructEntry line for a static field
#define GENERATE_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, &typeName::fieldName },
// This macro generates a VMStructEntry line for a static pointer volatile field,
// e.g.: "static ObjectMonitor * volatile gBlockList;"
#define GENERATE_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, (void *)&typeName::fieldName },
// This macro generates a VMStructEntry line for an unchecked
// nonstatic field, in which the size of the type is also specified.
// The type string is given as NULL, indicating an "opaque" type.
#define GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, size) \
{ QUOTE(typeName), QUOTE(fieldName), NULL, 0, offset_of(typeName, fieldName), NULL },
// This macro generates a VMStructEntry line for an unchecked
// static field, in which the size of the type is also specified.
// The type string is given as NULL, indicating an "opaque" type.
#define GENERATE_UNCHECKED_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, size) \
{ QUOTE(typeName), QUOTE(fieldName), NULL, 1, 0, (void*) &typeName::fieldName },
// This macro generates the sentinel value indicating the end of the list
#define GENERATE_VM_STRUCT_LAST_ENTRY() \
{ NULL, NULL, NULL, 0, 0, NULL }
// This macro checks the type of a VMStructEntry by comparing pointer types
#define CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName; \
assert(offset_of(typeName, fieldName) < sizeof(typeName), "Illegal nonstatic struct entry, field offset too large"); }
// This macro checks the type of a volatile VMStructEntry by comparing pointer types
#define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{typedef type dummyvtype; typeName *dummyObj = NULL; volatile dummyvtype* dummy = &dummyObj->fieldName; }
// This macro checks the type of a static VMStructEntry by comparing pointer types
#define CHECK_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{type* dummy = &typeName::fieldName; }
// This macro checks the type of a static pointer volatile VMStructEntry by comparing pointer types,
// e.g.: "static ObjectMonitor * volatile gBlockList;"
#define CHECK_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{type volatile * dummy = &typeName::fieldName; }
// This macro ensures the type of a field and its containing type are
// present in the type table. The assertion string is shorter than
// preferable because (incredibly) of a bug in Solstice NFS client
// which seems to prevent very long lines from compiling. This assertion
// means that an entry in VMStructs::localHotSpotVMStructs[] was not
// found in VMStructs::localHotSpotVMTypes[].
#define ENSURE_FIELD_TYPE_PRESENT(typeName, fieldName, type) \
{ assert(findType(QUOTE(typeName)) != 0, "type \"" QUOTE(typeName) "\" not found in type table"); \
assert(findType(QUOTE(type)) != 0, "type \"" QUOTE(type) "\" not found in type table"); }
// This is a no-op macro for unchecked fields
#define CHECK_NO_OP(a, b, c)
//
// Build-specific macros:
//
// Generate and check a nonstatic field in non-product builds
@ -2996,35 +2902,7 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
#endif /* COMPILER2 */
//--------------------------------------------------------------------------------
// VMTypeEntry macros
//
#define GENERATE_VM_TYPE_ENTRY(type, superclass) \
{ QUOTE(type), QUOTE(superclass), 0, 0, 0, sizeof(type) },
#define GENERATE_TOPLEVEL_VM_TYPE_ENTRY(type) \
{ QUOTE(type), NULL, 0, 0, 0, sizeof(type) },
#define GENERATE_OOP_VM_TYPE_ENTRY(type) \
{ QUOTE(type), NULL, 1, 0, 0, sizeof(type) },
#define GENERATE_INTEGER_VM_TYPE_ENTRY(type) \
{ QUOTE(type), NULL, 0, 1, 0, sizeof(type) },
#define GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY(type) \
{ QUOTE(type), NULL, 0, 1, 1, sizeof(type) },
#define GENERATE_VM_TYPE_LAST_ENTRY() \
{ NULL, NULL, 0, 0, 0, 0 }
#define CHECK_VM_TYPE_ENTRY(type, superclass) \
{ type* dummyObj = NULL; superclass* dummySuperObj = dummyObj; }
#define CHECK_VM_TYPE_NO_OP(a)
#define CHECK_SINGLE_ARG_VM_TYPE_NO_OP(a)
//
// Build-specific macros:
// VMTypeEntry build-specific macros
//
#ifdef COMPILER1
@ -3049,23 +2927,9 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
//--------------------------------------------------------------------------------
// VMIntConstantEntry macros
// VMIntConstantEntry build-specific macros
//
#define GENERATE_VM_INT_CONSTANT_ENTRY(name) \
{ QUOTE(name), (int32_t) name },
#define GENERATE_VM_INT_CONSTANT_WITH_VALUE_ENTRY(name, value) \
{ (name), (int32_t)(value) },
#define GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY(name, value) \
{ name, (int32_t) value },
// This macro generates the sentinel value indicating the end of the list
#define GENERATE_VM_INT_CONSTANT_LAST_ENTRY() \
{ NULL, 0 }
// Generate an int constant for a C1 build
#ifdef COMPILER1
# define GENERATE_C1_VM_INT_CONSTANT_ENTRY(name) GENERATE_VM_INT_CONSTANT_ENTRY(name)
@ -3082,20 +2946,11 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
# define GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY(name, value)
#endif /* COMPILER1 */
//--------------------------------------------------------------------------------
// VMLongConstantEntry macros
// VMLongConstantEntry build-specific macros
//
#define GENERATE_VM_LONG_CONSTANT_ENTRY(name) \
{ QUOTE(name), name },
#define GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY(name, value) \
{ name, value },
// This macro generates the sentinel value indicating the end of the list
#define GENERATE_VM_LONG_CONSTANT_LAST_ENTRY() \
{ NULL, 0 }
// Generate a long constant for a C1 build
#ifdef COMPILER1
# define GENERATE_C1_VM_LONG_CONSTANT_ENTRY(name) GENERATE_VM_LONG_CONSTANT_ENTRY(name)
@ -3112,22 +2967,6 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
# define GENERATE_C2_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY(name, value)
#endif /* COMPILER1 */
//--------------------------------------------------------------------------------
// VMAddressEntry macros
//
#define GENERATE_VM_ADDRESS_ENTRY(name) \
{ QUOTE(name), (void*) (name) },
#define GENERATE_PREPROCESSOR_VM_ADDRESS_ENTRY(name, value) \
{ name, (void*) (value) },
#define GENERATE_VM_FUNCTION_ENTRY(name) \
{ QUOTE(name), CAST_FROM_FN_PTR(void*, &(name)) },
// This macro generates the sentinel value indicating the end of the list
#define GENERATE_VM_ADDRESS_LAST_ENTRY() \
{ NULL, NULL }
//
// Instantiation of VMStructEntries, VMTypeEntries and VMIntConstantEntries
@ -3148,11 +2987,6 @@ VMStructEntry VMStructs::localHotSpotVMStructs[] = {
GENERATE_C1_UNCHECKED_STATIC_VM_STRUCT_ENTRY,
GENERATE_C2_UNCHECKED_STATIC_VM_STRUCT_ENTRY)
#if INCLUDE_JVMCI
VM_STRUCTS_JVMCI(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY)
#endif
#if INCLUDE_ALL_GCS
VM_STRUCTS_PARALLELGC(GENERATE_NONSTATIC_VM_STRUCT_ENTRY,
GENERATE_STATIC_VM_STRUCT_ENTRY)
@ -3214,11 +3048,6 @@ VMTypeEntry VMStructs::localHotSpotVMTypes[] = {
GENERATE_C2_VM_TYPE_ENTRY,
GENERATE_C2_TOPLEVEL_VM_TYPE_ENTRY)
#if INCLUDE_JVMCI
VM_TYPES_JVMCI(GENERATE_VM_TYPE_ENTRY,
GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
#endif
#if INCLUDE_ALL_GCS
VM_TYPES_PARALLELGC(GENERATE_VM_TYPE_ENTRY,
GENERATE_TOPLEVEL_VM_TYPE_ENTRY)
@ -3278,12 +3107,6 @@ VMIntConstantEntry VMStructs::localHotSpotVMIntConstants[] = {
GENERATE_C2_VM_INT_CONSTANT_ENTRY,
GENERATE_C2_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
#if INCLUDE_JVMCI
VM_INT_CONSTANTS_JVMCI(GENERATE_VM_INT_CONSTANT_ENTRY,
GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY)
#endif
#if INCLUDE_ALL_GCS
VM_INT_CONSTANTS_CMS(GENERATE_VM_INT_CONSTANT_ENTRY)
@ -3347,25 +3170,6 @@ VMLongConstantEntry VMStructs::localHotSpotVMLongConstants[] = {
GENERATE_VM_LONG_CONSTANT_LAST_ENTRY()
};
VMAddressEntry VMStructs::localHotSpotVMAddresses[] = {
VM_ADDRESSES(GENERATE_VM_ADDRESS_ENTRY,
GENERATE_PREPROCESSOR_VM_ADDRESS_ENTRY,
GENERATE_VM_FUNCTION_ENTRY)
VM_ADDRESSES_OS(GENERATE_VM_ADDRESS_ENTRY,
GENERATE_PREPROCESSOR_VM_ADDRESS_ENTRY,
GENERATE_VM_FUNCTION_ENTRY)
#if INCLUDE_JVMCI
VM_ADDRESSES_JVMCI(GENERATE_VM_ADDRESS_ENTRY,
GENERATE_PREPROCESSOR_VM_ADDRESS_ENTRY,
GENERATE_VM_FUNCTION_ENTRY)
#endif
GENERATE_VM_ADDRESS_LAST_ENTRY()
};
// This is used both to check the types of referenced fields and, in
// debug builds, to ensure that all of the field types are present.
void
@ -3574,11 +3378,6 @@ JNIEXPORT VMLongConstantEntry* gHotSpotVMLongConstants = VMStructs::localHotSpot
JNIEXPORT uint64_t gHotSpotVMLongConstantEntryNameOffset = offset_of(VMLongConstantEntry, name);
JNIEXPORT uint64_t gHotSpotVMLongConstantEntryValueOffset = offset_of(VMLongConstantEntry, value);
JNIEXPORT uint64_t gHotSpotVMLongConstantEntryArrayStride = STRIDE(gHotSpotVMLongConstants);
JNIEXPORT VMAddressEntry* gHotSpotVMAddresses = VMStructs::localHotSpotVMAddresses;
JNIEXPORT uint64_t gHotSpotVMAddressEntryNameOffset = offset_of(VMAddressEntry, name);
JNIEXPORT uint64_t gHotSpotVMAddressEntryValueOffset = offset_of(VMAddressEntry, value);
JNIEXPORT uint64_t gHotSpotVMAddressEntryArrayStride = STRIDE(gHotSpotVMAddresses);
}
#ifdef ASSERT
@ -3686,11 +3485,6 @@ void VMStructs::test() {
&long_last_entry,
sizeof(VMLongConstantEntry)) == 0, "Incorrect last entry in localHotSpotVMLongConstants");
static VMAddressEntry address_last_entry = GENERATE_VM_ADDRESS_LAST_ENTRY();
assert(memcmp(&localHotSpotVMAddresses[sizeof(localHotSpotVMAddresses) / sizeof(VMAddressEntry) - 1],
&address_last_entry,
sizeof(VMAddressEntry)) == 0, "Incorrect last entry in localHotSpotVMAddresses");
// Check for duplicate entries in type array
for (int i = 0; localHotSpotVMTypes[i].typeName != NULL; i++) {

View file

@ -143,4 +143,151 @@ private:
static int findType(const char* typeName);
};
// This utility macro quotes the passed string
#define QUOTE(x) #x
//--------------------------------------------------------------------------------
// VMStructEntry macros
//
// This macro generates a VMStructEntry line for a nonstatic field
#define GENERATE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 0, offset_of(typeName, fieldName), NULL },
// This macro generates a VMStructEntry line for a static field
#define GENERATE_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, &typeName::fieldName },
// This macro generates a VMStructEntry line for a static pointer volatile field,
// e.g.: "static ObjectMonitor * volatile gBlockList;"
#define GENERATE_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{ QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, (void *)&typeName::fieldName },
// This macro generates a VMStructEntry line for an unchecked
// nonstatic field, in which the size of the type is also specified.
// The type string is given as NULL, indicating an "opaque" type.
#define GENERATE_UNCHECKED_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, size) \
{ QUOTE(typeName), QUOTE(fieldName), NULL, 0, offset_of(typeName, fieldName), NULL },
// This macro generates a VMStructEntry line for an unchecked
// static field, in which the size of the type is also specified.
// The type string is given as NULL, indicating an "opaque" type.
#define GENERATE_UNCHECKED_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, size) \
{ QUOTE(typeName), QUOTE(fieldName), NULL, 1, 0, (void*) &typeName::fieldName },
// This macro generates the sentinel value indicating the end of the list
#define GENERATE_VM_STRUCT_LAST_ENTRY() \
{ NULL, NULL, NULL, 0, 0, NULL }
// This macro checks the type of a VMStructEntry by comparing pointer types
#define CHECK_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{typeName *dummyObj = NULL; type* dummy = &dummyObj->fieldName; \
assert(offset_of(typeName, fieldName) < sizeof(typeName), "Illegal nonstatic struct entry, field offset too large"); }
// This macro checks the type of a volatile VMStructEntry by comparing pointer types
#define CHECK_VOLATILE_NONSTATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{typedef type dummyvtype; typeName *dummyObj = NULL; volatile dummyvtype* dummy = &dummyObj->fieldName; }
// This macro checks the type of a static VMStructEntry by comparing pointer types
#define CHECK_STATIC_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{type* dummy = &typeName::fieldName; }
// This macro checks the type of a static pointer volatile VMStructEntry by comparing pointer types,
// e.g.: "static ObjectMonitor * volatile gBlockList;"
#define CHECK_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type) \
{type volatile * dummy = &typeName::fieldName; }
// This macro ensures the type of a field and its containing type are
// present in the type table. The assertion string is shorter than
// preferable because (incredibly) of a bug in Solstice NFS client
// which seems to prevent very long lines from compiling. This assertion
// means that an entry in VMStructs::localHotSpotVMStructs[] was not
// found in VMStructs::localHotSpotVMTypes[].
#define ENSURE_FIELD_TYPE_PRESENT(typeName, fieldName, type) \
{ assert(findType(QUOTE(typeName)) != 0, "type \"" QUOTE(typeName) "\" not found in type table"); \
assert(findType(QUOTE(type)) != 0, "type \"" QUOTE(type) "\" not found in type table"); }
// This is a no-op macro for unchecked fields
#define CHECK_NO_OP(a, b, c)
//--------------------------------------------------------------------------------
// VMTypeEntry macros
//
#define GENERATE_VM_TYPE_ENTRY(type, superclass) \
{ QUOTE(type), QUOTE(superclass), 0, 0, 0, sizeof(type) },
#define GENERATE_TOPLEVEL_VM_TYPE_ENTRY(type) \
{ QUOTE(type), NULL, 0, 0, 0, sizeof(type) },
#define GENERATE_OOP_VM_TYPE_ENTRY(type) \
{ QUOTE(type), NULL, 1, 0, 0, sizeof(type) },
#define GENERATE_INTEGER_VM_TYPE_ENTRY(type) \
{ QUOTE(type), NULL, 0, 1, 0, sizeof(type) },
#define GENERATE_UNSIGNED_INTEGER_VM_TYPE_ENTRY(type) \
{ QUOTE(type), NULL, 0, 1, 1, sizeof(type) },
#define GENERATE_VM_TYPE_LAST_ENTRY() \
{ NULL, NULL, 0, 0, 0, 0 }
#define CHECK_VM_TYPE_ENTRY(type, superclass) \
{ type* dummyObj = NULL; superclass* dummySuperObj = dummyObj; }
#define CHECK_VM_TYPE_NO_OP(a)
#define CHECK_SINGLE_ARG_VM_TYPE_NO_OP(a)
//--------------------------------------------------------------------------------
// VMIntConstantEntry macros
//
#define GENERATE_VM_INT_CONSTANT_ENTRY(name) \
{ QUOTE(name), (int32_t) name },
#define GENERATE_VM_INT_CONSTANT_WITH_VALUE_ENTRY(name, value) \
{ (name), (int32_t)(value) },
#define GENERATE_PREPROCESSOR_VM_INT_CONSTANT_ENTRY(name, value) \
{ name, (int32_t) value },
// This macro generates the sentinel value indicating the end of the list
#define GENERATE_VM_INT_CONSTANT_LAST_ENTRY() \
{ NULL, 0 }
//--------------------------------------------------------------------------------
// VMLongConstantEntry macros
//
#define GENERATE_VM_LONG_CONSTANT_ENTRY(name) \
{ QUOTE(name), name },
#define GENERATE_PREPROCESSOR_VM_LONG_CONSTANT_ENTRY(name, value) \
{ name, value },
// This macro generates the sentinel value indicating the end of the list
#define GENERATE_VM_LONG_CONSTANT_LAST_ENTRY() \
{ NULL, 0 }
//--------------------------------------------------------------------------------
// VMAddressEntry macros
//
#define GENERATE_VM_ADDRESS_ENTRY(name) \
{ QUOTE(name), (void*) (name) },
#define GENERATE_PREPROCESSOR_VM_ADDRESS_ENTRY(name, value) \
{ name, (void*) (value) },
#define GENERATE_VM_FUNCTION_ENTRY(name) \
{ QUOTE(name), CAST_FROM_FN_PTR(void*, &(name)) },
// This macro generates the sentinel value indicating the end of the list
#define GENERATE_VM_ADDRESS_LAST_ENTRY() \
{ NULL, NULL }
#endif // SHARE_VM_RUNTIME_VMSTRUCTS_HPP

View file

@ -30,6 +30,7 @@
#include "oops/oop.hpp"
#include "runtime/thread.hpp"
#include "utilities/top.hpp"
#include "code/codeCache.hpp"
// The following classes are used for operations
// initiated by a Java thread but that must
@ -44,6 +45,7 @@
template(ThreadDump) \
template(PrintThreads) \
template(FindDeadlocks) \
template(ClearICs) \
template(ForceSafepoint) \
template(ForceAsyncSafepoint) \
template(Deoptimize) \
@ -230,6 +232,13 @@ class VM_ThreadStop: public VM_Operation {
}
};
class VM_ClearICs: public VM_Operation {
public:
VM_ClearICs() {}
void doit() { CodeCache::clear_inline_caches(); }
VMOp_Type type() const { return VMOp_ClearICs; }
};
// dummy vm op, evaluated just to force a safepoint
class VM_ForceSafepoint: public VM_Operation {
public:

View file

@ -31,6 +31,10 @@
const char* Abstract_VM_Version::_s_vm_release = Abstract_VM_Version::vm_release();
const char* Abstract_VM_Version::_s_internal_vm_info_string = Abstract_VM_Version::internal_vm_info_string();
uint64_t Abstract_VM_Version::_features = 0;
const char* Abstract_VM_Version::_features_string = "";
bool Abstract_VM_Version::_supports_cx8 = false;
bool Abstract_VM_Version::_supports_atomic_getset4 = false;
bool Abstract_VM_Version::_supports_atomic_getset8 = false;

View file

@ -31,10 +31,17 @@
// VM_Version provides information about the VM.
class Abstract_VM_Version: AllStatic {
protected:
friend class VMStructs;
friend class JVMCIVMStructs;
protected:
static const char* _s_vm_release;
static const char* _s_internal_vm_info_string;
// CPU feature flags.
static uint64_t _features;
static const char* _features_string;
// These are set by machine-dependent initializations
static bool _supports_cx8;
static bool _supports_atomic_getset4;
@ -100,6 +107,14 @@ class Abstract_VM_Version: AllStatic {
static const char* jre_release_version();
static const char* jdk_debug_level();
static uint64_t features() {
return _features;
}
static const char* features_string() {
return _features_string;
}
// does HW support an 8-byte compare-exchange operation?
static bool supports_cx8() {
#ifdef SUPPORTS_NATIVE_CX8