8220623: [JVMCI] Update JVMCI to support JVMCI based Compiler compiled into shared library

Reviewed-by: dnsimon, never, stefank, rehn, neliasso, dholmes, kbarrett, coleenp
This commit is contained in:
Vladimir Kozlov 2019-05-01 12:31:29 -07:00
parent f9bbbb6e27
commit e9c523ae5f
173 changed files with 12881 additions and 5297 deletions

View File

@ -392,9 +392,8 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES],
JVM_FEATURES_jvmci=""
INCLUDE_JVMCI="false"
else
# Only enable jvmci on x86_64, sparcv9 and aarch64
# Only enable jvmci on x86_64 and aarch64
if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \
test "x$OPENJDK_TARGET_CPU" = "xsparcv9" || \
test "x$OPENJDK_TARGET_CPU" = "xaarch64" ; then
AC_MSG_RESULT([yes])
JVM_FEATURES_jvmci="jvmci"

View File

@ -56,6 +56,9 @@ suite = {
"jdk.vm.ci.common" : {
"subDir" : "../jdk.internal.vm.ci/share/classes",
"sourceDirs" : ["src"],
"dependencies" : [
"jdk.vm.ci.services",
],
"checkstyle" : "jdk.vm.ci.services",
"javaCompliance" : "9+",
"workingSets" : "API,JVMCI",
@ -258,9 +261,11 @@ suite = {
"subDir" : "../../test/hotspot/jtreg/compiler/jvmci",
"dependencies" : [
"jdk.vm.ci.runtime.test",
"jdk.vm.ci.hotspot.test",
],
"distDependencies" : [
"JVMCI_API",
"JVMCI_HOTSPOT",
],
"exclude" : ["mx:JUNIT"],
},

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -30,7 +30,7 @@
#include "runtime/sharedRuntime.hpp"
#include "vmreg_aarch64.inline.hpp"
jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Handle method, TRAPS) {
jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCIObject method, JVMCI_TRAPS) {
if (inst->is_call() || inst->is_jump() || inst->is_blr()) {
return pc_offset + NativeCall::instruction_size;
} else if (inst->is_general_jump()) {
@ -43,12 +43,12 @@ jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Hand
}
}
void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS) {
void CodeInstaller::pd_patch_OopConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
address pc = _instructions->start() + pc_offset;
#ifdef ASSERT
{
NativeInstruction *insn = nativeInstruction_at(pc);
if (HotSpotObjectConstantImpl::compressed(constant)) {
if (jvmci_env()->get_HotSpotObjectConstantImpl_compressed(constant)) {
// Mov narrow constant: movz n << 16, movk
assert(Instruction_aarch64::extract(insn->encoding(), 31, 21) == 0b11010010101 &&
nativeInstruction_at(pc+4)->is_movk(), "wrong insn in patch");
@ -59,7 +59,7 @@ void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS)
}
}
#endif // ASSERT
Handle obj(THREAD, HotSpotObjectConstantImpl::object(constant));
Handle obj = jvmci_env()->asConstant(constant, JVMCI_CHECK);
jobject value = JNIHandles::make_local(obj());
MacroAssembler::patch_oop(pc, (address)obj());
int oop_index = _oop_recorder->find_index(value);
@ -67,21 +67,21 @@ void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS)
_instructions->relocate(pc, rspec);
}
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) {
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
address pc = _instructions->start() + pc_offset;
if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, CHECK);
if (jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant)) {
narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, JVMCI_CHECK);
MacroAssembler::patch_narrow_klass(pc, narrowOop);
TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/0x%x", p2i(pc), narrowOop);
} else {
NativeMovConstReg* move = nativeMovConstReg_at(pc);
void* reference = record_metadata_reference(_instructions, pc, constant, CHECK);
void* reference = record_metadata_reference(_instructions, pc, constant, JVMCI_CHECK);
move->set_data((intptr_t) reference);
TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference));
}
}
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) {
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS) {
address pc = _instructions->start() + pc_offset;
NativeInstruction* inst = nativeInstruction_at(pc);
if (inst->is_adr_aligned() || inst->is_ldr_literal()
@ -94,7 +94,7 @@ void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset
}
}
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS) {
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS) {
address pc = (address) inst;
if (inst->is_call()) {
NativeCall* call = nativeCall_at(pc);
@ -118,12 +118,12 @@ void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong forei
TRACE_jvmci_3("relocating (foreign call) at " PTR_FORMAT, p2i(inst));
}
void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &cbuf, Handle hotspot_method, jint pc_offset, TRAPS) {
void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &cbuf, JVMCIObject hotspot_method, jint pc_offset, JVMCI_TRAPS) {
#ifdef ASSERT
Method* method = NULL;
// we need to check, this might also be an unresolved method
if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
method = getMethodFromHotSpotMethod(hotspot_method());
if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(hotspot_method)) {
method = JVMCIENV->asMethod(hotspot_method);
}
#endif
switch (_next_call_type) {
@ -157,7 +157,7 @@ void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &cbuf, Handle hotspot_meth
}
}
void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) {
void CodeInstaller::pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS) {
switch (mark) {
case POLL_NEAR:
JVMCI_ERROR("unimplemented");
@ -178,7 +178,7 @@ void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) {
}
// convert JVMCI register indices (as used in oop maps) to HotSpot registers
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, TRAPS) {
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, JVMCI_TRAPS) {
if (jvmci_reg < RegisterImpl::number_of_registers) {
return as_Register(jvmci_reg)->as_VMReg();
} else {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -31,7 +31,7 @@
#include "utilities/align.hpp"
#include "vmreg_sparc.inline.hpp"
jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Handle method, TRAPS) {
jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCIObject method, JVMCI_TRAPS) {
if (inst->is_call() || inst->is_jump()) {
return pc_offset + NativeCall::instruction_size;
} else if (inst->is_call_reg()) {
@ -44,11 +44,11 @@ jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Hand
}
}
void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS) {
void CodeInstaller::pd_patch_OopConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
address pc = _instructions->start() + pc_offset;
Handle obj(THREAD, HotSpotObjectConstantImpl::object(constant));
Handle obj = jvmci_env()->asConstant(constant, JVMCI_CHECK);
jobject value = JNIHandles::make_local(obj());
if (HotSpotObjectConstantImpl::compressed(constant)) {
if (jvmci_env()->get_HotSpotObjectConstantImpl_compressed(constant)) {
int oop_index = _oop_recorder->find_index(value);
RelocationHolder rspec = oop_Relocation::spec(oop_index);
_instructions->relocate(pc, rspec, 1);
@ -64,22 +64,22 @@ void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS)
}
}
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) {
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
address pc = _instructions->start() + pc_offset;
if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
if (jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant)) {
NativeMovConstReg32* move = nativeMovConstReg32_at(pc);
narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, CHECK);
narrowKlass narrowOop = record_narrow_metadata_reference(_instructions, pc, constant, JVMCI_CHECK);
move->set_data((intptr_t)narrowOop);
TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/0x%x", p2i(pc), narrowOop);
} else {
NativeMovConstReg* move = nativeMovConstReg_at(pc);
void* reference = record_metadata_reference(_instructions, pc, constant, CHECK);
void* reference = record_metadata_reference(_instructions, pc, constant, JVMCI_CHECK);
move->set_data((intptr_t)reference);
TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(reference));
}
}
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) {
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS) {
address pc = _instructions->start() + pc_offset;
NativeInstruction* inst = nativeInstruction_at(pc);
NativeInstruction* inst1 = nativeInstruction_at(pc + 4);
@ -100,7 +100,7 @@ void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset
}
}
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS) {
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS) {
address pc = (address) inst;
if (inst->is_call()) {
NativeCall* call = nativeCall_at(pc);
@ -116,12 +116,12 @@ void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong forei
TRACE_jvmci_3("relocating (foreign call) at " PTR_FORMAT, p2i(inst));
}
void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, Handle hotspot_method, jint pc_offset, TRAPS) {
void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, JVMCIObject hotspot_method, jint pc_offset, JVMCI_TRAPS) {
#ifdef ASSERT
Method* method = NULL;
// we need to check, this might also be an unresolved method
if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
method = getMethodFromHotSpotMethod(hotspot_method());
if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(hotspot_method)) {
method = JVMCIENV->asMethod(hotspot_method);
}
#endif
switch (_next_call_type) {
@ -155,7 +155,7 @@ void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, Handle hotspot_method,
}
}
void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) {
void CodeInstaller::pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS) {
switch (mark) {
case POLL_NEAR:
JVMCI_ERROR("unimplemented");
@ -176,7 +176,7 @@ void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) {
}
// convert JVMCI register indices (as used in oop maps) to HotSpot registers
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, TRAPS) {
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, JVMCI_TRAPS) {
// JVMCI Registers are numbered as follows:
// 0..31: Thirty-two General Purpose registers (CPU Registers)
// 32..63: Thirty-two single precision float registers

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -37,7 +37,7 @@
#include "code/vmreg.hpp"
#include "vmreg_x86.inline.hpp"
jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Handle method, TRAPS) {
jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCIObject method, JVMCI_TRAPS) {
if (inst->is_call() || inst->is_jump()) {
assert(NativeCall::instruction_size == (int)NativeJump::instruction_size, "unexpected size");
return (pc_offset + NativeCall::instruction_size);
@ -54,7 +54,7 @@ jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Hand
return (offset);
} else if (inst->is_call_reg()) {
// the inlined vtable stub contains a "call register" instruction
assert(method.not_null(), "only valid for virtual calls");
assert(method.is_non_null(), "only valid for virtual calls");
return (pc_offset + ((NativeCallReg *) inst)->next_instruction_offset());
} else if (inst->is_cond_jump()) {
address pc = (address) (inst);
@ -64,11 +64,12 @@ jint CodeInstaller::pd_next_offset(NativeInstruction* inst, jint pc_offset, Hand
}
}
void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS) {
void CodeInstaller::pd_patch_OopConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
address pc = _instructions->start() + pc_offset;
Handle obj(THREAD, HotSpotObjectConstantImpl::object(constant));
Handle obj = jvmci_env()->asConstant(constant, JVMCI_CHECK);
Thread* THREAD = Thread::current();
jobject value = JNIHandles::make_local(obj());
if (HotSpotObjectConstantImpl::compressed(constant)) {
if (jvmci_env()->get_HotSpotObjectConstantImpl_compressed(constant)) {
#ifdef _LP64
address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
int oop_index = _oop_recorder->find_index(value);
@ -85,24 +86,24 @@ void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS)
}
}
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS) {
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS) {
address pc = _instructions->start() + pc_offset;
if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
if (jvmci_env()->get_HotSpotMetaspaceConstantImpl_compressed(constant)) {
#ifdef _LP64
address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
*((narrowKlass*) operand) = record_narrow_metadata_reference(_instructions, operand, constant, CHECK);
*((narrowKlass*) operand) = record_narrow_metadata_reference(_instructions, operand, constant, JVMCI_CHECK);
TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
#else
JVMCI_ERROR("compressed Klass* on 32bit");
#endif
} else {
address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
*((void**) operand) = record_metadata_reference(_instructions, operand, constant, CHECK);
*((void**) operand) = record_metadata_reference(_instructions, operand, constant, JVMCI_CHECK);
TRACE_jvmci_3("relocating (metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
}
}
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS) {
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS) {
address pc = _instructions->start() + pc_offset;
address operand = Assembler::locate_operand(pc, Assembler::disp32_operand);
@ -117,7 +118,7 @@ void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset
TRACE_jvmci_3("relocating at " PTR_FORMAT "/" PTR_FORMAT " with destination at " PTR_FORMAT " (%d)", p2i(pc), p2i(operand), p2i(dest), data_offset);
}
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS) {
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS) {
address pc = (address) inst;
if (inst->is_call()) {
// NOTE: for call without a mov, the offset must fit a 32-bit immediate
@ -145,12 +146,12 @@ void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong forei
TRACE_jvmci_3("relocating (foreign call) at " PTR_FORMAT, p2i(inst));
}
void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, Handle hotspot_method, jint pc_offset, TRAPS) {
void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, JVMCIObject hotspot_method, jint pc_offset, JVMCI_TRAPS) {
#ifdef ASSERT
Method* method = NULL;
// we need to check, this might also be an unresolved method
if (hotspot_method->is_a(HotSpotResolvedJavaMethodImpl::klass())) {
method = getMethodFromHotSpotMethod(hotspot_method());
if (JVMCIENV->isa_HotSpotResolvedJavaMethodImpl(hotspot_method)) {
method = JVMCIENV->asMethod(hotspot_method);
}
#endif
switch (_next_call_type) {
@ -199,7 +200,7 @@ static void relocate_poll_near(address pc) {
}
void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) {
void CodeInstaller::pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS) {
switch (mark) {
case POLL_NEAR: {
relocate_poll_near(pc);
@ -229,7 +230,7 @@ void CodeInstaller::pd_relocate_poll(address pc, jint mark, TRAPS) {
}
// convert JVMCI register indices (as used in oop maps) to HotSpot registers
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, TRAPS) {
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg, JVMCI_TRAPS) {
if (jvmci_reg < RegisterImpl::number_of_registers) {
return as_Register(jvmci_reg)->as_VMReg();
} else {

View File

@ -32,8 +32,6 @@
#include "compiler/compilerOracle.hpp"
#include "gc/shared/cardTableBarrierSet.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "jvmci/compilerRuntime.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "oops/method.inline.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/handles.inline.hpp"

View File

@ -26,8 +26,8 @@
#include "aot/aotCodeHeap.hpp"
#include "aot/aotLoader.inline.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "oops/method.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/os.inline.hpp"

View File

@ -2607,6 +2607,45 @@ void java_lang_StackTraceElement::fill_in(Handle element,
}
}
#if INCLUDE_JVMCI
void java_lang_StackTraceElement::decode(Handle mirror, methodHandle method, int bci, Symbol*& methodname, Symbol*& filename, int& line_number) {
int method_id = method->orig_method_idnum();
int cpref = method->name_index();
decode(mirror, method_id, method->constants()->version(), bci, cpref, methodname, filename, line_number);
}
void java_lang_StackTraceElement::decode(Handle mirror, int method_id, int version, int bci, int cpref, Symbol*& methodname, Symbol*& filename, int& line_number) {
// Fill in class name
InstanceKlass* holder = InstanceKlass::cast(java_lang_Class::as_Klass(mirror()));
Method* method = holder->method_with_orig_idnum(method_id, version);
// The method can be NULL if the requested class version is gone
Symbol* sym = (method != NULL) ? method->name() : holder->constants()->symbol_at(cpref);
// Fill in method name
methodname = sym;
if (!version_matches(method, version)) {
// If the method was redefined, accurate line number information isn't available
filename = NULL;
line_number = -1;
} else {
// Fill in source file name and line number.
// Use a specific ik version as a holder since the mirror might
// refer to a version that is now obsolete and no longer accessible
// via the previous versions list.
holder = holder->get_klass_version(version);
assert(holder != NULL, "sanity check");
Symbol* source = holder->source_file_name();
if (ShowHiddenFrames && source == NULL) {
source = vmSymbols::unknown_class_name();
}
filename = source;
line_number = Backtrace::get_line_number(method, bci);
}
}
#endif // INCLUDE_JVMCI
Method* java_lang_StackFrameInfo::get_method(Handle stackFrame, InstanceKlass* holder, TRAPS) {
HandleMark hm(THREAD);
Handle mname(THREAD, stackFrame->obj_field(_memberName_offset));

View File

@ -1368,6 +1368,11 @@ class java_lang_StackTraceElement: AllStatic {
static void compute_offsets();
static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN;
#if INCLUDE_JVMCI
static void decode(Handle mirror, int method, int version, int bci, int cpref, Symbol*& methodName, Symbol*& fileName, int& lineNumber);
static void decode(Handle mirror, methodHandle method, int bci, Symbol*& methodName, Symbol*& fileName, int& lineNumber);
#endif
// Debugging
friend class JavaClasses;
};

View File

@ -33,7 +33,7 @@
#include "services/threadService.hpp"
#include "utilities/chunkedList.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/jvmci.hpp"
#endif
MetadataOnStackBuffer* MetadataOnStackMark::_used_buffers = NULL;
@ -73,7 +73,7 @@ MetadataOnStackMark::MetadataOnStackMark(bool walk_all_metadata, bool redefiniti
JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
ThreadService::metadata_do(Metadata::mark_on_stack);
#if INCLUDE_JVMCI
JVMCIRuntime::metadata_do(Metadata::mark_on_stack);
JVMCI::metadata_do(Metadata::mark_on_stack);
#endif
}
}

View File

@ -86,9 +86,6 @@
#if INCLUDE_CDS
#include "classfile/systemDictionaryShared.hpp"
#endif
#if INCLUDE_JVMCI
#include "jvmci/jvmciRuntime.hpp"
#endif
#if INCLUDE_JFR
#include "jfr/jfr.hpp"
#endif
@ -1922,13 +1919,6 @@ bool SystemDictionary::resolve_wk_klass(WKID id, TRAPS) {
Symbol* symbol = vmSymbols::symbol_at((vmSymbols::SID)sid);
InstanceKlass** klassp = &_well_known_klasses[id];
#if INCLUDE_JVMCI
if (id >= FIRST_JVMCI_WKID) {
assert(EnableJVMCI, "resolve JVMCI classes only when EnableJVMCI is true");
}
#endif
if ((*klassp) == NULL) {
Klass* k = resolve_or_fail(symbol, true, CHECK_0);
(*klassp) = InstanceKlass::cast(k);
@ -2017,7 +2007,7 @@ void SystemDictionary::resolve_well_known_classes(TRAPS) {
WKID jsr292_group_end = WK_KLASS_ENUM_NAME(VolatileCallSite_klass);
resolve_wk_klasses_until(jsr292_group_start, scan, CHECK);
resolve_wk_klasses_through(jsr292_group_end, scan, CHECK);
WKID last = NOT_JVMCI(WKID_LIMIT) JVMCI_ONLY(FIRST_JVMCI_WKID);
WKID last = WKID_LIMIT;
resolve_wk_klasses_until(last, scan, CHECK);
_box_klasses[T_BOOLEAN] = WK_KLASS(Boolean_klass);

View File

@ -26,7 +26,6 @@
#define SHARE_CLASSFILE_SYSTEMDICTIONARY_HPP
#include "classfile/classLoaderData.hpp"
#include "jvmci/systemDictionary_jvmci.hpp"
#include "oops/objArrayOop.hpp"
#include "oops/symbol.hpp"
#include "runtime/java.hpp"
@ -215,9 +214,6 @@ class OopStorage;
do_klass(Integer_klass, java_lang_Integer ) \
do_klass(Long_klass, java_lang_Long ) \
\
/* JVMCI classes. These are loaded on-demand. */ \
JVMCI_WK_KLASSES_DO(do_klass) \
\
/*end*/
@ -236,11 +232,6 @@ class SystemDictionary : AllStatic {
WKID_LIMIT,
#if INCLUDE_JVMCI
FIRST_JVMCI_WKID = WK_KLASS_ENUM_NAME(JVMCI_klass),
LAST_JVMCI_WKID = WK_KLASS_ENUM_NAME(Value_klass),
#endif
FIRST_WKID = NO_WKID + 1
};

View File

@ -358,8 +358,7 @@
template(destroyed_name, "destroyed") \
template(nthreads_name, "nthreads") \
template(ngroups_name, "ngroups") \
template(shutdown_method_name, "shutdown") \
template(bootstrapFinished_method_name, "bootstrapFinished") \
template(shutdown_name, "shutdown") \
template(finalize_method_name, "finalize") \
template(reference_lock_name, "lock") \
template(reference_discovered_name, "discovered") \

View File

@ -64,7 +64,7 @@
#include "utilities/resourceHash.hpp"
#include "utilities/xmlstream.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmciJavaClasses.hpp"
#include "jvmci/jvmciRuntime.hpp"
#endif
#ifdef DTRACE_ENABLED
@ -112,6 +112,10 @@ struct java_nmethod_stats_struct {
int dependencies_size;
int handler_table_size;
int nul_chk_table_size;
#if INCLUDE_JVMCI
int speculations_size;
int jvmci_data_size;
#endif
int oops_size;
int metadata_size;
@ -129,6 +133,10 @@ struct java_nmethod_stats_struct {
dependencies_size += nm->dependencies_size();
handler_table_size += nm->handler_table_size();
nul_chk_table_size += nm->nul_chk_table_size();
#if INCLUDE_JVMCI
speculations_size += nm->speculations_size();
jvmci_data_size += nm->jvmci_data_size();
#endif
}
void print_nmethod_stats(const char* name) {
if (nmethod_count == 0) return;
@ -146,6 +154,10 @@ struct java_nmethod_stats_struct {
if (dependencies_size != 0) tty->print_cr(" dependencies = %d", dependencies_size);
if (handler_table_size != 0) tty->print_cr(" handler table = %d", handler_table_size);
if (nul_chk_table_size != 0) tty->print_cr(" nul chk table = %d", nul_chk_table_size);
#if INCLUDE_JVMCI
if (speculations_size != 0) tty->print_cr(" speculations = %d", speculations_size);
if (jvmci_data_size != 0) tty->print_cr(" JVMCI data = %d", jvmci_data_size);
#endif
}
};
@ -426,11 +438,6 @@ void nmethod::init_defaults() {
#if INCLUDE_RTM_OPT
_rtm_state = NoRTM;
#endif
#if INCLUDE_JVMCI
_jvmci_installed_code = NULL;
_speculation_log = NULL;
_jvmci_installed_code_triggers_invalidation = false;
#endif
}
nmethod* nmethod::new_native_nmethod(const methodHandle& method,
@ -483,8 +490,11 @@ nmethod* nmethod::new_nmethod(const methodHandle& method,
AbstractCompiler* compiler,
int comp_level
#if INCLUDE_JVMCI
, jweak installed_code,
jweak speculationLog
, char* speculations,
int speculations_len,
int nmethod_mirror_index,
const char* nmethod_mirror_name,
FailedSpeculation** failed_speculations
#endif
)
{
@ -493,12 +503,19 @@ nmethod* nmethod::new_nmethod(const methodHandle& method,
// create nmethod
nmethod* nm = NULL;
{ MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
#if INCLUDE_JVMCI
int jvmci_data_size = !compiler->is_jvmci() ? 0 : JVMCINMethodData::compute_size(nmethod_mirror_name);
#endif
int nmethod_size =
CodeBlob::allocation_size(code_buffer, sizeof(nmethod))
+ adjust_pcs_size(debug_info->pcs_size())
+ align_up((int)dependencies->size_in_bytes(), oopSize)
+ align_up(handler_table->size_in_bytes() , oopSize)
+ align_up(nul_chk_table->size_in_bytes() , oopSize)
#if INCLUDE_JVMCI
+ align_up(speculations_len , oopSize)
+ align_up(jvmci_data_size , oopSize)
#endif
+ align_up(debug_info->data_size() , oopSize);
nm = new (nmethod_size, comp_level)
@ -510,12 +527,19 @@ nmethod* nmethod::new_nmethod(const methodHandle& method,
compiler,
comp_level
#if INCLUDE_JVMCI
, installed_code,
speculationLog
, speculations,
speculations_len,
jvmci_data_size
#endif
);
if (nm != NULL) {
#if INCLUDE_JVMCI
if (compiler->is_jvmci()) {
// Initialize the JVMCINMethodData object inlined into nm
nm->jvmci_nmethod_data()->initialize(nmethod_mirror_index, nmethod_mirror_name, failed_speculations);
}
#endif
// To make dependency checking during class loading fast, record
// the nmethod dependencies in the classes it is dependent on.
// This allows the dependency checking code to simply walk the
@ -591,7 +615,13 @@ nmethod::nmethod(
_dependencies_offset = _scopes_pcs_offset;
_handler_table_offset = _dependencies_offset;
_nul_chk_table_offset = _handler_table_offset;
#if INCLUDE_JVMCI
_speculations_offset = _nul_chk_table_offset;
_jvmci_data_offset = _speculations_offset;
_nmethod_end_offset = _jvmci_data_offset;
#else
_nmethod_end_offset = _nul_chk_table_offset;
#endif
_compile_id = compile_id;
_comp_level = CompLevel_none;
_entry_point = code_begin() + offsets->value(CodeOffsets::Entry);
@ -667,8 +697,9 @@ nmethod::nmethod(
AbstractCompiler* compiler,
int comp_level
#if INCLUDE_JVMCI
, jweak installed_code,
jweak speculation_log
, char* speculations,
int speculations_len,
int jvmci_data_size
#endif
)
: CompiledMethod(method, "nmethod", type, nmethod_size, sizeof(nmethod), code_buffer, offsets->value(CodeOffsets::Frame_Complete), frame_size, oop_maps, false),
@ -697,15 +728,6 @@ nmethod::nmethod(
set_ctable_begin(header_begin() + _consts_offset);
#if INCLUDE_JVMCI
_jvmci_installed_code = installed_code;
_speculation_log = speculation_log;
oop obj = JNIHandles::resolve(installed_code);
if (obj == NULL || (obj->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(obj))) {
_jvmci_installed_code_triggers_invalidation = false;
} else {
_jvmci_installed_code_triggers_invalidation = true;
}
if (compiler->is_jvmci()) {
// JVMCI might not produce any stub sections
if (offsets->value(CodeOffsets::Exceptions) != -1) {
@ -735,10 +757,10 @@ nmethod::nmethod(
_deopt_mh_handler_begin = (address) this + _stub_offset + offsets->value(CodeOffsets::DeoptMH);
} else {
_deopt_mh_handler_begin = NULL;
}
#if INCLUDE_JVMCI
}
#endif
}
if (offsets->value(CodeOffsets::UnwindHandler) != -1) {
_unwind_handler_offset = code_offset() + offsets->value(CodeOffsets::UnwindHandler);
} else {
@ -753,7 +775,13 @@ nmethod::nmethod(
_dependencies_offset = _scopes_pcs_offset + adjust_pcs_size(debug_info->pcs_size());
_handler_table_offset = _dependencies_offset + align_up((int)dependencies->size_in_bytes (), oopSize);
_nul_chk_table_offset = _handler_table_offset + align_up(handler_table->size_in_bytes(), oopSize);
#if INCLUDE_JVMCI
_speculations_offset = _nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize);
_jvmci_data_offset = _speculations_offset + align_up(speculations_len, oopSize);
_nmethod_end_offset = _jvmci_data_offset + align_up(jvmci_data_size, oopSize);
#else
_nmethod_end_offset = _nul_chk_table_offset + align_up(nul_chk_table->size_in_bytes(), oopSize);
#endif
_entry_point = code_begin() + offsets->value(CodeOffsets::Entry);
_verified_entry_point = code_begin() + offsets->value(CodeOffsets::Verified_Entry);
_osr_entry_point = code_begin() + offsets->value(CodeOffsets::OSR_Entry);
@ -779,6 +807,13 @@ nmethod::nmethod(
handler_table->copy_to(this);
nul_chk_table->copy_to(this);
#if INCLUDE_JVMCI
// Copy speculations to nmethod
if (speculations_size() != 0) {
memcpy(speculations_begin(), speculations, speculations_len);
}
#endif
// we use the information of entry points to find out if a method is
// static or non static
assert(compiler->is_c2() || compiler->is_jvmci() ||
@ -798,13 +833,14 @@ void nmethod::log_identity(xmlStream* log) const {
log->print(" level='%d'", comp_level());
}
#if INCLUDE_JVMCI
char buffer[O_BUFLEN];
char* jvmci_name = jvmci_installed_code_name(buffer, O_BUFLEN);
if (jvmci_nmethod_data() != NULL) {
const char* jvmci_name = jvmci_nmethod_data()->name();
if (jvmci_name != NULL) {
log->print(" jvmci_installed_code_name='");
log->print(" jvmci_mirror_name='");
log->text("%s", jvmci_name);
log->print("'");
}
}
#endif
}
@ -1115,13 +1151,6 @@ void nmethod::make_unloaded() {
// Log the unloading.
log_state_change();
#if INCLUDE_JVMCI
// The method can only be unloaded after the pointer to the installed code
// Java wrapper is no longer alive. Here we need to clear out this weak
// reference to the dead object.
maybe_invalidate_installed_code();
#endif
// The Method* is gone at this point
assert(_method == NULL, "Tautology");
@ -1134,6 +1163,15 @@ void nmethod::make_unloaded() {
// concurrent nmethod unloading. Therefore, there is no need for
// acquire on the loader side.
OrderAccess::release_store(&_state, (signed char)unloaded);
#if INCLUDE_JVMCI
// Clear the link between this nmethod and a HotSpotNmethod mirror
JVMCINMethodData* nmethod_data = jvmci_nmethod_data();
if (nmethod_data != NULL) {
nmethod_data->invalidate_nmethod_mirror(this);
nmethod_data->clear_nmethod_mirror(this);
}
#endif
}
void nmethod::invalidate_osr_method() {
@ -1265,13 +1303,18 @@ bool nmethod::make_not_entrant_or_zombie(int state) {
// Log the transition once
log_state_change();
// Invalidate while holding the patching lock
JVMCI_ONLY(maybe_invalidate_installed_code());
// Remove nmethod from method.
unlink_from_method(false /* already owns Patching_lock */);
} // leave critical region under Patching_lock
#if INCLUDE_JVMCI
// Invalidate can't occur while holding the Patching lock
JVMCINMethodData* nmethod_data = jvmci_nmethod_data();
if (nmethod_data != NULL) {
nmethod_data->invalidate_nmethod_mirror(this);
}
#endif
#ifdef ASSERT
if (is_osr_method() && method() != NULL) {
// Make sure osr nmethod is invalidated, i.e. not on the list
@ -1297,6 +1340,14 @@ bool nmethod::make_not_entrant_or_zombie(int state) {
flush_dependencies(/*delete_immediately*/true);
}
#if INCLUDE_JVMCI
// Now that the nmethod has been unregistered, it's
// safe to clear the HotSpotNmethod mirror oop.
if (nmethod_data != NULL) {
nmethod_data->clear_nmethod_mirror(this);
}
#endif
// Clear ICStubs to prevent back patching stubs of zombie or flushed
// nmethods during the next safepoint (see ICStub::finalize), as well
// as to free up CompiledICHolder resources.
@ -1324,7 +1375,7 @@ bool nmethod::make_not_entrant_or_zombie(int state) {
assert(state == not_entrant, "other cases may need to be handled differently");
}
if (TraceCreateZombies) {
if (TraceCreateZombies && state == zombie) {
ResourceMark m;
tty->print_cr("nmethod <" INTPTR_FORMAT "> %s code made %s", p2i(this), this->method() ? this->method()->name_and_sig_as_C_string() : "null", (state == not_entrant) ? "not entrant" : "zombie");
}
@ -1362,11 +1413,6 @@ void nmethod::flush() {
ec = next;
}
#if INCLUDE_JVMCI
assert(_jvmci_installed_code == NULL, "should have been nulled out when transitioned to zombie");
assert(_speculation_log == NULL, "should have been nulled out when transitioned to zombie");
#endif
Universe::heap()->flush_nmethod(this);
CodeBlob::flush();
@ -1660,17 +1706,6 @@ void nmethod::do_unloading(bool unloading_occurred) {
if (is_unloading()) {
make_unloaded();
} else {
#if INCLUDE_JVMCI
if (_jvmci_installed_code != NULL) {
if (JNIHandles::is_global_weak_cleared(_jvmci_installed_code)) {
if (_jvmci_installed_code_triggers_invalidation) {
make_not_entrant();
}
clear_jvmci_installed_code();
}
}
#endif
guarantee(unload_nmethod_caches(unloading_occurred),
"Should not need transition stubs");
}
@ -2066,7 +2101,7 @@ void nmethodLocker::lock_nmethod(CompiledMethod* cm, bool zombie_ok) {
if (cm->is_aot()) return; // FIXME: Revisit once _lock_count is added to aot_method
nmethod* nm = cm->as_nmethod();
Atomic::inc(&nm->_lock_count);
assert(zombie_ok || !nm->is_zombie(), "cannot lock a zombie method");
assert(zombie_ok || !nm->is_zombie(), "cannot lock a zombie method: %p", nm);
}
void nmethodLocker::unlock_nmethod(CompiledMethod* cm) {
@ -2275,6 +2310,16 @@ void nmethod::print() const {
p2i(nul_chk_table_begin()),
p2i(nul_chk_table_end()),
nul_chk_table_size());
#if INCLUDE_JVMCI
if (speculations_size () > 0) tty->print_cr(" speculations [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(speculations_begin()),
p2i(speculations_end()),
speculations_size());
if (jvmci_data_size () > 0) tty->print_cr(" JVMCI data [" INTPTR_FORMAT "," INTPTR_FORMAT "] = %d",
p2i(jvmci_data_begin()),
p2i(jvmci_data_end()),
jvmci_data_size());
#endif
}
#ifndef PRODUCT
@ -2857,115 +2902,18 @@ void nmethod::print_statistics() {
#endif // !PRODUCT
#if INCLUDE_JVMCI
void nmethod::clear_jvmci_installed_code() {
assert_locked_or_safepoint(Patching_lock);
if (_jvmci_installed_code != NULL) {
JNIHandles::destroy_weak_global(_jvmci_installed_code);
_jvmci_installed_code = NULL;
void nmethod::update_speculation(JavaThread* thread) {
jlong speculation = thread->pending_failed_speculation();
if (speculation != 0) {
guarantee(jvmci_nmethod_data() != NULL, "failed speculation in nmethod without failed speculation list");
jvmci_nmethod_data()->add_failed_speculation(this, speculation);
thread->set_pending_failed_speculation(0);
}
}
void nmethod::clear_speculation_log() {
assert_locked_or_safepoint(Patching_lock);
if (_speculation_log != NULL) {
JNIHandles::destroy_weak_global(_speculation_log);
_speculation_log = NULL;
}
}
void nmethod::maybe_invalidate_installed_code() {
if (!is_compiled_by_jvmci()) {
return;
}
assert(Patching_lock->is_locked() ||
SafepointSynchronize::is_at_safepoint(), "should be performed under a lock for consistency");
oop installed_code = JNIHandles::resolve(_jvmci_installed_code);
if (installed_code != NULL) {
// Update the values in the InstalledCode instance if it still refers to this nmethod
nmethod* nm = (nmethod*)InstalledCode::address(installed_code);
if (nm == this) {
if (!is_alive() || is_unloading()) {
// Break the link between nmethod and InstalledCode such that the nmethod
// can subsequently be flushed safely. The link must be maintained while
// the method could have live activations since invalidateInstalledCode
// might want to invalidate all existing activations.
InstalledCode::set_address(installed_code, 0);
InstalledCode::set_entryPoint(installed_code, 0);
} else if (is_not_entrant()) {
// Remove the entry point so any invocation will fail but keep
// the address link around that so that existing activations can
// be invalidated.
InstalledCode::set_entryPoint(installed_code, 0);
}
}
}
if (!is_alive() || is_unloading()) {
// Clear these out after the nmethod has been unregistered and any
// updates to the InstalledCode instance have been performed.
clear_jvmci_installed_code();
clear_speculation_log();
}
}
void nmethod::invalidate_installed_code(Handle installedCode, TRAPS) {
if (installedCode() == NULL) {
THROW(vmSymbols::java_lang_NullPointerException());
}
jlong nativeMethod = InstalledCode::address(installedCode);
nmethod* nm = (nmethod*)nativeMethod;
if (nm == NULL) {
// Nothing to do
return;
}
nmethodLocker nml(nm);
#ifdef ASSERT
{
MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag);
// This relationship can only be checked safely under a lock
assert(!nm->is_alive() || nm->is_unloading() || nm->jvmci_installed_code() == installedCode(), "sanity check");
}
#endif
if (nm->is_alive()) {
// Invalidating the InstalledCode means we want the nmethod
// to be deoptimized.
nm->mark_for_deoptimization();
VM_Deoptimize op;
VMThread::execute(&op);
}
// Multiple threads could reach this point so we now need to
// lock and re-check the link to the nmethod so that only one
// thread clears it.
MutexLocker pl(Patching_lock, Mutex::_no_safepoint_check_flag);
if (InstalledCode::address(installedCode) == nativeMethod) {
InstalledCode::set_address(installedCode, 0);
}
}
oop nmethod::jvmci_installed_code() {
return JNIHandles::resolve(_jvmci_installed_code);
}
oop nmethod::speculation_log() {
return JNIHandles::resolve(_speculation_log);
}
char* nmethod::jvmci_installed_code_name(char* buf, size_t buflen) const {
if (!this->is_compiled_by_jvmci()) {
return NULL;
}
oop installed_code = JNIHandles::resolve(_jvmci_installed_code);
if (installed_code != NULL) {
oop installed_code_name = NULL;
if (installed_code->is_a(InstalledCode::klass())) {
installed_code_name = InstalledCode::name(installed_code);
}
if (installed_code_name != NULL) {
return java_lang_String::as_utf8_string(installed_code_name, buf, (int)buflen);
}
const char* nmethod::jvmci_name() {
if (jvmci_nmethod_data() != NULL) {
return jvmci_nmethod_data()->name();
}
return NULL;
}

View File

@ -51,37 +51,28 @@ class DebugInformationRecorder;
// - handler entry point array
// [Implicit Null Pointer exception table]
// - implicit null table array
// [Speculations]
// - encoded speculations array
// [JVMCINMethodData]
// - meta data for JVMCI compiled nmethod
#if INCLUDE_JVMCI
class FailedSpeculation;
class JVMCINMethodData;
#endif
class nmethod : public CompiledMethod {
friend class VMStructs;
friend class JVMCIVMStructs;
friend class NMethodSweeper;
friend class CodeCache; // scavengable oops
friend class JVMCINMethodData;
private:
// Shared fields for all nmethod's
int _entry_bci; // != InvocationEntryBci if this nmethod is an on-stack replacement method
jmethodID _jmethod_id; // Cache of method()->jmethod_id()
#if INCLUDE_JVMCI
// A weak reference to an InstalledCode object associated with
// this nmethod.
jweak _jvmci_installed_code;
// A weak reference to a SpeculationLog object associated with
// this nmethod.
jweak _speculation_log;
// Determines whether this nmethod is unloaded when the
// referent in _jvmci_installed_code is cleared. This
// will be false if the referent is initialized to a
// HotSpotNMethod object whose isDefault field is true.
// That is, installed code other than a "default"
// HotSpotNMethod causes nmethod unloading.
// This field is ignored once _jvmci_installed_code is NULL.
bool _jvmci_installed_code_triggers_invalidation;
#endif
// To support simple linked-list chaining of nmethods:
nmethod* _osr_link; // from InstanceKlass::osr_nmethods_head
@ -107,6 +98,10 @@ class nmethod : public CompiledMethod {
int _dependencies_offset;
int _handler_table_offset;
int _nul_chk_table_offset;
#if INCLUDE_JVMCI
int _speculations_offset;
int _jvmci_data_offset;
#endif
int _nmethod_end_offset;
int code_offset() const { return (address) code_begin() - header_begin(); }
@ -207,8 +202,9 @@ class nmethod : public CompiledMethod {
AbstractCompiler* compiler,
int comp_level
#if INCLUDE_JVMCI
, jweak installed_code,
jweak speculation_log
, char* speculations,
int speculations_len,
int jvmci_data_size
#endif
);
@ -251,8 +247,11 @@ class nmethod : public CompiledMethod {
AbstractCompiler* compiler,
int comp_level
#if INCLUDE_JVMCI
, jweak installed_code = NULL,
jweak speculation_log = NULL
, char* speculations = NULL,
int speculations_len = 0,
int nmethod_mirror_index = -1,
const char* nmethod_mirror_name = NULL,
FailedSpeculation** failed_speculations = NULL
#endif
);
@ -299,12 +298,24 @@ class nmethod : public CompiledMethod {
address handler_table_begin () const { return header_begin() + _handler_table_offset ; }
address handler_table_end () const { return header_begin() + _nul_chk_table_offset ; }
address nul_chk_table_begin () const { return header_begin() + _nul_chk_table_offset ; }
#if INCLUDE_JVMCI
address nul_chk_table_end () const { return header_begin() + _speculations_offset ; }
address speculations_begin () const { return header_begin() + _speculations_offset ; }
address speculations_end () const { return header_begin() + _jvmci_data_offset ; }
address jvmci_data_begin () const { return header_begin() + _jvmci_data_offset ; }
address jvmci_data_end () const { return header_begin() + _nmethod_end_offset ; }
#else
address nul_chk_table_end () const { return header_begin() + _nmethod_end_offset ; }
#endif
// Sizes
int oops_size () const { return (address) oops_end () - (address) oops_begin (); }
int metadata_size () const { return (address) metadata_end () - (address) metadata_begin (); }
int dependencies_size () const { return dependencies_end () - dependencies_begin (); }
#if INCLUDE_JVMCI
int speculations_size () const { return speculations_end () - speculations_begin (); }
int jvmci_data_size () const { return jvmci_data_end () - jvmci_data_begin (); }
#endif
int oops_count() const { assert(oops_size() % oopSize == 0, ""); return (oops_size() / oopSize) + 1; }
int metadata_count() const { assert(metadata_size() % wordSize == 0, ""); return (metadata_size() / wordSize) + 1; }
@ -446,39 +457,19 @@ public:
void set_method(Method* method) { _method = method; }
#if INCLUDE_JVMCI
// Gets the InstalledCode object associated with this nmethod
// which may be NULL if this nmethod was not compiled by JVMCI
// or the weak reference has been cleared.
oop jvmci_installed_code();
// Gets the JVMCI name of this nmethod.
const char* jvmci_name();
// Copies the value of the name field in the InstalledCode
// object (if any) associated with this nmethod into buf.
// Returns the value of buf if it was updated otherwise NULL.
char* jvmci_installed_code_name(char* buf, size_t buflen) const;
// Records the pending failed speculation in the
// JVMCI speculation log associated with this nmethod.
void update_speculation(JavaThread* thread);
// Updates the state of the InstalledCode (if any) associated with
// this nmethod based on the current value of _state.
void maybe_invalidate_installed_code();
// Deoptimizes the nmethod (if any) in the address field of a given
// InstalledCode object. The address field is zeroed upon return.
static void invalidate_installed_code(Handle installed_code, TRAPS);
// Gets the SpeculationLog object associated with this nmethod
// which may be NULL if this nmethod was not compiled by JVMCI
// or the weak reference has been cleared.
oop speculation_log();
private:
// Deletes the weak reference (if any) to the InstalledCode object
// associated with this nmethod.
void clear_jvmci_installed_code();
// Deletes the weak reference (if any) to the SpeculationLog object
// associated with this nmethod.
void clear_speculation_log();
public:
// Gets the data specific to a JVMCI compiled method.
// This returns a non-NULL value iff this nmethod was
// compiled by the JVMCI compiler.
JVMCINMethodData* jvmci_nmethod_data() const {
return jvmci_data_size() == 0 ? NULL : (JVMCINMethodData*) jvmci_data_begin();
}
#endif
public:

View File

@ -154,9 +154,6 @@ class AbstractCompiler : public CHeapObj<mtCompiler> {
const bool is_jvmci() { return _type == compiler_jvmci; }
const CompilerType type() { return _type; }
// Extra tests to identify trivial methods for the tiered compilation policy.
virtual bool is_trivial(Method* method) { return false; }
// Customization
virtual void initialize () = 0;

View File

@ -68,9 +68,8 @@
#include "c1/c1_Compiler.hpp"
#endif
#if INCLUDE_JVMCI
#include "jvmci/jvmciCompiler.hpp"
#include "jvmci/jvmciEnv.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "runtime/vframe.hpp"
#endif
#ifdef COMPILER2
@ -1064,36 +1063,34 @@ void CompileBroker::compile_method_base(const methodHandle& method,
}
#if INCLUDE_JVMCI
if (UseJVMCICompiler) {
if (blocking) {
// Don't allow blocking compiles for requests triggered by JVMCI.
if (thread->is_Compiler_thread()) {
blocking = false;
}
if (UseJVMCICompiler && blocking && !UseJVMCINativeLibrary) {
// Don't allow blocking compiles for requests triggered by JVMCI.
if (thread->is_Compiler_thread()) {
blocking = false;
}
// Don't allow blocking compiles if inside a class initializer or while performing class loading
vframeStream vfst((JavaThread*) thread);
for (; !vfst.at_end(); vfst.next()) {
if (vfst.method()->is_static_initializer() ||
(vfst.method()->method_holder()->is_subclass_of(SystemDictionary::ClassLoader_klass()) &&
vfst.method()->name() == vmSymbols::loadClass_name())) {
blocking = false;
break;
}
}
// Don't allow blocking compilation requests to JVMCI
// if JVMCI itself is not yet initialized
if (!JVMCIRuntime::is_HotSpotJVMCIRuntime_initialized() && compiler(comp_level)->is_jvmci()) {
// Don't allow blocking compiles if inside a class initializer or while performing class loading
vframeStream vfst((JavaThread*) thread);
for (; !vfst.at_end(); vfst.next()) {
if (vfst.method()->is_static_initializer() ||
(vfst.method()->method_holder()->is_subclass_of(SystemDictionary::ClassLoader_klass()) &&
vfst.method()->name() == vmSymbols::loadClass_name())) {
blocking = false;
break;
}
}
// Don't allow blocking compilation requests if we are in JVMCIRuntime::shutdown
// to avoid deadlock between compiler thread(s) and threads run at shutdown
// such as the DestroyJavaVM thread.
if (JVMCIRuntime::shutdown_called()) {
blocking = false;
}
// Don't allow blocking compilation requests to JVMCI
// if JVMCI itself is not yet initialized
if (!JVMCI::is_compiler_initialized() && compiler(comp_level)->is_jvmci()) {
blocking = false;
}
// Don't allow blocking compilation requests if we are in JVMCIRuntime::shutdown
// to avoid deadlock between compiler thread(s) and threads run at shutdown
// such as the DestroyJavaVM thread.
if (JVMCI::shutdown_called()) {
blocking = false;
}
}
#endif // INCLUDE_JVMCI
@ -1193,7 +1190,7 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
}
#if INCLUDE_JVMCI
if (comp->is_jvmci() && !JVMCIRuntime::can_initialize_JVMCI()) {
if (comp->is_jvmci() && !JVMCI::can_initialize_JVMCI()) {
return NULL;
}
#endif
@ -2061,20 +2058,24 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
// Skip redefined methods
if (target_handle->is_old()) {
failure_reason = "redefined method";
retry_message = "not retryable";
compilable = ciEnv::MethodCompilable_never;
failure_reason = "redefined method";
retry_message = "not retryable";
compilable = ciEnv::MethodCompilable_never;
} else {
JVMCIEnv env(task, system_dictionary_modification_counter);
methodHandle method(thread, target_handle);
jvmci->compile_method(method, osr_bci, &env);
JVMCICompileState compile_state(task, system_dictionary_modification_counter);
JVMCIEnv env(&compile_state, __FILE__, __LINE__);
methodHandle method(thread, target_handle);
env.runtime()->compile_method(&env, jvmci, method, osr_bci);
failure_reason = env.failure_reason();
failure_reason_on_C_heap = env.failure_reason_on_C_heap();
if (!env.retryable()) {
retry_message = "not retryable";
compilable = ciEnv::MethodCompilable_not_at_tier;
}
failure_reason = compile_state.failure_reason();
failure_reason_on_C_heap = compile_state.failure_reason_on_C_heap();
if (!compile_state.retryable()) {
retry_message = "not retryable";
compilable = ciEnv::MethodCompilable_not_at_tier;
}
if (task->code() == NULL) {
assert(failure_reason != NULL, "must specify failure_reason");
}
}
post_compile(thread, task, task->code() != NULL, NULL, compilable, failure_reason);
if (event.should_commit()) {

View File

@ -396,6 +396,7 @@ void CompileTask::log_task_done(CompileLog* log) {
ResourceMark rm(thread);
if (!_is_success) {
assert(_failure_reason != NULL, "missing");
const char* reason = _failure_reason != NULL ? _failure_reason : "unknown";
log->elem("failure reason='%s'", reason);
}

View File

@ -253,22 +253,6 @@ void set_jvmci_specific_flags() {
if (FLAG_IS_DEFAULT(TypeProfileWidth)) {
FLAG_SET_DEFAULT(TypeProfileWidth, 8);
}
if (FLAG_IS_DEFAULT(OnStackReplacePercentage)) {
FLAG_SET_DEFAULT(OnStackReplacePercentage, 933);
}
// JVMCI needs values not less than defaults
if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
FLAG_SET_DEFAULT(ReservedCodeCacheSize, MAX2(64*M, ReservedCodeCacheSize));
}
if (FLAG_IS_DEFAULT(InitialCodeCacheSize)) {
FLAG_SET_DEFAULT(InitialCodeCacheSize, MAX2(16*M, InitialCodeCacheSize));
}
if (FLAG_IS_DEFAULT(MetaspaceSize)) {
FLAG_SET_DEFAULT(MetaspaceSize, MIN2(MAX2(12*M, MetaspaceSize), MaxMetaspaceSize));
}
if (FLAG_IS_DEFAULT(NewSizeThreadIncrease)) {
FLAG_SET_DEFAULT(NewSizeThreadIncrease, MAX2(4*K, NewSizeThreadIncrease));
}
if (TieredStopAtLevel != CompLevel_full_optimization) {
// Currently JVMCI compiler can only work at the full optimization level
warning("forcing TieredStopAtLevel to full optimization because JVMCI is enabled");
@ -277,7 +261,43 @@ void set_jvmci_specific_flags() {
if (FLAG_IS_DEFAULT(TypeProfileLevel)) {
FLAG_SET_DEFAULT(TypeProfileLevel, 0);
}
}
if (UseJVMCINativeLibrary) {
// SVM compiled code requires more stack space
if (FLAG_IS_DEFAULT(CompilerThreadStackSize)) {
// Duplicate logic in the implementations of os::create_thread
// so that we can then double the computed stack size. Once
// the stack size requirements of SVM are better understood,
// this logic can be pushed down into os::create_thread.
int stack_size = CompilerThreadStackSize;
if (stack_size == 0) {
stack_size = VMThreadStackSize;
}
if (stack_size != 0) {
FLAG_SET_DEFAULT(CompilerThreadStackSize, stack_size * 2);
}
}
} else {
// Adjust the on stack replacement percentage to avoid early
// OSR compilations while JVMCI itself is warming up
if (FLAG_IS_DEFAULT(OnStackReplacePercentage)) {
FLAG_SET_DEFAULT(OnStackReplacePercentage, 933);
}
// JVMCI needs values not less than defaults
if (FLAG_IS_DEFAULT(ReservedCodeCacheSize)) {
FLAG_SET_DEFAULT(ReservedCodeCacheSize, MAX2(64*M, ReservedCodeCacheSize));
}
if (FLAG_IS_DEFAULT(InitialCodeCacheSize)) {
FLAG_SET_DEFAULT(InitialCodeCacheSize, MAX2(16*M, InitialCodeCacheSize));
}
if (FLAG_IS_DEFAULT(MetaspaceSize)) {
FLAG_SET_DEFAULT(MetaspaceSize, MIN2(MAX2(12*M, MetaspaceSize), MaxMetaspaceSize));
}
if (FLAG_IS_DEFAULT(NewSizeThreadIncrease)) {
FLAG_SET_DEFAULT(NewSizeThreadIncrease, MAX2(4*K, NewSizeThreadIncrease));
}
} // !UseJVMCINativeLibrary
} // UseJVMCICompiler
}
#endif // INCLUDE_JVMCI
@ -392,6 +412,8 @@ void CompilerConfig::ergo_initialize() {
// Check that JVMCI compiler supports selested GC.
// Should be done after GCConfig::initialize() was called.
JVMCIGlobals::check_jvmci_supported_gc();
// Do JVMCI specific settings
set_jvmci_specific_flags();
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -672,8 +672,7 @@ void Disassembler::decode(nmethod* nm, outputStream* st) {
nm->method()->signature()->print_symbol_on(env.output());
#if INCLUDE_JVMCI
{
char buffer[O_BUFLEN];
char* jvmciName = nm->jvmci_installed_code_name(buffer, O_BUFLEN);
const char* jvmciName = nm->jvmci_name();
if (jvmciName != NULL) {
env.output()->print(" (%s)", jvmciName);
}

View File

@ -82,6 +82,9 @@
#include "services/runtimeService.hpp"
#include "utilities/align.hpp"
#include "utilities/stack.inline.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
// statics
CMSCollector* ConcurrentMarkSweepGeneration::_collector = NULL;
@ -5258,6 +5261,9 @@ void CMSCollector::refProcessingWork() {
// Prune dead klasses from subklass/sibling/implementor lists.
Klass::clean_weak_klass_links(purged_class);
// Clean JVMCI metadata handles.
JVMCI_ONLY(JVMCI::do_unloading(purged_class));
}
}

View File

@ -60,9 +60,8 @@ G1GCPhaseTimes::G1GCPhaseTimes(STWGCTimer* gc_timer, uint max_gc_threads) :
_gc_par_phases[SystemDictionaryRoots] = new WorkerDataArray<double>(max_gc_threads, "SystemDictionary Roots (ms):");
_gc_par_phases[CLDGRoots] = new WorkerDataArray<double>(max_gc_threads, "CLDG Roots (ms):");
_gc_par_phases[JVMTIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMTI Roots (ms):");
#if INCLUDE_AOT
_gc_par_phases[AOTCodeRoots] = new WorkerDataArray<double>(max_gc_threads, "AOT Root Scan (ms):");
#endif
AOT_ONLY(_gc_par_phases[AOTCodeRoots] = new WorkerDataArray<double>(max_gc_threads, "AOT Root Scan (ms):");)
JVMCI_ONLY(_gc_par_phases[JVMCIRoots] = new WorkerDataArray<double>(max_gc_threads, "JVMCI Root Scan (ms):");)
_gc_par_phases[CMRefRoots] = new WorkerDataArray<double>(max_gc_threads, "CM RefProcessor Roots (ms):");
_gc_par_phases[WaitForStrongCLD] = new WorkerDataArray<double>(max_gc_threads, "Wait For Strong CLD (ms):");
_gc_par_phases[WeakCLDRoots] = new WorkerDataArray<double>(max_gc_threads, "Weak CLD Roots (ms):");
@ -527,9 +526,8 @@ const char* G1GCPhaseTimes::phase_name(GCParPhases phase) {
"SystemDictionaryRoots",
"CLDGRoots",
"JVMTIRoots",
#if INCLUDE_AOT
"AOTCodeRoots",
#endif
AOT_ONLY("AOTCodeRoots" COMMA)
JVMCI_ONLY("JVMCIRoots" COMMA)
"CMRefRoots",
"WaitForStrongCLD",
"WeakCLDRoots",

View File

@ -55,9 +55,8 @@ class G1GCPhaseTimes : public CHeapObj<mtGC> {
SystemDictionaryRoots,
CLDGRoots,
JVMTIRoots,
#if INCLUDE_AOT
AOTCodeRoots,
#endif
AOT_ONLY(AOTCodeRoots COMMA)
JVMCI_ONLY(JVMCIRoots COMMA)
CMRefRoots,
WaitForStrongCLD,
WeakCLDRoots,

View File

@ -43,6 +43,9 @@
#include "runtime/mutex.hpp"
#include "services/management.hpp"
#include "utilities/macros.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
void G1RootProcessor::worker_has_discovered_all_strong_classes() {
assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
@ -267,6 +270,15 @@ void G1RootProcessor::process_vm_roots(G1RootClosures* closures,
}
#endif
#if INCLUDE_JVMCI
if (EnableJVMCI) {
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::JVMCIRoots, worker_i);
if (_process_strong_tasks.try_claim_task(G1RP_PS_JVMCI_oops_do)) {
JVMCI::oops_do(strong_roots);
}
}
#endif
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i);
if (_process_strong_tasks.try_claim_task(G1RP_PS_SystemDictionary_oops_do)) {

View File

@ -63,7 +63,8 @@ class G1RootProcessor : public StackObj {
G1RP_PS_ClassLoaderDataGraph_oops_do,
G1RP_PS_jvmti_oops_do,
G1RP_PS_CodeCache_oops_do,
G1RP_PS_aot_oops_do,
AOT_ONLY(G1RP_PS_aot_oops_do COMMA)
JVMCI_ONLY(G1RP_PS_JVMCI_oops_do COMMA)
G1RP_PS_filter_satb_buffers,
G1RP_PS_refProcessor_oops_do,
// Leave this one last.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -46,6 +46,9 @@
#include "runtime/vmThread.hpp"
#include "services/management.hpp"
#include "utilities/stack.inline.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
//
// ThreadRootsMarkingTask
@ -121,6 +124,12 @@ void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
AOTLoader::oops_do(&mark_and_push_closure);
break;
#if INCLUDE_JVMCI
case jvmci:
JVMCI::oops_do(&mark_and_push_closure);
break;
#endif
default:
fatal("Unknown root type");
}

View File

@ -98,6 +98,7 @@ class MarkFromRootsTask : public GCTask {
system_dictionary = 7,
class_loader_data = 8,
code_cache = 9
JVMCI_ONLY(COMMA jvmci = 10)
};
private:
RootType _root_type;

View File

@ -62,6 +62,9 @@
#include "utilities/align.hpp"
#include "utilities/events.hpp"
#include "utilities/stack.inline.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
elapsedTimer PSMarkSweep::_accumulated_time;
jlong PSMarkSweep::_time_of_last_gc = 0;
@ -524,7 +527,8 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
ClassLoaderDataGraph::always_strong_cld_do(follow_cld_closure());
// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
//ScavengableNMethods::scavengable_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
AOTLoader::oops_do(mark_and_push_closure());
AOT_ONLY(AOTLoader::oops_do(mark_and_push_closure());)
JVMCI_ONLY(JVMCI::oops_do(mark_and_push_closure());)
}
// Flush marking stack.
@ -562,6 +566,9 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
// Prune dead klasses from subklass/sibling/implementor lists.
Klass::clean_weak_klass_links(purged_class);
// Clean JVMCI metadata handles.
JVMCI_ONLY(JVMCI::do_unloading(purged_class));
}
_gc_tracer->report_object_count_after_gc(is_alive_closure());
@ -615,7 +622,10 @@ void PSMarkSweep::mark_sweep_phase3() {
CodeBlobToOopClosure adjust_from_blobs(adjust_pointer_closure(), CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&adjust_from_blobs);
AOTLoader::oops_do(adjust_pointer_closure());
AOT_ONLY(AOTLoader::oops_do(adjust_pointer_closure());)
JVMCI_ONLY(JVMCI::oops_do(adjust_pointer_closure());)
ref_processor()->weak_oops_do(adjust_pointer_closure());
PSScavenge::reference_processor()->weak_oops_do(adjust_pointer_closure());

View File

@ -77,6 +77,9 @@
#include "utilities/formatBuffer.hpp"
#include "utilities/macros.hpp"
#include "utilities/stack.inline.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
#include <math.h>
@ -2123,6 +2126,7 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::class_loader_data));
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
JVMCI_ONLY(q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmci));)
if (active_gc_threads > 1) {
for (uint j = 0; j < active_gc_threads; j++) {
@ -2176,6 +2180,9 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
// Prune dead klasses from subklass/sibling/implementor lists.
Klass::clean_weak_klass_links(purged_class);
// Clean JVMCI metadata handles.
JVMCI_ONLY(JVMCI::do_unloading(purged_class));
}
_gc_tracer.report_object_count_after_gc(is_alive_closure());
@ -2207,7 +2214,10 @@ void PSParallelCompact::adjust_roots(ParCompactionManager* cm) {
CodeBlobToOopClosure adjust_from_blobs(&oop_closure, CodeBlobToOopClosure::FixRelocations);
CodeCache::blobs_do(&adjust_from_blobs);
AOTLoader::oops_do(&oop_closure);
AOT_ONLY(AOTLoader::oops_do(&oop_closure);)
JVMCI_ONLY(JVMCI::oops_do(&oop_closure);)
ref_processor()->weak_oops_do(&oop_closure);
// Roots were visited so references into the young gen in roots
// may have been scanned. Process them also.

View File

@ -379,6 +379,7 @@ bool PSScavenge::invoke_no_policy() {
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::class_loader_data));
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
JVMCI_ONLY(q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmci));)
TaskTerminator terminator(active_workers,
(TaskQueueSetSuper*) promotion_manager->stack_array_depth());

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -44,6 +44,9 @@
#include "runtime/thread.hpp"
#include "runtime/vmThread.hpp"
#include "services/management.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
//
// ScavengeRootsTask
@ -95,7 +98,6 @@ void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
JvmtiExport::oops_do(&roots_closure);
break;
case code_cache:
{
MarkingCodeBlobClosure code_closure(&roots_to_old_closure, CodeBlobToOopClosure::FixRelocations);
@ -104,6 +106,12 @@ void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
}
break;
#if INCLUDE_JVMCI
case jvmci:
JVMCI::oops_do(&roots_closure);
break;
#endif
default:
fatal("Unknown root type");
}

View File

@ -61,6 +61,7 @@ class ScavengeRootsTask : public GCTask {
management = 7,
jvmti = 8,
code_cache = 9
JVMCI_ONLY(COMMA jvmci = 10)
};
private:
RootType _root_type;

View File

@ -56,6 +56,9 @@
#include "utilities/copy.hpp"
#include "utilities/events.hpp"
#include "utilities/stack.inline.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
void GenMarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, bool clear_all_softrefs) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
@ -233,6 +236,9 @@ void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
// Prune dead klasses from subklass/sibling/implementor lists.
Klass::clean_weak_klass_links(purged_class);
// Clean JVMCI metadata handles.
JVMCI_ONLY(JVMCI::do_unloading(purged_class));
}
gc_tracer()->report_object_count_after_gc(&is_alive);

View File

@ -69,6 +69,9 @@
#include "utilities/macros.hpp"
#include "utilities/stack.inline.hpp"
#include "utilities/vmError.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy,
Generation::Name young,
@ -857,10 +860,16 @@ void GenCollectedHeap::process_roots(StrongRootsScope* scope,
if (_process_strong_tasks->try_claim_task(GCH_PS_jvmti_oops_do)) {
JvmtiExport::oops_do(strong_roots);
}
#if INCLUDE_AOT
if (UseAOT && _process_strong_tasks->try_claim_task(GCH_PS_aot_oops_do)) {
AOTLoader::oops_do(strong_roots);
}
#endif
#if INCLUDE_JVMCI
if (EnableJVMCI && _process_strong_tasks->try_claim_task(GCH_PS_jvmci_oops_do)) {
JVMCI::oops_do(strong_roots);
}
#endif
if (_process_strong_tasks->try_claim_task(GCH_PS_SystemDictionary_oops_do)) {
SystemDictionary::oops_do(strong_roots);
}

View File

@ -117,7 +117,8 @@ protected:
GCH_PS_ClassLoaderDataGraph_oops_do,
GCH_PS_jvmti_oops_do,
GCH_PS_CodeCache_oops_do,
GCH_PS_aot_oops_do,
AOT_ONLY(GCH_PS_aot_oops_do COMMA)
JVMCI_ONLY(GCH_PS_jvmci_oops_do COMMA)
GCH_PS_younger_gens,
// Leave this one last.
GCH_PS_NumElements

View File

@ -30,6 +30,9 @@
#include "logging/log.hpp"
#include "memory/resourceArea.hpp"
#include "logging/log.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
StringDedupCleaningTask::StringDedupCleaningTask(BoolObjectClosure* is_alive,
OopClosure* keep_alive,
@ -158,6 +161,27 @@ void KlassCleaningTask::work() {
}
}
#if INCLUDE_JVMCI
JVMCICleaningTask::JVMCICleaningTask() :
_cleaning_claimed(0) {
}
bool JVMCICleaningTask::claim_cleaning_task() {
if (_cleaning_claimed) {
return false;
}
return Atomic::cmpxchg(1, &_cleaning_claimed, 0) == 0;
}
void JVMCICleaningTask::work(bool unloading_occurred) {
// One worker will clean JVMCI metadata handles.
if (unloading_occurred && EnableJVMCI && claim_cleaning_task()) {
JVMCI::do_unloading(unloading_occurred);
}
}
#endif // INCLUDE_JVMCI
ParallelCleaningTask::ParallelCleaningTask(BoolObjectClosure* is_alive,
uint num_workers,
bool unloading_occurred,
@ -166,11 +190,16 @@ ParallelCleaningTask::ParallelCleaningTask(BoolObjectClosure* is_alive,
_unloading_occurred(unloading_occurred),
_string_dedup_task(is_alive, NULL, resize_dedup_table),
_code_cache_task(num_workers, is_alive, unloading_occurred),
JVMCI_ONLY(_jvmci_cleaning_task() COMMA)
_klass_cleaning_task() {
}
// The parallel work done by all worker threads.
void ParallelCleaningTask::work(uint worker_id) {
// Clean JVMCI metadata handles.
// Execute this task first because it is serial task.
JVMCI_ONLY(_jvmci_cleaning_task.work(_unloading_occurred);)
// Do first pass of code cache cleaning.
_code_cache_task.work(worker_id);

View File

@ -87,6 +87,20 @@ public:
void work();
};
#if INCLUDE_JVMCI
class JVMCICleaningTask : public StackObj {
volatile int _cleaning_claimed;
public:
JVMCICleaningTask();
// Clean JVMCI metadata handles.
void work(bool unloading_occurred);
private:
bool claim_cleaning_task();
};
#endif
// Do cleanup of some weakly held data in the same parallel task.
// Assumes a non-moving context.
class ParallelCleaningTask : public AbstractGangTask {
@ -94,6 +108,9 @@ private:
bool _unloading_occurred;
StringDedupCleaningTask _string_dedup_task;
CodeCacheUnloadingTask _code_cache_task;
#if INCLUDE_JVMCI
JVMCICleaningTask _jvmci_cleaning_task;
#endif
KlassCleaningTask _klass_cleaning_task;
public:

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -40,6 +40,9 @@
#include "runtime/thread.hpp"
#include "services/management.hpp"
#include "utilities/align.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
RootSetClosure::RootSetClosure(EdgeQueue* edge_queue) :
_edge_queue(edge_queue) {
@ -104,4 +107,5 @@ void RootSetClosure::process_roots(OopClosure* closure) {
Management::oops_do(closure);
StringTable::oops_do(closure);
AOTLoader::oops_do(closure);
JVMCI_ONLY(JVMCI::oops_do(closure);)
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -40,6 +40,9 @@
#include "runtime/vframe_hp.hpp"
#include "services/management.hpp"
#include "utilities/growableArray.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
class ReferenceLocateClosure : public OopClosure {
protected:
@ -102,6 +105,7 @@ class ReferenceToRootClosure : public StackObj {
bool do_management_roots();
bool do_string_table_roots();
bool do_aot_loader_roots();
JVMCI_ONLY(bool do_jvmci_roots();)
bool do_roots();
@ -188,6 +192,15 @@ bool ReferenceToRootClosure::do_aot_loader_roots() {
return rcl.complete();
}
#if INCLUDE_JVMCI
bool ReferenceToRootClosure::do_jvmci_roots() {
assert(!complete(), "invariant");
ReferenceLocateClosure rcl(_callback, OldObjectRoot::_jvmci, OldObjectRoot::_type_undetermined, NULL);
JVMCI::oops_do(&rcl);
return rcl.complete();
}
#endif
bool ReferenceToRootClosure::do_roots() {
assert(!complete(), "invariant");
assert(OldObjectRoot::_system_undetermined == _info._system, "invariant");
@ -238,6 +251,13 @@ bool ReferenceToRootClosure::do_roots() {
return true;
}
#if INCLUDE_JVMCI
if (do_jvmci_roots()) {
_complete = true;
return true;
}
#endif
return false;
}

View File

@ -43,6 +43,7 @@ class OldObjectRoot : public AllStatic {
_code_cache,
_string_table,
_aot,
JVMCI_ONLY(_jvmci COMMA)
_number_of_systems
};
@ -81,6 +82,10 @@ class OldObjectRoot : public AllStatic {
return "String Table";
case _aot:
return "AOT";
#if INCLUDE_JVMCI
case _jvmci:
return "JVMCI";
#endif
default:
ShouldNotReachHere();
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_JVMCI_JNIACCESSMARK_INLINE_HPP
#define SHARE_JVMCI_JNIACCESSMARK_INLINE_HPP
#include "jvmci/jvmciEnv.hpp"
#include "runtime/interfaceSupport.inline.hpp"
// Wrapper for a JNI call into the JVMCI shared library.
// This performs a ThreadToNativeFromVM transition so that the VM
// will not be blocked if the call takes a long time (e.g., due
// to a GC in the shared library).
class JNIAccessMark : public StackObj {
private:
ThreadToNativeFromVM ttnfv;
HandleMark hm;
JNIEnv* _env;
public:
inline JNIAccessMark(JVMCIEnv* jvmci_env) :
ttnfv(JavaThread::current()), hm(JavaThread::current()) {
_env = jvmci_env->_env;
}
JNIEnv* env() const { return _env; }
JNIEnv* operator () () const { return _env; }
};
#endif // SHARE_JVMCI_JNIACCESSMARK_INLINE_HPP

View File

@ -0,0 +1,151 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "gc/shared/oopStorage.inline.hpp"
#include "jvmci/jvmci.hpp"
#include "jvmci/jvmci_globals.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/metadataHandleBlock.hpp"
OopStorage* JVMCI::_object_handles = NULL;
MetadataHandleBlock* JVMCI::_metadata_handles = NULL;
JVMCIRuntime* JVMCI::_compiler_runtime = NULL;
JVMCIRuntime* JVMCI::_java_runtime = NULL;
bool JVMCI::can_initialize_JVMCI() {
// Initializing JVMCI requires the module system to be initialized past phase 3.
// The JVMCI API itself isn't available until phase 2 and ServiceLoader (which
// JVMCI initialization requires) isn't usable until after phase 3. Testing
// whether the system loader is initialized satisfies all these invariants.
if (SystemDictionary::java_system_loader() == NULL) {
return false;
}
assert(Universe::is_module_initialized(), "must be");
return true;
}
void JVMCI::initialize_compiler(TRAPS) {
if (JVMCILibDumpJNIConfig) {
JNIJVMCI::initialize_ids(NULL);
ShouldNotReachHere();
}
JVMCI::compiler_runtime()->call_getCompiler(CHECK);
}
void JVMCI::initialize_globals() {
_object_handles = new OopStorage("JVMCI Global Oop Handles",
JVMCIGlobalAlloc_lock,
JVMCIGlobalActive_lock);
_metadata_handles = MetadataHandleBlock::allocate_block();
if (UseJVMCINativeLibrary) {
// There are two runtimes.
_compiler_runtime = new JVMCIRuntime();
_java_runtime = new JVMCIRuntime();
} else {
// There is only a single runtime
_java_runtime = _compiler_runtime = new JVMCIRuntime();
}
}
OopStorage* JVMCI::object_handles() {
assert(_object_handles != NULL, "Uninitialized");
return _object_handles;
}
jobject JVMCI::make_global(const Handle& obj) {
assert(!Universe::heap()->is_gc_active(), "can't extend the root set during GC");
assert(oopDesc::is_oop(obj()), "not an oop");
oop* ptr = object_handles()->allocate();
jobject res = NULL;
if (ptr != NULL) {
assert(*ptr == NULL, "invariant");
NativeAccess<>::oop_store(ptr, obj());
res = reinterpret_cast<jobject>(ptr);
} else {
vm_exit_out_of_memory(sizeof(oop), OOM_MALLOC_ERROR,
"Cannot create JVMCI oop handle");
}
return res;
}
bool JVMCI::is_global_handle(jobject handle) {
const oop* ptr = reinterpret_cast<oop*>(handle);
return object_handles()->allocation_status(ptr) == OopStorage::ALLOCATED_ENTRY;
}
jmetadata JVMCI::allocate_handle(const methodHandle& handle) {
assert(_metadata_handles != NULL, "uninitialized");
MutexLocker ml(JVMCI_lock);
return _metadata_handles->allocate_handle(handle);
}
jmetadata JVMCI::allocate_handle(const constantPoolHandle& handle) {
assert(_metadata_handles != NULL, "uninitialized");
MutexLocker ml(JVMCI_lock);
return _metadata_handles->allocate_handle(handle);
}
void JVMCI::release_handle(jmetadata handle) {
MutexLocker ml(JVMCI_lock);
_metadata_handles->chain_free_list(handle);
}
void JVMCI::oops_do(OopClosure* f) {
if (_object_handles != NULL) {
_object_handles->oops_do(f);
}
}
void JVMCI::metadata_do(void f(Metadata*)) {
if (_metadata_handles != NULL) {
_metadata_handles->metadata_do(f);
}
}
void JVMCI::do_unloading(bool unloading_occurred) {
if (_metadata_handles != NULL && unloading_occurred) {
_metadata_handles->do_unloading();
}
}
bool JVMCI::is_compiler_initialized() {
return compiler_runtime()->is_HotSpotJVMCIRuntime_initialized();
}
void JVMCI::shutdown() {
if (compiler_runtime() != NULL) {
compiler_runtime()->shutdown();
}
}
bool JVMCI::shutdown_called() {
if (compiler_runtime() != NULL) {
return compiler_runtime()->shutdown_called();
}
return false;
}

View File

@ -0,0 +1,106 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef SHARE_JVMCI_JVMCI_HPP
#define SHARE_JVMCI_JVMCI_HPP
#include "compiler/compilerDefinitions.hpp"
#include "utilities/exceptions.hpp"
class BoolObjectClosure;
class constantPoolHandle;
class JavaThread;
class JVMCIEnv;
class JVMCIRuntime;
class Metadata;
class MetadataHandleBlock;
class OopClosure;
class OopStorage;
struct _jmetadata;
typedef struct _jmetadata *jmetadata;
class JVMCI : public AllStatic {
friend class JVMCIRuntime;
friend class JVMCIEnv;
private:
// Handles to objects in the HotSpot heap.
static OopStorage* _object_handles;
static OopStorage* object_handles();
// Handles to Metadata objects.
static MetadataHandleBlock* _metadata_handles;
// Access to the HotSpotJVMCIRuntime used by the CompileBroker.
static JVMCIRuntime* _compiler_runtime;
// Access to the HotSpotJVMCIRuntime used by Java code running on the
// HotSpot heap. It will be the same as _compiler_runtime if
// UseJVMCINativeLibrary is false
static JVMCIRuntime* _java_runtime;
public:
enum CodeInstallResult {
ok,
dependencies_failed,
dependencies_invalid,
cache_full,
code_too_large
};
static void do_unloading(bool unloading_occurred);
static void metadata_do(void f(Metadata*));
static void oops_do(OopClosure* f);
static void shutdown();
static bool shutdown_called();
static bool is_compiler_initialized();
/**
* Determines if the VM is sufficiently booted to initialize JVMCI.
*/
static bool can_initialize_JVMCI();
static void initialize_globals();
static void initialize_compiler(TRAPS);
static jobject make_global(const Handle& obj);
static bool is_global_handle(jobject handle);
static jmetadata allocate_handle(const methodHandle& handle);
static jmetadata allocate_handle(const constantPoolHandle& handle);
static void release_handle(jmetadata handle);
static JVMCIRuntime* compiler_runtime() { return _compiler_runtime; }
static JVMCIRuntime* java_runtime() { return _java_runtime; }
};
#endif // SHARE_JVMCI_JVMCI_HPP

File diff suppressed because it is too large Load Diff

View File

@ -24,9 +24,11 @@
#ifndef SHARE_JVMCI_JVMCICODEINSTALLER_HPP
#define SHARE_JVMCI_JVMCICODEINSTALLER_HPP
#include "jvmci/jvmciCompiler.hpp"
#include "jvmci/jvmciEnv.hpp"
#include "code/debugInfoRec.hpp"
#include "code/exceptionHandlerTable.hpp"
#include "code/nativeInst.hpp"
#include "jvmci/jvmci.hpp"
#include "jvmci/jvmciEnv.hpp"
#if INCLUDE_AOT
class RelocBuffer : public StackObj {
@ -44,9 +46,11 @@ private:
char *_buffer;
};
class CodeInstaller;
class AOTOopRecorder : public OopRecorder {
public:
AOTOopRecorder(Arena* arena = NULL, bool deduplicate = false);
AOTOopRecorder(CodeInstaller* code_inst, Arena* arena = NULL, bool deduplicate = false);
virtual int find_index(Metadata* h);
virtual int find_index(jobject h);
@ -57,7 +61,10 @@ private:
void record_meta_ref(jobject ref, int index);
GrowableArray<jobject>* _meta_refs;
CodeInstaller* _code_inst;
};
#endif // INCLUDE_AOT
class CodeMetadata {
public:
@ -71,9 +78,10 @@ public:
u_char* get_scopes_desc() const { return _scopes_desc; }
int get_scopes_size() const { return _nr_scopes_desc; }
#if INCLUDE_AOT
RelocBuffer* get_reloc_buffer() { return &_reloc_buffer; }
AOTOopRecorder* get_oop_recorder() { return _oop_recorder; }
#endif
ExceptionHandlerTable* get_exception_table() { return _exception_table; }
@ -87,9 +95,11 @@ public:
_nr_scopes_desc = size;
}
#if INCLUDE_AOT
void set_oop_recorder(AOTOopRecorder* recorder) {
_oop_recorder = recorder;
}
#endif
void set_exception_table(ExceptionHandlerTable* table) {
_exception_table = table;
@ -103,11 +113,12 @@ private:
u_char* _scopes_desc;
int _nr_scopes_desc;
#if INCLUDE_AOT
RelocBuffer _reloc_buffer;
AOTOopRecorder* _oop_recorder;
#endif
ExceptionHandlerTable* _exception_table;
};
#endif // INCLUDE_AOT
/*
* This class handles the conversion from a InstalledCode to a CodeBlob or an nmethod.
@ -143,24 +154,26 @@ private:
};
Arena _arena;
JVMCIEnv* _jvmci_env;
JVMCIPrimitiveArray _data_section_handle;
JVMCIObjectArray _data_section_patches_handle;
JVMCIObjectArray _sites_handle;
#ifndef PRODUCT
JVMCIObjectArray _comments_handle;
#endif
JVMCIPrimitiveArray _code_handle;
JVMCIObject _word_kind_handle;
jobject _data_section_handle;
jobject _data_section_patches_handle;
jobject _sites_handle;
CodeOffsets _offsets;
jobject _code_handle;
jint _code_size;
jint _total_frame_size;
jint _orig_pc_offset;
jint _parameter_count;
jint _constants_size;
#ifndef PRODUCT
jobject _comments_handle;
#endif
bool _has_wide_vector;
jobject _word_kind_handle;
MarkId _next_call_type;
address _invoke_mark_pc;
@ -182,72 +195,84 @@ private:
static ConstantIntValue* _int_2_scope_value;
static LocationValue* _illegal_value;
jint pd_next_offset(NativeInstruction* inst, jint pc_offset, Handle method, TRAPS);
void pd_patch_OopConstant(int pc_offset, Handle constant, TRAPS);
void pd_patch_MetaspaceConstant(int pc_offset, Handle constant, TRAPS);
void pd_patch_DataSectionReference(int pc_offset, int data_offset, TRAPS);
void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, TRAPS);
void pd_relocate_JavaMethod(CodeBuffer &cbuf, Handle method, jint pc_offset, TRAPS);
void pd_relocate_poll(address pc, jint mark, TRAPS);
jint pd_next_offset(NativeInstruction* inst, jint pc_offset, JVMCIObject method, JVMCI_TRAPS);
void pd_patch_OopConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS);
void pd_patch_MetaspaceConstant(int pc_offset, JVMCIObject constant, JVMCI_TRAPS);
void pd_patch_DataSectionReference(int pc_offset, int data_offset, JVMCI_TRAPS);
void pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination, JVMCI_TRAPS);
void pd_relocate_JavaMethod(CodeBuffer &cbuf, JVMCIObject method, jint pc_offset, JVMCI_TRAPS);
void pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS);
objArrayOop sites();
arrayOop code();
arrayOop data_section();
objArrayOop data_section_patches();
JVMCIObjectArray sites() { return _sites_handle; }
JVMCIPrimitiveArray code() { return _code_handle; }
JVMCIPrimitiveArray data_section() { return _data_section_handle; }
JVMCIObjectArray data_section_patches() { return _data_section_patches_handle; }
#ifndef PRODUCT
objArrayOop comments();
JVMCIObjectArray comments() { return _comments_handle; }
#endif
oop word_kind();
JVMCIObject word_kind() { return _word_kind_handle; }
public:
CodeInstaller(bool immutable_pic_compilation) : _arena(mtCompiler), _immutable_pic_compilation(immutable_pic_compilation) {}
CodeInstaller(JVMCIEnv* jvmci_env, bool immutable_pic_compilation) : _arena(mtJVMCI), _jvmci_env(jvmci_env), _immutable_pic_compilation(immutable_pic_compilation) {}
#if INCLUDE_AOT
JVMCIEnv::CodeInstallResult gather_metadata(Handle target, Handle compiled_code, CodeMetadata& metadata, TRAPS);
JVMCI::CodeInstallResult gather_metadata(JVMCIObject target, JVMCIObject compiled_code, CodeMetadata& metadata, JVMCI_TRAPS);
#endif
JVMCIEnv::CodeInstallResult install(JVMCICompiler* compiler, Handle target, Handle compiled_code, CodeBlob*& cb, Handle installed_code, Handle speculation_log, TRAPS);
JVMCI::CodeInstallResult install(JVMCICompiler* compiler,
JVMCIObject target,
JVMCIObject compiled_code,
CodeBlob*& cb,
JVMCIObject installed_code,
FailedSpeculation** failed_speculations,
char* speculations,
int speculations_len,
JVMCI_TRAPS);
JVMCIEnv* jvmci_env() { return _jvmci_env; }
JVMCIRuntime* runtime() { return _jvmci_env->runtime(); }
static address runtime_call_target_address(oop runtime_call);
static VMReg get_hotspot_reg(jint jvmciRegisterNumber, TRAPS);
static VMReg get_hotspot_reg(jint jvmciRegisterNumber, JVMCI_TRAPS);
static bool is_general_purpose_reg(VMReg hotspotRegister);
const OopMapSet* oopMapSet() const { return _debug_recorder->_oopmaps; }
protected:
Location::Type get_oop_type(Thread* thread, Handle value);
ScopeValue* get_scope_value(Handle value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, TRAPS);
MonitorValue* get_monitor_value(Handle value, GrowableArray<ScopeValue*>* objects, TRAPS);
Location::Type get_oop_type(JVMCIObject value);
ScopeValue* get_scope_value(JVMCIObject value, BasicType type, GrowableArray<ScopeValue*>* objects, ScopeValue* &second, JVMCI_TRAPS);
MonitorValue* get_monitor_value(JVMCIObject value, GrowableArray<ScopeValue*>* objects, JVMCI_TRAPS);
void* record_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS);
void* record_metadata_reference(CodeSection* section, address dest, JVMCIObject constant, JVMCI_TRAPS);
#ifdef _LP64
narrowKlass record_narrow_metadata_reference(CodeSection* section, address dest, Handle constant, TRAPS);
narrowKlass record_narrow_metadata_reference(CodeSection* section, address dest, JVMCIObject constant, JVMCI_TRAPS);
#endif
// extract the fields of the HotSpotCompiledCode
void initialize_fields(oop target, oop target_method, TRAPS);
void initialize_dependencies(oop target_method, OopRecorder* oop_recorder, TRAPS);
void initialize_fields(JVMCIObject target, JVMCIObject compiled_code, JVMCI_TRAPS);
void initialize_dependencies(JVMCIObject compiled_code, OopRecorder* oop_recorder, JVMCI_TRAPS);
int estimate_stubs_size(TRAPS);
int estimate_stubs_size(JVMCI_TRAPS);
// perform data and call relocation on the CodeBuffer
JVMCIEnv::CodeInstallResult initialize_buffer(CodeBuffer& buffer, bool check_size, TRAPS);
JVMCI::CodeInstallResult initialize_buffer(CodeBuffer& buffer, bool check_size, JVMCI_TRAPS);
void assumption_NoFinalizableSubclass(Thread* thread, Handle assumption);
void assumption_ConcreteSubtype(Thread* thread, Handle assumption);
void assumption_LeafType(Thread* thread, Handle assumption);
void assumption_ConcreteMethod(Thread* thread, Handle assumption);
void assumption_CallSiteTargetValue(Thread* thread, Handle assumption);
void assumption_NoFinalizableSubclass(JVMCIObject assumption);
void assumption_ConcreteSubtype(JVMCIObject assumption);
void assumption_LeafType(JVMCIObject assumption);
void assumption_ConcreteMethod(JVMCIObject assumption);
void assumption_CallSiteTargetValue(JVMCIObject assumption, JVMCI_TRAPS);
void site_Safepoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS);
void site_Infopoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS);
void site_Call(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS);
void site_DataPatch(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS);
void site_Mark(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS);
void site_ExceptionHandler(jint pc_offset, Handle site);
void site_Safepoint(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS);
void site_Infopoint(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS);
void site_Call(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS);
void site_DataPatch(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS);
void site_Mark(CodeBuffer& buffer, jint pc_offset, JVMCIObject site, JVMCI_TRAPS);
void site_ExceptionHandler(jint pc_offset, JVMCIObject site);
OopMap* create_oop_map(Handle debug_info, TRAPS);
OopMap* create_oop_map(JVMCIObject debug_info, JVMCI_TRAPS);
VMReg getVMRegFromLocation(JVMCIObject location, int total_frame_size, JVMCI_TRAPS);
/**
* Specifies the level of detail to record for a scope.
@ -260,23 +285,17 @@ protected:
};
int map_jvmci_bci(int bci);
void record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, bool return_oop, TRAPS);
void record_scope(jint pc_offset, Handle debug_info, ScopeMode scope_mode, TRAPS) {
record_scope(pc_offset, debug_info, scope_mode, false /* return_oop */, THREAD);
}
void record_scope(jint pc_offset, Handle position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, bool return_oop, TRAPS);
void record_object_value(ObjectValue* sv, Handle value, GrowableArray<ScopeValue*>* objects, TRAPS);
GrowableArray<ScopeValue*>* record_virtual_objects(Handle debug_info, TRAPS);
void record_scope(jint pc_offset, JVMCIObject debug_info, ScopeMode scope_mode, bool return_oop, JVMCI_TRAPS);
void record_scope(jint pc_offset, JVMCIObject debug_info, ScopeMode scope_mode, JVMCI_TRAPS) {
record_scope(pc_offset, debug_info, scope_mode, false /* return_oop */, JVMCIENV);
}
void record_scope(jint pc_offset, JVMCIObject position, ScopeMode scope_mode, GrowableArray<ScopeValue*>* objects, bool return_oop, JVMCI_TRAPS);
void record_object_value(ObjectValue* sv, JVMCIObject value, GrowableArray<ScopeValue*>* objects, JVMCI_TRAPS);
GrowableArray<ScopeValue*>* record_virtual_objects(JVMCIObject debug_info, JVMCI_TRAPS);
int estimateStubSpace(int static_call_stubs);
};
/**
* Gets the Method metaspace object from a HotSpotResolvedJavaMethodImpl Java object.
*/
Method* getMethodFromHotSpotMethod(oop hotspot_method);
#endif // SHARE_JVMCI_JVMCICODEINSTALLER_HPP

View File

@ -22,19 +22,10 @@
*/
#include "precompiled.hpp"
#include "jvm.h"
#include "compiler/compileBroker.hpp"
#include "classfile/moduleEntry.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/handles.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "jvmci/jvmciCompiler.hpp"
#include "jvmci/jvmciEnv.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "runtime/compilationPolicy.hpp"
#include "runtime/globals_extension.hpp"
#include "runtime/handles.inline.hpp"
JVMCICompiler* JVMCICompiler::_instance = NULL;
@ -104,112 +95,39 @@ void JVMCICompiler::bootstrap(TRAPS) {
tty->print_cr(" in " JLONG_FORMAT " ms (compiled %d methods)", os::javaTimeMillis() - start, _methods_compiled);
}
_bootstrapping = false;
JVMCIRuntime::bootstrap_finished(CHECK);
JVMCI::compiler_runtime()->bootstrap_finished(CHECK);
}
#define CHECK_EXIT THREAD); \
if (HAS_PENDING_EXCEPTION) { \
char buf[256]; \
jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
JVMCICompiler::exit_on_pending_exception(PENDING_EXCEPTION, buf); \
return; \
} \
(void)(0
void JVMCICompiler::compile_method(const methodHandle& method, int entry_bci, JVMCIEnv* env) {
JVMCI_EXCEPTION_CONTEXT
bool is_osr = entry_bci != InvocationEntryBci;
if (_bootstrapping && is_osr) {
// no OSR compilations during bootstrap - the compiler is just too slow at this point,
// and we know that there are no endless loops
env->set_failure(true, "No OSR during boostrap");
return;
bool JVMCICompiler::force_comp_at_level_simple(Method *method) {
if (UseJVMCINativeLibrary) {
// This mechanism exists to force compilation of a JVMCI compiler by C1
// to reduces the compilation time spent on the JVMCI compiler itself. In
// +UseJVMCINativeLibrary mode, the JVMCI compiler is AOT compiled.
return false;
}
JVMCIRuntime::initialize_well_known_classes(CHECK_EXIT);
HandleMark hm;
Handle receiver = JVMCIRuntime::get_HotSpotJVMCIRuntime(CHECK_EXIT);
JavaValue method_result(T_OBJECT);
JavaCallArguments args;
args.push_long((jlong) (address) method());
JavaCalls::call_static(&method_result, SystemDictionary::HotSpotResolvedJavaMethodImpl_klass(),
vmSymbols::fromMetaspace_name(), vmSymbols::method_fromMetaspace_signature(), &args, THREAD);
JavaValue result(T_OBJECT);
if (!HAS_PENDING_EXCEPTION) {
JavaCallArguments args;
args.push_oop(receiver);
args.push_oop(Handle(THREAD, (oop)method_result.get_jobject()));
args.push_int(entry_bci);
args.push_long((jlong) (address) env);
args.push_int(env->task()->compile_id());
JavaCalls::call_special(&result, receiver->klass(),
vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD);
if (_bootstrapping) {
// When bootstrapping, the JVMCI compiler can compile its own methods.
return false;
}
// An uncaught exception was thrown during compilation. Generally these
// should be handled by the Java code in some useful way but if they leak
// through to here report them instead of dying or silently ignoring them.
if (HAS_PENDING_EXCEPTION) {
Handle exception(THREAD, PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
java_lang_Throwable::java_printStackTrace(exception, THREAD);
if (HAS_PENDING_EXCEPTION) {
CLEAR_PENDING_EXCEPTION;
}
env->set_failure(false, "unexpected exception thrown");
} else {
oop result_object = (oop) result.get_jobject();
if (result_object != NULL) {
oop failure_message = HotSpotCompilationRequestResult::failureMessage(result_object);
if (failure_message != NULL) {
// Copy failure reason into resource memory first ...
const char* failure_reason = java_lang_String::as_utf8_string(failure_message);
// ... and then into the C heap.
failure_reason = os::strdup(failure_reason, mtCompiler);
bool retryable = HotSpotCompilationRequestResult::retry(result_object) != 0;
env->set_failure(retryable, failure_reason, true);
} else {
if (env->task()->code() == NULL) {
env->set_failure(true, "no nmethod produced");
} else {
env->task()->set_num_inlined_bytecodes(HotSpotCompilationRequestResult::inlinedBytecodes(result_object));
Atomic::inc(&_methods_compiled);
JVMCIRuntime* runtime = JVMCI::compiler_runtime();
if (runtime != NULL && runtime->is_HotSpotJVMCIRuntime_initialized()) {
JavaThread* thread = JavaThread::current();
HandleMark hm(thread);
THREAD_JVMCIENV(thread);
JVMCIObject receiver = runtime->get_HotSpotJVMCIRuntime(JVMCIENV);
objArrayHandle excludeModules(thread, HotSpotJVMCI::HotSpotJVMCIRuntime::excludeFromJVMCICompilation(JVMCIENV, HotSpotJVMCI::resolve(receiver)));
if (excludeModules.not_null()) {
ModuleEntry* moduleEntry = method->method_holder()->module();
for (int i = 0; i < excludeModules->length(); i++) {
if (oopDesc::equals(excludeModules->obj_at(i), moduleEntry->module())) {
return true;
}
}
} else {
assert(false, "JVMCICompiler.compileMethod should always return non-null");
}
}
if (_bootstrapping) {
_bootstrap_compilation_request_handled = true;
}
}
void JVMCICompiler::exit_on_pending_exception(oop exception, const char* message) {
JavaThread* THREAD = JavaThread::current();
CLEAR_PENDING_EXCEPTION;
static volatile int report_error = 0;
if (!report_error && Atomic::cmpxchg(1, &report_error, 0) == 0) {
// Only report an error once
tty->print_raw_cr(message);
Handle ex(THREAD, exception);
java_lang_Throwable::java_printStackTrace(ex, THREAD);
} else {
// Allow error reporting thread to print the stack trace. Windows
// doesn't allow uninterruptible wait for JavaThreads
const bool interruptible = true;
os::sleep(THREAD, 200, interruptible);
}
before_exit(THREAD);
vm_exit(-1);
return false;
}
// Compilation entry point for methods
@ -227,33 +145,3 @@ void JVMCICompiler::print_compilation_timers() {
TRACE_jvmci_1("JVMCICompiler::print_timers");
tty->print_cr(" JVMCI code install time: %6.3f s", _codeInstallTimer.seconds());
}
bool JVMCICompiler::force_comp_at_level_simple(Method *method) {
JVMCI_EXCEPTION_CONTEXT
if (_bootstrapping) {
// When bootstrapping, the JVMCI compiler can compile its own methods.
return false;
}
if (!JVMCIRuntime::is_HotSpotJVMCIRuntime_initialized()) {
// JVMCI cannot participate in compilation scheduling until
// JVMCI is initialized and indicates it wants to participate.
return false;
}
// Support for graal.CompileGraalWithC1Only
HandleMark hm(thread);
jobject runtime = JVMCIRuntime::get_HotSpotJVMCIRuntime_jobject(CATCH);
objArrayHandle excludeFromJVMCICompilation(thread, HotSpotJVMCIRuntime::excludeFromJVMCICompilation(runtime));
if (excludeFromJVMCICompilation.is_null()) {
return false;
}
ModuleEntry *module = method->method_holder()->module();
for (int i = 0; i < excludeFromJVMCICompilation->length(); ++i) {
if (module->module() == excludeFromJVMCICompilation->obj_at(i)) {
return true;
}
}
return false;
}

View File

@ -25,8 +25,6 @@
#define SHARE_JVMCI_JVMCICOMPILER_HPP
#include "compiler/abstractCompiler.hpp"
#include "jvmci/jvmciEnv.hpp"
#include "utilities/exceptions.hpp"
class JVMCICompiler : public AbstractCompiler {
private:
@ -65,7 +63,7 @@ public:
return _instance;
}
virtual const char* name() { return "JVMCI"; }
virtual const char* name() { return UseJVMCINativeLibrary ? "JVMCI-native" : "JVMCI"; }
virtual bool supports_native() { return true; }
virtual bool supports_osr () { return true; }
@ -90,11 +88,13 @@ public:
bool is_bootstrapping() const { return _bootstrapping; }
void set_bootstrap_compilation_request_handled() {
_instance->_bootstrap_compilation_request_handled = true;
}
// Compilation entry point for methods
virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci, DirectiveSet* directive);
void compile_method(const methodHandle& target, int entry_bci, JVMCIEnv* env);
// Print compilation timers and statistics
virtual void print_timers();
@ -104,6 +104,10 @@ public:
*/
int methods_compiled() { return _methods_compiled; }
void inc_methods_compiled() {
Atomic::inc(&_methods_compiled);
}
// Print compilation timers and statistics
static void print_compilation_timers();

File diff suppressed because it is too large Load Diff

View File

@ -24,40 +24,12 @@
#ifndef SHARE_JVMCI_JVMCICOMPILERTOVM_HPP
#define SHARE_JVMCI_JVMCICOMPILERTOVM_HPP
#include "jni.h"
#include "gc/shared/cardTable.hpp"
#include "jvmci/jvmciExceptions.hpp"
#include "runtime/javaCalls.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "runtime/signature.hpp"
// Helper class to ensure that references to Klass* are kept alive for G1
class JVMCIKlassHandle : public StackObj {
private:
Klass* _klass;
Handle _holder;
Thread* _thread;
Klass* klass() const { return _klass; }
Klass* non_null_klass() const { assert(_klass != NULL, "resolving NULL _klass"); return _klass; }
public:
/* Constructors */
JVMCIKlassHandle (Thread* thread) : _klass(NULL), _thread(thread) {}
JVMCIKlassHandle (Thread* thread, Klass* klass);
JVMCIKlassHandle (const JVMCIKlassHandle &h): _klass(h._klass), _holder(h._holder), _thread(h._thread) {}
JVMCIKlassHandle& operator=(const JVMCIKlassHandle &s);
JVMCIKlassHandle& operator=(Klass* klass);
/* Operators for ease of use */
Klass* operator () () const { return klass(); }
Klass* operator -> () const { return non_null_klass(); }
bool operator == (Klass* o) const { return klass() == o; }
bool operator == (const JVMCIKlassHandle& h) const { return klass() == h.klass(); }
/* Null checks */
bool is_null() const { return _klass == NULL; }
bool not_null() const { return _klass != NULL; }
};
class JVMCIObjectArray;
class CompilerToVM {
public:
@ -118,7 +90,7 @@ class CompilerToVM {
static address symbol_clinit;
public:
static void initialize(TRAPS);
static void initialize(JVMCI_TRAPS);
static int max_oop_map_stack_offset() {
assert(_max_oop_map_stack_offset > 0, "must be initialized");
@ -141,60 +113,15 @@ class CompilerToVM {
}
static JNINativeMethod methods[];
static JNINativeMethod jni_methods[];
static objArrayHandle initialize_intrinsics(TRAPS);
static JVMCIObjectArray initialize_intrinsics(JVMCI_TRAPS);
public:
static int methods_count();
static inline Method* asMethod(jobject jvmci_method) {
return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
}
static inline Method* asMethod(Handle jvmci_method) {
return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
}
static inline Method* asMethod(oop jvmci_method) {
return (Method*) (address) HotSpotResolvedJavaMethodImpl::metaspaceMethod(jvmci_method);
}
static inline ConstantPool* asConstantPool(jobject jvmci_constant_pool) {
return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
}
static inline ConstantPool* asConstantPool(Handle jvmci_constant_pool) {
return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
}
static inline ConstantPool* asConstantPool(oop jvmci_constant_pool) {
return (ConstantPool*) (address) HotSpotConstantPool::metaspaceConstantPool(jvmci_constant_pool);
}
static inline Klass* asKlass(jobject jvmci_type) {
return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
}
static inline Klass* asKlass(Handle jvmci_type) {
return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
}
static inline Klass* asKlass(oop jvmci_type) {
return java_lang_Class::as_Klass(HotSpotResolvedObjectTypeImpl::javaClass(jvmci_type));
}
static inline Klass* asKlass(jlong metaspaceKlass) {
return (Klass*) (address) metaspaceKlass;
}
static inline MethodData* asMethodData(jlong metaspaceMethodData) {
return (MethodData*) (address) metaspaceMethodData;
}
static oop get_jvmci_method(const methodHandle& method, TRAPS);
static oop get_jvmci_type(JVMCIKlassHandle& klass, TRAPS);
};
class JavaArgumentUnboxer : public SignatureIterator {
protected:
JavaCallArguments* _jca;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -25,13 +25,10 @@
#include "ci/ciUtilities.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/cardTable.hpp"
#include "memory/oopFactory.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "jvmci/jvmciEnv.hpp"
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/vmStructs_jvmci.hpp"
#include "runtime/flags/jvmFlag.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "utilities/resourceHash.hpp"
@ -88,7 +85,7 @@ address CompilerToVM::Data::dpow;
address CompilerToVM::Data::symbol_init;
address CompilerToVM::Data::symbol_clinit;
void CompilerToVM::Data::initialize(TRAPS) {
void CompilerToVM::Data::initialize(JVMCI_TRAPS) {
Klass_vtable_start_offset = in_bytes(Klass::vtable_start_offset());
Klass_vtable_length_offset = in_bytes(Klass::vtable_length_offset());
@ -157,29 +154,23 @@ void CompilerToVM::Data::initialize(TRAPS) {
#undef SET_TRIGFUNC
}
objArrayHandle CompilerToVM::initialize_intrinsics(TRAPS) {
objArrayHandle vmIntrinsics = oopFactory::new_objArray_handle(VMIntrinsicMethod::klass(), (vmIntrinsics::ID_LIMIT - 1), CHECK_(objArrayHandle()));
JVMCIObjectArray CompilerToVM::initialize_intrinsics(JVMCI_TRAPS) {
JVMCIObjectArray vmIntrinsics = JVMCIENV->new_VMIntrinsicMethod_array(vmIntrinsics::ID_LIMIT - 1, JVMCI_CHECK_NULL);
int index = 0;
// The intrinsics for a class are usually adjacent to each other.
// When they are, the string for the class name can be reused.
vmSymbols::SID kls_sid = vmSymbols::NO_SID;
Handle kls_str;
JVMCIObject kls_str;
#define VM_SYMBOL_TO_STRING(s) \
java_lang_String::create_from_symbol(vmSymbols::symbol_at(vmSymbols::VM_SYMBOL_ENUM_NAME(s)), CHECK_(objArrayHandle()))
JVMCIENV->create_string(vmSymbols::symbol_at(vmSymbols::VM_SYMBOL_ENUM_NAME(s)), JVMCI_CHECK_NULL)
#define VM_INTRINSIC_INFO(id, kls, name, sig, ignore_fcode) { \
instanceHandle vmIntrinsicMethod = InstanceKlass::cast(VMIntrinsicMethod::klass())->allocate_instance_handle(CHECK_(objArrayHandle())); \
vmSymbols::SID sid = vmSymbols::VM_SYMBOL_ENUM_NAME(kls); \
if (kls_sid != sid) { \
kls_str = VM_SYMBOL_TO_STRING(kls); \
kls_sid = sid; \
} \
Handle name_str = VM_SYMBOL_TO_STRING(name); \
Handle sig_str = VM_SYMBOL_TO_STRING(sig); \
VMIntrinsicMethod::set_declaringClass(vmIntrinsicMethod, kls_str()); \
VMIntrinsicMethod::set_name(vmIntrinsicMethod, name_str()); \
VMIntrinsicMethod::set_descriptor(vmIntrinsicMethod, sig_str()); \
VMIntrinsicMethod::set_id(vmIntrinsicMethod, vmIntrinsics::id); \
vmIntrinsics->obj_at_put(index++, vmIntrinsicMethod()); \
JVMCIObject name_str = VM_SYMBOL_TO_STRING(name); \
JVMCIObject sig_str = VM_SYMBOL_TO_STRING(sig); \
JVMCIObject vmIntrinsicMethod = JVMCIENV->new_VMIntrinsicMethod(kls_str, name_str, sig_str, (jint) vmIntrinsics::id, JVMCI_CHECK_NULL); \
JVMCIENV->put_object_at(vmIntrinsics, index++, vmIntrinsicMethod); \
}
VM_INTRINSICS_DO(VM_INTRINSIC_INFO, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE)
@ -190,9 +181,6 @@ objArrayHandle CompilerToVM::initialize_intrinsics(TRAPS) {
return vmIntrinsics;
}
/**
* The set of VM flags known to be used.
*/
#define PREDEFINED_CONFIG_FLAGS(do_bool_flag, do_intx_flag, do_uintx_flag) \
do_intx_flag(AllocateInstancePrefetchLines) \
do_intx_flag(AllocatePrefetchDistance) \
@ -258,30 +246,28 @@ objArrayHandle CompilerToVM::initialize_intrinsics(TRAPS) {
do_bool_flag(UseTLAB) \
do_bool_flag(VerifyOops) \
#define BOXED_BOOLEAN(name, value) oop name = ((jboolean)(value) ? boxedTrue() : boxedFalse())
#define BOXED_DOUBLE(name, value) oop name; do { jvalue p; p.d = (jdouble) (value); name = java_lang_boxing_object::create(T_DOUBLE, &p, CHECK_NULL);} while(0)
#define BOXED_BOOLEAN(name, value) name = ((jboolean)(value) ? boxedTrue : boxedFalse)
#define BOXED_DOUBLE(name, value) do { jvalue p; p.d = (jdouble) (value); name = JVMCIENV->create_box(T_DOUBLE, &p, JVMCI_CHECK_NULL);} while(0)
#define BOXED_LONG(name, value) \
oop name; \
do { \
jvalue p; p.j = (jlong) (value); \
Handle* e = longs.get(p.j); \
JVMCIObject* e = longs.get(p.j); \
if (e == NULL) { \
oop o = java_lang_boxing_object::create(T_LONG, &p, CHECK_NULL); \
Handle h(THREAD, o); \
JVMCIObject h = JVMCIENV->create_box(T_LONG, &p, JVMCI_CHECK_NULL); \
longs.put(p.j, h); \
name = h(); \
name = h; \
} else { \
name = (*e)(); \
name = (*e); \
} \
} while (0)
#define CSTRING_TO_JSTRING(name, value) \
Handle name; \
JVMCIObject name; \
do { \
if (value != NULL) { \
Handle* e = strings.get(value); \
JVMCIObject* e = strings.get(value); \
if (e == NULL) { \
Handle h = java_lang_String::create_from_str(value, CHECK_NULL); \
JVMCIObject h = JVMCIENV->create_string(value, JVMCI_CHECK_NULL); \
strings.put(value, h); \
name = h; \
} else { \
@ -290,51 +276,42 @@ objArrayHandle CompilerToVM::initialize_intrinsics(TRAPS) {
} \
} while (0)
jobjectArray readConfiguration0(JNIEnv *env, TRAPS) {
ResourceMark rm;
HandleMark hm;
// Used to canonicalize Long and String values.
ResourceHashtable<jlong, Handle> longs;
ResourceHashtable<const char*, Handle, &CompilerToVM::cstring_hash, &CompilerToVM::cstring_equals> strings;
jobjectArray readConfiguration0(JNIEnv *env, JVMCI_TRAPS) {
Thread* THREAD = Thread::current();
ResourceHashtable<jlong, JVMCIObject> longs;
ResourceHashtable<const char*, JVMCIObject, &CompilerToVM::cstring_hash, &CompilerToVM::cstring_equals> strings;
jvalue prim;
prim.z = true; oop boxedTrueOop = java_lang_boxing_object::create(T_BOOLEAN, &prim, CHECK_NULL);
Handle boxedTrue(THREAD, boxedTrueOop);
prim.z = false; oop boxedFalseOop = java_lang_boxing_object::create(T_BOOLEAN, &prim, CHECK_NULL);
Handle boxedFalse(THREAD, boxedFalseOop);
prim.z = true; JVMCIObject boxedTrue = JVMCIENV->create_box(T_BOOLEAN, &prim, JVMCI_CHECK_NULL);
prim.z = false; JVMCIObject boxedFalse = JVMCIENV->create_box(T_BOOLEAN, &prim, JVMCI_CHECK_NULL);
CompilerToVM::Data::initialize(CHECK_NULL);
CompilerToVM::Data::initialize(JVMCI_CHECK_NULL);
VMField::klass()->initialize(CHECK_NULL);
VMFlag::klass()->initialize(CHECK_NULL);
VMIntrinsicMethod::klass()->initialize(CHECK_NULL);
JVMCIENV->VMField_initialize(JVMCI_CHECK_NULL);
JVMCIENV->VMFlag_initialize(JVMCI_CHECK_NULL);
JVMCIENV->VMIntrinsicMethod_initialize(JVMCI_CHECK_NULL);
int len = JVMCIVMStructs::localHotSpotVMStructs_count();
objArrayHandle vmFields = oopFactory::new_objArray_handle(VMField::klass(), len, CHECK_NULL);
JVMCIObjectArray vmFields = JVMCIENV->new_VMField_array(len, JVMCI_CHECK_NULL);
for (int i = 0; i < len ; i++) {
VMStructEntry vmField = JVMCIVMStructs::localHotSpotVMStructs[i];
instanceHandle vmFieldObj = InstanceKlass::cast(VMField::klass())->allocate_instance_handle(CHECK_NULL);
size_t name_buf_len = strlen(vmField.typeName) + strlen(vmField.fieldName) + 2 /* "::" */;
char* name_buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, name_buf_len + 1);
sprintf(name_buf, "%s::%s", vmField.typeName, vmField.fieldName);
CSTRING_TO_JSTRING(name, name_buf);
CSTRING_TO_JSTRING(type, vmField.typeString);
VMField::set_name(vmFieldObj, name());
VMField::set_type(vmFieldObj, type());
VMField::set_offset(vmFieldObj, vmField.offset);
VMField::set_address(vmFieldObj, (jlong) vmField.address);
JVMCIObject box;
if (vmField.isStatic && vmField.typeString != NULL) {
if (strcmp(vmField.typeString, "bool") == 0) {
BOXED_BOOLEAN(box, *(jbyte*) vmField.address);
VMField::set_value(vmFieldObj, box);
assert(box.is_non_null(), "must have a box");
} else if (strcmp(vmField.typeString, "int") == 0 ||
strcmp(vmField.typeString, "jint") == 0) {
BOXED_LONG(box, *(jint*) vmField.address);
VMField::set_value(vmFieldObj, box);
assert(box.is_non_null(), "must have a box");
} else if (strcmp(vmField.typeString, "uint64_t") == 0) {
BOXED_LONG(box, *(uint64_t*) vmField.address);
VMField::set_value(vmFieldObj, box);
assert(box.is_non_null(), "must have a box");
} else if (strcmp(vmField.typeString, "address") == 0 ||
strcmp(vmField.typeString, "intptr_t") == 0 ||
strcmp(vmField.typeString, "uintptr_t") == 0 ||
@ -343,43 +320,47 @@ jobjectArray readConfiguration0(JNIEnv *env, TRAPS) {
// All foo* types are addresses.
vmField.typeString[strlen(vmField.typeString) - 1] == '*') {
BOXED_LONG(box, *((address*) vmField.address));
VMField::set_value(vmFieldObj, box);
assert(box.is_non_null(), "must have a box");
} else {
JVMCI_ERROR_NULL("VM field %s has unsupported type %s", name_buf, vmField.typeString);
}
}
vmFields->obj_at_put(i, vmFieldObj());
JVMCIObject vmFieldObj = JVMCIENV->new_VMField(name, type, vmField.offset, (jlong) vmField.address, box, JVMCI_CHECK_NULL);
JVMCIENV->put_object_at(vmFields, i, vmFieldObj);
}
int ints_len = JVMCIVMStructs::localHotSpotVMIntConstants_count();
int longs_len = JVMCIVMStructs::localHotSpotVMLongConstants_count();
len = ints_len + longs_len;
objArrayHandle vmConstants = oopFactory::new_objArray_handle(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
JVMCIObjectArray vmConstants = JVMCIENV->new_Object_array(len * 2, JVMCI_CHECK_NULL);
int insert = 0;
for (int i = 0; i < ints_len ; i++) {
VMIntConstantEntry c = JVMCIVMStructs::localHotSpotVMIntConstants[i];
CSTRING_TO_JSTRING(name, c.name);
JVMCIObject value;
BOXED_LONG(value, c.value);
vmConstants->obj_at_put(insert++, name());
vmConstants->obj_at_put(insert++, value);
JVMCIENV->put_object_at(vmConstants, insert++, name);
JVMCIENV->put_object_at(vmConstants, insert++, value);
}
for (int i = 0; i < longs_len ; i++) {
VMLongConstantEntry c = JVMCIVMStructs::localHotSpotVMLongConstants[i];
CSTRING_TO_JSTRING(name, c.name);
JVMCIObject value;
BOXED_LONG(value, c.value);
vmConstants->obj_at_put(insert++, name());
vmConstants->obj_at_put(insert++, value);
JVMCIENV->put_object_at(vmConstants, insert++, name);
JVMCIENV->put_object_at(vmConstants, insert++, value);
}
assert(insert == len * 2, "must be");
len = JVMCIVMStructs::localHotSpotVMAddresses_count();
objArrayHandle vmAddresses = oopFactory::new_objArray_handle(SystemDictionary::Object_klass(), len * 2, CHECK_NULL);
JVMCIObjectArray vmAddresses = JVMCIENV->new_Object_array(len * 2, JVMCI_CHECK_NULL);
for (int i = 0; i < len ; i++) {
VMAddressEntry a = JVMCIVMStructs::localHotSpotVMAddresses[i];
CSTRING_TO_JSTRING(name, a.name);
JVMCIObject value;
BOXED_LONG(value, a.value);
vmAddresses->obj_at_put(i * 2, name());
vmAddresses->obj_at_put(i * 2 + 1, value);
JVMCIENV->put_object_at(vmAddresses, i * 2, name);
JVMCIENV->put_object_at(vmAddresses, i * 2 + 1, value);
}
#define COUNT_FLAG(ignore) +1
@ -393,40 +374,32 @@ jobjectArray readConfiguration0(JNIEnv *env, TRAPS) {
#define CHECK_FLAG(type, name)
#endif
#define ADD_FLAG(type, name, convert) { \
CHECK_FLAG(type, name) \
instanceHandle vmFlagObj = InstanceKlass::cast(VMFlag::klass())->allocate_instance_handle(CHECK_NULL); \
CSTRING_TO_JSTRING(fname, #name); \
CSTRING_TO_JSTRING(ftype, #type); \
VMFlag::set_name(vmFlagObj, fname()); \
VMFlag::set_type(vmFlagObj, ftype()); \
convert(value, name); \
VMFlag::set_value(vmFlagObj, value); \
vmFlags->obj_at_put(i++, vmFlagObj()); \
#define ADD_FLAG(type, name, convert) { \
CHECK_FLAG(type, name) \
CSTRING_TO_JSTRING(fname, #name); \
CSTRING_TO_JSTRING(ftype, #type); \
convert(value, name); \
JVMCIObject vmFlagObj = JVMCIENV->new_VMFlag(fname, ftype, value, JVMCI_CHECK_NULL); \
JVMCIENV->put_object_at(vmFlags, i++, vmFlagObj); \
}
#define ADD_BOOL_FLAG(name) ADD_FLAG(bool, name, BOXED_BOOLEAN)
#define ADD_INTX_FLAG(name) ADD_FLAG(intx, name, BOXED_LONG)
#define ADD_UINTX_FLAG(name) ADD_FLAG(uintx, name, BOXED_LONG)
len = 0 + PREDEFINED_CONFIG_FLAGS(COUNT_FLAG, COUNT_FLAG, COUNT_FLAG);
objArrayHandle vmFlags = oopFactory::new_objArray_handle(VMFlag::klass(), len, CHECK_NULL);
JVMCIObjectArray vmFlags = JVMCIENV->new_VMFlag_array(len, JVMCI_CHECK_NULL);
int i = 0;
JVMCIObject value;
PREDEFINED_CONFIG_FLAGS(ADD_BOOL_FLAG, ADD_INTX_FLAG, ADD_UINTX_FLAG)
objArrayHandle vmIntrinsics = CompilerToVM::initialize_intrinsics(CHECK_NULL);
JVMCIObjectArray vmIntrinsics = CompilerToVM::initialize_intrinsics(JVMCI_CHECK_NULL);
objArrayOop data = oopFactory::new_objArray(SystemDictionary::Object_klass(), 5, CHECK_NULL);
data->obj_at_put(0, vmFields());
data->obj_at_put(1, vmConstants());
data->obj_at_put(2, vmAddresses());
data->obj_at_put(3, vmFlags());
data->obj_at_put(4, vmIntrinsics());
JVMCIObjectArray data = JVMCIENV->new_Object_array(5, JVMCI_CHECK_NULL);
JVMCIENV->put_object_at(data, 0, vmFields);
JVMCIENV->put_object_at(data, 1, vmConstants);
JVMCIENV->put_object_at(data, 2, vmAddresses);
JVMCIENV->put_object_at(data, 3, vmFlags);
JVMCIENV->put_object_at(data, 4, vmIntrinsics);
return (jobjectArray) JNIHandles::make_local(THREAD, data);
#undef COUNT_FLAG
#undef ADD_FLAG
#undef ADD_BOOL_FLAG
#undef ADD_INTX_FLAG
#undef ADD_UINTX_FLAG
#undef CHECK_FLAG
return JVMCIENV->get_jobjectArray(data);
}

File diff suppressed because it is too large Load Diff

View File

@ -25,14 +25,16 @@
#ifndef SHARE_JVMCI_JVMCIENV_HPP
#define SHARE_JVMCI_JVMCIENV_HPP
#include "classfile/systemDictionary.hpp"
#include "code/debugInfoRec.hpp"
#include "code/dependencies.hpp"
#include "code/exceptionHandlerTable.hpp"
#include "compiler/oopMap.hpp"
#include "classfile/javaClasses.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "runtime/thread.hpp"
class CompileTask;
class JVMCIObject;
class JVMCIObjectArray;
class JVMCIPrimitiveArray;
class JVMCICompiler;
class JVMCIRuntime;
// Bring the JVMCI compiler thread into the VM state.
#define JVMCI_VM_ENTRY_MARK \
@ -47,64 +49,58 @@ class CompileTask;
JavaThread* thread=JavaThread::current(); \
Thread* THREAD = thread;
//
// This class is the top level broker for requests from the compiler
// to the VM.
class JVMCIEnv : StackObj {
CI_PACKAGE_ACCESS_TO
// Helper to log more context on a JNI exception
#define JVMCI_EXCEPTION_CHECK(env, ...) \
do { \
if (env->ExceptionCheck()) { \
if (env != JavaThread::current()->jni_environment() && JVMCIEnv::get_shared_library_path() != NULL) { \
tty->print_cr("In JVMCI shared library (%s):", JVMCIEnv::get_shared_library_path()); \
} \
tty->print_cr(__VA_ARGS__); \
return; \
} \
} while(0)
friend class JVMCIVMStructs;
friend class CompileBroker;
friend class Dependencies; // for get_object, during logging
// Helper class to ensure that references to Klass* are kept alive for G1
class JVMCIKlassHandle : public StackObj {
private:
Klass* _klass;
Handle _holder;
Thread* _thread;
public:
Klass* klass() const { return _klass; }
Klass* non_null_klass() const { assert(_klass != NULL, "resolving NULL _klass"); return _klass; }
enum CodeInstallResult {
ok,
dependencies_failed,
dependencies_invalid,
cache_full,
code_too_large
};
public:
/* Constructors */
JVMCIKlassHandle (Thread* thread) : _klass(NULL), _thread(thread) {}
JVMCIKlassHandle (Thread* thread, Klass* klass);
// Look up a klass by name from a particular class loader (the accessor's).
// If require_local, result must be defined in that class loader, or NULL.
// If !require_local, a result from remote class loader may be reported,
// if sufficient class loader constraints exist such that initiating
// a class loading request from the given loader is bound to return
// the class defined in the remote loader (or throw an error).
//
// Return an unloaded klass if !require_local and no class at all is found.
//
// The CI treats a klass as loaded if it is consistently defined in
// another loader, even if it hasn't yet been loaded in all loaders
// that could potentially see it via delegation.
static Klass* get_klass_by_name(Klass* accessing_klass, Symbol* klass_name, bool require_local);
JVMCIKlassHandle (const JVMCIKlassHandle &h): _klass(h._klass), _holder(h._holder), _thread(h._thread) {}
JVMCIKlassHandle& operator=(const JVMCIKlassHandle &s);
JVMCIKlassHandle& operator=(Klass* klass);
// Constant pool access.
static Klass* get_klass_by_index(const constantPoolHandle& cpool,
int klass_index,
bool& is_accessible,
Klass* loading_klass);
static void get_field_by_index(InstanceKlass* loading_klass, fieldDescriptor& fd,
int field_index);
static methodHandle get_method_by_index(const constantPoolHandle& cpool,
int method_index, Bytecodes::Code bc,
InstanceKlass* loading_klass);
/* Operators for ease of use */
Klass* operator () () const { return klass(); }
Klass* operator -> () const { return non_null_klass(); }
JVMCIEnv(CompileTask* task, int system_dictionary_modification_counter);
bool operator == (Klass* o) const { return klass() == o; }
bool operator == (const JVMCIKlassHandle& h) const { return klass() == h.klass(); }
private:
/* Null checks */
bool is_null() const { return _klass == NULL; }
bool not_null() const { return _klass != NULL; }
};
// A class that maintains the state needed for compilations requested
// by the CompileBroker. It is created in the broker and passed through
// into the code installation step.
class JVMCICompileState : public ResourceObj {
friend class VMStructs;
private:
CompileTask* _task;
int _system_dictionary_modification_counter;
// Compilation result values
bool _retryable;
const char* _failure_reason;
// Specifies if _failure_reason is on the C heap.
bool _failure_reason_on_C_heap;
// Cache JVMTI state. Defined as bytes so that reading them from Java
// via Unsafe is well defined (the C++ type for bool is implementation
// defined and may not be the same as a Java boolean).
@ -113,43 +109,20 @@ private:
jbyte _jvmti_can_post_on_exceptions;
jbyte _jvmti_can_pop_frame;
// Implementation methods for loading and constant pool access.
static Klass* get_klass_by_name_impl(Klass* accessing_klass,
const constantPoolHandle& cpool,
Symbol* klass_name,
bool require_local);
static Klass* get_klass_by_index_impl(const constantPoolHandle& cpool,
int klass_index,
bool& is_accessible,
Klass* loading_klass);
static void get_field_by_index_impl(InstanceKlass* loading_klass, fieldDescriptor& fd,
int field_index);
static methodHandle get_method_by_index_impl(const constantPoolHandle& cpool,
int method_index, Bytecodes::Code bc,
InstanceKlass* loading_klass);
// Compilation result values.
bool _retryable;
const char* _failure_reason;
// Helper methods
static bool check_klass_accessibility(Klass* accessing_klass, Klass* resolved_klass);
static methodHandle lookup_method(InstanceKlass* accessor,
Klass* holder,
Symbol* name,
Symbol* sig,
Bytecodes::Code bc,
constantTag tag);
// Specifies if _failure_reason is on the C heap. If so, it is allocated
// with the mtJVMCI NMT flag.
bool _failure_reason_on_C_heap;
private:
public:
JVMCICompileState(CompileTask* task, int system_dictionary_modification_counter);
// Is this thread currently in the VM state?
static bool is_in_vm();
// Helper routine for determining the validity of a compilation
// with respect to concurrent class loading.
static JVMCIEnv::CodeInstallResult validate_compile_task_dependencies(Dependencies* target, Handle compiled_code,
JVMCIEnv* env, char** failure_detail);
public:
CompileTask* task() { return _task; }
int system_dictionary_modification_counter() { return _system_dictionary_modification_counter; }
bool jvmti_state_changed() const;
bool jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint != 0; }
bool jvmti_can_access_local_variables() const { return _jvmti_can_access_local_variables != 0; }
@ -165,34 +138,355 @@ public:
_failure_reason_on_C_heap = reason_on_C_heap;
_retryable = retryable;
}
};
// Register the result of a compilation.
static JVMCIEnv::CodeInstallResult register_method(
const methodHandle& target,
nmethod*& nm,
int entry_bci,
CodeOffsets* offsets,
int orig_pc_offset,
CodeBuffer* code_buffer,
int frame_words,
OopMapSet* oop_map_set,
ExceptionHandlerTable* handler_table,
AbstractCompiler* compiler,
DebugInformationRecorder* debug_info,
Dependencies* dependencies,
JVMCIEnv* env,
int compile_id,
bool has_unsafe_access,
bool has_wide_vector,
Handle installed_code,
Handle compiled_code,
Handle speculation_log);
// converts the Klass* representing the holder of a method into a
// InstanceKlass*. This is needed since the holder of a method in
// the bytecodes could be an array type. Basically this converts
// array types into java/lang/Object and other types stay as they are.
static InstanceKlass* get_instance_klass_for_declared_method_holder(Klass* klass);
// This class is a top level wrapper around interactions between HotSpot
// and the JVMCI Java code. It supports both a HotSpot heap based
// runtime with HotSpot oop based accessors as well as a shared library
// based runtime that is accessed through JNI. It abstracts away all
// interactions with JVMCI objects so that a single version of the
// HotSpot C++ code can can work with either runtime.
class JVMCIEnv : public ResourceObj {
friend class JNIAccessMark;
static char* _shared_library_path; // argument to os:dll_load
static void* _shared_library_handle; // result of os::dll_load
static JavaVM* _shared_library_javavm; // result of calling JNI_CreateJavaVM in shared library
// Attaches the current thread to the JavaVM in the shared library,
// initializing the shared library VM first if necessary.
// Returns the JNI interface pointer of the current thread.
// The _shared_library_* fields are initialized by the first
// call to this method.
static JNIEnv* attach_shared_library();
// Initializes the _env, _mode and _runtime fields.
void init_env_mode_runtime(JNIEnv* parent_env);
void init(bool is_hotspot, const char* file, int line);
JNIEnv* _env; // JNI env for calling into shared library
JVMCIRuntime* _runtime; // Access to a HotSpotJVMCIRuntime
bool _is_hotspot; // Which heap is the HotSpotJVMCIRuntime in
bool _throw_to_caller; // Propagate an exception raised in this env to the caller?
const char* _file; // The file and ...
int _line; // ... line where this JNIEnv was created
// Translates an exception on the HotSpot heap to an exception on
// the shared library heap. The translation includes the stack and
// causes of `throwable`. The translated exception is pending in the
// shared library thread upon returning.
void translate_hotspot_exception_to_jni_exception(JavaThread* THREAD, const Handle& throwable);
public:
// Opens a JVMCIEnv scope for a Java to VM call (e.g., via CompilerToVM).
// An exception occurring within the scope is left pending when the
// scope closes so that it will be propagated back to Java.
// The JVMCIEnv destructor translates the exception object for the
// Java runtime if necessary.
JVMCIEnv(JNIEnv* env, const char* file, int line);
// Opens a JVMCIEnv scope for a compilation scheduled by the CompileBroker.
// An exception occurring within the scope must not be propagated back to
// the CompileBroker.
JVMCIEnv(JVMCICompileState* compile_state, const char* file, int line);
// Opens a JNIEnv scope for a call from within the VM. An exception occurring
// within the scope must not be propagated back to the caller.
JVMCIEnv(JavaThread* env, const char* file, int line);
// Opens a JNIEnv scope for accessing `for_object`. An exception occurring
// within the scope must not be propagated back to the caller.
JVMCIEnv(JVMCIObject for_object, const char* file, int line) {
// A JNI call to access an object in the shared library heap
// can block or take a long time so do not allow such access
// on the VM thread.
assert(for_object.is_hotspot() || !Thread::current()->is_VM_thread(),
"cannot open JVMCIEnv scope when in the VM thread for accessing a shared library heap object");
init(for_object.is_hotspot(), file, line);
}
// Opens a JNIEnv scope for the HotSpot runtime if `is_hotspot` is true
// otherwise for the shared library runtime. An exception occurring
// within the scope must not be propagated back to the caller.
JVMCIEnv(bool is_hotspot, const char* file, int line) {
init(is_hotspot, file, line);
}
~JVMCIEnv();
JVMCIRuntime* runtime() {
return _runtime;
}
// Initializes Services.savedProperties in the shared library by copying
// the values from the same field in the HotSpot heap.
void copy_saved_properties();
jboolean has_pending_exception();
void clear_pending_exception();
// Prints an exception and stack trace of a pending exception.
void describe_pending_exception(bool clear);
int get_length(JVMCIArray array);
JVMCIObject get_object_at(JVMCIObjectArray array, int index);
void put_object_at(JVMCIObjectArray array, int index, JVMCIObject value);
jboolean get_bool_at(JVMCIPrimitiveArray array, int index);
void put_bool_at(JVMCIPrimitiveArray array, int index, jboolean value);
jbyte get_byte_at(JVMCIPrimitiveArray array, int index);
void put_byte_at(JVMCIPrimitiveArray array, int index, jbyte value);
jint get_int_at(JVMCIPrimitiveArray array, int index);
void put_int_at(JVMCIPrimitiveArray array, int index, jint value);
long get_long_at(JVMCIPrimitiveArray array, int index);
void put_long_at(JVMCIPrimitiveArray array, int index, jlong value);
void copy_bytes_to(JVMCIPrimitiveArray src, jbyte* dest, int offset, int size_in_bytes);
void copy_bytes_from(jbyte* src, JVMCIPrimitiveArray dest, int offset, int size_in_bytes);
JVMCIObjectArray initialize_intrinsics(JVMCI_TRAPS);
jboolean is_boxing_object(BasicType type, JVMCIObject object);
// Get the primitive value from a Java boxing object. It's hard error to
// pass a non-primitive BasicType.
jvalue get_boxed_value(BasicType type, JVMCIObject object);
// Return the BasicType of the object if it's a boxing object, otherwise return T_ILLEGAL.
BasicType get_box_type(JVMCIObject object);
// Create a boxing object of the appropriate primitive type.
JVMCIObject create_box(BasicType type, jvalue* value, JVMCI_TRAPS);
const char* as_utf8_string(JVMCIObject str);
char* as_utf8_string(JVMCIObject str, char* buf, int buflen);
JVMCIObject create_string(Symbol* str, JVMCI_TRAPS) {
return create_string(str->as_C_string(), JVMCI_CHECK_(JVMCIObject()));
}
JVMCIObject create_string(const char* str, JVMCI_TRAPS);
bool equals(JVMCIObject a, JVMCIObject b);
// Convert into a JNI handle for the appropriate runtime
jobject get_jobject(JVMCIObject object) { assert(object.as_jobject() == NULL || is_hotspot() == object.is_hotspot(), "mismatch"); return object.as_jobject(); }
jarray get_jarray(JVMCIArray array) { assert(array.as_jobject() == NULL || is_hotspot() == array.is_hotspot(), "mismatch"); return array.as_jobject(); }
jobjectArray get_jobjectArray(JVMCIObjectArray objectArray) { assert(objectArray.as_jobject() == NULL || is_hotspot() == objectArray.is_hotspot(), "mismatch"); return objectArray.as_jobject(); }
jbyteArray get_jbyteArray(JVMCIPrimitiveArray primitiveArray) { assert(primitiveArray.as_jobject() == NULL || is_hotspot() == primitiveArray.is_hotspot(), "mismatch"); return primitiveArray.as_jbyteArray(); }
JVMCIObject wrap(jobject obj);
JVMCIObjectArray wrap(jobjectArray obj) { return (JVMCIObjectArray) wrap((jobject) obj); }
JVMCIPrimitiveArray wrap(jintArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); }
JVMCIPrimitiveArray wrap(jbooleanArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); }
JVMCIPrimitiveArray wrap(jbyteArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); }
JVMCIPrimitiveArray wrap(jlongArray obj) { return (JVMCIPrimitiveArray) wrap((jobject) obj); }
private:
JVMCIObject wrap(oop obj) { assert(is_hotspot(), "must be"); return wrap(JNIHandles::make_local(obj)); }
JVMCIObjectArray wrap(objArrayOop obj) { assert(is_hotspot(), "must be"); return (JVMCIObjectArray) wrap(JNIHandles::make_local(obj)); }
JVMCIPrimitiveArray wrap(typeArrayOop obj) { assert(is_hotspot(), "must be"); return (JVMCIPrimitiveArray) wrap(JNIHandles::make_local(obj)); }
public:
// Compiles a method with the JVMIC compiler.
// Caller must handle pending exception.
JVMCIObject call_HotSpotJVMCIRuntime_compileMethod(JVMCIObject runtime, JVMCIObject method, int entry_bci,
jlong compile_state, int id);
void call_HotSpotJVMCIRuntime_bootstrapFinished(JVMCIObject runtime, JVMCI_TRAPS);
void call_HotSpotJVMCIRuntime_shutdown(JVMCIObject runtime);
JVMCIObject call_HotSpotJVMCIRuntime_runtime(JVMCI_TRAPS);
JVMCIObject call_JVMCI_getRuntime(JVMCI_TRAPS);
JVMCIObject call_HotSpotJVMCIRuntime_getCompiler(JVMCIObject runtime, JVMCI_TRAPS);
JVMCIObject call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCI_TRAPS);
JVMCIObject call_PrimitiveConstant_forTypeChar(jchar kind, jlong value, JVMCI_TRAPS);
JVMCIObject call_JavaConstant_forFloat(float value, JVMCI_TRAPS);
JVMCIObject call_JavaConstant_forDouble(double value, JVMCI_TRAPS);
BasicType kindToBasicType(JVMCIObject kind, JVMCI_TRAPS);
#define DO_THROW(name) \
void throw_##name(const char* msg = NULL);
DO_THROW(InternalError)
DO_THROW(ArrayIndexOutOfBoundsException)
DO_THROW(IllegalStateException)
DO_THROW(NullPointerException)
DO_THROW(IllegalArgumentException)
DO_THROW(InvalidInstalledCodeException)
DO_THROW(UnsatisfiedLinkError)
#undef DO_THROW
void fthrow_error(const char* file, int line, const char* format, ...) ATTRIBUTE_PRINTF(4, 5);
// Given an instance of HotSpotInstalledCode return the corresponding CodeBlob*
CodeBlob* asCodeBlob(JVMCIObject code);
nmethod* asNmethod(JVMCIObject code) {
CodeBlob* cb = asCodeBlob(code);
if (cb == NULL) {
return NULL;
}
nmethod* nm = cb->as_nmethod_or_null();
guarantee(nm != NULL, "not an nmethod");
return nm;
}
MethodData* asMethodData(jlong metaspaceMethodData) {
return (MethodData*) (address) metaspaceMethodData;
}
const char* klass_name(JVMCIObject object);
// Unpack an instance of HotSpotResolvedJavaMethodImpl into the original Method*
Method* asMethod(JVMCIObject jvmci_method);
Method* asMethod(jobject jvmci_method) { return asMethod(wrap(jvmci_method)); }
// Unpack an instance of HotSpotResolvedObjectTypeImpl into the original Klass*
Klass* asKlass(JVMCIObject jvmci_type);
Klass* asKlass(jobject jvmci_type) { return asKlass(wrap(jvmci_type)); }
JVMCIObject get_jvmci_method(const methodHandle& method, JVMCI_TRAPS);
JVMCIObject get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS);
// Unpack an instance of HotSpotConstantPool into the original ConstantPool*
ConstantPool* asConstantPool(JVMCIObject constant_pool);
ConstantPool* asConstantPool(jobject constant_pool) { return asConstantPool(wrap(constant_pool)); }
JVMCIObject get_jvmci_constant_pool(const constantPoolHandle& cp, JVMCI_TRAPS);
JVMCIObject get_jvmci_primitive_type(BasicType type);
Handle asConstant(JVMCIObject object, JVMCI_TRAPS);
JVMCIObject get_object_constant(oop objOop, bool compressed = false, bool dont_register = false);
JVMCIPrimitiveArray new_booleanArray(int length, JVMCI_TRAPS);
JVMCIPrimitiveArray new_byteArray(int length, JVMCI_TRAPS);
JVMCIPrimitiveArray new_intArray(int length, JVMCI_TRAPS);
JVMCIPrimitiveArray new_longArray(int length, JVMCI_TRAPS);
JVMCIObjectArray new_byte_array_array(int length, JVMCI_TRAPS);
JVMCIObject new_StackTraceElement(const methodHandle& method, int bci, JVMCI_TRAPS);
JVMCIObject new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS);
JVMCIObject new_VMField(JVMCIObject name, JVMCIObject type, jlong offset, jlong address, JVMCIObject value, JVMCI_TRAPS);
JVMCIObject new_VMFlag(JVMCIObject name, JVMCIObject type, JVMCIObject value, JVMCI_TRAPS);
JVMCIObject new_VMIntrinsicMethod(JVMCIObject declaringClass, JVMCIObject name, JVMCIObject descriptor, int id, JVMCI_TRAPS);
JVMCIObject new_HotSpotStackFrameReference(JVMCI_TRAPS);
JVMCIObject new_JVMCIError(JVMCI_TRAPS);
jlong make_handle(const Handle& obj);
oop resolve_handle(jlong objectHandle);
// These are analagous to the JNI routines
JVMCIObject make_local(JVMCIObject object);
JVMCIObject make_global(JVMCIObject object);
JVMCIObject make_weak(JVMCIObject object);
void destroy_local(JVMCIObject object);
void destroy_global(JVMCIObject object);
void destroy_weak(JVMCIObject object);
// Deoptimizes the nmethod (if any) in the HotSpotNmethod.address
// field of mirror. The field is subsequently zeroed.
void invalidate_nmethod_mirror(JVMCIObject mirror, JVMCI_TRAPS);
void initialize_installed_code(JVMCIObject installed_code, CodeBlob* cb, JVMCI_TRAPS);
private:
JVMCICompileState* _compile_state;
public:
static JavaVM* get_shared_library_javavm() { return _shared_library_javavm; }
static void* get_shared_library_handle() { return _shared_library_handle; }
static char* get_shared_library_path() { return _shared_library_path; }
// Determines if this is for the JVMCI runtime in the HotSpot
// heap (true) or the shared library heap (false).
bool is_hotspot() { return _is_hotspot; }
JVMCICompileState* compile_state() { return _compile_state; }
void set_compile_state(JVMCICompileState* compile_state) {
assert(_compile_state == NULL, "set only once");
_compile_state = compile_state;
}
// Generate declarations for the initialize, new, isa, get and set methods for all the types and
// fields declared in the JVMCI_CLASSES_DO macro.
#define START_CLASS(className, fullClassName) \
void className##_initialize(JVMCI_TRAPS); \
JVMCIObjectArray new_##className##_array(int length, JVMCI_TRAPS); \
bool isa_##className(JVMCIObject object);
#define END_CLASS
#define FIELD(className, name, type, accessor) \
type get_ ## className ## _ ## name(JVMCIObject obj); \
void set_ ## className ## _ ## name(JVMCIObject obj, type x);
#define OOPISH_FIELD(className, name, type, hstype, accessor) \
FIELD(className, name, type, accessor)
#define STATIC_FIELD(className, name, type) \
type get_ ## className ## _ ## name(); \
void set_ ## className ## _ ## name(type x);
#define STATIC_OOPISH_FIELD(className, name, type, hstype) \
STATIC_FIELD(className, name, type)
#define EMPTY_CAST
#define CHAR_FIELD(className, name) FIELD(className, name, jchar, char_field)
#define INT_FIELD(className, name) FIELD(className, name, jint, int_field)
#define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, bool_field)
#define LONG_FIELD(className, name) FIELD(className, name, jlong, long_field)
#define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, float_field)
#define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, oop, obj_field)
#define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, objArrayOop, obj_field)
#define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, typeArrayOop, obj_field)
#define STATIC_INT_FIELD(className, name) STATIC_FIELD(className, name, jint)
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_FIELD(className, name, jboolean)
#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, oop)
#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, objArrayOop)
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
#define CONSTRUCTOR(className, signature)
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
#undef JNI_START_CLASS
#undef START_CLASS
#undef END_CLASS
#undef METHOD
#undef CONSTRUCTOR
#undef FIELD
#undef CHAR_FIELD
#undef INT_FIELD
#undef BOOLEAN_FIELD
#undef LONG_FIELD
#undef FLOAT_FIELD
#undef OBJECT_FIELD
#undef PRIMARRAY_FIELD
#undef OBJECTARRAY_FIELD
#undef FIELD
#undef OOPISH_FIELD
#undef STATIC_FIELD
#undef STATIC_OOPISH_FIELD
#undef STATIC_FIELD
#undef STATIC_OBJECT_FIELD
#undef STATIC_OBJECTARRAY_FIELD
#undef STATIC_INT_FIELD
#undef STATIC_BOOLEAN_FIELD
#undef EMPTY_CAST
// End of JVMCIEnv
};
#endif // SHARE_JVMCI_JVMCIENV_HPP

View File

@ -0,0 +1,79 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_JVMCI_JVMCIEXCEPTIONS_HPP
#define SHARE_JVMCI_JVMCIEXCEPTIONS_HPP
class JVMCIEnv;
// JVMCIEnv exception utility macros. Analagous to the regular CHECK, TRAP and THREAD macros.
#define JVMCIENV __jvmci_env__
#define JVMCI_TRAPS JVMCIEnv* JVMCIENV
#define JNI_JVMCIENV(env) \
JVMCIEnv __stack_jvmci_env__(env, __FILE__, __LINE__); \
JVMCIEnv* JVMCIENV = &__stack_jvmci_env__
#define THREAD_JVMCIENV(thread) \
JVMCIEnv __stack_jvmci_env__(thread, __FILE__, __LINE__); \
JVMCIEnv* JVMCIENV = &__stack_jvmci_env__
#define JVMCI_PENDING_EXCEPTION (JVMCIENV->pending_exception())
#define JVMCI_HAS_PENDING_EXCEPTION (JVMCIENV->has_pending_exception())
#define JVMCI_CLEAR_PENDING_EXCEPTION (JVMCIENV->clear_pending_exception())
#define JVMCI_CHECK JVMCIENV); if (JVMCI_HAS_PENDING_EXCEPTION) return ; (void)(0
#define JVMCI_CHECK_(result) JVMCIENV); if (JVMCI_HAS_PENDING_EXCEPTION) return result; (void)(0
#define JVMCI_CHECK_0 JVMCI_CHECK_(0)
#define JVMCI_CHECK_NULL JVMCI_CHECK_(NULL)
#define JVMCI_CHECK_false JVMCI_CHECK_(false)
#define JVMCI_CHECK_OK JVMCI_CHECK_(JVMCI::ok)
#define JVMCI_ERROR(...) \
{ JVMCIENV->fthrow_error(__FILE__, __LINE__, __VA_ARGS__); return; }
#define JVMCI_ERROR_(ret, ...) \
{ JVMCIENV->fthrow_error( __FILE__, __LINE__, __VA_ARGS__); return ret; }
#define JVMCI_ERROR_0(...) JVMCI_ERROR_(0, __VA_ARGS__)
#define JVMCI_ERROR_NULL(...) JVMCI_ERROR_(NULL, __VA_ARGS__)
#define JVMCI_ERROR_OK(...) JVMCI_ERROR_(JVMCI::ok, __VA_ARGS__)
#define JVMCI_THROW(name) { JVMCIENV->throw_##name(); return; }
#define JVMCI_THROW_NULL(name) { JVMCIENV->throw_##name(); return NULL; }
#define JVMCI_THROW_0(name) { JVMCIENV->throw_##name(); return 0; }
#define JVMCI_THROW_MSG_NULL(name, msg) { JVMCIENV->throw_##name(msg); return NULL; }
#define JVMCI_THROW_MSG_(name, msg, value) { JVMCIENV->throw_##name(msg); return (value); }
#define JVMCI_THROW_MSG_0(name, msg) { JVMCIENV->throw_##name(msg); return 0; }
#define JVMCI_THROW_MSG(name, msg) { JVMCIENV->throw_##name(msg); return; }
#define JVMCI_THROW_(name, value) { JVMCIENV->throw_##name(); return (value); }
#define JVMCI_CATCH \
JVMCIENV); if (JVMCI_HAS_PENDING_EXCEPTION) { \
JVMCIENV->describe_pending_exception(true); \
ShouldNotReachHere(); \
} (void)(0
#endif // SHARE_JVMCI_JVMCIEXCEPTIONS_HPP

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,95 +23,43 @@
#include "precompiled.hpp"
#include "classfile/symbolTable.hpp"
#include "interpreter/linkResolver.hpp"
#include "jvmci/jniAccessMark.inline.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "memory/resourceArea.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
// ------------------------------------------------------------------
// This macro expands for non-inline functions, in class declarations.
oop HotSpotJVMCI::resolve(JVMCIObject obj) {
return JNIHandles::resolve(obj.as_jobject());
}
#define START_CLASS(name) \
void name::check(oop obj, const char* field_name, int offset) { \
assert(obj != NULL, "NULL field access of %s.%s", #name, field_name); \
assert(obj->is_a(SystemDictionary::name##_klass()), "wrong class, " #name " expected, found %s", obj->klass()->external_name()); \
assert(offset != 0, "must be valid offset"); \
}
arrayOop HotSpotJVMCI::resolve(JVMCIArray obj) {
return (arrayOop) JNIHandles::resolve(obj.as_jobject());
}
#define END_CLASS
objArrayOop HotSpotJVMCI::resolve(JVMCIObjectArray obj) {
return (objArrayOop) JNIHandles::resolve(obj.as_jobject());
}
#define FIELD(klass, name, type, accessor, cast) \
type klass::name(jobject obj) { check(JNIHandles::resolve(obj), #name, _##name##_offset); return cast JNIHandles::resolve(obj)->accessor(_##name##_offset); } \
void klass::set_##name(jobject obj, type x) { check(JNIHandles::resolve(obj), #name, _##name##_offset); JNIHandles::resolve(obj)->accessor##_put(_##name##_offset, x); }
typeArrayOop HotSpotJVMCI::resolve(JVMCIPrimitiveArray obj) {
return (typeArrayOop) JNIHandles::resolve(obj.as_jobject());
}
#define EMPTY_CAST
#define CHAR_FIELD(klass, name) FIELD(klass, name, jchar, char_field, EMPTY_CAST)
#define INT_FIELD(klass, name) FIELD(klass, name, jint, int_field, EMPTY_CAST)
#define BOOLEAN_FIELD(klass, name) FIELD(klass, name, jboolean, bool_field, EMPTY_CAST)
#define LONG_FIELD(klass, name) FIELD(klass, name, jlong, long_field, EMPTY_CAST)
#define FLOAT_FIELD(klass, name) FIELD(klass, name, jfloat, float_field, EMPTY_CAST)
#define OOP_FIELD(klass, name, signature) FIELD(klass, name, oop, obj_field, EMPTY_CAST)
#define OBJARRAYOOP_FIELD(klass, name, signature) FIELD(klass, name, objArrayOop, obj_field, (objArrayOop))
#define TYPEARRAYOOP_FIELD(klass, name, signature) FIELD(klass, name, typeArrayOop, obj_field, (typeArrayOop))
#define STATIC_OOP_FIELD(klassName, name, signature) STATIC_OOPISH_FIELD(klassName, name, oop, signature)
#define STATIC_OBJARRAYOOP_FIELD(klassName, name, signature) STATIC_OOPISH_FIELD(klassName, name, objArrayOop, signature)
#define STATIC_OOPISH_FIELD(klassName, name, type, signature) \
type klassName::name() { \
assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
InstanceKlass* ik = klassName::klass(); \
oop base = ik->static_field_base_raw(); \
oop result = HeapAccess<>::oop_load_at(base, _##name##_offset); \
return type(result); \
} \
void klassName::set_##name(type x) { \
assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
assert(klassName::klass() != NULL, "Class not yet loaded: " #klassName); \
InstanceKlass* ik = klassName::klass(); \
oop base = ik->static_field_base_raw(); \
HeapAccess<>::oop_store_at(base, _##name##_offset, x); \
}
#define STATIC_PRIMITIVE_FIELD(klassName, name, jtypename) \
jtypename klassName::name() { \
assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
InstanceKlass* ik = klassName::klass(); \
oop base = ik->static_field_base_raw(); \
return HeapAccess<>::load_at(base, _##name##_offset); \
} \
void klassName::set_##name(jtypename x) { \
assert(klassName::klass() != NULL && klassName::klass()->is_linked(), "Class not yet linked: " #klassName); \
InstanceKlass* ik = klassName::klass(); \
oop base = ik->static_field_base_raw(); \
HeapAccess<>::store_at(base, _##name##_offset, x); \
}
JVMCIObject HotSpotJVMCI::wrap(oop obj) {
assert(Thread::current()->is_Java_thread(), "must be");
return JVMCIObject(JNIHandles::make_local(obj), true);
}
#define STATIC_INT_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, jint)
#define STATIC_BOOLEAN_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, jboolean)
COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, TYPEARRAYOOP_FIELD, OBJARRAYOOP_FIELD, STATIC_OOP_FIELD, STATIC_OBJARRAYOOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
#undef START_CLASS
#undef END_CLASS
#undef FIELD
#undef CHAR_FIELD
#undef INT_FIELD
#undef BOOLEAN_FIELD
#undef LONG_FIELD
#undef FLOAT_FIELD
#undef OOP_FIELD
#undef TYPEARRAYOOP_FIELD
#undef OBJARRAYOOP_FIELD
#undef STATIC_OOPISH_FIELD
#undef STATIC_OOP_FIELD
#undef STATIC_OBJARRAYOOP_FIELD
#undef STATIC_INT_FIELD
#undef STATIC_BOOLEAN_FIELD
#undef STATIC_PRIMITIVE_FIELD
#undef EMPTY_CAST
// This function is similar to javaClasses.cpp, it computes the field offset of a (static or instance) field.
// It looks up the name and signature symbols without creating new ones, all the symbols of these classes need to be already loaded.
void compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field, TRAPS) {
/**
* Computes the field offset of a static or instance field.
* It looks up the name and signature symbols without creating new ones;
* all the symbols of these classes need to be already loaded.
*/
void HotSpotJVMCI::compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field, TRAPS) {
InstanceKlass* ik = InstanceKlass::cast(klass);
Symbol* name_symbol = SymbolTable::probe(name, (int)strlen(name));
Symbol* signature_symbol = SymbolTable::probe(signature, (int)strlen(signature));
@ -125,7 +73,7 @@ void compute_offset(int &dest_offset, Klass* klass, const char* name, const char
fieldDescriptor fd;
if (!ik->find_field(name_symbol, signature_symbol, &fd)) {
ResourceMark rm;
fatal("Invalid layout of %s %s at %s", name_symbol->as_C_string(), signature_symbol->as_C_string(), ik->external_name());
fatal("Could not find field %s.%s with signature %s", ik->external_name(), name, signature);
}
guarantee(fd.is_static() == static_field, "static/instance mismatch");
dest_offset = fd.offset();
@ -137,33 +85,548 @@ void compute_offset(int &dest_offset, Klass* klass, const char* name, const char
}
}
// This piece of macro magic creates the contents of the jvmci_compute_offsets method that initializes the field indices of all the access classes.
#ifndef PRODUCT
static void check_resolve_method(const char* call_type, Klass* resolved_klass, Symbol* method_name, Symbol* method_signature, TRAPS) {
methodHandle method;
LinkInfo link_info(resolved_klass, method_name, method_signature, NULL, LinkInfo::skip_access_check);
if (strcmp(call_type, "call_static") == 0) {
method = LinkResolver::resolve_static_call_or_null(link_info);
} else if (strcmp(call_type, "call_virtual") == 0) {
method = LinkResolver::resolve_virtual_call_or_null(resolved_klass, link_info);
} else if (strcmp(call_type, "call_special") == 0) {
method = LinkResolver::resolve_special_call_or_null(link_info);
} else {
fatal("Unknown or unsupported call type: %s", call_type);
}
if (method.is_null()) {
fatal("Could not resolve %s.%s%s", resolved_klass->external_name(), method_name->as_C_string(), method_signature->as_C_string());
}
}
#endif
#define START_CLASS(name) { Klass* k = SystemDictionary::name##_klass(); assert(k != NULL, "Could not find class " #name "");
jclass JNIJVMCI::_box_classes[T_CONFLICT+1];
jclass JNIJVMCI::_byte_array;
jfieldID JNIJVMCI::_box_fields[T_CONFLICT+1];
jmethodID JNIJVMCI::_box_constructors[T_CONFLICT+1];
jmethodID JNIJVMCI::_Class_getName_method;
jmethodID JNIJVMCI::_HotSpotResolvedJavaMethodImpl_fromMetaspace_method;
jmethodID JNIJVMCI::_HotSpotConstantPool_fromMetaspace_method;
jmethodID JNIJVMCI::_HotSpotResolvedObjectTypeImpl_fromMetaspace_method;
jmethodID JNIJVMCI::_HotSpotResolvedPrimitiveType_fromMetaspace_method;
#define START_CLASS(className, fullClassName) { \
Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::fullClassName(), true, CHECK); \
className::_klass = InstanceKlass::cast(k); \
className::_klass->initialize(CHECK);
#define END_CLASS }
#define FIELD(klass, name, signature, static_field) compute_offset(klass::_##name##_offset, k, #name, signature, static_field, CHECK);
#define CHAR_FIELD(klass, name) FIELD(klass, name, "C", false)
#define INT_FIELD(klass, name) FIELD(klass, name, "I", false)
#define BOOLEAN_FIELD(klass, name) FIELD(klass, name, "Z", false)
#define LONG_FIELD(klass, name) FIELD(klass, name, "J", false)
#define FLOAT_FIELD(klass, name) FIELD(klass, name, "F", false)
#define OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, false)
#define STATIC_OOP_FIELD(klass, name, signature) FIELD(klass, name, signature, true)
#define STATIC_INT_FIELD(klass, name) FIELD(klass, name, "I", true)
#define STATIC_BOOLEAN_FIELD(klass, name) FIELD(klass, name, "Z", true)
void JVMCIJavaClasses::compute_offsets(TRAPS) {
COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, OOP_FIELD, OOP_FIELD, STATIC_OOP_FIELD, STATIC_OOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
#define FIELD(className, name, signature, static_field) compute_offset(className::_##name##_offset, className::_klass, #name, signature, static_field, CHECK);
#define CHAR_FIELD(className, name) FIELD(className, name, "C", false)
#define INT_FIELD(className, name) FIELD(className, name, "I", false)
#define BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", false)
#define LONG_FIELD(className, name) FIELD(className, name, "J", false)
#define FLOAT_FIELD(className, name) FIELD(className, name, "F", false)
#define OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, false)
#define STATIC_OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, true)
#define STATIC_INT_FIELD(className, name) FIELD(className, name, "I", true)
#define STATIC_BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", true)
#ifdef PRODUCT
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
#define CONSTRUCTOR(className, signature)
#else
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \
check_resolve_method(#hsCallType, k, vmSymbols::methodName##_name(), vmSymbols::signatureSymbolName(), CHECK);
#define CONSTRUCTOR(className, signature) { \
TempNewSymbol sig = SymbolTable::new_symbol(signature, CHECK); \
check_resolve_method("call_special", k, vmSymbols::object_initializer_name(), sig, CHECK); \
}
#endif
/**
* Computes and initializes the offsets used by HotSpotJVMCI.
*/
void HotSpotJVMCI::compute_offsets(TRAPS) {
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, OBJECT_FIELD, OBJECT_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECT_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
}
#undef START_CLASS
#undef END_CLASS
#undef METHOD
#undef CONSTRUCTOR
#undef FIELD
#undef CHAR_FIELD
#undef INT_FIELD
#undef BOOLEAN_FIELD
#undef LONG_FIELD
#undef FLOAT_FIELD
#undef OBJECT_FIELD
#undef PRIMARRAY_FIELD
#undef OBJECTARRAY_FIELD
#undef STATIC_FIELD
#undef STATIC_OBJECT_FIELD
#undef STATIC_OBJECTARRAY_FIELD
#undef STATIC_INT_FIELD
#undef STATIC_BOOLEAN_FIELD
#undef EMPTY_CAST
// ------------------------------------------------------------------
#define START_CLASS(className, fullClassName) \
void HotSpotJVMCI::className::initialize(JVMCI_TRAPS) { \
Thread* THREAD = Thread::current(); \
className::klass()->initialize(CHECK); \
} \
bool HotSpotJVMCI::className::is_instance(JVMCIEnv* env, JVMCIObject object) { \
return resolve(object)->is_a(className::klass()); \
} \
void HotSpotJVMCI::className::check(oop obj, const char* field_name, int offset) { \
assert(obj != NULL, "NULL field access of %s.%s", #className, field_name); \
assert(obj->is_a(className::klass()), "wrong class, " #className " expected, found %s", obj->klass()->external_name()); \
assert(offset != 0, "must be valid offset"); \
} \
InstanceKlass* HotSpotJVMCI::className::_klass = NULL;
#define END_CLASS
#define FIELD(className, name, type, accessor, cast) \
type HotSpotJVMCI::className::name(JVMCIEnv* env, oop obj) { className::check(obj, #name, className::_##name##_offset); return cast obj->accessor(className::_##name##_offset); } \
void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, oop obj, type x) { className::check(obj, #name, className::_##name##_offset); obj->accessor##_put(className::_##name##_offset, x); }
#define EMPTY_CAST
#define CHAR_FIELD(className, name) FIELD(className, name, jchar, char_field, EMPTY_CAST)
#define INT_FIELD(className, name) FIELD(className, name, jint, int_field, EMPTY_CAST)
#define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, bool_field, EMPTY_CAST)
#define LONG_FIELD(className, name) FIELD(className, name, jlong, long_field, EMPTY_CAST)
#define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, float_field, EMPTY_CAST)
#define OBJECT_FIELD(className, name, signature) FIELD(className, name, oop, obj_field, EMPTY_CAST)
#define OBJECTARRAY_FIELD(className, name, signature) FIELD(className, name, objArrayOop, obj_field, (objArrayOop))
#define PRIMARRAY_FIELD(className, name, signature) FIELD(className, name, typeArrayOop, obj_field, (typeArrayOop))
#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, oop)
#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, objArrayOop)
#define STATIC_OOPISH_FIELD(className, name, type) \
type HotSpotJVMCI::className::name(JVMCIEnv* env) { \
assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \
InstanceKlass* ik = className::klass(); \
oop base = ik->static_field_base_raw(); \
oop result = HeapAccess<>::oop_load_at(base, className::_##name##_offset); \
return type(result); \
} \
void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, type x) { \
assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \
assert(className::klass() != NULL, "Class not yet loaded: " #className); \
InstanceKlass* ik = className::klass(); \
oop base = ik->static_field_base_raw(); \
HeapAccess<>::oop_store_at(base, className::_##name##_offset, x); \
}
#define STATIC_PRIMITIVE_FIELD(className, name, jtypename) \
jtypename HotSpotJVMCI::className::get_##name(JVMCIEnv* env) { \
assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \
InstanceKlass* ik = className::klass(); \
oop base = ik->static_field_base_raw(); \
return HeapAccess<>::load_at(base, className::_##name##_offset); \
} \
void HotSpotJVMCI::className::set_##name(JVMCIEnv* env, jtypename x) { \
assert(className::klass() != NULL && className::klass()->is_linked(), "Class not yet linked: " #className); \
InstanceKlass* ik = className::klass(); \
oop base = ik->static_field_base_raw(); \
HeapAccess<>::store_at(base, _##name##_offset, x); \
}
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint)
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean)
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
#define CONSTRUCTOR(className, signature)
/**
* Generates the method and field definitions for the classes in HotSpotJVMCI. For example:
*
* void HotSpotJVMCI::Architecture::initialize(JVMCIEnv* env) { ... }
* bool HotSpotJVMCI::Architecture::is_instance(JVMCIEnv* env, JVMCIObject object) { ... }
* void HotSpotJVMCI::Architecture::check(oop obj, const char* field_name, int offset) { ... }
* oop HotSpotJVMCI::Architecture::wordKind(JVMCIEnv* env, oop obj) { ... }
* void HotSpotJVMCI::Architecture::set_wordKind(JVMCIEnv* env, oop obj, oop x) { ... }
*
* InstanceKlass *HotSpotJVMCI::Architecture::_klass = NULL;
*/
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
#undef START_CLASS
#undef END_CLASS
#undef METHOD
#undef CONSTRUCTOR
#undef FIELD
#undef CHAR_FIELD
#undef INT_FIELD
#undef BOOLEAN_FIELD
#undef LONG_FIELD
#undef FLOAT_FIELD
#undef OBJECT_FIELD
#undef PRIMARRAY_FIELD
#undef OBJECTARRAY_FIELD
#undef STATIC_OOPISH_FIELD
#undef STATIC_OBJECT_FIELD
#undef STATIC_OBJECTARRAY_FIELD
#undef STATIC_INT_FIELD
#undef STATIC_BOOLEAN_FIELD
#undef STATIC_PRIMITIVE_FIELD
#undef EMPTY_CAST
/**
* Initializes the JNI id of a field. As per the JNI specification,
* this ensures the declaring class is initialized.
*/
void JNIJVMCI::initialize_field_id(JNIEnv* env, jfieldID &fieldid, jclass clazz, const char* class_name, const char* name, const char* signature, bool static_field) {
if (JVMCILibDumpJNIConfig != NULL) {
fileStream* st = JVMCIGlobals::get_jni_config_file();
st->print_cr("field %s %s %s", class_name, name, signature);
return;
}
if (env->ExceptionCheck()) {
return;
}
if (static_field) {
// Class initialization barrier
fieldid = env->GetStaticFieldID(clazz, name, signature);
} else {
// Class initialization barrier
fieldid = env->GetFieldID(clazz, name, signature);
}
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
ResourceMark rm;
Thread* THREAD = Thread::current();
fatal("Could not find field %s.%s with signature %s", class_name, name, signature);
}
}
#define START_CLASS(className, fullClassName) { \
current_class_name = vmSymbols::fullClassName()->as_C_string(); \
if (JVMCILibDumpJNIConfig != NULL) { \
fileStream* st = JVMCIGlobals::get_jni_config_file(); \
st->print_cr("class %s", current_class_name); \
} else { \
jclass k = env->FindClass(current_class_name); \
JVMCI_EXCEPTION_CHECK(env, "FindClass(%s)", current_class_name); \
assert(k != NULL, #fullClassName " not initialized"); \
className::_class = (jclass) env->NewGlobalRef(k); \
}
#define END_CLASS current_class_name = NULL; }
#define FIELD(className, name, signature, static_field) initialize_field_id(env, className::_##name##_field_id, className::_class, current_class_name, #name, signature, static_field);
#define CHAR_FIELD(className, name) FIELD(className, name, "C", false)
#define INT_FIELD(className, name) FIELD(className, name, "I", false)
#define BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", false)
#define LONG_FIELD(className, name) FIELD(className, name, "J", false)
#define FLOAT_FIELD(className, name) FIELD(className, name, "F", false)
#define OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, false)
#define STATIC_OBJECT_FIELD(className, name, signature) FIELD(className, name, signature, true)
#define STATIC_INT_FIELD(className, name) FIELD(className, name, "I", true)
#define STATIC_BOOLEAN_FIELD(className, name) FIELD(className, name, "Z", true)
#define GET_JNI_METHOD(jniGetMethod, dst, clazz, methodName, signature) \
if (JVMCILibDumpJNIConfig != NULL) { \
fileStream* st = JVMCIGlobals::get_jni_config_file(); \
st->print_cr("method %s %s %s", current_class_name, methodName, signature); \
} else { \
dst = env->jniGetMethod(clazz, methodName, signature); \
JVMCI_EXCEPTION_CHECK(env, #jniGetMethod "(%s.%s%s)", current_class_name, methodName, signature); \
assert(dst != NULL, "uninitialized"); \
}
#define GET_JNI_CONSTRUCTOR(clazz, signature) \
GET_JNI_METHOD(GetMethodID, JNIJVMCI::clazz::_constructor, clazz::_class, "<init>", signature) \
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \
GET_JNI_METHOD(jniGetMethod, \
className::_##methodName##_method, \
className::clazz(), \
vmSymbols::methodName##_name()->as_C_string(), \
vmSymbols::signatureSymbolName()->as_C_string())
#define CONSTRUCTOR(className, signature) \
GET_JNI_CONSTRUCTOR(className, signature)
extern "C" {
void JNICALL JVM_RegisterJVMCINatives(JNIEnv *env, jclass compilerToVMClass);
jobject JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);
}
#define IN_CLASS(fullClassName) current_class_name = vmSymbols::fullClassName()->as_C_string()
/**
* Initializes the JNI method and field ids used in JNIJVMCI.
*/
void JNIJVMCI::initialize_ids(JNIEnv* env) {
ResourceMark rm;
const char* current_class_name = NULL;
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, OBJECT_FIELD, OBJECT_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECT_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
IN_CLASS(java_lang_Class);
GET_JNI_METHOD(GetMethodID, _Class_getName_method, Class::_class, "getName", "()Ljava/lang/String;");
IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedPrimitiveType);
GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedPrimitiveType_fromMetaspace_method, HotSpotResolvedPrimitiveType::_class,
vmSymbols::fromMetaspace_name()->as_C_string(),
vmSymbols::primitive_fromMetaspace_signature()->as_C_string());
IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl);
GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedObjectTypeImpl_fromMetaspace_method, HotSpotResolvedObjectTypeImpl::_class,
vmSymbols::fromMetaspace_name()->as_C_string(),
vmSymbols::klass_fromMetaspace_signature()->as_C_string());
IN_CLASS(jdk_vm_ci_hotspot_HotSpotConstantPool);
GET_JNI_METHOD(GetStaticMethodID, _HotSpotConstantPool_fromMetaspace_method, HotSpotConstantPool::_class,
vmSymbols::fromMetaspace_name()->as_C_string(),
vmSymbols::constantPool_fromMetaspace_signature()->as_C_string());
IN_CLASS(jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl);
GET_JNI_METHOD(GetStaticMethodID, _HotSpotResolvedJavaMethodImpl_fromMetaspace_method, HotSpotResolvedJavaMethodImpl::_class,
vmSymbols::fromMetaspace_name()->as_C_string(),
vmSymbols::method_fromMetaspace_signature()->as_C_string());
#define BOX_CLASSES(generate) \
generate(Boolean, T_BOOLEAN, Z) \
generate(Byte, T_BYTE, B) \
generate(Character, T_CHAR, C) \
generate(Short, T_SHORT, S) \
generate(Integer, T_INT, I) \
generate(Long, T_LONG, J) \
generate(Float, T_FLOAT, F) \
generate(Double, T_DOUBLE, D) \
#define DO_BOX_CLASS(klass, basicType, type) \
current_class_name = "java/lang/" #klass; \
if (JVMCILibDumpJNIConfig == NULL) { \
_box_classes[basicType] = env->FindClass("java/lang/" #klass); \
JVMCI_EXCEPTION_CHECK(env, "FindClass(%s)", #klass); \
_box_classes[basicType] = (jclass) env->NewGlobalRef(_box_classes[basicType]); \
assert(_box_classes[basicType] != NULL, "uninitialized"); \
_box_fields[basicType] = env->GetFieldID(_box_classes[basicType], "value", #type); \
JVMCI_EXCEPTION_CHECK(env, "GetFieldID(%s, value, %s)", #klass, #type); \
GET_JNI_METHOD(GetMethodID, _box_constructors[basicType], _box_classes[basicType], "<init>", "(" #type ")V"); \
} else { \
fileStream* st = JVMCIGlobals::get_jni_config_file(); \
st->print_cr("field %s value %s", current_class_name, #type); \
st->print_cr("method %s <init> (%s)V", current_class_name, #type); \
}
BOX_CLASSES(DO_BOX_CLASS);
if (JVMCILibDumpJNIConfig == NULL) {
_byte_array = env->FindClass("[B");
JVMCI_EXCEPTION_CHECK(env, "FindClass([B)");
_byte_array = (jclass) env->NewGlobalRef(_byte_array);
assert(_byte_array != NULL, "uninitialized");
} else {
fileStream* st = JVMCIGlobals::get_jni_config_file();
st->print_cr("class [B");
}
#define DUMP_ALL_NATIVE_METHODS(class_symbol) do { \
current_class_name = class_symbol->as_C_string(); \
Klass* k = SystemDictionary::resolve_or_fail(class_symbol, true, CHECK_EXIT); \
InstanceKlass* iklass = InstanceKlass::cast(k); \
Array<Method*>* methods = iklass->methods(); \
for (int i = 0; i < methods->length(); i++) { \
Method* m = methods->at(i); \
if (m->is_native()) { \
st->print_cr("method %s %s %s", current_class_name, m->name()->as_C_string(), m->signature()->as_C_string()); \
} \
} \
} while(0)
if (JVMCILibDumpJNIConfig != NULL) {
Thread* THREAD = Thread::current();
fileStream* st = JVMCIGlobals::get_jni_config_file();
DUMP_ALL_NATIVE_METHODS(vmSymbols::jdk_vm_ci_hotspot_CompilerToVM());
st->flush();
tty->print_cr("Dumped JVMCI shared library JNI configuration to %s", JVMCILibDumpJNIConfig);
vm_exit(0);
}
#undef DUMP_ALL_NATIVE_METHODS
#undef DO_BOX_CLASS
#undef BOX_CLASSES
#undef IN_CLASS
#define CC (char*) /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(f))
if (env != JavaThread::current()->jni_environment()) {
jclass clazz = env->FindClass("jdk/vm/ci/hotspot/CompilerToVM");
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
guarantee(false, "Could not find class jdk/vm/ci/hotspot/CompilerToVM");
}
JNINativeMethod CompilerToVM_native_methods[] = {
{ CC"registerNatives", CC"()V", FN_PTR(JVM_RegisterJVMCINatives) },
};
env->RegisterNatives(clazz, CompilerToVM_native_methods, 1);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
guarantee(false, "");
}
JNINativeMethod JVMCI_native_methods[] = {
{ CC"initializeRuntime", CC"()Ljdk/vm/ci/runtime/JVMCIRuntime;", FN_PTR(JVM_GetJVMCIRuntime) },
};
env->RegisterNatives(JVMCI::clazz(), JVMCI_native_methods, 1);
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
guarantee(false, "");
}
}
}
#undef METHOD
#undef CONSTRUCTOR
#undef FIELD2
#define EMPTY0
#define EMPTY1(x)
#define EMPTY2(x,y)
#define FIELD2(klass, name) int klass::_##name##_offset = 0;
#define FIELD3(klass, name, sig) FIELD2(klass, name)
#define FIELD3(className, name, sig) FIELD2(className, name)
#define FIELD2(className, name) \
jfieldID JNIJVMCI::className::_##name##_field_id = 0; \
int HotSpotJVMCI::className::_##name##_offset = 0;
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args)
#define CONSTRUCTOR(className, signature)
COMPILER_CLASSES_DO(EMPTY1, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2, FIELD2)
// Generates the definitions of static fields used by the accessors. For example:
// jfieldID JNIJVMCI::Architecture::_wordKind_field_id = 0;
// jfieldID HotSpotJVMCI::Architecture::_wordKind_offset = 0;
JVMCI_CLASSES_DO(EMPTY2, EMPTY0, FIELD2, FIELD2, FIELD2, FIELD2, FIELD2, FIELD3, FIELD3, FIELD3, FIELD3, FIELD3, FIELD2, FIELD2, METHOD, CONSTRUCTOR)
#undef START_CLASS
#undef END_CLASS
#undef METHOD
#undef CONSTRUCTOR
#undef FIELD
#undef CHAR_FIELD
#undef INT_FIELD
#undef BOOLEAN_FIELD
#undef LONG_FIELD
#undef FLOAT_FIELD
#undef OBJECT_FIELD
#undef PRIMARRAY_FIELD
#undef OBJECTARRAY_FIELD
#undef STATIC_FIELD
#undef STATIC_OBJECT_FIELD
#undef STATIC_OBJECTARRAY_FIELD
#undef STATIC_INT_FIELD
#undef STATIC_BOOLEAN_FIELD
#undef EMPTY_CAST
#define START_CLASS(className, fullClassName) \
void JNIJVMCI::className::initialize(JVMCI_TRAPS) { \
/* should already be initialized */ \
} \
bool JNIJVMCI::className::is_instance(JVMCIEnv* jvmciEnv, JVMCIObject object) { \
JNIAccessMark jni(jvmciEnv); \
return jni()->IsInstanceOf(object.as_jobject(), className::clazz()) != 0; \
} \
void JNIJVMCI::className::check(JVMCIEnv* jvmciEnv, JVMCIObject obj, const char* field_name, jfieldID offset) { \
assert(obj.is_non_null(), "NULL field access of %s.%s", #className, field_name); \
assert(jvmciEnv->isa_##className(obj), "wrong class, " #className " expected, found %s", jvmciEnv->klass_name(obj)); \
assert(offset != 0, "must be valid offset"); \
} \
jclass JNIJVMCI::className::_class = NULL;
#define END_CLASS
#define FIELD(className, name, type, accessor, cast) \
type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj) { \
className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \
JNIAccessMark jni(jvmciEnv); \
return cast jni()->Get##accessor##Field(resolve_handle(obj), className::_##name##_field_id); \
} \
void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj, type x) { \
className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \
JNIAccessMark jni(jvmciEnv); \
jni()->Set##accessor##Field(resolve_handle(obj), className::_##name##_field_id, x); \
} \
#define EMPTY_CAST
#define CHAR_FIELD(className, name) FIELD(className, name, jchar, Char, EMPTY_CAST)
#define INT_FIELD(className, name) FIELD(className, name, jint, Int, EMPTY_CAST)
#define BOOLEAN_FIELD(className, name) FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
#define LONG_FIELD(className, name) FIELD(className, name, jlong, Long, EMPTY_CAST)
#define FLOAT_FIELD(className, name) FIELD(className, name, jfloat, Float, EMPTY_CAST)
#define OBJECT_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObject, Object, EMPTY_CAST)
#define OBJECTARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
#define PRIMARRAY_FIELD(className, name, signature) OOPISH_FIELD(className, name, JVMCIPrimitiveArray, Object, (JVMCIPrimitiveArray))
#define STATIC_OBJECT_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObject, Object, (JVMCIObject))
#define STATIC_OBJECTARRAY_FIELD(className, name, signature) STATIC_OOPISH_FIELD(className, name, JVMCIObjectArray, Object, (JVMCIObjectArray))
#define OOPISH_FIELD(className, name, type, accessor, cast) \
type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj) { \
className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \
JNIAccessMark jni(jvmciEnv); \
return cast wrap(jni()->Get##accessor##Field(resolve_handle(obj), className::_##name##_field_id)); \
} \
void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, JVMCIObject obj, type x) { \
className::check(jvmciEnv, obj, #name, className::_##name##_field_id); \
JNIAccessMark jni(jvmciEnv); \
jni()->Set##accessor##Field(resolve_handle(obj), className::_##name##_field_id, resolve_handle(x)); \
}
#define STATIC_OOPISH_FIELD(className, name, type, accessor, cast) \
type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv) { \
JNIAccessMark jni(jvmciEnv); \
return cast wrap(jni()->GetStatic##accessor##Field(className::clazz(), className::_##name##_field_id)); \
} \
void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, type x) { \
JNIAccessMark jni(jvmciEnv); \
jni()->SetStatic##accessor##Field(className::clazz(), className::_##name##_field_id, resolve_handle(x)); \
}
#define STATIC_PRIMITIVE_FIELD(className, name, type, accessor, cast) \
type JNIJVMCI::className::get_##name(JVMCIEnv* jvmciEnv) { \
JNIAccessMark jni(jvmciEnv); \
return cast jni()->GetStatic##accessor##Field(className::clazz(), className::_##name##_field_id); \
} \
void JNIJVMCI::className::set_##name(JVMCIEnv* jvmciEnv, type x) { \
JNIAccessMark jni(jvmciEnv); \
jni()->SetStatic##accessor##Field(className::clazz(), className::_##name##_field_id, x); \
}
#define STATIC_INT_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jint, Int, EMPTY_CAST)
#define STATIC_BOOLEAN_FIELD(className, name) STATIC_PRIMITIVE_FIELD(className, name, jboolean, Boolean, EMPTY_CAST)
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \
jmethodID JNIJVMCI::className::_##methodName##_method;
#define CONSTRUCTOR(className, signature) \
jmethodID JNIJVMCI::className::_constructor;
/**
* Generates the method definitions for the classes in HotSpotJVMCI.
*/
JVMCI_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
#undef METHOD
#undef CONSTRUCTOR
#undef START_CLASS
#undef END_CLASS
#undef FIELD
#undef CHAR_FIELD
#undef INT_FIELD
#undef BOOLEAN_FIELD
#undef LONG_FIELD
#undef FLOAT_FIELD
#undef OBJECT_FIELD
#undef PRIMARRAY_FIELD
#undef OBJECTARRAY_FIELD
#undef STATIC_OOPISH_FIELD
#undef STATIC_OBJECT_FIELD
#undef STATIC_OBJECTARRAY_FIELD
#undef STATIC_INT_FIELD
#undef STATIC_BOOLEAN_FIELD
#undef STATIC_PRIMITIVE_FIELD
#undef OOPISH_FIELD
#undef EMPTY_CAST

View File

@ -24,361 +24,644 @@
#ifndef SHARE_JVMCI_JVMCIJAVACLASSES_HPP
#define SHARE_JVMCI_JVMCIJAVACLASSES_HPP
#include "classfile/systemDictionary.hpp"
#include "oops/access.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/oop.hpp"
#include "classfile/vmSymbols.hpp"
#include "jvmci/jvmciExceptions.hpp"
#include "jvmci/jvmciObject.hpp"
#include "runtime/jniHandles.hpp"
class JVMCIJavaClasses : AllStatic {
public:
static void compute_offsets(TRAPS);
};
/* This macro defines the structure of the JVMCI classes accessed from VM code.
* It will generate classes with accessors similar to javaClasses.hpp, but with specializations for oops, Handles and jni handles.
/*
* This macro defines the structure of the JVMCI classes accessed from VM code. It is used to
* generate accessors similar to javaClasses.hpp, but with specializations for HotSpot and JNI based
* access.
*
* The public interface of these classes will look like this:
* class StackSlot : AllStatic {
* public:
* static Klass* klass();
* static jint index(oop obj);
* static jint index(Handle obj);
* static jint index(jobject obj);
* static void set_index(oop obj, jint x);
* static void set_index(Handle obj, jint x);
* static void set_index(jobject obj, jint x);
* };
* HotSpotJVMCI: This class contains accessors based on the VM internal
* interface to Java. It is used for JVMCI Java code executing on the HotSpot heap.
*
* JNIJVMCI: This class contains JNI based accessors and is used for JVMCI
* Java code executing in the JVMCI shared library.
*/
#define COMPILER_CLASSES_DO(start_class, end_class, char_field, int_field, boolean_field, long_field, float_field, oop_field, typeArrayOop_field, objArrayOop_field, static_oop_field, static_objArrayOop_field, static_int_field, static_boolean_field) \
start_class(Architecture) \
oop_field(Architecture, wordKind, "Ljdk/vm/ci/meta/PlatformKind;") \
end_class \
start_class(TargetDescription) \
oop_field(TargetDescription, arch, "Ljdk/vm/ci/code/Architecture;") \
end_class \
start_class(HotSpotResolvedObjectTypeImpl) \
oop_field(HotSpotResolvedObjectTypeImpl, javaClass, "Ljava/lang/Class;") \
end_class \
start_class(HotSpotResolvedJavaMethodImpl) \
long_field(HotSpotResolvedJavaMethodImpl, metaspaceMethod) \
end_class \
start_class(InstalledCode) \
long_field(InstalledCode, address) \
long_field(InstalledCode, entryPoint) \
long_field(InstalledCode, version) \
oop_field(InstalledCode, name, "Ljava/lang/String;") \
end_class \
start_class(HotSpotInstalledCode) \
int_field(HotSpotInstalledCode, size) \
long_field(HotSpotInstalledCode, codeStart) \
int_field(HotSpotInstalledCode, codeSize) \
end_class \
start_class(HotSpotNmethod) \
boolean_field(HotSpotNmethod, isDefault) \
end_class \
start_class(HotSpotCompiledCode) \
oop_field(HotSpotCompiledCode, name, "Ljava/lang/String;") \
typeArrayOop_field(HotSpotCompiledCode, targetCode, "[B") \
int_field(HotSpotCompiledCode, targetCodeSize) \
objArrayOop_field(HotSpotCompiledCode, sites, "[Ljdk/vm/ci/code/site/Site;") \
objArrayOop_field(HotSpotCompiledCode, assumptions, "[Ljdk/vm/ci/meta/Assumptions$Assumption;") \
objArrayOop_field(HotSpotCompiledCode, methods, "[Ljdk/vm/ci/meta/ResolvedJavaMethod;") \
objArrayOop_field(HotSpotCompiledCode, comments, "[Ljdk/vm/ci/hotspot/HotSpotCompiledCode$Comment;") \
typeArrayOop_field(HotSpotCompiledCode, dataSection, "[B") \
int_field(HotSpotCompiledCode, dataSectionAlignment) \
objArrayOop_field(HotSpotCompiledCode, dataSectionPatches, "[Ljdk/vm/ci/code/site/DataPatch;") \
boolean_field(HotSpotCompiledCode, isImmutablePIC) \
int_field(HotSpotCompiledCode, totalFrameSize) \
oop_field(HotSpotCompiledCode, deoptRescueSlot, "Ljdk/vm/ci/code/StackSlot;") \
end_class \
start_class(HotSpotCompiledCode_Comment) \
oop_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;") \
int_field(HotSpotCompiledCode_Comment, pcOffset) \
end_class \
start_class(HotSpotCompiledNmethod) \
oop_field(HotSpotCompiledNmethod, method, "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;") \
oop_field(HotSpotCompiledNmethod, installationFailureMessage, "Ljava/lang/String;") \
int_field(HotSpotCompiledNmethod, entryBCI) \
int_field(HotSpotCompiledNmethod, id) \
long_field(HotSpotCompiledNmethod, jvmciEnv) \
boolean_field(HotSpotCompiledNmethod, hasUnsafeAccess) \
end_class \
start_class(HotSpotJVMCIMetaAccessContext) \
static_objArrayOop_field(HotSpotJVMCIMetaAccessContext, allContexts, "[Ljava/lang/ref/WeakReference;") \
objArrayOop_field(HotSpotJVMCIMetaAccessContext, metadataRoots, "[Ljava/lang/Object;") \
end_class \
start_class(HotSpotForeignCallTarget) \
long_field(HotSpotForeignCallTarget, address) \
end_class \
start_class(VMField) \
oop_field(VMField, name, "Ljava/lang/String;") \
oop_field(VMField, type, "Ljava/lang/String;") \
long_field(VMField, offset) \
long_field(VMField, address) \
oop_field(VMField, value, "Ljava/lang/Object;") \
end_class \
start_class(VMFlag) \
oop_field(VMFlag, name, "Ljava/lang/String;") \
oop_field(VMFlag, type, "Ljava/lang/String;") \
oop_field(VMFlag, value, "Ljava/lang/Object;") \
end_class \
start_class(VMIntrinsicMethod) \
oop_field(VMIntrinsicMethod, declaringClass, "Ljava/lang/String;") \
oop_field(VMIntrinsicMethod, name, "Ljava/lang/String;") \
oop_field(VMIntrinsicMethod, descriptor, "Ljava/lang/String;") \
int_field(VMIntrinsicMethod, id) \
end_class \
start_class(Assumptions_NoFinalizableSubclass) \
oop_field(Assumptions_NoFinalizableSubclass, receiverType, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
end_class \
start_class(Assumptions_ConcreteSubtype) \
oop_field(Assumptions_ConcreteSubtype, context, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
oop_field(Assumptions_ConcreteSubtype, subtype, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
end_class \
start_class(Assumptions_LeafType) \
oop_field(Assumptions_LeafType, context, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
end_class \
start_class(Assumptions_ConcreteMethod) \
oop_field(Assumptions_ConcreteMethod, method, "Ljdk/vm/ci/meta/ResolvedJavaMethod;") \
oop_field(Assumptions_ConcreteMethod, context, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
oop_field(Assumptions_ConcreteMethod, impl, "Ljdk/vm/ci/meta/ResolvedJavaMethod;") \
end_class \
start_class(Assumptions_CallSiteTargetValue) \
oop_field(Assumptions_CallSiteTargetValue, callSite, "Ljdk/vm/ci/meta/JavaConstant;") \
oop_field(Assumptions_CallSiteTargetValue, methodHandle, "Ljdk/vm/ci/meta/JavaConstant;") \
end_class \
start_class(site_Site) \
int_field(site_Site, pcOffset) \
end_class \
start_class(site_Call) \
oop_field(site_Call, target, "Ljdk/vm/ci/meta/InvokeTarget;") \
oop_field(site_Call, debugInfo, "Ljdk/vm/ci/code/DebugInfo;") \
end_class \
start_class(site_DataPatch) \
oop_field(site_DataPatch, reference, "Ljdk/vm/ci/code/site/Reference;") \
end_class \
start_class(site_ConstantReference) \
oop_field(site_ConstantReference, constant, "Ljdk/vm/ci/meta/VMConstant;") \
end_class \
start_class(site_DataSectionReference) \
int_field(site_DataSectionReference, offset) \
end_class \
start_class(site_InfopointReason) \
static_oop_field(site_InfopointReason, SAFEPOINT, "Ljdk/vm/ci/code/site/InfopointReason;") \
static_oop_field(site_InfopointReason, CALL, "Ljdk/vm/ci/code/site/InfopointReason;") \
static_oop_field(site_InfopointReason, IMPLICIT_EXCEPTION, "Ljdk/vm/ci/code/site/InfopointReason;") \
end_class \
start_class(site_Infopoint) \
oop_field(site_Infopoint, debugInfo, "Ljdk/vm/ci/code/DebugInfo;") \
oop_field(site_Infopoint, reason, "Ljdk/vm/ci/code/site/InfopointReason;") \
end_class \
start_class(site_ExceptionHandler) \
int_field(site_ExceptionHandler, handlerPos) \
end_class \
start_class(site_Mark) \
oop_field(site_Mark, id, "Ljava/lang/Object;") \
end_class \
start_class(HotSpotCompilationRequestResult) \
oop_field(HotSpotCompilationRequestResult, failureMessage, "Ljava/lang/String;") \
boolean_field(HotSpotCompilationRequestResult, retry) \
int_field(HotSpotCompilationRequestResult, inlinedBytecodes) \
end_class \
start_class(DebugInfo) \
oop_field(DebugInfo, bytecodePosition, "Ljdk/vm/ci/code/BytecodePosition;") \
oop_field(DebugInfo, referenceMap, "Ljdk/vm/ci/code/ReferenceMap;") \
oop_field(DebugInfo, calleeSaveInfo, "Ljdk/vm/ci/code/RegisterSaveLayout;") \
objArrayOop_field(DebugInfo, virtualObjectMapping, "[Ljdk/vm/ci/code/VirtualObject;") \
end_class \
start_class(HotSpotReferenceMap) \
objArrayOop_field(HotSpotReferenceMap, objects, "[Ljdk/vm/ci/code/Location;") \
objArrayOop_field(HotSpotReferenceMap, derivedBase, "[Ljdk/vm/ci/code/Location;") \
typeArrayOop_field(HotSpotReferenceMap, sizeInBytes, "[I") \
int_field(HotSpotReferenceMap, maxRegisterSize) \
end_class \
start_class(RegisterSaveLayout) \
objArrayOop_field(RegisterSaveLayout, registers, "[Ljdk/vm/ci/code/Register;") \
typeArrayOop_field(RegisterSaveLayout, slots, "[I") \
end_class \
start_class(BytecodeFrame) \
objArrayOop_field(BytecodeFrame, values, "[Ljdk/vm/ci/meta/JavaValue;") \
objArrayOop_field(BytecodeFrame, slotKinds, "[Ljdk/vm/ci/meta/JavaKind;") \
int_field(BytecodeFrame, numLocals) \
int_field(BytecodeFrame, numStack) \
int_field(BytecodeFrame, numLocks) \
boolean_field(BytecodeFrame, rethrowException) \
boolean_field(BytecodeFrame, duringCall) \
static_int_field(BytecodeFrame, UNKNOWN_BCI) \
static_int_field(BytecodeFrame, UNWIND_BCI) \
static_int_field(BytecodeFrame, BEFORE_BCI) \
static_int_field(BytecodeFrame, AFTER_BCI) \
static_int_field(BytecodeFrame, AFTER_EXCEPTION_BCI) \
static_int_field(BytecodeFrame, INVALID_FRAMESTATE_BCI) \
end_class \
start_class(BytecodePosition) \
oop_field(BytecodePosition, caller, "Ljdk/vm/ci/code/BytecodePosition;") \
oop_field(BytecodePosition, method, "Ljdk/vm/ci/meta/ResolvedJavaMethod;") \
int_field(BytecodePosition, bci) \
end_class \
start_class(JavaConstant) \
end_class \
start_class(PrimitiveConstant) \
oop_field(PrimitiveConstant, kind, "Ljdk/vm/ci/meta/JavaKind;") \
long_field(PrimitiveConstant, primitive) \
end_class \
start_class(RawConstant) \
long_field(RawConstant, primitive) \
end_class \
start_class(NullConstant) \
end_class \
start_class(HotSpotCompressedNullConstant) \
end_class \
start_class(HotSpotObjectConstantImpl) \
oop_field(HotSpotObjectConstantImpl, object, "Ljava/lang/Object;") \
boolean_field(HotSpotObjectConstantImpl, compressed) \
end_class \
start_class(HotSpotMetaspaceConstantImpl) \
oop_field(HotSpotMetaspaceConstantImpl, metaspaceObject, "Ljdk/vm/ci/hotspot/MetaspaceWrapperObject;") \
boolean_field(HotSpotMetaspaceConstantImpl, compressed) \
end_class \
start_class(HotSpotSentinelConstant) \
end_class \
start_class(JavaKind) \
char_field(JavaKind, typeChar) \
static_oop_field(JavaKind, Boolean, "Ljdk/vm/ci/meta/JavaKind;") \
static_oop_field(JavaKind, Byte, "Ljdk/vm/ci/meta/JavaKind;") \
static_oop_field(JavaKind, Char, "Ljdk/vm/ci/meta/JavaKind;") \
static_oop_field(JavaKind, Short, "Ljdk/vm/ci/meta/JavaKind;") \
static_oop_field(JavaKind, Int, "Ljdk/vm/ci/meta/JavaKind;") \
static_oop_field(JavaKind, Long, "Ljdk/vm/ci/meta/JavaKind;") \
end_class \
start_class(ValueKind) \
oop_field(ValueKind, platformKind, "Ljdk/vm/ci/meta/PlatformKind;") \
end_class \
start_class(Value) \
oop_field(Value, valueKind, "Ljdk/vm/ci/meta/ValueKind;") \
static_oop_field(Value, ILLEGAL, "Ljdk/vm/ci/meta/AllocatableValue;") \
end_class \
start_class(RegisterValue) \
oop_field(RegisterValue, reg, "Ljdk/vm/ci/code/Register;") \
end_class \
start_class(code_Location) \
oop_field(code_Location, reg, "Ljdk/vm/ci/code/Register;") \
int_field(code_Location, offset) \
end_class \
start_class(code_Register) \
int_field(code_Register, number) \
int_field(code_Register, encoding) \
end_class \
start_class(StackSlot) \
int_field(StackSlot, offset) \
boolean_field(StackSlot, addFrameSize) \
end_class \
start_class(VirtualObject) \
int_field(VirtualObject, id) \
oop_field(VirtualObject, type, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
objArrayOop_field(VirtualObject, values, "[Ljdk/vm/ci/meta/JavaValue;") \
objArrayOop_field(VirtualObject, slotKinds, "[Ljdk/vm/ci/meta/JavaKind;") \
end_class \
start_class(StackLockValue) \
oop_field(StackLockValue, owner, "Ljdk/vm/ci/meta/JavaValue;") \
oop_field(StackLockValue, slot, "Ljdk/vm/ci/meta/AllocatableValue;") \
boolean_field(StackLockValue, eliminated) \
end_class \
start_class(HotSpotSpeculationLog) \
long_field(HotSpotSpeculationLog, lastFailed) \
end_class \
start_class(HotSpotStackFrameReference) \
oop_field(HotSpotStackFrameReference, compilerToVM, "Ljdk/vm/ci/hotspot/CompilerToVM;") \
boolean_field(HotSpotStackFrameReference, objectsMaterialized) \
long_field(HotSpotStackFrameReference, stackPointer) \
int_field(HotSpotStackFrameReference, frameNumber) \
int_field(HotSpotStackFrameReference, bci) \
oop_field(HotSpotStackFrameReference, method, "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;") \
objArrayOop_field(HotSpotStackFrameReference, locals, "[Ljava/lang/Object;") \
typeArrayOop_field(HotSpotStackFrameReference, localIsVirtual, "[Z") \
end_class \
start_class(HotSpotMetaData) \
typeArrayOop_field(HotSpotMetaData, pcDescBytes, "[B") \
typeArrayOop_field(HotSpotMetaData, scopesDescBytes, "[B") \
typeArrayOop_field(HotSpotMetaData, relocBytes, "[B") \
typeArrayOop_field(HotSpotMetaData, exceptionBytes, "[B") \
typeArrayOop_field(HotSpotMetaData, oopMaps, "[B") \
objArrayOop_field(HotSpotMetaData, metadata, "[Ljava/lang/Object;") \
end_class \
start_class(HotSpotConstantPool) \
long_field(HotSpotConstantPool, metaspaceConstantPool) \
end_class \
start_class(HotSpotJVMCIRuntime) \
objArrayOop_field(HotSpotJVMCIRuntime, excludeFromJVMCICompilation, "[Ljava/lang/Module;") \
end_class \
#define JVMCI_CLASSES_DO(start_class, \
end_class, \
char_field, \
int_field, \
boolean_field, \
long_field, \
float_field, \
object_field, \
primarray_field, \
objectarray_field, \
static_object_field, \
static_objectarray_field, \
static_int_field, \
static_boolean_field, \
jvmci_method, \
jvmci_constructor) \
start_class(Services, jdk_vm_ci_services_Services) \
jvmci_method(CallStaticVoidMethod, GetStaticMethodID, call_static, void, Services, initializeSavedProperties, byte_array_void_signature, (JVMCIObject serializedProperties)) \
end_class \
start_class(Architecture, jdk_vm_ci_code_Architecture) \
object_field(Architecture, wordKind, "Ljdk/vm/ci/meta/PlatformKind;") \
end_class \
start_class(TargetDescription, jdk_vm_ci_code_TargetDescription) \
object_field(TargetDescription, arch, "Ljdk/vm/ci/code/Architecture;") \
end_class \
start_class(HotSpotResolvedObjectTypeImpl, jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl) \
long_field(HotSpotResolvedObjectTypeImpl, metadataPointer) \
end_class \
start_class(HotSpotResolvedPrimitiveType, jdk_vm_ci_hotspot_HotSpotResolvedPrimitiveType) \
object_field(HotSpotResolvedPrimitiveType, mirror, "Ljdk/vm/ci/hotspot/HotSpotObjectConstantImpl;") \
object_field(HotSpotResolvedPrimitiveType, kind, "Ljdk/vm/ci/meta/JavaKind;") \
static_objectarray_field(HotSpotResolvedPrimitiveType, primitives, "[Ljdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType;") \
end_class \
start_class(HotSpotResolvedJavaFieldImpl, jdk_vm_ci_hotspot_HotSpotResolvedJavaFieldImpl) \
object_field(HotSpotResolvedJavaFieldImpl, type, "Ljdk/vm/ci/meta/JavaType;") \
object_field(HotSpotResolvedJavaFieldImpl, holder, "Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;") \
int_field(HotSpotResolvedJavaFieldImpl, offset) \
int_field(HotSpotResolvedJavaFieldImpl, modifiers) \
end_class \
start_class(HotSpotResolvedJavaMethodImpl, jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl) \
long_field(HotSpotResolvedJavaMethodImpl, metadataHandle) \
end_class \
start_class(InstalledCode, jdk_vm_ci_code_InstalledCode) \
long_field(InstalledCode, address) \
long_field(InstalledCode, entryPoint) \
long_field(InstalledCode, version) \
object_field(InstalledCode, name, "Ljava/lang/String;") \
end_class \
start_class(HotSpotInstalledCode, jdk_vm_ci_hotspot_HotSpotInstalledCode) \
int_field(HotSpotInstalledCode, size) \
long_field(HotSpotInstalledCode, codeStart) \
int_field(HotSpotInstalledCode, codeSize) \
end_class \
start_class(HotSpotNmethod, jdk_vm_ci_hotspot_HotSpotNmethod) \
boolean_field(HotSpotNmethod, isDefault) \
long_field(HotSpotNmethod, compileIdSnapshot) \
object_field(HotSpotNmethod, method, "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;") \
jvmci_constructor(HotSpotNmethod, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZJ)V") \
end_class \
start_class(HotSpotCompiledCode, jdk_vm_ci_hotspot_HotSpotCompiledCode) \
object_field(HotSpotCompiledCode, name, "Ljava/lang/String;") \
primarray_field(HotSpotCompiledCode, targetCode, "[B") \
int_field(HotSpotCompiledCode, targetCodeSize) \
objectarray_field(HotSpotCompiledCode, sites, "[Ljdk/vm/ci/code/site/Site;") \
objectarray_field(HotSpotCompiledCode, assumptions, "[Ljdk/vm/ci/meta/Assumptions$Assumption;") \
objectarray_field(HotSpotCompiledCode, methods, "[Ljdk/vm/ci/meta/ResolvedJavaMethod;") \
objectarray_field(HotSpotCompiledCode, comments, "[Ljdk/vm/ci/hotspot/HotSpotCompiledCode$Comment;") \
primarray_field(HotSpotCompiledCode, dataSection, "[B") \
int_field(HotSpotCompiledCode, dataSectionAlignment) \
objectarray_field(HotSpotCompiledCode, dataSectionPatches, "[Ljdk/vm/ci/code/site/DataPatch;") \
boolean_field(HotSpotCompiledCode, isImmutablePIC) \
int_field(HotSpotCompiledCode, totalFrameSize) \
object_field(HotSpotCompiledCode, deoptRescueSlot, "Ljdk/vm/ci/code/StackSlot;") \
end_class \
start_class(HotSpotCompiledCode_Comment, jdk_vm_ci_hotspot_HotSpotCompiledCode_Comment) \
object_field(HotSpotCompiledCode_Comment, text, "Ljava/lang/String;") \
int_field(HotSpotCompiledCode_Comment, pcOffset) \
end_class \
start_class(HotSpotCompiledNmethod, jdk_vm_ci_hotspot_HotSpotCompiledNmethod) \
object_field(HotSpotCompiledNmethod, method, "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;") \
object_field(HotSpotCompiledNmethod, installationFailureMessage, "Ljava/lang/String;") \
int_field(HotSpotCompiledNmethod, entryBCI) \
int_field(HotSpotCompiledNmethod, id) \
long_field(HotSpotCompiledNmethod, compileState) \
boolean_field(HotSpotCompiledNmethod, hasUnsafeAccess) \
end_class \
start_class(HotSpotForeignCallTarget, jdk_vm_ci_hotspot_HotSpotForeignCallTarget) \
long_field(HotSpotForeignCallTarget, address) \
end_class \
start_class(VMField, jdk_vm_ci_hotspot_VMField) \
object_field(VMField, name, "Ljava/lang/String;") \
object_field(VMField, type, "Ljava/lang/String;") \
long_field(VMField, offset) \
long_field(VMField, address) \
object_field(VMField, value, "Ljava/lang/Object;") \
jvmci_constructor(VMField, "(Ljava/lang/String;Ljava/lang/String;JJLjava/lang/Object;)V") \
end_class \
start_class(VMFlag, jdk_vm_ci_hotspot_VMFlag) \
object_field(VMFlag, name, "Ljava/lang/String;") \
object_field(VMFlag, type, "Ljava/lang/String;") \
object_field(VMFlag, value, "Ljava/lang/Object;") \
jvmci_constructor(VMFlag, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V") \
end_class \
start_class(VMIntrinsicMethod, jdk_vm_ci_hotspot_VMIntrinsicMethod) \
object_field(VMIntrinsicMethod, declaringClass, "Ljava/lang/String;") \
object_field(VMIntrinsicMethod, name, "Ljava/lang/String;") \
object_field(VMIntrinsicMethod, descriptor, "Ljava/lang/String;") \
int_field(VMIntrinsicMethod, id) \
jvmci_constructor(VMIntrinsicMethod, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V") \
end_class \
start_class(Assumptions_NoFinalizableSubclass, jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass) \
object_field(Assumptions_NoFinalizableSubclass, receiverType, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
end_class \
start_class(Assumptions_ConcreteSubtype, jdk_vm_ci_meta_Assumptions_ConcreteSubtype) \
object_field(Assumptions_ConcreteSubtype, context, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
object_field(Assumptions_ConcreteSubtype, subtype, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
end_class \
start_class(Assumptions_LeafType, jdk_vm_ci_meta_Assumptions_LeafType) \
object_field(Assumptions_LeafType, context, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
end_class \
start_class(Assumptions_ConcreteMethod, jdk_vm_ci_meta_Assumptions_ConcreteMethod) \
object_field(Assumptions_ConcreteMethod, method, "Ljdk/vm/ci/meta/ResolvedJavaMethod;") \
object_field(Assumptions_ConcreteMethod, context, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
object_field(Assumptions_ConcreteMethod, impl, "Ljdk/vm/ci/meta/ResolvedJavaMethod;") \
end_class \
start_class(Assumptions_CallSiteTargetValue, jdk_vm_ci_meta_Assumptions_CallSiteTargetValue) \
object_field(Assumptions_CallSiteTargetValue, callSite, "Ljdk/vm/ci/meta/JavaConstant;") \
object_field(Assumptions_CallSiteTargetValue, methodHandle, "Ljdk/vm/ci/meta/JavaConstant;") \
end_class \
start_class(site_Site, jdk_vm_ci_code_site_Site) \
int_field(site_Site, pcOffset) \
end_class \
start_class(site_Call, jdk_vm_ci_code_site_Call) \
object_field(site_Call, target, "Ljdk/vm/ci/meta/InvokeTarget;") \
end_class \
start_class(site_DataPatch, jdk_vm_ci_code_site_DataPatch) \
object_field(site_DataPatch, reference, "Ljdk/vm/ci/code/site/Reference;") \
end_class \
start_class(site_ConstantReference, jdk_vm_ci_code_site_ConstantReference) \
object_field(site_ConstantReference, constant, "Ljdk/vm/ci/meta/VMConstant;") \
end_class \
start_class(site_DataSectionReference, jdk_vm_ci_code_site_DataSectionReference) \
int_field(site_DataSectionReference, offset) \
end_class \
start_class(site_InfopointReason, jdk_vm_ci_code_site_InfopointReason) \
static_object_field(site_InfopointReason, SAFEPOINT, "Ljdk/vm/ci/code/site/InfopointReason;") \
static_object_field(site_InfopointReason, CALL, "Ljdk/vm/ci/code/site/InfopointReason;") \
static_object_field(site_InfopointReason, IMPLICIT_EXCEPTION, "Ljdk/vm/ci/code/site/InfopointReason;") \
end_class \
start_class(site_Infopoint, jdk_vm_ci_code_site_Infopoint) \
object_field(site_Infopoint, debugInfo, "Ljdk/vm/ci/code/DebugInfo;") \
object_field(site_Infopoint, reason, "Ljdk/vm/ci/code/site/InfopointReason;") \
end_class \
start_class(site_ExceptionHandler, jdk_vm_ci_code_site_ExceptionHandler) \
int_field(site_ExceptionHandler, handlerPos) \
end_class \
start_class(site_Mark, jdk_vm_ci_code_site_Mark) \
object_field(site_Mark, id, "Ljava/lang/Object;") \
end_class \
start_class(HotSpotCompilationRequestResult, jdk_vm_ci_hotspot_HotSpotCompilationRequestResult) \
object_field(HotSpotCompilationRequestResult, failureMessage, "Ljava/lang/String;") \
boolean_field(HotSpotCompilationRequestResult, retry) \
int_field(HotSpotCompilationRequestResult, inlinedBytecodes) \
end_class \
start_class(DebugInfo, jdk_vm_ci_code_DebugInfo) \
object_field(DebugInfo, bytecodePosition, "Ljdk/vm/ci/code/BytecodePosition;") \
object_field(DebugInfo, referenceMap, "Ljdk/vm/ci/code/ReferenceMap;") \
object_field(DebugInfo, calleeSaveInfo, "Ljdk/vm/ci/code/RegisterSaveLayout;") \
objectarray_field(DebugInfo, virtualObjectMapping, "[Ljdk/vm/ci/code/VirtualObject;") \
end_class \
start_class(HotSpotReferenceMap, jdk_vm_ci_hotspot_HotSpotReferenceMap) \
objectarray_field(HotSpotReferenceMap, objects, "[Ljdk/vm/ci/code/Location;") \
objectarray_field(HotSpotReferenceMap, derivedBase, "[Ljdk/vm/ci/code/Location;") \
primarray_field(HotSpotReferenceMap, sizeInBytes, "[I") \
int_field(HotSpotReferenceMap, maxRegisterSize) \
end_class \
start_class(RegisterSaveLayout, jdk_vm_ci_code_RegisterSaveLayout) \
objectarray_field(RegisterSaveLayout, registers, "[Ljdk/vm/ci/code/Register;") \
primarray_field(RegisterSaveLayout, slots, "[I") \
end_class \
start_class(BytecodeFrame, jdk_vm_ci_code_BytecodeFrame) \
objectarray_field(BytecodeFrame, values, "[Ljdk/vm/ci/meta/JavaValue;") \
objectarray_field(BytecodeFrame, slotKinds, "[Ljdk/vm/ci/meta/JavaKind;") \
int_field(BytecodeFrame, numLocals) \
int_field(BytecodeFrame, numStack) \
int_field(BytecodeFrame, numLocks) \
boolean_field(BytecodeFrame, rethrowException) \
boolean_field(BytecodeFrame, duringCall) \
static_int_field(BytecodeFrame, UNKNOWN_BCI) \
static_int_field(BytecodeFrame, UNWIND_BCI) \
static_int_field(BytecodeFrame, BEFORE_BCI) \
static_int_field(BytecodeFrame, AFTER_BCI) \
static_int_field(BytecodeFrame, AFTER_EXCEPTION_BCI) \
static_int_field(BytecodeFrame, INVALID_FRAMESTATE_BCI) \
end_class \
start_class(BytecodePosition, jdk_vm_ci_code_BytecodePosition) \
object_field(BytecodePosition, caller, "Ljdk/vm/ci/code/BytecodePosition;") \
object_field(BytecodePosition, method, "Ljdk/vm/ci/meta/ResolvedJavaMethod;") \
int_field(BytecodePosition, bci) \
end_class \
start_class(JavaConstant, jdk_vm_ci_meta_JavaConstant) \
static_object_field(JavaConstant, NULL_POINTER, "Ljdk/vm/ci/meta/JavaConstant;") \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JavaConstant, forFloat, forFloat_signature, (JVMCIObject kind, jlong value, JVMCI_TRAPS)) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JavaConstant, forDouble, forDouble_signature, (JVMCIObject kind, jlong value, JVMCI_TRAPS)) \
end_class \
start_class(ResolvedJavaMethod, jdk_vm_ci_meta_ResolvedJavaMethod) \
end_class \
start_class(PrimitiveConstant, jdk_vm_ci_meta_PrimitiveConstant) \
object_field(PrimitiveConstant, kind, "Ljdk/vm/ci/meta/JavaKind;") \
long_field(PrimitiveConstant, primitive) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, PrimitiveConstant, forTypeChar, forTypeChar_signature, (JVMCIObject kind, jlong value, JVMCI_TRAPS)) \
end_class \
start_class(RawConstant, jdk_vm_ci_meta_RawConstant) \
end_class \
start_class(NullConstant, jdk_vm_ci_meta_NullConstant) \
end_class \
start_class(HotSpotCompressedNullConstant, jdk_vm_ci_hotspot_HotSpotCompressedNullConstant) \
end_class \
start_class(HotSpotObjectConstantImpl, jdk_vm_ci_hotspot_HotSpotObjectConstantImpl) \
boolean_field(HotSpotObjectConstantImpl, compressed) \
end_class \
start_class(DirectHotSpotObjectConstantImpl, jdk_vm_ci_hotspot_DirectHotSpotObjectConstantImpl) \
object_field(DirectHotSpotObjectConstantImpl, object, "Ljava/lang/Object;") \
jvmci_constructor(DirectHotSpotObjectConstantImpl, "(Ljava/lang/Object;Z)V") \
end_class \
start_class(IndirectHotSpotObjectConstantImpl, jdk_vm_ci_hotspot_IndirectHotSpotObjectConstantImpl) \
long_field(IndirectHotSpotObjectConstantImpl, objectHandle) \
jvmci_constructor(IndirectHotSpotObjectConstantImpl, "(JZZ)V") \
end_class \
start_class(HotSpotMetaspaceConstantImpl, jdk_vm_ci_hotspot_HotSpotMetaspaceConstantImpl) \
object_field(HotSpotMetaspaceConstantImpl, metaspaceObject, "Ljdk/vm/ci/hotspot/MetaspaceObject;") \
boolean_field(HotSpotMetaspaceConstantImpl, compressed) \
end_class \
start_class(HotSpotSentinelConstant, jdk_vm_ci_hotspot_HotSpotSentinelConstant) \
end_class \
start_class(JavaKind, jdk_vm_ci_meta_JavaKind) \
char_field(JavaKind, typeChar) \
static_object_field(JavaKind, Boolean, "Ljdk/vm/ci/meta/JavaKind;") \
static_object_field(JavaKind, Byte, "Ljdk/vm/ci/meta/JavaKind;") \
static_object_field(JavaKind, Char, "Ljdk/vm/ci/meta/JavaKind;") \
static_object_field(JavaKind, Short, "Ljdk/vm/ci/meta/JavaKind;") \
static_object_field(JavaKind, Int, "Ljdk/vm/ci/meta/JavaKind;") \
static_object_field(JavaKind, Long, "Ljdk/vm/ci/meta/JavaKind;") \
end_class \
start_class(ValueKind, jdk_vm_ci_meta_ValueKind) \
object_field(ValueKind, platformKind, "Ljdk/vm/ci/meta/PlatformKind;") \
end_class \
start_class(Value, jdk_vm_ci_meta_Value) \
object_field(Value, valueKind, "Ljdk/vm/ci/meta/ValueKind;") \
static_object_field(Value, ILLEGAL, "Ljdk/vm/ci/meta/AllocatableValue;") \
end_class \
start_class(RegisterValue, jdk_vm_ci_code_RegisterValue) \
object_field(RegisterValue, reg, "Ljdk/vm/ci/code/Register;") \
end_class \
start_class(code_Location, jdk_vm_ci_code_Location) \
object_field(code_Location, reg, "Ljdk/vm/ci/code/Register;") \
int_field(code_Location, offset) \
end_class \
start_class(code_Register, jdk_vm_ci_code_Register) \
int_field(code_Register, number) \
int_field(code_Register, encoding) \
end_class \
start_class(StackSlot, jdk_vm_ci_code_StackSlot) \
int_field(StackSlot, offset) \
boolean_field(StackSlot, addFrameSize) \
end_class \
start_class(VirtualObject, jdk_vm_ci_code_VirtualObject) \
int_field(VirtualObject, id) \
object_field(VirtualObject, type, "Ljdk/vm/ci/meta/ResolvedJavaType;") \
objectarray_field(VirtualObject, values, "[Ljdk/vm/ci/meta/JavaValue;") \
objectarray_field(VirtualObject, slotKinds, "[Ljdk/vm/ci/meta/JavaKind;") \
end_class \
start_class(StackLockValue, jdk_vm_ci_code_StackLockValue) \
object_field(StackLockValue, owner, "Ljdk/vm/ci/meta/JavaValue;") \
object_field(StackLockValue, slot, "Ljdk/vm/ci/meta/AllocatableValue;") \
boolean_field(StackLockValue, eliminated) \
end_class \
start_class(HotSpotStackFrameReference, jdk_vm_ci_hotspot_HotSpotStackFrameReference) \
object_field(HotSpotStackFrameReference, compilerToVM, "Ljdk/vm/ci/hotspot/CompilerToVM;") \
boolean_field(HotSpotStackFrameReference, objectsMaterialized) \
long_field(HotSpotStackFrameReference, stackPointer) \
int_field(HotSpotStackFrameReference, frameNumber) \
int_field(HotSpotStackFrameReference, bci) \
object_field(HotSpotStackFrameReference, method, "Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;") \
objectarray_field(HotSpotStackFrameReference, locals, "[Ljava/lang/Object;") \
primarray_field(HotSpotStackFrameReference, localIsVirtual, "[Z") \
end_class \
start_class(HotSpotMetaData, jdk_vm_ci_hotspot_HotSpotMetaData) \
primarray_field(HotSpotMetaData, pcDescBytes, "[B") \
primarray_field(HotSpotMetaData, scopesDescBytes, "[B") \
primarray_field(HotSpotMetaData, relocBytes, "[B") \
primarray_field(HotSpotMetaData, exceptionBytes, "[B") \
primarray_field(HotSpotMetaData, oopMaps, "[B") \
object_field(HotSpotMetaData, metadata, "[Ljava/lang/Object;") \
end_class \
start_class(HotSpotConstantPool, jdk_vm_ci_hotspot_HotSpotConstantPool) \
long_field(HotSpotConstantPool, metadataHandle) \
end_class \
start_class(HotSpotJVMCIRuntime, jdk_vm_ci_hotspot_HotSpotJVMCIRuntime) \
objectarray_field(HotSpotJVMCIRuntime, excludeFromJVMCICompilation, "[Ljava/lang/Module;") \
jvmci_method(CallNonvirtualObjectMethod, GetMethodID, call_special, JVMCIObject, HotSpotJVMCIRuntime, compileMethod, compileMethod_signature, (JVMCIObject runtime, JVMCIObject method, int entry_bci, jlong env, int id)) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, encodeThrowable, encodeThrowable_signature, (JVMCIObject throwable)) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, decodeThrowable, decodeThrowable_signature, (JVMCIObject encodedThrowable)) \
jvmci_method(CallNonvirtualVoidMethod, GetMethodID, call_special, void, HotSpotJVMCIRuntime, bootstrapFinished, void_method_signature, (JVMCIObject runtime, JVMCI_TRAPS)) \
jvmci_method(CallNonvirtualVoidMethod, GetMethodID, call_special, void, HotSpotJVMCIRuntime, shutdown, void_method_signature, (JVMCIObject runtime)) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, runtime, runtime_signature, (JVMCI_TRAPS)) \
jvmci_method(CallObjectMethod, GetMethodID, call_virtual, JVMCIObject, HotSpotJVMCIRuntime, getCompiler, getCompiler_signature, (JVMCIObject runtime, JVMCI_TRAPS)) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, HotSpotJVMCIRuntime, callToString, callToString_signature, (JVMCIObject object, JVMCI_TRAPS)) \
end_class \
start_class(JVMCIError, jdk_vm_ci_common_JVMCIError) \
jvmci_constructor(JVMCIError, "(Ljava/lang/String;)V") \
end_class \
start_class(InspectedFrameVisitor, jdk_vm_ci_code_stack_InspectedFrameVisitor) \
end_class \
start_class(JVMCI, jdk_vm_ci_runtime_JVMCI) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JVMCI, getRuntime, getRuntime_signature, (JVMCI_TRAPS)) \
jvmci_method(CallStaticObjectMethod, GetStaticMethodID, call_static, JVMCIObject, JVMCI, initializeRuntime, initializeRuntime_signature, (JVMCI_TRAPS)) \
end_class \
start_class(Object, java_lang_Object) \
end_class \
start_class(String, java_lang_String) \
end_class \
start_class(Class, java_lang_Class) \
jvmci_method(CallObjectMethod, GetMethodID, call_virtual, JVMCIObject, Class, getName, void_string_signature, (JVMCI_TRAPS)) \
end_class \
start_class(ArrayIndexOutOfBoundsException, java_lang_ArrayIndexOutOfBoundsException) \
jvmci_constructor(ArrayIndexOutOfBoundsException, "(Ljava/lang/String;)V") \
end_class \
start_class(IllegalStateException, java_lang_IllegalStateException) \
jvmci_constructor(IllegalStateException, "(Ljava/lang/String;)V") \
end_class \
start_class(NullPointerException, java_lang_NullPointerException) \
jvmci_constructor(NullPointerException, "(Ljava/lang/String;)V") \
end_class \
start_class(IllegalArgumentException, java_lang_IllegalArgumentException) \
jvmci_constructor(IllegalArgumentException, "(Ljava/lang/String;)V") \
end_class \
start_class(InternalError, java_lang_InternalError) \
jvmci_constructor(InternalError, "(Ljava/lang/String;)V") \
end_class \
start_class(InvalidInstalledCodeException, jdk_vm_ci_code_InvalidInstalledCodeException) \
jvmci_constructor(InvalidInstalledCodeException, "(Ljava/lang/String;)V") \
end_class \
start_class(UnsatisfiedLinkError, java_lang_UnsatisfiedLinkError) \
jvmci_constructor(UnsatisfiedLinkError, "(Ljava/lang/String;)V") \
end_class \
start_class(StackTraceElement, java_lang_StackTraceElement) \
object_field(StackTraceElement, declaringClass, "Ljava/lang/String;") \
object_field(StackTraceElement, methodName, "Ljava/lang/String;") \
object_field(StackTraceElement, fileName, "Ljava/lang/String;") \
int_field(StackTraceElement, lineNumber) \
jvmci_constructor(StackTraceElement, "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V") \
end_class \
start_class(Throwable, java_lang_Throwable) \
object_field(Throwable, detailMessage, "Ljava/lang/String;") \
end_class \
/* end*/
#define START_CLASS(name) \
class name : AllStatic { \
private: \
friend class JVMCICompiler; \
static void check(oop obj, const char* field_name, int offset); \
static void compute_offsets(TRAPS); \
public: \
static InstanceKlass* klass() { return SystemDictionary::name##_klass_is_loaded() ? SystemDictionary::name##_klass() : NULL; }
class JVMCICompiler;
class JVMCIEnv;
#define START_CLASS(simpleClassName, fullClassName) \
class simpleClassName { \
friend class JVMCIEnv; \
static void initialize(JVMCI_TRAPS); \
static bool is_instance(JVMCIEnv* jvmciEnv, JVMCIObject object); \
#define END_CLASS };
#define FIELD(name, type, accessor, cast) \
static int _##name##_offset; \
static type name(oop obj) { check(obj, #name, _##name##_offset); return cast obj->accessor(_##name##_offset); } \
static type name(Handle obj) { check(obj(), #name, _##name##_offset); return cast obj->accessor(_##name##_offset); } \
static type name(jobject obj); \
static void set_##name(oop obj, type x) { check(obj, #name, _##name##_offset); obj->accessor##_put(_##name##_offset, x); } \
static void set_##name(Handle obj, type x) { check(obj(), #name, _##name##_offset); obj->accessor##_put(_##name##_offset, x); } \
static void set_##name(jobject obj, type x); \
#define EMPTY_CAST
#define CHAR_FIELD(klass, name) FIELD(name, jchar, char_field, EMPTY_CAST)
#define INT_FIELD(klass, name) FIELD(name, jint, int_field, EMPTY_CAST)
#define BOOLEAN_FIELD(klass, name) FIELD(name, jboolean, bool_field, EMPTY_CAST)
#define LONG_FIELD(klass, name) FIELD(name, jlong, long_field, EMPTY_CAST)
#define FLOAT_FIELD(klass, name) FIELD(name, jfloat, float_field, EMPTY_CAST)
#define OOP_FIELD(klass, name, signature) FIELD(name, oop, obj_field, EMPTY_CAST)
#define OBJARRAYOOP_FIELD(klass, name, signature) FIELD(name, objArrayOop, obj_field, (objArrayOop))
#define TYPEARRAYOOP_FIELD(klass, name, signature) FIELD(name, typeArrayOop, obj_field, (typeArrayOop))
#define STATIC_OOP_FIELD(klassName, name, signature) STATIC_OOPISH_FIELD(klassName, name, oop, signature)
#define STATIC_OBJARRAYOOP_FIELD(klassName, name, signature) STATIC_OOPISH_FIELD(klassName, name, objArrayOop, signature)
#define STATIC_OOPISH_FIELD(klassName, name, type, signature) \
static int _##name##_offset; \
static type name(); \
static void set_##name(type x);
#define STATIC_PRIMITIVE_FIELD(klassName, name, jtypename) \
static int _##name##_offset; \
static jtypename name(); \
static void set_##name(jtypename x);
#define CHAR_FIELD(simpleClassName, name) FIELD(simpleClassName, name, jchar)
#define INT_FIELD(simpleClassName, name) FIELD(simpleClassName, name, jint)
#define BOOLEAN_FIELD(simpleClassName, name) FIELD(simpleClassName, name, jboolean)
#define LONG_FIELD(simpleClassName, name) FIELD(simpleClassName, name, jlong)
#define FLOAT_FIELD(simpleClassName, name) FIELD(simpleClassName, name, jfloat)
#define STATIC_INT_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, jint)
#define STATIC_BOOLEAN_FIELD(klassName, name) STATIC_PRIMITIVE_FIELD(klassName, name, jboolean)
#define OBJECT_FIELD(simpleClassName, name, signature) OOPISH_FIELD(simpleClassName, name, JVMCIObject, oop)
#define OBJECTARRAY_FIELD(simpleClassName, name, signature) OOPISH_FIELD(simpleClassName, name, JVMCIObjectArray, objArrayOop)
#define PRIMARRAY_FIELD(simpleClassName, name, signature) OOPISH_FIELD(simpleClassName, name, JVMCIPrimitiveArray, typeArrayOop)
COMPILER_CLASSES_DO(START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OOP_FIELD, TYPEARRAYOOP_FIELD, OBJARRAYOOP_FIELD, STATIC_OOP_FIELD, STATIC_OBJARRAYOOP_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD)
#define STATIC_INT_FIELD(simpleClassName, name) STATIC_FIELD(simpleClassName, name, jint)
#define STATIC_BOOLEAN_FIELD(simpleClassName, name) STATIC_FIELD(simpleClassName, name, jboolean)
#define STATIC_OBJECT_FIELD(simpleClassName, name, signature) STATIC_OOPISH_FIELD(simpleClassName, name, JVMCIObject, oop)
#define STATIC_OBJECTARRAY_FIELD(simpleClassName, name, signature) STATIC_OOPISH_FIELD(simpleClassName, name, JVMCIObjectArray, objArrayOop)
#define HS_START_CLASS(simpleClassName, fullClassName) \
START_CLASS(simpleClassName, fullClassName) \
friend class HotSpotJVMCI; \
private: \
static void check(oop obj, const char* field_name, int offset); \
static InstanceKlass* _klass; \
public: \
static InstanceKlass* klass() { assert(_klass != NULL, "uninit"); return _klass; } \
static Symbol* symbol() { return vmSymbols::fullClassName(); }
#define FIELD(simpleClassName, name, type) \
private: \
static int _##name##_offset; \
public: \
static type get_ ## name(JVMCIEnv* env, JVMCIObject obj) { return name(env, resolve(obj)); } \
static void set_ ## name(JVMCIEnv* env, JVMCIObject obj, type x) { set_ ## name(env, resolve(obj), x); } \
static type name(JVMCIEnv* env, oop obj); \
static void set_ ## name(JVMCIEnv* env, oop obj, type x);
#define OOPISH_FIELD(simpleClassName, name, type, hstype) \
private: \
static int _##name##_offset; \
public: \
static type get_ ## name(JVMCIEnv* env, JVMCIObject obj) { return (type) wrap(name(env, resolve(obj))); } \
static void set_ ## name(JVMCIEnv* env, JVMCIObject obj, type x) { set_ ## name(env, resolve(obj), (hstype) resolve(x)); } \
static hstype name(JVMCIEnv* env, oop obj); \
static void set_ ## name(JVMCIEnv* env, oop obj, hstype x);
#define STATIC_FIELD(simpleClassName, name, type) \
private: \
static int _##name##_offset; \
public: \
static type get_ ## name(JVMCIEnv* env); \
static void set_ ## name(JVMCIEnv* env, type x);
#define STATIC_OOPISH_FIELD(simpleClassName, name, type, hstype) \
private: \
static int _##name##_offset; \
public: \
static type get_ ## name(JVMCIEnv* env) { return (type) wrap(name(env)); } \
static void set_ ## name(JVMCIEnv* env, type x) { set_ ## name(env, (hstype) resolve(x)); } \
static hstype name(JVMCIEnv* env); \
static void set_ ## name(JVMCIEnv* env, hstype hstype);
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, simpleClassName, methodName, signatureSymbolName, args)
#define CONSTRUCTOR(className, signature)
/**
* VM internal interface to Java classes, methods and objects. For example:
*
* class HotSpotJVMCI {
* ...
* class Architecture {
* static void initialize(JVMCIEnv* env);
* static bool is_instance(JVMCIEnv* env, JVMCIObject object);
* private:
* static void check(oop obj, const char *field_name, int offset);
* public:
* static InstanceKlass *klass() { ... }
* static Symbol *symbol() { return vmSymbols::jdk_vm_ci_code_Architecture(); }
* private:
* static int _wordKind_offset;
* public:
* static JVMCIObject get_wordKind(JVMCIEnv *env, JVMCIObject obj) { ... }
* static void set_wordKind(JVMCIEnv *env, JVMCIObject obj, JVMCIObject x) { ... }
* static oop wordKind(JVMCIEnv *env, oop obj);
* static void set_wordKind(JVMCIEnv *env, oop obj, oop x);
* }
* ...
* };
*/
class HotSpotJVMCI {
friend class JVMCIEnv;
public:
static oop resolve(JVMCIObject obj);
static arrayOop resolve(JVMCIArray obj);
static objArrayOop resolve(JVMCIObjectArray obj);
static typeArrayOop resolve(JVMCIPrimitiveArray obj);
static JVMCIObject wrap(jobject obj) { return JVMCIObject(obj, true); }
static JVMCIObject wrap(oop obj);
static inline Method* asMethod(JVMCIEnv* env, oop jvmci_method) {
return *(Method**) HotSpotResolvedJavaMethodImpl::metadataHandle(env, jvmci_method);
}
static inline ConstantPool* asConstantPool(JVMCIEnv* env, oop jvmci_constant_pool) {
return *(ConstantPool**) HotSpotConstantPool::metadataHandle(env, jvmci_constant_pool);
}
static inline Klass* asKlass(JVMCIEnv* env, oop jvmci_type) {
return (Klass*) HotSpotResolvedObjectTypeImpl::metadataPointer(env, jvmci_type);
}
static void compute_offsets(TRAPS);
static void compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field, TRAPS);
JVMCI_CLASSES_DO(HS_START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
};
#undef HS_START_CLASS
#define JNI_START_CLASS(simpleClassName, fullClassName) \
START_CLASS(simpleClassName, fullClassName) \
friend class JNIJVMCI; \
private: \
static void check(JVMCIEnv* jvmciEnv, JVMCIObject obj, const char* field_name, jfieldID offset); \
static jclass _class; \
public: \
static jclass clazz() { assert(_class != NULL, #fullClassName " uninitialized"); return _class; } \
static jclass fullClassName ##_class() { assert(_class != NULL, "uninit"); return _class; }
#undef METHOD
#undef CONSTRUCTOR
#undef FIELD
#undef OOPISH_FIELD
#undef STATIC_FIELD
#undef STATIC_OOPISH_FIELD
#define FIELD(simpleClassName, name, type) \
private: \
static jfieldID _##name##_field_id; \
public: \
static type get_ ## name(JVMCIEnv* jvmciEnv, JVMCIObject obj); \
static void set_ ## name(JVMCIEnv* jvmciEnv, JVMCIObject obj, type x);
#define OOPISH_FIELD(simpleClassName, name, type, hstype) \
FIELD(simpleClassName, name, type)
#define STATIC_FIELD(simpleClassName, name, type) \
private: \
static jfieldID _##name##_field_id; \
public: \
static type get_ ## name(JVMCIEnv* jvmciEnv); \
static void set_ ## name(JVMCIEnv* jvmciEnv, type x);
#define STATIC_OOPISH_FIELD(simpleClassName, name, type, hstype) \
STATIC_FIELD(simpleClassName, name, type)
#define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \
public: \
static jmethodID methodName##_method() { return _##methodName##_method; } \
private: \
static jmethodID _##methodName##_method;
#define CONSTRUCTOR(className, signature) \
public: \
static jmethodID constructor() { return _constructor; } \
private: \
static jmethodID _constructor;
/**
* JNI based interface to Java classes, methods and objects. For example:
*
* class JNIJVMCI {
* ...
* class Architecture {
* static void initialize(JVMCIEnv* env);
* static bool is_instance(JVMCIEnv* env, JVMCIObject object);
* private:
* static void check(oop obj, const char *field_name, int offset);
* static jclass _class;
* public:
* static jclass clazz() { return _class; }
* static jclass jdk_vm_ci_code_Architecture_class() { return _class; }
* private:
* static jfieldID _wordKind_field_id;
* public:
* static JVMCIObject get_wordKind(JVMCIEnv *env, JVMCIObject obj) { ... }
* static void set_wordKind(JVMCIEnv *env, JVMCIObject obj, JVMCIObject x) { ... }
* }
* ...
* };
*/
class JNIJVMCI {
friend class JVMCIEnv;
static jclass _byte_array;
static jclass _box_classes[T_CONFLICT+1];
static jfieldID _box_fields[T_CONFLICT+1];
static jmethodID _box_constructors[T_CONFLICT+1];
static jmethodID _Class_getName_method;
static jmethodID _HotSpotResolvedJavaMethodImpl_fromMetaspace_method;
static jmethodID _HotSpotConstantPool_fromMetaspace_method;
static jmethodID _HotSpotResolvedObjectTypeImpl_fromMetaspace_method;
static jmethodID _HotSpotResolvedPrimitiveType_fromMetaspace_method;
public:
static jmethodID Class_getName_method() { return _Class_getName_method; }
static jclass byte_array() { assert(_byte_array != NULL, "uninit"); return _byte_array; }
static jclass box_class(BasicType type) { assert(_box_classes[type]!= NULL, "uninit"); return _box_classes[type]; }
static jfieldID box_field(BasicType type) { assert(_box_fields[type]!= NULL, "uninit"); return _box_fields[type]; }
static jmethodID box_constructor(BasicType type) { assert(_box_constructors[type]!= NULL, "uninit"); return _box_constructors[type]; }
static jmethodID HotSpotResolvedJavaMethodImpl_fromMetaspace_method() { assert(_HotSpotResolvedJavaMethodImpl_fromMetaspace_method != NULL, "uninit"); return _HotSpotResolvedJavaMethodImpl_fromMetaspace_method; }
static jmethodID HotSpotConstantPool_fromMetaspace_method() { assert(_HotSpotConstantPool_fromMetaspace_method != NULL, "uninit"); return _HotSpotConstantPool_fromMetaspace_method; }
static jmethodID HotSpotResolvedObjectTypeImpl_fromMetaspace_method() { assert(_HotSpotResolvedObjectTypeImpl_fromMetaspace_method != NULL, "uninit"); return _HotSpotResolvedObjectTypeImpl_fromMetaspace_method; }
static jmethodID HotSpotResolvedPrimitiveType_fromMetaspace_method() { assert(_HotSpotResolvedPrimitiveType_fromMetaspace_method != NULL, "uninit"); return _HotSpotResolvedPrimitiveType_fromMetaspace_method; }
static void initialize_ids(JNIEnv* env);
static void initialize_field_id(JNIEnv* env, jfieldID &dest_offset, jclass klass, const char* klass_name, const char* name, const char* signature, bool static_field);
static jobject resolve_handle(JVMCIObject obj) { return obj.as_jobject(); }
static JVMCIObject wrap(jobject obj) { return JVMCIObject(obj, false); }
JVMCI_CLASSES_DO(JNI_START_CLASS, END_CLASS, CHAR_FIELD, INT_FIELD, BOOLEAN_FIELD, LONG_FIELD, FLOAT_FIELD, OBJECT_FIELD, PRIMARRAY_FIELD, OBJECTARRAY_FIELD, STATIC_OBJECT_FIELD, STATIC_OBJECTARRAY_FIELD, STATIC_INT_FIELD, STATIC_BOOLEAN_FIELD, METHOD, CONSTRUCTOR)
};
#undef JNI_START_CLASS
#undef START_CLASS
#undef END_CLASS
#undef METHOD
#undef CONSTRUCTOR
#undef FIELD
#undef CHAR_FIELD
#undef INT_FIELD
#undef BOOLEAN_FIELD
#undef LONG_FIELD
#undef FLOAT_FIELD
#undef OOP_FIELD
#undef TYPEARRAYOOP_FIELD
#undef OBJARRAYOOP_FIELD
#undef OBJECT_FIELD
#undef PRIMARRAY_FIELD
#undef OBJECTARRAY_FIELD
#undef FIELD
#undef OOPISH_FIELD
#undef STATIC_FIELD
#undef STATIC_OOPISH_FIELD
#undef STATIC_OOP_FIELD
#undef STATIC_OBJARRAYOOP_FIELD
#undef STATIC_FIELD
#undef STATIC_OBJECT_FIELD
#undef STATIC_OBJECTARRAY_FIELD
#undef STATIC_INT_FIELD
#undef STATIC_BOOLEAN_FIELD
#undef STATIC_PRIMITIVE_FIELD
#undef EMPTY_CAST
void compute_offset(int &dest_offset, Klass* klass, const char* name, const char* signature, bool static_field, TRAPS);
#endif // SHARE_JVMCI_JVMCIJAVACLASSES_HPP

View File

@ -0,0 +1,94 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef SHARE_JVMCI_JVMCIOBJECT_HPP
#define SHARE_JVMCI_JVMCIOBJECT_HPP
#include "jni.h"
#include "utilities/debug.hpp"
class JVMCIArray;
class JVMCIPrimitiveArray;
class JVMCIObjectArray;
class JVMCIObject {
private:
jobject _object;
bool _is_hotspot;
public:
JVMCIObject(): _object(NULL), _is_hotspot(false) {}
JVMCIObject(jobject o, bool is_hotspot): _object(o), _is_hotspot(is_hotspot) { }
static JVMCIObject create(jobject o, bool is_hotspot) { JVMCIObject r(o, is_hotspot); return r; }
jobject as_jobject() { return _object; }
jobject as_jweak() { return (jweak) _object; }
jstring as_jstring() { return (jstring) _object; }
bool is_hotspot() { return _is_hotspot; }
bool is_null() const { return _object == NULL; }
bool is_non_null() const { return _object != NULL; }
operator JVMCIArray();
operator JVMCIPrimitiveArray();
operator JVMCIObjectArray();
};
class JVMCIArray : public JVMCIObject {
public:
JVMCIArray() {}
JVMCIArray(jobject o, bool is_hotspot): JVMCIObject(o, is_hotspot) {}
jarray as_jobject() { return (jarray) JVMCIObject::as_jobject(); }
};
class JVMCIObjectArray : public JVMCIArray {
public:
JVMCIObjectArray() {}
JVMCIObjectArray(void* v): JVMCIArray() { assert(v == NULL, "must be NULL"); }
JVMCIObjectArray(jobject o, bool is_hotspot): JVMCIArray(o, is_hotspot) {}
jobjectArray as_jobject() { return (jobjectArray) JVMCIArray::as_jobject(); }
};
class JVMCIPrimitiveArray : public JVMCIArray {
public:
JVMCIPrimitiveArray() {}
JVMCIPrimitiveArray(void* v): JVMCIArray() { assert(v == NULL, "must be NULL"); }
JVMCIPrimitiveArray(jobject o, bool is_hotspot): JVMCIArray(o, is_hotspot) {}
jbooleanArray as_jbooleanArray() { return (jbooleanArray) as_jobject(); }
jbyteArray as_jbyteArray() { return (jbyteArray) as_jobject(); }
jcharArray as_jcharArray() { return (jcharArray) as_jobject(); }
jshortArray as_jshortArray() { return (jshortArray) as_jobject(); }
jintArray as_jintArray() { return (jintArray) as_jobject(); }
jfloatArray as_jfloatArray() { return (jfloatArray) as_jobject(); }
jlongArray as_jlongArray() { return (jlongArray) as_jobject(); }
jdoubleArray as_jdoubleArray() { return (jdoubleArray) as_jobject(); }
};
inline JVMCIObject::operator JVMCIArray() { return JVMCIArray(_object, _is_hotspot); }
inline JVMCIObject::operator JVMCIPrimitiveArray() { return JVMCIPrimitiveArray(_object, _is_hotspot); }
inline JVMCIObject::operator JVMCIObjectArray() { return JVMCIObjectArray(_object, _is_hotspot); }
#endif // SHARE_JVMCI_JVMCIOBJECT_HPP

File diff suppressed because it is too large Load Diff

View File

@ -24,23 +24,68 @@
#ifndef SHARE_JVMCI_JVMCIRUNTIME_HPP
#define SHARE_JVMCI_JVMCIRUNTIME_HPP
#include "interpreter/interpreter.hpp"
#include "memory/allocation.hpp"
#include "runtime/arguments.hpp"
#include "runtime/deoptimization.hpp"
#include "code/nmethod.hpp"
#include "jvmci/jvmci.hpp"
#include "jvmci/jvmciExceptions.hpp"
#include "jvmci/jvmciObject.hpp"
#define JVMCI_ERROR(...) \
{ Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::jdk_vm_ci_common_JVMCIError(), __VA_ARGS__); return; }
class JVMCIEnv;
class JVMCICompiler;
class JVMCICompileState;
#define JVMCI_ERROR_(ret, ...) \
{ Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::jdk_vm_ci_common_JVMCIError(), __VA_ARGS__); return ret; }
// Encapsulates the JVMCI metadata for an nmethod.
// JVMCINMethodData objects are inlined into nmethods
// at nmethod::_jvmci_data_offset.
class JVMCINMethodData {
// Index for the HotSpotNmethod mirror in the nmethod's oops table.
// This is -1 if there is no mirror in the oops table.
int _nmethod_mirror_index;
#define JVMCI_ERROR_0(...) JVMCI_ERROR_(0, __VA_ARGS__)
#define JVMCI_ERROR_NULL(...) JVMCI_ERROR_(NULL, __VA_ARGS__)
#define JVMCI_ERROR_OK(...) JVMCI_ERROR_(JVMCIEnv::ok, __VA_ARGS__)
#define CHECK_OK CHECK_(JVMCIEnv::ok)
// Is HotSpotNmethod.name non-null? If so, the value is
// embedded in the end of this object.
bool _has_name;
class JVMCIRuntime: public AllStatic {
// Address of the failed speculations list to which a speculation
// is appended when it causes a deoptimization.
FailedSpeculation** _failed_speculations;
public:
// Computes the size of a JVMCINMethodData object
static int compute_size(const char* nmethod_mirror_name) {
int size = sizeof(JVMCINMethodData);
if (nmethod_mirror_name != NULL) {
size += (int) strlen(nmethod_mirror_name) + 1;
}
return size;
}
void initialize(int nmethod_mirror_index,
const char* name,
FailedSpeculation** failed_speculations);
// Adds `speculation` to the failed speculations list.
void add_failed_speculation(nmethod* nm, jlong speculation);
// Gets the JVMCI name of the nmethod (which may be NULL).
const char* name() { return _has_name ? (char*)(((address) this) + sizeof(JVMCINMethodData)) : NULL; }
// Clears the HotSpotNmethod.address field in the mirror. If nm
// is dead, the HotSpotNmethod.entryPoint field is also cleared.
void invalidate_nmethod_mirror(nmethod* nm);
// Gets the mirror from nm's oops table.
oop get_nmethod_mirror(nmethod* nm);
// Sets the mirror in nm's oops table.
void set_nmethod_mirror(nmethod* nm, oop mirror);
// Clears the mirror in nm's oops table.
void clear_nmethod_mirror(nmethod* nm);
};
// A top level class that represents an initialized JVMCI runtime.
// There is one instance of this class per HotSpotJVMCIRuntime object.
class JVMCIRuntime: public CHeapObj<mtJVMCI> {
public:
// Constants describing whether JVMCI wants to be able to adjust the compilation
// level selected for a method by the VM compilation policy and if so, based on
@ -52,57 +97,187 @@ class JVMCIRuntime: public AllStatic {
};
private:
static jobject _HotSpotJVMCIRuntime_instance;
static bool _well_known_classes_initialized;
volatile bool _being_initialized;
volatile bool _initialized;
static bool _shutdown_called;
JVMCIObject _HotSpotJVMCIRuntime_instance;
bool _shutdown_called;
JVMCIObject create_jvmci_primitive_type(BasicType type, JVMCI_TRAPS);
// Implementation methods for loading and constant pool access.
static Klass* get_klass_by_name_impl(Klass*& accessing_klass,
const constantPoolHandle& cpool,
Symbol* klass_name,
bool require_local);
static Klass* get_klass_by_index_impl(const constantPoolHandle& cpool,
int klass_index,
bool& is_accessible,
Klass* loading_klass);
static void get_field_by_index_impl(InstanceKlass* loading_klass, fieldDescriptor& fd,
int field_index);
static methodHandle get_method_by_index_impl(const constantPoolHandle& cpool,
int method_index, Bytecodes::Code bc,
InstanceKlass* loading_klass);
// Helper methods
static bool check_klass_accessibility(Klass* accessing_klass, Klass* resolved_klass);
static methodHandle lookup_method(InstanceKlass* accessor,
Klass* holder,
Symbol* name,
Symbol* sig,
Bytecodes::Code bc,
constantTag tag);
public:
static bool is_HotSpotJVMCIRuntime_initialized() {
return _HotSpotJVMCIRuntime_instance != NULL;
JVMCIRuntime() {
_initialized = false;
_being_initialized = false;
_shutdown_called = false;
}
/**
* Compute offsets and construct any state required before executing JVMCI code.
*/
void initialize(JVMCIEnv* jvmciEnv);
/**
* Gets the singleton HotSpotJVMCIRuntime instance, initializing it if necessary
*/
static Handle get_HotSpotJVMCIRuntime(TRAPS);
JVMCIObject get_HotSpotJVMCIRuntime(JVMCI_TRAPS);
static jobject get_HotSpotJVMCIRuntime_jobject(TRAPS) {
initialize_JVMCI(CHECK_NULL);
assert(_HotSpotJVMCIRuntime_instance != NULL, "must be");
return _HotSpotJVMCIRuntime_instance;
bool is_HotSpotJVMCIRuntime_initialized() {
return _HotSpotJVMCIRuntime_instance.is_non_null();
}
static Handle callStatic(const char* className, const char* methodName, const char* returnType, JavaCallArguments* args, TRAPS);
/**
* Determines if the VM is sufficiently booted to initialize JVMCI.
*/
static bool can_initialize_JVMCI();
/**
* Trigger initialization of HotSpotJVMCIRuntime through JVMCI.getRuntime()
*/
static void initialize_JVMCI(TRAPS);
void initialize_JVMCI(JVMCI_TRAPS);
/**
* Explicitly initialize HotSpotJVMCIRuntime itself
*/
static void initialize_HotSpotJVMCIRuntime(TRAPS);
void initialize_HotSpotJVMCIRuntime(JVMCI_TRAPS);
static void initialize_well_known_classes(TRAPS);
void call_getCompiler(TRAPS);
static void metadata_do(void f(Metadata*));
void shutdown();
static void shutdown(TRAPS);
static void bootstrap_finished(TRAPS);
static bool shutdown_called() {
bool shutdown_called() {
return _shutdown_called;
}
static BasicType kindToBasicType(Handle kind, TRAPS);
void bootstrap_finished(TRAPS);
// Look up a klass by name from a particular class loader (the accessor's).
// If require_local, result must be defined in that class loader, or NULL.
// If !require_local, a result from remote class loader may be reported,
// if sufficient class loader constraints exist such that initiating
// a class loading request from the given loader is bound to return
// the class defined in the remote loader (or throw an error).
//
// Return an unloaded klass if !require_local and no class at all is found.
//
// The CI treats a klass as loaded if it is consistently defined in
// another loader, even if it hasn't yet been loaded in all loaders
// that could potentially see it via delegation.
static Klass* get_klass_by_name(Klass* accessing_klass,
Symbol* klass_name,
bool require_local);
// Constant pool access.
static Klass* get_klass_by_index(const constantPoolHandle& cpool,
int klass_index,
bool& is_accessible,
Klass* loading_klass);
static void get_field_by_index(InstanceKlass* loading_klass, fieldDescriptor& fd,
int field_index);
static methodHandle get_method_by_index(const constantPoolHandle& cpool,
int method_index, Bytecodes::Code bc,
InstanceKlass* loading_klass);
// converts the Klass* representing the holder of a method into a
// InstanceKlass*. This is needed since the holder of a method in
// the bytecodes could be an array type. Basically this converts
// array types into java/lang/Object and other types stay as they are.
static InstanceKlass* get_instance_klass_for_declared_method_holder(Klass* klass);
// Helper routine for determining the validity of a compilation
// with respect to concurrent class loading.
static JVMCI::CodeInstallResult validate_compile_task_dependencies(Dependencies* target, JVMCICompileState* task, char** failure_detail);
// Compiles `target` with the JVMCI compiler.
void compile_method(JVMCIEnv* JVMCIENV, JVMCICompiler* compiler, const methodHandle& target, int entry_bci);
// Register the result of a compilation.
JVMCI::CodeInstallResult register_method(JVMCIEnv* JVMCIENV,
const methodHandle& target,
nmethod*& nm,
int entry_bci,
CodeOffsets* offsets,
int orig_pc_offset,
CodeBuffer* code_buffer,
int frame_words,
OopMapSet* oop_map_set,
ExceptionHandlerTable* handler_table,
AbstractCompiler* compiler,
DebugInformationRecorder* debug_info,
Dependencies* dependencies,
int compile_id,
bool has_unsafe_access,
bool has_wide_vector,
JVMCIObject compiled_code,
JVMCIObject nmethod_mirror,
FailedSpeculation** failed_speculations,
char* speculations,
int speculations_len);
/**
* Exits the VM due to an unexpected exception.
*/
static void exit_on_pending_exception(JVMCIEnv* JVMCIENV, const char* message);
static void describe_pending_hotspot_exception(JavaThread* THREAD, bool clear);
#define CHECK_EXIT THREAD); \
if (HAS_PENDING_EXCEPTION) { \
char buf[256]; \
jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
JVMCIRuntime::exit_on_pending_exception(NULL, buf); \
return; \
} \
(void)(0
#define CHECK_EXIT_(v) THREAD); \
if (HAS_PENDING_EXCEPTION) { \
char buf[256]; \
jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
JVMCIRuntime::exit_on_pending_exception(NULL, buf); \
return v; \
} \
(void)(0
#define JVMCI_CHECK_EXIT JVMCIENV); \
if (JVMCIENV->has_pending_exception()) { \
char buf[256]; \
jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
JVMCIRuntime::exit_on_pending_exception(JVMCIENV, buf); \
return; \
} \
(void)(0
#define JVMCI_CHECK_EXIT_(result) JVMCIENV); \
if (JVMCIENV->has_pending_exception()) { \
char buf[256]; \
jio_snprintf(buf, 256, "Uncaught exception at %s:%d", __FILE__, __LINE__); \
JVMCIRuntime::exit_on_pending_exception(JVMCIENV, buf); \
return result; \
} \
(void)(0
static BasicType kindToBasicType(const Handle& kind, TRAPS);
static void new_instance_common(JavaThread* thread, Klass* klass, bool null_on_fail);
static void new_array_common(JavaThread* thread, Klass* klass, jint length, bool null_on_fail);
@ -162,11 +337,8 @@ class JVMCIRuntime: public AllStatic {
static void throw_klass_external_name_exception(JavaThread* thread, const char* exception, Klass* klass);
static void throw_class_cast_exception(JavaThread* thread, const char* exception, Klass* caster_klass, Klass* target_klass);
// Forces initialization of the JVMCI runtime.
static void force_initialization(TRAPS);
// Test only function
static int test_deoptimize_call_int(JavaThread* thread, int value);
static jint test_deoptimize_call_int(JavaThread* thread, int value);
};
// Tracing macros.
@ -177,10 +349,10 @@ class JVMCIRuntime: public AllStatic {
#define IF_TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4)) ; else
#define IF_TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5)) ; else
#define TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1 && (tty->print("JVMCITrace-1: "), true))) ; else tty->print_cr
#define TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2 && (tty->print(" JVMCITrace-2: "), true))) ; else tty->print_cr
#define TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3 && (tty->print(" JVMCITrace-3: "), true))) ; else tty->print_cr
#define TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4 && (tty->print(" JVMCITrace-4: "), true))) ; else tty->print_cr
#define TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5 && (tty->print(" JVMCITrace-5: "), true))) ; else tty->print_cr
#define TRACE_jvmci_1 if (!(JVMCITraceLevel >= 1 && (tty->print(PTR_FORMAT " JVMCITrace-1: ", p2i(JavaThread::current())), true))) ; else tty->print_cr
#define TRACE_jvmci_2 if (!(JVMCITraceLevel >= 2 && (tty->print(PTR_FORMAT " JVMCITrace-2: ", p2i(JavaThread::current())), true))) ; else tty->print_cr
#define TRACE_jvmci_3 if (!(JVMCITraceLevel >= 3 && (tty->print(PTR_FORMAT " JVMCITrace-3: ", p2i(JavaThread::current())), true))) ; else tty->print_cr
#define TRACE_jvmci_4 if (!(JVMCITraceLevel >= 4 && (tty->print(PTR_FORMAT " JVMCITrace-4: ", p2i(JavaThread::current())), true))) ; else tty->print_cr
#define TRACE_jvmci_5 if (!(JVMCITraceLevel >= 5 && (tty->print(PTR_FORMAT " JVMCITrace-5: ", p2i(JavaThread::current())), true))) ; else tty->print_cr
#endif // SHARE_JVMCI_JVMCIRUNTIME_HPP

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,8 +27,11 @@
#include "jvmci/jvmci_globals.hpp"
#include "gc/shared/gcConfig.hpp"
#include "utilities/defaultStream.hpp"
#include "utilities/ostream.hpp"
#include "runtime/globals_extension.hpp"
fileStream* JVMCIGlobals::_jni_config_file = NULL;
JVMCI_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
MATERIALIZE_PD_DEVELOPER_FLAG, \
MATERIALIZE_PRODUCT_FLAG, \
@ -79,6 +82,10 @@ bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
return false;
}
FLAG_SET_DEFAULT(EnableJVMCI, true);
if (BootstrapJVMCI && UseJVMCINativeLibrary) {
jio_fprintf(defaultStream::error_stream(), "-XX:+BootstrapJVMCI is not compatible with -XX:+UseJVMCINativeLibrary");
return false;
}
}
if (!EnableJVMCI) {
@ -97,7 +104,9 @@ bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
CHECK_NOT_SET(JVMCINMethodSizeLimit, EnableJVMCI)
CHECK_NOT_SET(MethodProfileWidth, EnableJVMCI)
CHECK_NOT_SET(JVMCIPrintProperties, EnableJVMCI)
CHECK_NOT_SET(TraceUncollectedSpeculations, EnableJVMCI)
CHECK_NOT_SET(UseJVMCINativeLibrary, EnableJVMCI)
CHECK_NOT_SET(JVMCILibPath, EnableJVMCI)
CHECK_NOT_SET(JVMCILibDumpJNIConfig, EnableJVMCI)
#ifndef PRODUCT
#define JVMCI_CHECK4(type, name, value, doc) assert(name##checked, #name " flag not checked");
@ -110,10 +119,21 @@ bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
#undef JVMCI_CHECK3
#undef JVMCI_CHECK4
#undef JVMCI_FLAG_CHECKED
#endif
#endif // PRODUCT
#undef CHECK_NOT_SET
if (JVMCILibDumpJNIConfig != NULL) {
_jni_config_file = new(ResourceObj::C_HEAP, mtJVMCI) fileStream(JVMCILibDumpJNIConfig);
if (_jni_config_file == NULL || !_jni_config_file->is_open()) {
jio_fprintf(defaultStream::error_stream(),
"Could not open file for dumping JVMCI shared library JNI config: %s\n", JVMCILibDumpJNIConfig);
return false;
}
}
return true;
}
void JVMCIGlobals::check_jvmci_supported_gc() {
if (EnableJVMCI) {
// Check if selected GC is supported by JVMCI and Java compiler

View File

@ -25,7 +25,7 @@
#ifndef SHARE_JVMCI_JVMCI_GLOBALS_HPP
#define SHARE_JVMCI_JVMCI_GLOBALS_HPP
#include "runtime/globals.hpp"
#include "utilities/ostream.hpp"
//
// Defines all global flags used by the JVMCI compiler. Only flags that need
@ -62,11 +62,13 @@
"Print JVMCI bootstrap progress and summary") \
\
experimental(intx, JVMCIThreads, 1, \
"Force number of JVMCI compiler threads to use") \
"Force number of JVMCI compiler threads to use. Ignored if " \
"UseJVMCICompiler is false.") \
range(1, max_jint) \
\
experimental(intx, JVMCIHostThreads, 1, \
"Force number of compiler threads for JVMCI host compiler") \
"Force number of C1 compiler threads. Ignored if " \
"UseJVMCICompiler is false.") \
range(1, max_jint) \
\
NOT_COMPILER2(product(intx, MaxVectorSize, 64, \
@ -97,8 +99,17 @@
experimental(intx, MethodProfileWidth, 0, \
"Number of methods to record in call profile") \
\
develop(bool, TraceUncollectedSpeculations, false, \
"Print message when a failed speculation was not collected") \
experimental(ccstr, JVMCILibPath, NULL, \
"LD path for loading the JVMCI shared library") \
\
experimental(ccstr, JVMCILibDumpJNIConfig, NULL, \
"Dumps to the given file a description of the classes, fields " \
"and methods the JVMCI shared library must provide") \
\
experimental(bool, UseJVMCINativeLibrary, false, \
"Execute JVMCI Java code from a shared library " \
"instead of loading it from class files and executing it " \
"on the HotSpot heap") \
\
NOT_COMPILER2(diagnostic(bool, UseMultiplyToLenIntrinsic, false, \
"Enables intrinsification of BigInteger.multiplyToLen()")) \
@ -130,14 +141,22 @@ JVMCI_FLAGS(DECLARE_DEVELOPER_FLAG, \
IGNORE_CONSTRAINT, \
IGNORE_WRITEABLE)
// The base name for the shared library containing the JVMCI based compiler
#define JVMCI_SHARED_LIBRARY_NAME "jvmcicompiler"
class JVMCIGlobals {
private:
static fileStream* _jni_config_file;
public:
// Return true if jvmci flags are consistent. If not consistent,
// Returns true if jvmci flags are consistent. If not consistent,
// an error message describing the inconsistency is printed before
// returning false.
static bool check_jvmci_flags_are_consistent();
// Check and exit VM with error if selected GC is not supported by JVMCI.
static void check_jvmci_supported_gc();
static fileStream* get_jni_config_file() { return _jni_config_file; }
};
#endif // SHARE_JVMCI_JVMCI_GLOBALS_HPP

View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#include "precompiled.hpp"
#include "jvmci/metadataHandleBlock.hpp"
MetadataHandleBlock* MetadataHandleBlock::_last = NULL;
intptr_t MetadataHandleBlock::_free_list = 0;
int MetadataHandleBlock::_allocate_before_rebuild = 0;
jmetadata MetadataHandleBlock::allocate_metadata_handle(Metadata* obj) {
assert(obj->is_valid() && obj->is_metadata(), "must be");
if (_last == NULL) {
// This is the first allocation.
_last = this;
}
HandleRecord* handle = get_handle();
if (handle != NULL) {
handle->set_value(obj);
#ifdef METADATA_TRACK_NAMES
handle->set_name(obj->print_value_string());
#endif
return (jmetadata) handle;
}
// Check if unused block follow last
if (_last->_next != NULL) {
// update last and retry
_last = _last->_next;
return allocate_metadata_handle(obj);
}
// No space available, we have to rebuild free list or expand
if (_allocate_before_rebuild == 0) {
rebuild_free_list(); // updates _allocate_before_rebuild counter
} else {
// Append new block
// This can block, but the caller has a metadata handle around this object.
_last->_next = allocate_block();
_last = _last->_next;
_allocate_before_rebuild--;
}
return allocate_metadata_handle(obj); // retry
}
void MetadataHandleBlock::rebuild_free_list() {
assert(_allocate_before_rebuild == 0 && _free_list == 0, "just checking");
int free = 0;
int blocks = 0;
for (MetadataHandleBlock* current = this; current != NULL; current = current->_next) {
for (int index = 0; index < current->_top; index++) {
HandleRecord* handle = &(current->_handles)[index];
if (handle->value() == NULL) {
// this handle was cleared out by a delete call, reuse it
chain_free_list(handle);
free++;
}
}
// we should not rebuild free list if there are unused handles at the end
assert(current->_top == block_size_in_handles, "just checking");
blocks++;
}
// Heuristic: if more than half of the handles are NOT free we rebuild next time
// as well, otherwise we append a corresponding number of new blocks before
// attempting a free list rebuild again.
int total = blocks * block_size_in_handles;
int extra = total - 2*free;
if (extra > 0) {
// Not as many free handles as we would like - compute number of new blocks to append
_allocate_before_rebuild = (extra + block_size_in_handles - 1) / block_size_in_handles;
}
}
void MetadataHandleBlock::metadata_do(void f(Metadata*)) {
for (MetadataHandleBlock* current = this; current != NULL; current = current->_next) {
for (int index = 0; index < current->_top; index++) {
HandleRecord* root = &(current->_handles)[index];
Metadata* value = root->value();
// traverse heap pointers only, not deleted handles or free list
// pointers
if (value != NULL && ((intptr_t) value & ptr_tag) == 0) {
assert(value->is_valid(), "invalid metadata %s", get_name(index));
f(value);
}
}
// the next handle block is valid only if current block is full
if (current->_top < block_size_in_handles) {
break;
}
}
}
// Visit any live metadata handles and clean them up. Since clearing of these handles is driven by
// weak references they will be cleared at some point in the future when the reference cleaning logic is run.
void MetadataHandleBlock::do_unloading() {
for (MetadataHandleBlock* current = this; current != NULL; current = current->_next) {
for (int index = 0; index < current->_top; index++) {
HandleRecord* handle = &(current->_handles)[index];
Metadata* value = handle->value();
// traverse heap pointers only, not deleted handles or free list
// pointers
if (value != NULL && ((intptr_t) value & ptr_tag) == 0) {
Klass* klass = NULL;
if (value->is_klass()) {
klass = (Klass*)value;
} else if (value->is_method()) {
Method* m = (Method*)value;
klass = m->method_holder();
} else if (value->is_constantPool()) {
ConstantPool* cp = (ConstantPool*)value;
klass = cp->pool_holder();
} else {
ShouldNotReachHere();
}
if (klass->class_loader_data()->is_unloading()) {
// This needs to be marked so that it's no longer scanned
// but can't be put on the free list yet. The
// HandleCleaner will set this to NULL and
// put it on the free list.
jlong old_value = Atomic::cmpxchg((jlong) (ptr_tag), (jlong*)handle, (jlong) value);
if (old_value == (jlong) value) {
// Success
} else {
guarantee(old_value == 0, "only other possible value");
}
}
}
}
// the next handle block is valid only if current block is full
if (current->_top < block_size_in_handles) {
break;
}
}
}

View File

@ -0,0 +1,170 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef SHARE_JVMCI_METADATAHANDLEBLOCK_HPP
#define SHARE_JVMCI_METADATAHANDLEBLOCK_HPP
#include "oops/constantPool.hpp"
#include "oops/metadata.hpp"
#include "oops/method.hpp"
#include "runtime/handles.hpp"
#include "runtime/os.hpp"
#ifdef ASSERT
#define METADATA_TRACK_NAMES
#endif
struct _jmetadata {
private:
Metadata* _value;
#ifdef METADATA_TRACK_NAMES
// Debug data for tracking stale metadata
const char* _name;
#endif
public:
Metadata* value() { return _value; }
#ifdef METADATA_TRACK_NAMES
void initialize() {
_value = NULL;
_name = NULL;
}
#endif
void set_value(Metadata* value) {
_value = value;
}
#ifdef METADATA_TRACK_NAMES
const char* name() { return _name; }
void set_name(const char* name) {
if (_name != NULL) {
os::free((void*) _name);
_name = NULL;
}
if (name != NULL) {
_name = os::strdup(name);
}
}
#endif
};
typedef struct _jmetadata HandleRecord;
typedef struct _jmetadata *jmetadata;
// JVMCI maintains direct references to metadata. To make these references safe in the face of
// class redefinition, they are held in handles so they can be scanned during GC. They are
// managed in a cooperative way between the Java code and HotSpot. A handle is filled in and
// passed back to the Java code which is responsible for setting the handle to NULL when it
// is no longer in use. This is done by jdk.vm.ci.hotspot.HandleCleaner. The
// rebuild_free_list function notices when the handle is clear and reclaims it for re-use.
class MetadataHandleBlock : public CHeapObj<mtJVMCI> {
private:
enum SomeConstants {
block_size_in_handles = 32, // Number of handles per handle block
ptr_tag = 1,
ptr_mask = ~((intptr_t)ptr_tag)
};
// Free handles always have their low bit set so those pointers can
// be distinguished from handles which are in use. The last handle
// on the free list has a NULL pointer with the tag bit set, so it's
// clear that the handle has been reclaimed. The _free_list is
// always a real pointer to a handle.
HandleRecord _handles[block_size_in_handles]; // The handles
int _top; // Index of next unused handle
MetadataHandleBlock* _next; // Link to next block
// The following instance variables are only used by the first block in a chain.
// Having two types of blocks complicates the code and the space overhead is negligible.
static MetadataHandleBlock* _last; // Last block in use
static intptr_t _free_list; // Handle free list
static int _allocate_before_rebuild; // Number of blocks to allocate before rebuilding free list
MetadataHandleBlock() {
_top = 0;
_next = NULL;
#ifdef METADATA_TRACK_NAMES
for (int i = 0; i < block_size_in_handles; i++) {
_handles[i].initialize();
}
#endif
}
const char* get_name(int index) {
#ifdef METADATA_TRACK_NAMES
return _handles[index].name();
#else
return "<missing>";
#endif
}
static HandleRecord* get_free_handle() {
assert(_free_list != 0, "should check before calling");
HandleRecord* handle = (HandleRecord*) (_free_list & ptr_mask);
_free_list = (ptr_mask & (intptr_t) (handle->value()));
assert(_free_list != ptr_tag, "should be null");
handle->set_value(NULL);
return handle;
}
static HandleRecord* get_handle() {
assert(_last != NULL, "sanity");
// Try last block
if (_last->_top < block_size_in_handles) {
return &(_last->_handles)[_last->_top++];
} else if (_free_list != 0) {
// Try free list
return get_free_handle();
}
return NULL;
}
void rebuild_free_list();
jmetadata allocate_metadata_handle(Metadata* metadata);
public:
jmetadata allocate_handle(const methodHandle& handle) { return allocate_metadata_handle(handle()); }
jmetadata allocate_handle(const constantPoolHandle& handle) { return allocate_metadata_handle(handle()); }
static MetadataHandleBlock* allocate_block() { return new MetadataHandleBlock(); }
// Adds `handle` to the free list in this block
static void chain_free_list(HandleRecord* handle) {
handle->set_value((Metadata*) (ptr_tag | _free_list));
#ifdef METADATA_TRACK_NAMES
handle->set_name(NULL);
#endif
_free_list = (intptr_t) handle;
}
void metadata_do(void f(Metadata*));
void do_unloading();
};
#endif // SHARE_JVMCI_METADATAHANDLEBLOCK_HPP

View File

@ -1,94 +0,0 @@
/*
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
#ifndef SHARE_JVMCI_SYSTEMDICTIONARY_JVMCI_HPP
#define SHARE_JVMCI_SYSTEMDICTIONARY_JVMCI_HPP
#if !INCLUDE_JVMCI
#define JVMCI_WK_KLASSES_DO(do_klass)
#else
#define JVMCI_WK_KLASSES_DO(do_klass) \
/* JVMCI classes. These are loaded on-demand. */ \
do_klass(JVMCI_klass, jdk_vm_ci_runtime_JVMCI ) \
do_klass(HotSpotCompiledCode_klass, jdk_vm_ci_hotspot_HotSpotCompiledCode ) \
do_klass(HotSpotCompiledCode_Comment_klass, jdk_vm_ci_hotspot_HotSpotCompiledCode_Comment ) \
do_klass(HotSpotCompiledNmethod_klass, jdk_vm_ci_hotspot_HotSpotCompiledNmethod ) \
do_klass(HotSpotForeignCallTarget_klass, jdk_vm_ci_hotspot_HotSpotForeignCallTarget ) \
do_klass(HotSpotReferenceMap_klass, jdk_vm_ci_hotspot_HotSpotReferenceMap ) \
do_klass(HotSpotInstalledCode_klass, jdk_vm_ci_hotspot_HotSpotInstalledCode ) \
do_klass(HotSpotNmethod_klass, jdk_vm_ci_hotspot_HotSpotNmethod ) \
do_klass(HotSpotResolvedJavaMethodImpl_klass, jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl ) \
do_klass(HotSpotResolvedObjectTypeImpl_klass, jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl ) \
do_klass(HotSpotCompressedNullConstant_klass, jdk_vm_ci_hotspot_HotSpotCompressedNullConstant ) \
do_klass(HotSpotObjectConstantImpl_klass, jdk_vm_ci_hotspot_HotSpotObjectConstantImpl ) \
do_klass(HotSpotMetaspaceConstantImpl_klass, jdk_vm_ci_hotspot_HotSpotMetaspaceConstantImpl ) \
do_klass(HotSpotSentinelConstant_klass, jdk_vm_ci_hotspot_HotSpotSentinelConstant ) \
do_klass(HotSpotStackFrameReference_klass, jdk_vm_ci_hotspot_HotSpotStackFrameReference ) \
do_klass(HotSpotMetaData_klass, jdk_vm_ci_hotspot_HotSpotMetaData ) \
do_klass(HotSpotConstantPool_klass, jdk_vm_ci_hotspot_HotSpotConstantPool ) \
do_klass(HotSpotJVMCIMetaAccessContext_klass, jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext ) \
do_klass(HotSpotJVMCIRuntime_klass, jdk_vm_ci_hotspot_HotSpotJVMCIRuntime ) \
do_klass(HotSpotSpeculationLog_klass, jdk_vm_ci_hotspot_HotSpotSpeculationLog ) \
do_klass(HotSpotCompilationRequestResult_klass, jdk_vm_ci_hotspot_HotSpotCompilationRequestResult) \
do_klass(VMField_klass, jdk_vm_ci_hotspot_VMField ) \
do_klass(VMFlag_klass, jdk_vm_ci_hotspot_VMFlag ) \
do_klass(VMIntrinsicMethod_klass, jdk_vm_ci_hotspot_VMIntrinsicMethod ) \
do_klass(Assumptions_ConcreteMethod_klass, jdk_vm_ci_meta_Assumptions_ConcreteMethod ) \
do_klass(Assumptions_NoFinalizableSubclass_klass, jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass ) \
do_klass(Assumptions_ConcreteSubtype_klass, jdk_vm_ci_meta_Assumptions_ConcreteSubtype ) \
do_klass(Assumptions_LeafType_klass, jdk_vm_ci_meta_Assumptions_LeafType ) \
do_klass(Assumptions_CallSiteTargetValue_klass, jdk_vm_ci_meta_Assumptions_CallSiteTargetValue ) \
do_klass(Architecture_klass, jdk_vm_ci_code_Architecture ) \
do_klass(TargetDescription_klass, jdk_vm_ci_code_TargetDescription ) \
do_klass(BytecodePosition_klass, jdk_vm_ci_code_BytecodePosition ) \
do_klass(DebugInfo_klass, jdk_vm_ci_code_DebugInfo ) \
do_klass(RegisterSaveLayout_klass, jdk_vm_ci_code_RegisterSaveLayout ) \
do_klass(BytecodeFrame_klass, jdk_vm_ci_code_BytecodeFrame ) \
do_klass(InstalledCode_klass, jdk_vm_ci_code_InstalledCode ) \
do_klass(code_Location_klass, jdk_vm_ci_code_Location ) \
do_klass(code_Register_klass, jdk_vm_ci_code_Register ) \
do_klass(RegisterValue_klass, jdk_vm_ci_code_RegisterValue ) \
do_klass(StackSlot_klass, jdk_vm_ci_code_StackSlot ) \
do_klass(StackLockValue_klass, jdk_vm_ci_code_StackLockValue ) \
do_klass(VirtualObject_klass, jdk_vm_ci_code_VirtualObject ) \
do_klass(site_Call_klass, jdk_vm_ci_code_site_Call ) \
do_klass(site_ConstantReference_klass, jdk_vm_ci_code_site_ConstantReference ) \
do_klass(site_DataPatch_klass, jdk_vm_ci_code_site_DataPatch ) \
do_klass(site_DataSectionReference_klass, jdk_vm_ci_code_site_DataSectionReference ) \
do_klass(site_ExceptionHandler_klass, jdk_vm_ci_code_site_ExceptionHandler ) \
do_klass(site_Mark_klass, jdk_vm_ci_code_site_Mark ) \
do_klass(site_Infopoint_klass, jdk_vm_ci_code_site_Infopoint ) \
do_klass(site_Site_klass, jdk_vm_ci_code_site_Site ) \
do_klass(site_InfopointReason_klass, jdk_vm_ci_code_site_InfopointReason ) \
do_klass(InspectedFrameVisitor_klass, jdk_vm_ci_code_stack_InspectedFrameVisitor ) \
do_klass(JavaConstant_klass, jdk_vm_ci_meta_JavaConstant ) \
do_klass(PrimitiveConstant_klass, jdk_vm_ci_meta_PrimitiveConstant ) \
do_klass(RawConstant_klass, jdk_vm_ci_meta_RawConstant ) \
do_klass(NullConstant_klass, jdk_vm_ci_meta_NullConstant ) \
do_klass(ExceptionHandler_klass, jdk_vm_ci_meta_ExceptionHandler ) \
do_klass(JavaKind_klass, jdk_vm_ci_meta_JavaKind ) \
do_klass(ValueKind_klass, jdk_vm_ci_meta_ValueKind ) \
do_klass(Value_klass, jdk_vm_ci_meta_Value )
#endif
#endif // SHARE_JVMCI_SYSTEMDICTIONARY_JVMCI_HPP

View File

@ -23,27 +23,16 @@
*/
#include "precompiled.hpp"
#include "code/codeBlob.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/compileBroker.hpp"
#include "gc/shared/cardTable.hpp"
#include "gc/shared/collectedHeap.hpp"
#include "jvmci/jvmciCodeInstaller.hpp"
#include "jvmci/jvmciCompilerToVM.hpp"
#include "jvmci/jvmciEnv.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/vmStructs_compiler_runtime.hpp"
#include "jvmci/vmStructs_jvmci.hpp"
#include "oops/oop.hpp"
#include "oops/oopHandle.hpp"
#include "oops/objArrayKlass.hpp"
#include "runtime/flags/jvmFlag.hpp"
#include "runtime/globals.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/thread.hpp"
#include "runtime/vm_version.hpp"
#if INCLUDE_G1GC
#include "gc/g1/g1BarrierSet.hpp"
#include "gc/g1/g1CardTable.hpp"
#include "gc/g1/heapRegion.hpp"
#include "gc/g1/g1ThreadLocalData.hpp"
@ -180,7 +169,7 @@
volatile_nonstatic_field(JavaThread, _is_method_handle_return, int) \
nonstatic_field(JavaThread, _osthread, OSThread*) \
nonstatic_field(JavaThread, _pending_deoptimization, int) \
nonstatic_field(JavaThread, _pending_failed_speculation, long) \
nonstatic_field(JavaThread, _pending_failed_speculation, jlong) \
nonstatic_field(JavaThread, _pending_transfer_to_interpreter, bool) \
nonstatic_field(JavaThread, _jvmci_counters, jlong*) \
nonstatic_field(JavaThread, _should_post_on_exceptions_flag, int) \
@ -189,12 +178,6 @@
static_field(java_lang_Class, _klass_offset, int) \
static_field(java_lang_Class, _array_klass_offset, int) \
\
nonstatic_field(JVMCIEnv, _task, CompileTask*) \
nonstatic_field(JVMCIEnv, _jvmti_can_hotswap_or_post_breakpoint, jbyte) \
nonstatic_field(JVMCIEnv, _jvmti_can_access_local_variables, jbyte) \
nonstatic_field(JVMCIEnv, _jvmti_can_post_on_exceptions, jbyte) \
nonstatic_field(JVMCIEnv, _jvmti_can_pop_frame, jbyte) \
\
nonstatic_field(InvocationCounter, _counter, unsigned int) \
\
nonstatic_field(Klass, _secondary_super_cache, Klass*) \
@ -209,6 +192,7 @@
nonstatic_field(Klass, _java_mirror, OopHandle) \
nonstatic_field(Klass, _modifier_flags, jint) \
nonstatic_field(Klass, _access_flags, AccessFlags) \
nonstatic_field(Klass, _class_loader_data, ClassLoaderData*) \
\
nonstatic_field(LocalVariableTableElement, start_bci, u2) \
nonstatic_field(LocalVariableTableElement, length, u2) \
@ -359,6 +343,7 @@
declare_toplevel_type(JVMFlag) \
declare_toplevel_type(JVMFlag*) \
declare_toplevel_type(InvocationCounter) \
declare_toplevel_type(JVMCICompileState) \
declare_toplevel_type(JVMCIEnv) \
declare_toplevel_type(LocalVariableTableElement) \
declare_toplevel_type(narrowKlass) \
@ -401,6 +386,7 @@
declare_preprocessor_constant("JVM_ACC_ANNOTATION", JVM_ACC_ANNOTATION) \
declare_preprocessor_constant("JVM_ACC_ENUM", JVM_ACC_ENUM) \
declare_preprocessor_constant("JVM_ACC_SYNTHETIC", JVM_ACC_SYNTHETIC) \
declare_preprocessor_constant("JVM_ACC_INTERFACE", JVM_ACC_INTERFACE) \
\
declare_constant(JVM_CONSTANT_Utf8) \
declare_constant(JVM_CONSTANT_Unicode) \
@ -544,11 +530,11 @@
declare_constant(JumpData::taken_off_set) \
declare_constant(JumpData::displacement_off_set) \
\
declare_constant(JVMCIEnv::ok) \
declare_constant(JVMCIEnv::dependencies_failed) \
declare_constant(JVMCIEnv::dependencies_invalid) \
declare_constant(JVMCIEnv::cache_full) \
declare_constant(JVMCIEnv::code_too_large) \
declare_preprocessor_constant("JVMCIEnv::ok", JVMCI::ok) \
declare_preprocessor_constant("JVMCIEnv::dependencies_failed", JVMCI::dependencies_failed) \
declare_preprocessor_constant("JVMCIEnv::dependencies_invalid", JVMCI::dependencies_invalid) \
declare_preprocessor_constant("JVMCIEnv::cache_full", JVMCI::cache_full) \
declare_preprocessor_constant("JVMCIEnv::code_too_large", JVMCI::code_too_large) \
declare_constant(JVMCIRuntime::none) \
declare_constant(JVMCIRuntime::by_holder) \
declare_constant(JVMCIRuntime::by_full_signature) \

View File

@ -28,78 +28,110 @@
#if !INCLUDE_JVMCI
#define JVMCI_VM_SYMBOLS_DO(template, do_alias)
#else
#define JVMCI_VM_SYMBOLS_DO(template, do_alias) \
template(jdk_vm_ci_runtime_JVMCI, "jdk/vm/ci/runtime/JVMCI") \
template(jdk_vm_ci_hotspot_HotSpotCompiledCode, "jdk/vm/ci/hotspot/HotSpotCompiledCode") \
template(jdk_vm_ci_hotspot_HotSpotCompiledCode_Comment, "jdk/vm/ci/hotspot/HotSpotCompiledCode$Comment") \
template(jdk_vm_ci_hotspot_HotSpotCompiledNmethod, "jdk/vm/ci/hotspot/HotSpotCompiledNmethod") \
template(jdk_vm_ci_hotspot_HotSpotForeignCallTarget, "jdk/vm/ci/hotspot/HotSpotForeignCallTarget") \
template(jdk_vm_ci_hotspot_HotSpotReferenceMap, "jdk/vm/ci/hotspot/HotSpotReferenceMap") \
template(jdk_vm_ci_hotspot_CompilerToVM, "jdk/vm/ci/hotspot/CompilerToVM") \
template(jdk_vm_ci_hotspot_HotSpotInstalledCode, "jdk/vm/ci/hotspot/HotSpotInstalledCode") \
template(jdk_vm_ci_hotspot_HotSpotNmethod, "jdk/vm/ci/hotspot/HotSpotNmethod") \
template(jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl, "jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl") \
template(jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl, "jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl") \
template(jdk_vm_ci_hotspot_HotSpotCompressedNullConstant, "jdk/vm/ci/hotspot/HotSpotCompressedNullConstant") \
template(jdk_vm_ci_hotspot_HotSpotObjectConstantImpl, "jdk/vm/ci/hotspot/HotSpotObjectConstantImpl") \
template(jdk_vm_ci_hotspot_HotSpotMetaspaceConstantImpl, "jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl") \
template(jdk_vm_ci_hotspot_HotSpotSentinelConstant, "jdk/vm/ci/hotspot/HotSpotSentinelConstant") \
template(jdk_vm_ci_hotspot_HotSpotStackFrameReference, "jdk/vm/ci/hotspot/HotSpotStackFrameReference") \
template(jdk_vm_ci_hotspot_HotSpotMetaData, "jdk/vm/ci/hotspot/HotSpotMetaData") \
template(jdk_vm_ci_hotspot_HotSpotConstantPool, "jdk/vm/ci/hotspot/HotSpotConstantPool") \
template(jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext, "jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext") \
template(jdk_vm_ci_hotspot_HotSpotJVMCIRuntime, "jdk/vm/ci/hotspot/HotSpotJVMCIRuntime") \
template(jdk_vm_ci_hotspot_HotSpotSpeculationLog, "jdk/vm/ci/hotspot/HotSpotSpeculationLog") \
template(jdk_vm_ci_hotspot_HotSpotCompilationRequestResult, "jdk/vm/ci/hotspot/HotSpotCompilationRequestResult") \
template(jdk_vm_ci_hotspot_VMField, "jdk/vm/ci/hotspot/VMField") \
template(jdk_vm_ci_hotspot_VMFlag, "jdk/vm/ci/hotspot/VMFlag") \
template(jdk_vm_ci_hotspot_VMIntrinsicMethod, "jdk/vm/ci/hotspot/VMIntrinsicMethod") \
template(jdk_vm_ci_meta_JavaConstant, "jdk/vm/ci/meta/JavaConstant") \
template(jdk_vm_ci_meta_PrimitiveConstant, "jdk/vm/ci/meta/PrimitiveConstant") \
template(jdk_vm_ci_meta_RawConstant, "jdk/vm/ci/meta/RawConstant") \
template(jdk_vm_ci_meta_NullConstant, "jdk/vm/ci/meta/NullConstant") \
template(jdk_vm_ci_meta_ExceptionHandler, "jdk/vm/ci/meta/ExceptionHandler") \
template(jdk_vm_ci_meta_JavaKind, "jdk/vm/ci/meta/JavaKind") \
template(jdk_vm_ci_meta_ValueKind, "jdk/vm/ci/meta/ValueKind") \
template(jdk_vm_ci_meta_Value, "jdk/vm/ci/meta/Value") \
template(jdk_vm_ci_meta_Assumptions_ConcreteSubtype, "jdk/vm/ci/meta/Assumptions$ConcreteSubtype") \
template(jdk_vm_ci_meta_Assumptions_LeafType, "jdk/vm/ci/meta/Assumptions$LeafType") \
template(jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass, "jdk/vm/ci/meta/Assumptions$NoFinalizableSubclass") \
template(jdk_vm_ci_meta_Assumptions_ConcreteMethod, "jdk/vm/ci/meta/Assumptions$ConcreteMethod") \
template(jdk_vm_ci_meta_Assumptions_CallSiteTargetValue, "jdk/vm/ci/meta/Assumptions$CallSiteTargetValue") \
template(jdk_vm_ci_code_Architecture, "jdk/vm/ci/code/Architecture") \
template(jdk_vm_ci_code_BytecodeFrame, "jdk/vm/ci/code/BytecodeFrame") \
template(jdk_vm_ci_code_BytecodePosition, "jdk/vm/ci/code/BytecodePosition") \
template(jdk_vm_ci_code_DebugInfo, "jdk/vm/ci/code/DebugInfo") \
template(jdk_vm_ci_code_InstalledCode, "jdk/vm/ci/code/InstalledCode") \
template(jdk_vm_ci_code_Location, "jdk/vm/ci/code/Location") \
template(jdk_vm_ci_code_Register, "jdk/vm/ci/code/Register") \
template(jdk_vm_ci_code_RegisterValue, "jdk/vm/ci/code/RegisterValue") \
template(jdk_vm_ci_code_StackSlot, "jdk/vm/ci/code/StackSlot") \
template(jdk_vm_ci_code_StackLockValue, "jdk/vm/ci/code/StackLockValue") \
template(jdk_vm_ci_code_TargetDescription, "jdk/vm/ci/code/TargetDescription") \
template(jdk_vm_ci_code_VirtualObject, "jdk/vm/ci/code/VirtualObject") \
template(jdk_vm_ci_code_RegisterSaveLayout, "jdk/vm/ci/code/RegisterSaveLayout") \
template(jdk_vm_ci_code_InvalidInstalledCodeException, "jdk/vm/ci/code/InvalidInstalledCodeException") \
template(jdk_vm_ci_code_site_Call, "jdk/vm/ci/code/site/Call") \
template(jdk_vm_ci_code_site_ConstantReference, "jdk/vm/ci/code/site/ConstantReference") \
template(jdk_vm_ci_code_site_DataPatch, "jdk/vm/ci/code/site/DataPatch") \
template(jdk_vm_ci_code_site_DataSectionReference, "jdk/vm/ci/code/site/DataSectionReference") \
template(jdk_vm_ci_code_site_ExceptionHandler, "jdk/vm/ci/code/site/ExceptionHandler") \
template(jdk_vm_ci_code_site_Mark, "jdk/vm/ci/code/site/Mark") \
template(jdk_vm_ci_code_site_Infopoint, "jdk/vm/ci/code/site/Infopoint") \
template(jdk_vm_ci_code_stack_InspectedFrameVisitor, "jdk/vm/ci/code/stack/InspectedFrameVisitor") \
template(jdk_vm_ci_code_site_Site, "jdk/vm/ci/code/site/Site") \
template(jdk_vm_ci_code_site_InfopointReason, "jdk/vm/ci/code/site/InfopointReason") \
template(jdk_vm_ci_common_JVMCIError, "jdk/vm/ci/common/JVMCIError") \
template(visitFrame_name, "visitFrame") \
template(visitFrame_signature, "(Ljdk/vm/ci/code/stack/InspectedFrame;)Ljava/lang/Object;") \
template(compileMethod_name, "compileMethod") \
#define JVMCI_VM_SYMBOLS_DO(template, do_alias) \
template(jdk_vm_ci_services_Services, "jdk/vm/ci/services/Services") \
template(jdk_vm_ci_runtime_JVMCI, "jdk/vm/ci/runtime/JVMCI") \
template(jdk_vm_ci_hotspot_HotSpotCompiledCode, "jdk/vm/ci/hotspot/HotSpotCompiledCode") \
template(jdk_vm_ci_hotspot_HotSpotCompiledCode_Comment, "jdk/vm/ci/hotspot/HotSpotCompiledCode$Comment") \
template(jdk_vm_ci_hotspot_HotSpotCompiledNmethod, "jdk/vm/ci/hotspot/HotSpotCompiledNmethod") \
template(jdk_vm_ci_hotspot_HotSpotForeignCallTarget, "jdk/vm/ci/hotspot/HotSpotForeignCallTarget") \
template(jdk_vm_ci_hotspot_HotSpotReferenceMap, "jdk/vm/ci/hotspot/HotSpotReferenceMap") \
template(jdk_vm_ci_hotspot_CompilerToVM, "jdk/vm/ci/hotspot/CompilerToVM") \
template(jdk_vm_ci_hotspot_HotSpotInstalledCode, "jdk/vm/ci/hotspot/HotSpotInstalledCode") \
template(jdk_vm_ci_hotspot_HotSpotNmethod, "jdk/vm/ci/hotspot/HotSpotNmethod") \
template(jdk_vm_ci_hotspot_HotSpotResolvedJavaMethodImpl, "jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl") \
template(jdk_vm_ci_hotspot_HotSpotResolvedObjectTypeImpl, "jdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl") \
template(jdk_vm_ci_hotspot_HotSpotResolvedPrimitiveType, "jdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType") \
template(jdk_vm_ci_hotspot_HotSpotResolvedJavaFieldImpl, "jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl") \
template(jdk_vm_ci_hotspot_HotSpotCompressedNullConstant, "jdk/vm/ci/hotspot/HotSpotCompressedNullConstant") \
template(jdk_vm_ci_hotspot_HotSpotObjectConstantImpl, "jdk/vm/ci/hotspot/HotSpotObjectConstantImpl") \
template(jdk_vm_ci_hotspot_DirectHotSpotObjectConstantImpl, "jdk/vm/ci/hotspot/DirectHotSpotObjectConstantImpl") \
template(jdk_vm_ci_hotspot_IndirectHotSpotObjectConstantImpl, "jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl") \
template(jdk_vm_ci_hotspot_HotSpotMetaspaceConstantImpl, "jdk/vm/ci/hotspot/HotSpotMetaspaceConstantImpl") \
template(jdk_vm_ci_hotspot_HotSpotSentinelConstant, "jdk/vm/ci/hotspot/HotSpotSentinelConstant") \
template(jdk_vm_ci_hotspot_HotSpotStackFrameReference, "jdk/vm/ci/hotspot/HotSpotStackFrameReference") \
template(jdk_vm_ci_hotspot_HotSpotMetaData, "jdk/vm/ci/hotspot/HotSpotMetaData") \
template(jdk_vm_ci_hotspot_HotSpotConstantPool, "jdk/vm/ci/hotspot/HotSpotConstantPool") \
template(jdk_vm_ci_hotspot_HotSpotJVMCIRuntime, "jdk/vm/ci/hotspot/HotSpotJVMCIRuntime") \
template(jdk_vm_ci_hotspot_HotSpotSpeculationLog, "jdk/vm/ci/hotspot/HotSpotSpeculationLog") \
template(jdk_vm_ci_hotspot_HotSpotCompilationRequestResult, "jdk/vm/ci/hotspot/HotSpotCompilationRequestResult") \
template(jdk_vm_ci_hotspot_VMField, "jdk/vm/ci/hotspot/VMField") \
template(jdk_vm_ci_hotspot_VMFlag, "jdk/vm/ci/hotspot/VMFlag") \
template(jdk_vm_ci_hotspot_VMIntrinsicMethod, "jdk/vm/ci/hotspot/VMIntrinsicMethod") \
template(jdk_vm_ci_meta_ResolvedJavaMethod, "jdk/vm/ci/meta/ResolvedJavaMethod") \
template(jdk_vm_ci_meta_JavaConstant, "jdk/vm/ci/meta/JavaConstant") \
template(jdk_vm_ci_meta_PrimitiveConstant, "jdk/vm/ci/meta/PrimitiveConstant") \
template(jdk_vm_ci_meta_RawConstant, "jdk/vm/ci/meta/RawConstant") \
template(jdk_vm_ci_meta_NullConstant, "jdk/vm/ci/meta/NullConstant") \
template(jdk_vm_ci_meta_ExceptionHandler, "jdk/vm/ci/meta/ExceptionHandler") \
template(jdk_vm_ci_meta_JavaKind, "jdk/vm/ci/meta/JavaKind") \
template(jdk_vm_ci_meta_ValueKind, "jdk/vm/ci/meta/ValueKind") \
template(jdk_vm_ci_meta_Value, "jdk/vm/ci/meta/Value") \
template(jdk_vm_ci_meta_Assumptions_ConcreteSubtype, "jdk/vm/ci/meta/Assumptions$ConcreteSubtype") \
template(jdk_vm_ci_meta_Assumptions_LeafType, "jdk/vm/ci/meta/Assumptions$LeafType") \
template(jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass, "jdk/vm/ci/meta/Assumptions$NoFinalizableSubclass") \
template(jdk_vm_ci_meta_Assumptions_ConcreteMethod, "jdk/vm/ci/meta/Assumptions$ConcreteMethod") \
template(jdk_vm_ci_meta_Assumptions_CallSiteTargetValue, "jdk/vm/ci/meta/Assumptions$CallSiteTargetValue") \
template(jdk_vm_ci_code_Architecture, "jdk/vm/ci/code/Architecture") \
template(jdk_vm_ci_code_BytecodeFrame, "jdk/vm/ci/code/BytecodeFrame") \
template(jdk_vm_ci_code_BytecodePosition, "jdk/vm/ci/code/BytecodePosition") \
template(jdk_vm_ci_code_DebugInfo, "jdk/vm/ci/code/DebugInfo") \
template(jdk_vm_ci_code_InstalledCode, "jdk/vm/ci/code/InstalledCode") \
template(jdk_vm_ci_code_Location, "jdk/vm/ci/code/Location") \
template(jdk_vm_ci_code_Register, "jdk/vm/ci/code/Register") \
template(jdk_vm_ci_code_RegisterValue, "jdk/vm/ci/code/RegisterValue") \
template(jdk_vm_ci_code_StackSlot, "jdk/vm/ci/code/StackSlot") \
template(jdk_vm_ci_code_StackLockValue, "jdk/vm/ci/code/StackLockValue") \
template(jdk_vm_ci_code_TargetDescription, "jdk/vm/ci/code/TargetDescription") \
template(jdk_vm_ci_code_VirtualObject, "jdk/vm/ci/code/VirtualObject") \
template(jdk_vm_ci_code_RegisterSaveLayout, "jdk/vm/ci/code/RegisterSaveLayout") \
template(jdk_vm_ci_code_InvalidInstalledCodeException, "jdk/vm/ci/code/InvalidInstalledCodeException") \
template(jdk_vm_ci_code_site_Call, "jdk/vm/ci/code/site/Call") \
template(jdk_vm_ci_code_site_ConstantReference, "jdk/vm/ci/code/site/ConstantReference") \
template(jdk_vm_ci_code_site_DataPatch, "jdk/vm/ci/code/site/DataPatch") \
template(jdk_vm_ci_code_site_DataSectionReference, "jdk/vm/ci/code/site/DataSectionReference") \
template(jdk_vm_ci_code_site_ExceptionHandler, "jdk/vm/ci/code/site/ExceptionHandler") \
template(jdk_vm_ci_code_site_Mark, "jdk/vm/ci/code/site/Mark") \
template(jdk_vm_ci_code_site_Infopoint, "jdk/vm/ci/code/site/Infopoint") \
template(jdk_vm_ci_code_stack_InspectedFrameVisitor, "jdk/vm/ci/code/stack/InspectedFrameVisitor") \
template(jdk_vm_ci_code_site_Site, "jdk/vm/ci/code/site/Site") \
template(jdk_vm_ci_code_site_InfopointReason, "jdk/vm/ci/code/site/InfopointReason") \
template(jdk_vm_ci_common_JVMCIError, "jdk/vm/ci/common/JVMCIError") \
\
template(visitFrame_name, "visitFrame") \
template(visitFrame_signature, "(Ljdk/vm/ci/code/stack/InspectedFrame;)Ljava/lang/Object;") \
template(compileMethod_name, "compileMethod") \
template(compileMethod_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;IJI)Ljdk/vm/ci/hotspot/HotSpotCompilationRequestResult;") \
template(fromMetaspace_name, "fromMetaspace") \
template(method_fromMetaspace_signature, "(J)Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;") \
template(constantPool_fromMetaspace_signature, "(J)Ljdk/vm/ci/hotspot/HotSpotConstantPool;") \
template(klass_fromMetaspace_signature, "(Ljava/lang/Class;)Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;")
template(encodeThrowable_name, "encodeThrowable") \
template(encodeThrowable_signature, "(Ljava/lang/Throwable;)Ljava/lang/String;") \
template(decodeThrowable_name, "decodeThrowable") \
template(decodeThrowable_signature, "(Ljava/lang/String;)Ljava/lang/Throwable;") \
template(fromMetaspace_name, "fromMetaspace") \
template(method_fromMetaspace_signature, "(J)Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethod;") \
template(constantPool_fromMetaspace_signature, "(J)Ljdk/vm/ci/hotspot/HotSpotConstantPool;") \
template(klass_fromMetaspace_signature, "(JLjava/lang/String;)Ljdk/vm/ci/hotspot/HotSpotResolvedObjectTypeImpl;") \
template(primitive_fromMetaspace_signature, "(Ljdk/vm/ci/hotspot/HotSpotObjectConstantImpl;C)Ljdk/vm/ci/hotspot/HotSpotResolvedPrimitiveType;") \
template(getRuntime_name, "getRuntime") \
template(getRuntime_signature, "()Ljdk/vm/ci/runtime/JVMCIRuntime;") \
template(initializeRuntime_name, "initializeRuntime") \
do_alias(initializeRuntime_signature, getRuntime_signature) \
template(runtime_name, "runtime") \
template(runtime_signature, "()Ljdk/vm/ci/hotspot/HotSpotJVMCIRuntime;") \
template(getCompiler_name, "getCompiler") \
template(getCompiler_signature, "()Ljdk/vm/ci/runtime/JVMCICompiler;") \
template(callToString_name, "callToString") \
template(callToString_signature, "(Ljava/lang/Object;)Ljava/lang/String;") \
template(getName_name, "getName") \
template(bootstrapFinished_name, "bootstrapFinished") \
template(forTypeChar_name, "forTypeChar") \
template(forTypeChar_signature, "(CJ)Ljdk/vm/ci/meta/PrimitiveConstant;") \
template(forFloat_name, "forFloat") \
template(forFloat_signature, "(F)Ljdk/vm/ci/meta/PrimitiveConstant;") \
template(forDouble_name, "forDouble") \
template(forDouble_signature, "(D)Ljdk/vm/ci/meta/PrimitiveConstant;") \
template(method_string_bool_long_signature, "(Ljdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl;Ljava/lang/String;ZJ)V") \
template(initializeSavedProperties_name, "initializeSavedProperties") \
#endif
#endif // SHARE_JVMCI_VMSYMBOLS_JVMCI_HPP

View File

@ -118,6 +118,7 @@ class AllocatedObj {
f(mtCode, "Code") /* generated code */ \
f(mtGC, "GC") \
f(mtCompiler, "Compiler") \
f(mtJVMCI, "JVMCI") \
f(mtInternal, "Internal") /* memory used by VM, but does not belong to */ \
/* any of above categories, and not used by */ \
/* NMT */ \

View File

@ -116,6 +116,11 @@ Method::Method(ConstMethod* xconst, AccessFlags access_flags) {
void Method::deallocate_contents(ClassLoaderData* loader_data) {
MetadataFactory::free_metadata(loader_data, constMethod());
set_constMethod(NULL);
#if INCLUDE_JVMCI
if (method_data()) {
FailedSpeculation::free_failed_speculations(method_data()->get_failed_speculations_address());
}
#endif
MetadataFactory::free_metadata(loader_data, method_data());
set_method_data(NULL);
MetadataFactory::free_metadata(loader_data, method_counters());

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -846,6 +846,86 @@ bool MethodData::is_speculative_trap_bytecode(Bytecodes::Code code) {
return false;
}
#if INCLUDE_JVMCI
void* FailedSpeculation::operator new(size_t size, size_t fs_size) throw() {
return CHeapObj<mtCompiler>::operator new(fs_size, std::nothrow);
}
FailedSpeculation::FailedSpeculation(address speculation, int speculation_len) : _data_len(speculation_len), _next(NULL) {
memcpy(data(), speculation, speculation_len);
}
// A heuristic check to detect nmethods that outlive a failed speculations list.
static void guarantee_failed_speculations_alive(nmethod* nm, FailedSpeculation** failed_speculations_address) {
jlong head = (jlong)(address) *failed_speculations_address;
if ((head & 0x1) == 0x1) {
stringStream st;
if (nm != NULL) {
st.print("%d", nm->compile_id());
Method* method = nm->method();
st.print_raw("{");
if (method != NULL) {
method->print_name(&st);
} else {
const char* jvmci_name = nm->jvmci_name();
if (jvmci_name != NULL) {
st.print_raw(jvmci_name);
}
}
st.print_raw("}");
} else {
st.print("<unknown>");
}
fatal("Adding to failed speculations list that appears to have been freed. Source: %s", st.as_string());
}
}
bool FailedSpeculation::add_failed_speculation(nmethod* nm, FailedSpeculation** failed_speculations_address, address speculation, int speculation_len) {
assert(failed_speculations_address != NULL, "must be");
size_t fs_size = sizeof(FailedSpeculation) + speculation_len;
FailedSpeculation* fs = new (fs_size) FailedSpeculation(speculation, speculation_len);
if (fs == NULL) {
// no memory -> ignore failed speculation
return false;
}
guarantee(is_aligned(fs, sizeof(FailedSpeculation*)), "FailedSpeculation objects must be pointer aligned");
guarantee_failed_speculations_alive(nm, failed_speculations_address);
FailedSpeculation** cursor = failed_speculations_address;
do {
if (*cursor == NULL) {
FailedSpeculation* old_fs = Atomic::cmpxchg(fs, cursor, (FailedSpeculation*) NULL);
if (old_fs == NULL) {
// Successfully appended fs to end of the list
return true;
}
cursor = old_fs->next_adr();
} else {
cursor = (*cursor)->next_adr();
}
} while (true);
}
void FailedSpeculation::free_failed_speculations(FailedSpeculation** failed_speculations_address) {
assert(failed_speculations_address != NULL, "must be");
FailedSpeculation* fs = *failed_speculations_address;
while (fs != NULL) {
FailedSpeculation* next = fs->next();
delete fs;
fs = next;
}
// Write an unaligned value to failed_speculations_address to denote
// that it is no longer a valid pointer. This is allows for the check
// in add_failed_speculation against adding to a freed failed
// speculations list.
long* head = (long*) failed_speculations_address;
(*head) = (*head) | 0x1;
}
#endif // INCLUDE_JVMCI
int MethodData::compute_extra_data_count(int data_size, int empty_bc_count, bool needs_speculative_traps) {
#if INCLUDE_JVMCI
if (ProfileTraps) {
@ -1227,6 +1307,7 @@ void MethodData::init() {
#if INCLUDE_JVMCI
_jvmci_ir_size = 0;
_failed_speculations = NULL;
#endif
#if INCLUDE_RTM_OPT

View File

@ -1949,6 +1949,42 @@ public:
};
#if INCLUDE_JVMCI
// Encapsulates an encoded speculation reason. These are linked together in
// a list that is atomically appended to during deoptimization. Entries are
// never removed from the list.
// @see jdk.vm.ci.hotspot.HotSpotSpeculationLog.HotSpotSpeculationEncoding
class FailedSpeculation: public CHeapObj<mtCompiler> {
private:
// The length of HotSpotSpeculationEncoding.toByteArray(). The data itself
// is an array embedded at the end of this object.
int _data_len;
// Next entry in a linked list.
FailedSpeculation* _next;
FailedSpeculation(address data, int data_len);
FailedSpeculation** next_adr() { return &_next; }
// Placement new operator for inlining the speculation data into
// the FailedSpeculation object.
void* operator new(size_t size, size_t fs_size) throw();
public:
char* data() { return (char*)(((address) this) + sizeof(FailedSpeculation)); }
int data_len() const { return _data_len; }
FailedSpeculation* next() const { return _next; }
// Atomically appends a speculation from nm to the list whose head is at (*failed_speculations_address).
// Returns false if the FailedSpeculation object could not be allocated.
static bool add_failed_speculation(nmethod* nm, FailedSpeculation** failed_speculations_address, address speculation, int speculation_len);
// Frees all entries in the linked list whose head is at (*failed_speculations_address).
static void free_failed_speculations(FailedSpeculation** failed_speculations_address);
};
#endif
class MethodData : public Metadata {
friend class VMStructs;
friend class JVMCIVMStructs;
@ -2030,7 +2066,8 @@ private:
#if INCLUDE_JVMCI
// Support for HotSpotMethodData.setCompiledIRSize(int)
int _jvmci_ir_size;
int _jvmci_ir_size;
FailedSpeculation* _failed_speculations;
#endif
// Size of _data array in bytes. (Excludes header and extra_data fields.)
@ -2191,6 +2228,12 @@ public:
InvocationCounter* invocation_counter() { return &_invocation_counter; }
InvocationCounter* backedge_counter() { return &_backedge_counter; }
#if INCLUDE_JVMCI
FailedSpeculation** get_failed_speculations_address() {
return &_failed_speculations;
}
#endif
#if INCLUDE_RTM_OPT
int rtm_state() const {
return _rtm_state;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -2084,9 +2084,7 @@ static char *print_reg( OptoReg::Name reg, const PhaseChaitin *pc, char *buf ) {
// Dump a register name into a buffer. Be intelligent if we get called
// before allocation is complete.
char *PhaseChaitin::dump_register( const Node *n, char *buf ) const {
if( this == NULL ) { // Not got anything?
sprintf(buf,"N%d",n->_idx); // Then use Node index
} else if( _node_regs ) {
if( _node_regs ) {
// Post allocation, use direct mappings, no LRG info available
print_reg( get_reg_first(n), this, buf );
} else {

View File

@ -88,10 +88,6 @@
#include "utilities/histogram.hpp"
#include "utilities/macros.hpp"
#include "utilities/vmError.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmciCompiler.hpp"
#include "jvmci/jvmciRuntime.hpp"
#endif
static jint CurrentVersion = JNI_VERSION_10;
@ -1318,14 +1314,15 @@ static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str,
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
}
Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
// Throw a NoSuchMethodError exception if we have an instance of a
// primitive java.lang.Class
if (java_lang_Class::is_primitive(JNIHandles::resolve_non_null(clazz))) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
ResourceMark rm;
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), err_msg("%s%s.%s%s", is_static ? "static " : "", klass->signature_name(), name_str, sig));
}
Klass* klass = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
// Make sure class is linked and initialized before handing id's out to
// Method*s.
klass->initialize(CHECK_NULL);
@ -1346,7 +1343,8 @@ static jmethodID get_method_id(JNIEnv *env, jclass clazz, const char *name_str,
}
}
if (m == NULL || (m->is_static() != is_static)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), name_str);
ResourceMark rm;
THROW_MSG_0(vmSymbols::java_lang_NoSuchMethodError(), err_msg("%s%s.%s%s", is_static ? "static " : "", klass->signature_name(), name_str, sig));
}
return m->jmethod_id();
}
@ -2014,22 +2012,26 @@ JNI_ENTRY(jfieldID, jni_GetFieldID(JNIEnv *env, jclass clazz,
jfieldID ret = 0;
DT_RETURN_MARK(GetFieldID, jfieldID, (const jfieldID&)ret);
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
// The class should have been loaded (we have an instance of the class
// passed in) so the field and signature should already be in the symbol
// table. If they're not there, the field doesn't exist.
TempNewSymbol fieldname = SymbolTable::probe(name, (int)strlen(name));
TempNewSymbol signame = SymbolTable::probe(sig, (int)strlen(sig));
if (fieldname == NULL || signame == NULL) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
ResourceMark rm;
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
}
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
// Make sure class is initialized before handing id's out to fields
k->initialize(CHECK_NULL);
fieldDescriptor fd;
if (!k->is_instance_klass() ||
!InstanceKlass::cast(k)->find_field(fieldname, signame, false, &fd)) {
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), (char*) name);
ResourceMark rm;
THROW_MSG_0(vmSymbols::java_lang_NoSuchFieldError(), err_msg("%s.%s %s", k->external_name(), name, sig));
}
// A jfieldID for a non-static field is simply the offset of the field within the instanceOop

View File

@ -62,6 +62,9 @@
#if INCLUDE_ZGC
#include "gc/z/zGlobals.hpp"
#endif
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
// JvmtiTagHashmapEntry
//
@ -3034,6 +3037,17 @@ inline bool VM_HeapWalkOperation::collect_simple_roots() {
// exceptions) will be visible.
blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
Universe::oops_do(&blk);
if (blk.stopped()) {
return false;
}
#if INCLUDE_JVMCI
blk.set_kind(JVMTI_HEAP_REFERENCE_OTHER);
JVMCI::oops_do(&blk);
if (blk.stopped()) {
return false;
}
#endif
return true;
}

View File

@ -33,11 +33,6 @@
class NativeLookup : AllStatic {
private:
// JNI name computation
static char* pure_jni_name(const methodHandle& method);
static char* long_jni_name(const methodHandle& method);
static char* critical_jni_name(const methodHandle& method);
// Style specific lookup
static address lookup_style(const methodHandle& method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS);
static address lookup_critical_style(const methodHandle& method, char* pure_name, const char* long_name, int args_size, bool os_style);
@ -45,6 +40,11 @@ class NativeLookup : AllStatic {
static address lookup_entry(const methodHandle& method, bool& in_base_library, TRAPS);
static address lookup_entry_prefixed(const methodHandle& method, bool& in_base_library, TRAPS);
public:
// JNI name computation
static char* pure_jni_name(const methodHandle& method);
static char* long_jni_name(const methodHandle& method);
static char* critical_jni_name(const methodHandle& method);
// Lookup native function. May throw UnsatisfiedLinkError.
static address lookup(const methodHandle& method, bool& in_base_library, TRAPS);
static address lookup_critical_entry(const methodHandle& method);

View File

@ -57,9 +57,6 @@
#include "utilities/defaultStream.hpp"
#include "utilities/macros.hpp"
#include "utilities/stringUtils.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmciRuntime.hpp"
#endif
#if INCLUDE_JFR
#include "jfr/jfr.hpp"
#endif

View File

@ -63,11 +63,6 @@
#include "utilities/preserveException.hpp"
#include "utilities/xmlstream.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/jvmciJavaClasses.hpp"
#endif
bool DeoptimizationMarker::_is_active = false;
@ -1520,33 +1515,11 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra
methodHandle trap_method = trap_scope->method();
int trap_bci = trap_scope->bci();
#if INCLUDE_JVMCI
long speculation = thread->pending_failed_speculation();
if (nm->is_compiled_by_jvmci()) {
if (speculation != 0) {
oop speculation_log = nm->as_nmethod()->speculation_log();
if (speculation_log != NULL) {
if (TraceDeoptimization || TraceUncollectedSpeculations) {
if (HotSpotSpeculationLog::lastFailed(speculation_log) != 0) {
tty->print_cr("A speculation that was not collected by the compiler is being overwritten");
}
}
if (TraceDeoptimization) {
tty->print_cr("Saving speculation to speculation log");
}
HotSpotSpeculationLog::set_lastFailed(speculation_log, speculation);
} else {
if (TraceDeoptimization) {
tty->print_cr("Speculation present but no speculation log");
}
}
thread->set_pending_failed_speculation(0);
} else {
if (TraceDeoptimization) {
tty->print_cr("No speculation");
}
}
jlong speculation = thread->pending_failed_speculation();
if (nm->is_compiled_by_jvmci() && nm->is_nmethod()) { // Exclude AOTed methods
nm->as_nmethod()->update_speculation(thread);
} else {
assert(speculation == 0, "There should not be a speculation for method compiled by non-JVMCI compilers");
assert(speculation == 0, "There should not be a speculation for methods compiled by non-JVMCI compilers");
}
if (trap_bci == SynchronizationEntryBCI) {
@ -1595,6 +1568,11 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra
xtty->begin_head("uncommon_trap thread='" UINTX_FORMAT "' %s",
os::current_thread_id(),
format_trap_request(buf, sizeof(buf), trap_request));
#if INCLUDE_JVMCI
if (speculation != 0) {
xtty->print(" speculation='" JLONG_FORMAT "'", speculation);
}
#endif
nm->log_identity(xtty);
}
Symbol* class_name = NULL;
@ -1640,7 +1618,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* thread, jint tra
tty->print(" compiler=%s compile_id=%d", nm->compiler_name(), nm->compile_id());
#if INCLUDE_JVMCI
if (nm->is_nmethod()) {
char* installed_code_name = nm->as_nmethod()->jvmci_installed_code_name(buf, sizeof(buf));
const char* installed_code_name = nm->as_nmethod()->jvmci_name();
if (installed_code_name != NULL) {
tty->print(" (JVMCI: installed code name=%s) ", installed_code_name);
}

View File

@ -629,7 +629,7 @@ void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose
#if INCLUDE_JVMCI
if (cm->is_nmethod()) {
nmethod* nm = cm->as_nmethod();
char* jvmciName = nm->jvmci_installed_code_name(buf, buflen);
const char* jvmciName = nm->jvmci_name();
if (jvmciName != NULL) {
st->print(" (%s)", jvmciName);
}

View File

@ -27,6 +27,9 @@
#include "classfile/symbolTable.hpp"
#include "code/icBuffer.hpp"
#include "gc/shared/collectedHeap.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmci.hpp"
#endif
#include "interpreter/bytecodes.hpp"
#include "logging/log.hpp"
#include "logging/logTag.hpp"
@ -140,6 +143,11 @@ jint init_globals() {
if (!compileBroker_init()) {
return JNI_EINVAL;
}
#if INCLUDE_JVMCI
if (EnableJVMCI) {
JVMCI::initialize_globals();
}
#endif
if (!universe_post_init()) {
return JNI_ERR;

View File

@ -36,8 +36,7 @@
#include "jfr/jfrEvents.hpp"
#include "jfr/support/jfrThreadId.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmciCompiler.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/jvmci.hpp"
#endif
#include "logging/log.hpp"
#include "logging/logStream.hpp"
@ -439,15 +438,7 @@ void before_exit(JavaThread* thread) {
}
#if INCLUDE_JVMCI
// We are not using CATCH here because we want the exit to continue normally.
Thread* THREAD = thread;
JVMCIRuntime::shutdown(THREAD);
if (HAS_PENDING_EXCEPTION) {
HandleMark hm(THREAD);
Handle exception(THREAD, PENDING_EXCEPTION);
CLEAR_PENDING_EXCEPTION;
java_lang_Throwable::java_printStackTrace(exception, THREAD);
}
JVMCI::shutdown();
#endif
// Hang forever on exit if we're reporting an error.

View File

@ -44,10 +44,6 @@
#include "runtime/signature.hpp"
#include "runtime/stubRoutines.hpp"
#include "runtime/thread.inline.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmciJavaClasses.hpp"
#include "jvmci/jvmciRuntime.hpp"
#endif
// -----------------------------------------------------
// Implementation of JavaCallWrapper

View File

@ -157,6 +157,13 @@ Mutex* NMTQuery_lock = NULL;
Mutex* CDSClassFileStream_lock = NULL;
#endif
#if INCLUDE_JVMCI
Monitor* JVMCI_lock = NULL;
Mutex* JVMCIGlobalAlloc_lock = NULL;
Mutex* JVMCIGlobalActive_lock = NULL;
#endif
#define MAX_NUM_MUTEX 128
static Monitor * _mutex_array[MAX_NUM_MUTEX];
static int _num_mutex;
@ -348,6 +355,12 @@ void mutex_init() {
#if INCLUDE_CDS && INCLUDE_JVMTI
def(CDSClassFileStream_lock , PaddedMutex , max_nonleaf, false, Monitor::_safepoint_check_always);
#endif
#if INCLUDE_JVMCI
def(JVMCI_lock , PaddedMonitor, nonleaf+2, true, Monitor::_safepoint_check_always);
def(JVMCIGlobalAlloc_lock , PaddedMutex , nonleaf, true, Monitor::_safepoint_check_never);
def(JVMCIGlobalActive_lock , PaddedMutex , nonleaf-1, true, Monitor::_safepoint_check_never);
#endif
}
GCMutexLocker::GCMutexLocker(Monitor * mutex) {

View File

@ -155,6 +155,12 @@ extern Mutex* ClassLoaderDataGraph_lock; // protects CLDG list, needed f
extern Monitor* CodeHeapStateAnalytics_lock; // lock print functions against concurrent analyze functions.
// Only used locally in PrintCodeCacheLayout processing.
#if INCLUDE_JVMCI
extern Monitor* JVMCI_lock; // Monitor to control initialization of JVMCI
extern Mutex* JVMCIGlobalAlloc_lock; // JVMCI global storage allocate list lock
extern Mutex* JVMCIGlobalActive_lock; // JVMCI global storage active list lock
#endif
// A MutexLocker provides mutual exclusion with respect to a given mutex
// for the scope which contains the locker. The lock is an OS lock, not
// an object lock, and the two do not interoperate. Do not use Mutex-based

View File

@ -117,9 +117,8 @@
#include "utilities/singleWriterSynchronizer.hpp"
#include "utilities/vmError.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmciCompiler.hpp"
#include "jvmci/jvmciRuntime.hpp"
#include "logging/logHandle.hpp"
#include "jvmci/jvmci.hpp"
#include "jvmci/jvmciEnv.hpp"
#endif
#ifdef COMPILER1
#include "c1/c1_Compiler.hpp"
@ -1576,16 +1575,17 @@ bool jvmci_counters_include(JavaThread* thread) {
return !JVMCICountersExcludeCompiler || !thread->is_Compiler_thread();
}
void JavaThread::collect_counters(typeArrayOop array) {
void JavaThread::collect_counters(JVMCIEnv* jvmci_env, JVMCIPrimitiveArray array) {
if (JVMCICounterSize > 0) {
JavaThreadIteratorWithHandle jtiwh;
for (int i = 0; i < array->length(); i++) {
array->long_at_put(i, _jvmci_old_thread_counters[i]);
int len = jvmci_env->get_length(array);
for (int i = 0; i < len; i++) {
jvmci_env->put_long_at(array, i, _jvmci_old_thread_counters[i]);
}
for (; JavaThread *tp = jtiwh.next(); ) {
if (jvmci_counters_include(tp)) {
for (int i = 0; i < array->length(); i++) {
array->long_at_put(i, array->long_at(i) + tp->_jvmci_counters[i]);
for (int i = 0; i < len; i++) {
jvmci_env->put_long_at(array, i, jvmci_env->get_long_at(array, i) + tp->_jvmci_counters[i]);
}
}
}
@ -3922,10 +3922,8 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
bool force_JVMCI_intialization = false;
if (EnableJVMCI) {
// Initialize JVMCI eagerly when it is explicitly requested.
// Or when JVMCIPrintProperties is enabled.
// The JVMCI Java initialization code will read this flag and
// do the printing if it's set.
force_JVMCI_intialization = EagerJVMCI || JVMCIPrintProperties;
// Or when JVMCILibDumpJNIConfig or JVMCIPrintProperties is enabled.
force_JVMCI_intialization = EagerJVMCI || JVMCIPrintProperties || JVMCILibDumpJNIConfig;
if (!force_JVMCI_intialization) {
// 8145270: Force initialization of JVMCI runtime otherwise requests for blocking
@ -3974,7 +3972,7 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
#if INCLUDE_JVMCI
if (force_JVMCI_intialization) {
JVMCIRuntime::force_initialization(CHECK_JNI_ERR);
JVMCI::initialize_compiler(CHECK_JNI_ERR);
CompileBroker::compilation_init_phase2();
}
#endif
@ -4274,7 +4272,7 @@ void JavaThread::invoke_shutdown_hooks() {
JavaValue result(T_VOID);
JavaCalls::call_static(&result,
shutdown_klass,
vmSymbols::shutdown_method_name(),
vmSymbols::shutdown_name(),
vmSymbols::void_method_signature(),
THREAD);
}

View File

@ -88,6 +88,9 @@ class ThreadClosure;
class ICRefillVerifier;
class IdealGraphPrinter;
class JVMCIEnv;
class JVMCIPrimitiveArray;
class Metadata;
class ResourceArea;
@ -1132,7 +1135,7 @@ class JavaThread: public Thread {
// An id of a speculation that JVMCI compiled code can use to further describe and
// uniquely identify the speculative optimization guarded by the uncommon trap
long _pending_failed_speculation;
jlong _pending_failed_speculation;
// These fields are mutually exclusive in terms of live ranges.
union {
@ -1149,7 +1152,7 @@ class JavaThread: public Thread {
public:
static jlong* _jvmci_old_thread_counters;
static void collect_counters(typeArrayOop array);
static void collect_counters(JVMCIEnv* JVMCIENV, JVMCIPrimitiveArray array);
private:
#endif // INCLUDE_JVMCI
@ -1532,11 +1535,11 @@ class JavaThread: public Thread {
#if INCLUDE_JVMCI
int pending_deoptimization() const { return _pending_deoptimization; }
long pending_failed_speculation() const { return _pending_failed_speculation; }
jlong pending_failed_speculation() const { return _pending_failed_speculation; }
bool has_pending_monitorenter() const { return _pending_monitorenter; }
void set_pending_monitorenter(bool b) { _pending_monitorenter = b; }
void set_pending_deoptimization(int reason) { _pending_deoptimization = reason; }
void set_pending_failed_speculation(long failed_speculation) { _pending_failed_speculation = failed_speculation; }
void set_pending_failed_speculation(jlong failed_speculation) { _pending_failed_speculation = failed_speculation; }
void set_pending_transfer_to_interpreter(bool b) { _pending_transfer_to_interpreter = b; }
void set_jvmci_alternate_call_target(address a) { assert(_jvmci._alternate_call_target == NULL, "must be"); _jvmci._alternate_call_target = a; }
void set_jvmci_implicit_exception_pc(address a) { assert(_jvmci._implicit_exception_pc == NULL, "must be"); _jvmci._implicit_exception_pc = a; }

View File

@ -34,7 +34,7 @@
#include "code/scopeDesc.hpp"
#include "oops/method.inline.hpp"
#if INCLUDE_JVMCI
#include "jvmci/jvmciRuntime.hpp"
#include "jvmci/jvmci.hpp"
#endif
#ifdef TIERED

View File

@ -435,7 +435,20 @@ int VM_Exit::wait_for_threads_in_native_to_block() {
if (thr!=thr_cur && thr->thread_state() == _thread_in_native) {
num_active++;
if (thr->is_Compiler_thread()) {
#if INCLUDE_JVMCI
CompilerThread* ct = (CompilerThread*) thr;
if (ct->compiler() == NULL || !ct->compiler()->is_jvmci() || !UseJVMCINativeLibrary) {
num_active_compiler_thread++;
} else {
// When using a compiler in a JVMCI shared library, it's possible
// for one compiler thread to grab a lock in the shared library,
// enter HotSpot and go to sleep on the shutdown safepoint. Another
// JVMCI shared library compiler thread can then attempt to grab the
// lock and thus never make progress.
}
#else
num_active_compiler_thread++;
#endif
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -214,6 +214,7 @@ module java.base {
java.sql,
java.sql.rowset,
jdk.dynalink,
jdk.internal.vm.ci,
jdk.scripting.nashorn,
jdk.unsupported;
exports jdk.internal.vm to

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -191,7 +191,9 @@ public abstract class Architecture {
public abstract PlatformKind getLargestStorableKind(RegisterCategory category);
/**
* Return the {@link PlatformKind} that is used to store values of a given {@link JavaKind}.
* Gets the {@link PlatformKind} that is used to store values of a given {@link JavaKind}.
*
* @return {@code null} if there no deterministic {@link PlatformKind} for {@code javaKind}
*/
public abstract PlatformKind getPlatformKind(JavaKind javaKind);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -87,7 +87,11 @@ public class BytecodePosition {
@Override
public int hashCode() {
return getBCI();
int hc = method.hashCode() * 31 + bci;
if (caller != null) {
hc = (hc * 31) + caller.hashCode();
}
return hc;
}
/**

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -44,6 +44,8 @@ public interface CodeCacheProvider {
* created.
* @return a reference to the ready-to-run code
* @throws BailoutException if the code installation failed
* @throws IllegalArgumentException if {@code installedCode != null} and this object does not
* support a predefined {@link InstalledCode} object
*/
default InstalledCode addCode(ResolvedJavaMethod method, CompiledCode compiledCode, SpeculationLog log, InstalledCode installedCode) {
return installCode(method, compiledCode, installedCode, log, false);
@ -58,6 +60,8 @@ public interface CodeCacheProvider {
* @param compiledCode the compiled code to be added
* @return a reference to the ready-to-run code
* @throws BailoutException if the code installation failed
* @throws IllegalArgumentException if {@code installedCode != null} and this object does not
* support a predefined {@link InstalledCode} object
*/
default InstalledCode setDefaultCode(ResolvedJavaMethod method, CompiledCode compiledCode) {
return installCode(method, compiledCode, null, null, true);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -52,14 +52,14 @@ public class InstalledCode {
/**
* @return the address of entity representing this installed code.
*/
public final long getAddress() {
public long getAddress() {
return address;
}
/**
* @return the address of the normal entry point of the installed code.
*/
public final long getEntryPoint() {
public long getEntryPoint() {
return entryPoint;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,5 +27,12 @@ package jdk.vm.ci.code;
*/
public final class InvalidInstalledCodeException extends Exception {
public InvalidInstalledCodeException() {
}
public InvalidInstalledCodeException(String message) {
super(message);
}
private static final long serialVersionUID = -3540232440794244844L;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,8 @@ package jdk.vm.ci.common;
import java.util.concurrent.atomic.AtomicInteger;
import jdk.vm.ci.services.Services;
/**
* A facility for timing a step in the runtime initialization sequence. This is independent from all
* other JVMCI code so as to not perturb the initialization sequence. It is enabled by setting the
@ -58,21 +60,32 @@ public final class InitTimer implements AutoCloseable {
}
public static InitTimer timer(String name) {
return ENABLED ? new InitTimer(name) : null;
return isEnabled() ? new InitTimer(name) : null;
}
public static InitTimer timer(String name, Object suffix) {
return ENABLED ? new InitTimer(name + suffix) : null;
return isEnabled() ? new InitTimer(name + suffix) : null;
}
/**
* Specifies if initialization timing is enabled. Note: This property cannot use
* Determines if initialization timing is enabled. Note: This property cannot use
* {@code HotSpotJVMCIRuntime.Option} since that class is not visible from this package.
*/
private static final boolean ENABLED = Boolean.getBoolean("jvmci.InitTimer");
private static boolean isEnabled() {
if (enabledPropertyValue == null) {
enabledPropertyValue = Boolean.parseBoolean(Services.getSavedProperty("jvmci.InitTimer"));
nesting = new AtomicInteger();
}
return enabledPropertyValue;
}
public static final AtomicInteger nesting = ENABLED ? new AtomicInteger() : null;
public static final String SPACES = " ";
/**
* Cache for value of {@code jvmci.InitTimer} system property.
*/
@NativeImageReinitialize private static Boolean enabledPropertyValue;
private static AtomicInteger nesting;
private static final String SPACES = " ";
/**
* Used to assert the invariant that all related initialization happens on the same thread.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -28,7 +28,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Denotes a field that should have the default value for its type when building a native image.
* Denotes a field that should have the default value for its type in an ahead of time image.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,7 @@ package jdk.vm.ci.hotspot.aarch64;
import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
import jdk.vm.ci.services.Services;
/**
* Used to access native configuration details.
@ -36,7 +37,7 @@ class AArch64HotSpotVMConfig extends HotSpotVMConfigAccess {
super(config);
}
final boolean linuxOs = System.getProperty("os.name", "").startsWith("Linux");
final boolean linuxOs = Services.getSavedProperty("os.name", "").startsWith("Linux");
final boolean useCompressedOops = getFlag("UseCompressedOops", Boolean.class);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -24,6 +24,7 @@ package jdk.vm.ci.hotspot.amd64;
import jdk.vm.ci.hotspot.HotSpotVMConfigAccess;
import jdk.vm.ci.hotspot.HotSpotVMConfigStore;
import jdk.vm.ci.services.Services;
/**
* Used to access AMD64 specific native configuration details.
@ -34,7 +35,7 @@ class AMD64HotSpotVMConfig extends HotSpotVMConfigAccess {
super(config);
}
final boolean windowsOs = System.getProperty("os.name", "").startsWith("Windows");
final boolean windowsOs = Services.getSavedProperty("os.name", "").startsWith("Windows");
final boolean useCountLeadingZerosInstruction = getFlag("UseCountLeadingZerosInstruction", Boolean.class);
final boolean useCountTrailingZerosInstruction = getFlag("UseCountTrailingZerosInstruction", Boolean.class);

View File

@ -0,0 +1,120 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import jdk.vm.ci.common.NativeImageReinitialize;
import jdk.vm.ci.meta.ResolvedJavaType;
/**
* A cleaner tracks a referent object and includes some {@linkplain #doCleanup() cleanup code} that
* is run some time after the referent object has become weakly-reachable.
*
* This is like {@link sun.misc.Cleaner} but with weak semantics instead of phantom. Objects
* referenced by this might be referenced by {@link ResolvedJavaType} which is kept alive by a
* {@link WeakReference} so we need equivalent reference strength.
*/
abstract class Cleaner extends WeakReference<Object> {
/**
* Head of linked list of cleaners.
*/
@NativeImageReinitialize private static Cleaner first;
/**
* Linked list pointers.
*/
private Cleaner next = null;
private Cleaner prev = null;
Cleaner(Object referent) {
super(referent, queue);
add(this);
}
private static synchronized Cleaner add(Cleaner cl) {
if (first != null) {
clean();
}
if (first != null) {
cl.next = first;
first.prev = cl;
}
first = cl;
return cl;
}
/**
* Removes {@code cl} from the linked list of cleaners.
*/
private static synchronized void remove(Cleaner cl) {
// If already removed, do nothing
if (cl.next == cl) {
return;
}
// Update list
if (first == cl) {
if (cl.next != null) {
first = cl.next;
} else {
first = cl.prev;
}
}
if (cl.next != null) {
cl.next.prev = cl.prev;
}
if (cl.prev != null) {
cl.prev.next = cl.next;
}
// Indicate removal by pointing the cleaner to itself
cl.next = cl;
cl.prev = cl;
}
/**
* Performs the cleanup action now that this object's referent has become weakly reachable.
*/
abstract void doCleanup();
/**
* Remove the cleaners whose referents have become weakly reachable.
*/
static void clean() {
Cleaner c = (Cleaner) queue.poll();
while (c != null) {
remove(c);
c.doCleanup();
c = (Cleaner) queue.poll();
}
}
/**
* The {@link ReferenceQueue} to which {@link Cleaner}s are enqueued once their referents'
* become unreachable.
*/
private static final ReferenceQueue<Object> queue = new ReferenceQueue<>();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -36,6 +36,10 @@ import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.code.stack.InspectedFrameVisitor;
import jdk.vm.ci.common.InitTimer;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
@ -51,17 +55,60 @@ final class CompilerToVM {
*/
private static native void registerNatives();
static {
initialize();
}
/**
* These values mirror the equivalent values from {@link Unsafe} but are approriate for the JVM
* being compiled against.
*/
// Checkstyle: stop
final int ARRAY_BOOLEAN_BASE_OFFSET;
final int ARRAY_BYTE_BASE_OFFSET;
final int ARRAY_SHORT_BASE_OFFSET;
final int ARRAY_CHAR_BASE_OFFSET;
final int ARRAY_INT_BASE_OFFSET;
final int ARRAY_LONG_BASE_OFFSET;
final int ARRAY_FLOAT_BASE_OFFSET;
final int ARRAY_DOUBLE_BASE_OFFSET;
final int ARRAY_OBJECT_BASE_OFFSET;
final int ARRAY_BOOLEAN_INDEX_SCALE;
final int ARRAY_BYTE_INDEX_SCALE;
final int ARRAY_SHORT_INDEX_SCALE;
final int ARRAY_CHAR_INDEX_SCALE;
final int ARRAY_INT_INDEX_SCALE;
final int ARRAY_LONG_INDEX_SCALE;
final int ARRAY_FLOAT_INDEX_SCALE;
final int ARRAY_DOUBLE_INDEX_SCALE;
final int ARRAY_OBJECT_INDEX_SCALE;
// Checkstyle: resume
@SuppressWarnings("try")
private static void initialize() {
CompilerToVM() {
try (InitTimer t = timer("CompilerToVM.registerNatives")) {
registerNatives();
ARRAY_BOOLEAN_BASE_OFFSET = arrayBaseOffset(JavaKind.Boolean);
ARRAY_BYTE_BASE_OFFSET = arrayBaseOffset(JavaKind.Byte);
ARRAY_SHORT_BASE_OFFSET = arrayBaseOffset(JavaKind.Short);
ARRAY_CHAR_BASE_OFFSET = arrayBaseOffset(JavaKind.Char);
ARRAY_INT_BASE_OFFSET = arrayBaseOffset(JavaKind.Int);
ARRAY_LONG_BASE_OFFSET = arrayBaseOffset(JavaKind.Long);
ARRAY_FLOAT_BASE_OFFSET = arrayBaseOffset(JavaKind.Float);
ARRAY_DOUBLE_BASE_OFFSET = arrayBaseOffset(JavaKind.Double);
ARRAY_OBJECT_BASE_OFFSET = arrayBaseOffset(JavaKind.Object);
ARRAY_BOOLEAN_INDEX_SCALE = arrayIndexScale(JavaKind.Boolean);
ARRAY_BYTE_INDEX_SCALE = arrayIndexScale(JavaKind.Byte);
ARRAY_SHORT_INDEX_SCALE = arrayIndexScale(JavaKind.Short);
ARRAY_CHAR_INDEX_SCALE = arrayIndexScale(JavaKind.Char);
ARRAY_INT_INDEX_SCALE = arrayIndexScale(JavaKind.Int);
ARRAY_LONG_INDEX_SCALE = arrayIndexScale(JavaKind.Long);
ARRAY_FLOAT_INDEX_SCALE = arrayIndexScale(JavaKind.Float);
ARRAY_DOUBLE_INDEX_SCALE = arrayIndexScale(JavaKind.Double);
ARRAY_OBJECT_INDEX_SCALE = arrayIndexScale(JavaKind.Object);
}
}
native int arrayBaseOffset(JavaKind kind);
native int arrayIndexScale(JavaKind kind);
/**
* Gets the {@link CompilerToVM} instance associated with the singleton
* {@link HotSpotJVMCIRuntime} instance.
@ -152,13 +199,16 @@ final class CompilerToVM {
* Converts a name to a type.
*
* @param name a well formed Java type in {@linkplain JavaType#getName() internal} format
* @param accessingClass the context of resolution (must not be null)
* @param accessingClass the context of resolution. A value of {@code null} implies that the
* class should be resolved with the class loader.
* @param resolve force resolution to a {@link ResolvedJavaType}. If true, this method will
* either return a {@link ResolvedJavaType} or throw an exception
* @return the type for {@code name} or 0 if resolution failed and {@code resolve == false}
* @throws ClassNotFoundException if {@code resolve == true} and the resolution failed
*/
native HotSpotResolvedObjectTypeImpl lookupType(String name, Class<?> accessingClass, boolean resolve) throws ClassNotFoundException;
native HotSpotResolvedJavaType lookupType(String name, HotSpotResolvedObjectTypeImpl accessingClass, boolean resolve) throws ClassNotFoundException;
native HotSpotResolvedJavaType lookupClass(Class<?> javaClass);
/**
* Resolves the entry at index {@code cpi} in {@code constantPool} to an object.
@ -167,7 +217,7 @@ final class CompilerToVM {
* entry types: {@code JVM_CONSTANT_MethodHandle}, {@code JVM_CONSTANT_MethodHandleInError},
* {@code JVM_CONSTANT_MethodType} and {@code JVM_CONSTANT_MethodTypeInError}.
*/
native Object resolveConstantInPool(HotSpotConstantPool constantPool, int cpi);
native HotSpotObjectConstantImpl resolveConstantInPool(HotSpotConstantPool constantPool, int cpi);
/**
* Resolves the entry at index {@code cpi} in {@code constantPool} to an object, looking in the
@ -176,7 +226,7 @@ final class CompilerToVM {
* The behavior of this method is undefined if {@code cpi} does not denote a
* {@code JVM_CONSTANT_String} entry.
*/
native Object resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi);
native HotSpotObjectConstantImpl resolvePossiblyCachedConstantInPool(HotSpotConstantPool constantPool, int cpi);
/**
* Gets the {@code JVM_CONSTANT_NameAndType} index from the entry at index {@code cpi} in
@ -318,7 +368,7 @@ final class CompilerToVM {
* Gets the appendix object (if any) associated with the entry at index {@code cpi} in
* {@code constantPool}.
*/
native Object lookupAppendixInPool(HotSpotConstantPool constantPool, int cpi);
native HotSpotObjectConstantImpl lookupAppendixInPool(HotSpotConstantPool constantPool, int cpi);
/**
* Installs the result of a compilation into the code cache.
@ -335,7 +385,7 @@ final class CompilerToVM {
* @throws JVMCIError if there is something wrong with the compiled code or the associated
* metadata.
*/
native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, HotSpotSpeculationLog speculationLog);
native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, long failedSpeculationsAddress, byte[] speculations);
/**
* Generates the VM metadata for some compiled code and copies them into {@code metaData}. This
@ -433,10 +483,10 @@ final class CompilerToVM {
/**
* Executes some {@code installedCode} with arguments {@code args}.
*
* @return the result of executing {@code installedCode}
* @throws InvalidInstalledCodeException if {@code installedCode} has been invalidated
* @return the result of executing {@code nmethodMirror}
* @throws InvalidInstalledCodeException if {@code nmethodMirror} has been invalidated
*/
native Object executeInstalledCode(Object[] args, InstalledCode installedCode) throws InvalidInstalledCodeException;
native Object executeHotSpotNmethod(Object[] args, HotSpotNmethod nmethodMirror) throws InvalidInstalledCodeException;
/**
* Gets the line number table for {@code method}. The line number table is encoded as (bci,
@ -471,6 +521,19 @@ final class CompilerToVM {
*/
native long getLocalVariableTableStart(HotSpotResolvedJavaMethodImpl method);
/**
* Reads an object pointer within a VM data structure. That is, any {@link VMField} whose
* {@link VMField#type type} is {@code "oop"} (e.g.,
* {@code Klass::_java_mirror}, {@code JavaThread::_threadObj}).
*
* Note that {@link Unsafe#getObject(Object, long)} cannot be used for this since it does a
* {@code narrowOop} read if the VM is using compressed oops whereas oops within VM data
* structures are (currently) always uncompressed.
*
* @param address address of an oop field within a VM data structure
*/
native HotSpotObjectConstantImpl readUncompressedOop(long address);
/**
* Sets flags on {@code method} indicating that it should never be inlined or compiled by the
* VM.
@ -484,10 +547,12 @@ final class CompilerToVM {
native void reprofile(HotSpotResolvedJavaMethodImpl method);
/**
* Invalidates {@code installedCode} such that {@link InvalidInstalledCodeException} will be
* raised the next time {@code installedCode} is executed.
* Invalidates {@code nmethodMirror} such that {@link InvalidInstalledCodeException} will be
* raised the next time {@code nmethodMirror} is {@linkplain #executeHotSpotNmethod executed}.
* The {@code nmethod} associated with {@code nmethodMirror} is also made non-entrant and any
* current activations of the {@code nmethod} are deoptimized.
*/
native void invalidateInstalledCode(InstalledCode installedCode);
native void invalidateHotSpotNmethod(HotSpotNmethod nmethodMirror);
/**
* Collects the current values of all JVMCI benchmark counters, summed up over all threads.
@ -572,7 +637,7 @@ final class CompilerToVM {
* @param displacement
* @return null or the resolved method for this location
*/
native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(Object base, long displacement);
native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(HotSpotObjectConstantImpl base, long displacement);
/**
* Gets the {@code ConstantPool*} associated with {@code object} and returns a
@ -586,7 +651,7 @@ final class CompilerToVM {
* @throws IllegalArgumentException if {@code object} is neither a
* {@link HotSpotResolvedJavaMethodImpl} nor a {@link HotSpotResolvedObjectTypeImpl}
*/
native HotSpotConstantPool getConstantPool(Object object);
native HotSpotConstantPool getConstantPool(MetaspaceObject object);
/**
* Read a HotSpot Klass* value from the memory location described by {@code base} plus
@ -604,7 +669,19 @@ final class CompilerToVM {
* @param compressed true if the location contains a compressed Klass*
* @return null or the resolved method for this location
*/
native HotSpotResolvedObjectTypeImpl getResolvedJavaType(Object base, long displacement, boolean compressed);
private native HotSpotResolvedObjectTypeImpl getResolvedJavaType0(Object base, long displacement, boolean compressed);
HotSpotResolvedObjectTypeImpl getResolvedJavaType(MetaspaceObject base, long displacement, boolean compressed) {
return getResolvedJavaType0(base, displacement, compressed);
}
HotSpotResolvedObjectTypeImpl getResolvedJavaType(HotSpotObjectConstantImpl base, long displacement, boolean compressed) {
return getResolvedJavaType0(base, displacement, compressed);
}
HotSpotResolvedObjectTypeImpl getResolvedJavaType(long displacement, boolean compressed) {
return getResolvedJavaType0(null, displacement, compressed);
}
/**
* Return the size of the HotSpot ProfileData* pointed at by {@code position}. If
@ -641,7 +718,7 @@ final class CompilerToVM {
* Invokes non-public method {@code java.lang.invoke.LambdaForm.compileToBytecode()} on
* {@code lambdaForm} (which must be a {@code java.lang.invoke.LambdaForm} instance).
*/
native void compileToBytecode(Object lambdaForm);
native void compileToBytecode(HotSpotObjectConstantImpl lambdaForm);
/**
* Gets the value of the VM flag named {@code name}.
@ -659,6 +736,164 @@ final class CompilerToVM {
*/
native HotSpotResolvedObjectTypeImpl getHostClass(HotSpotResolvedObjectTypeImpl type);
/**
* Gets the object at the address {@code oopAddress}.
*
* @param oopAddress a valid {@code oopDesc**} value
*/
native Object getObjectAtAddress(long oopAddress);
/**
* @see ResolvedJavaType#getInterfaces()
*/
native HotSpotResolvedObjectTypeImpl[] getInterfaces(HotSpotResolvedObjectTypeImpl type);
/**
* @see ResolvedJavaType#getComponentType()
*/
native HotSpotResolvedJavaType getComponentType(HotSpotResolvedObjectTypeImpl type);
/**
* Forces initialization of {@code type}.
*/
native void ensureInitialized(HotSpotResolvedObjectTypeImpl type);
/**
* Checks if {@code object} is a String and is an interned string value.
*/
native boolean isInternedString(HotSpotObjectConstantImpl object);
/**
* Gets the {@linkplain System#identityHashCode(Object) identity} has code for the object
* represented by this constant.
*/
native int getIdentityHashCode(HotSpotObjectConstantImpl object);
/**
* Converts a constant object representing a boxed primitive into a boxed primitive.
*/
native Object unboxPrimitive(HotSpotObjectConstantImpl object);
/**
* Converts a boxed primitive into a JavaConstant representing the same value.
*/
native HotSpotObjectConstantImpl boxPrimitive(Object source);
/**
* Gets the {@link ResolvedJavaMethod}s for all the constructors of the type {@code holder}.
*/
native ResolvedJavaMethod[] getDeclaredConstructors(HotSpotResolvedObjectTypeImpl holder);
/**
* Gets the {@link ResolvedJavaMethod}s for all the non-constructor methods of the type
* {@code holder}.
*/
native ResolvedJavaMethod[] getDeclaredMethods(HotSpotResolvedObjectTypeImpl holder);
/**
* Reads the current value of a static field.
*/
native JavaConstant readFieldValue(HotSpotResolvedObjectTypeImpl resolvedObjectType, HotSpotResolvedJavaField field, boolean isVolatile);
/**
* Reads the current value of an instance field.
*/
native JavaConstant readFieldValue(HotSpotObjectConstantImpl object, HotSpotResolvedJavaField field, boolean isVolatile);
/**
* @see ResolvedJavaType#isInstance(JavaConstant)
*/
native boolean isInstance(HotSpotResolvedObjectTypeImpl holder, HotSpotObjectConstantImpl object);
/**
* @see ResolvedJavaType#isAssignableFrom(ResolvedJavaType)
*/
native boolean isAssignableFrom(HotSpotResolvedObjectTypeImpl holder, HotSpotResolvedObjectTypeImpl otherType);
/**
* @see ConstantReflectionProvider#asJavaType(Constant)
*/
native HotSpotResolvedJavaType asJavaType(HotSpotObjectConstantImpl object);
/**
* Converts a String constant into a String.
*/
native String asString(HotSpotObjectConstantImpl object);
/**
* Compares the contents of {@code xHandle} and {@code yHandle} for pointer equality.
*/
native boolean equals(HotSpotObjectConstantImpl x, long xHandle, HotSpotObjectConstantImpl y, long yHandle);
/**
* Gets a {@link JavaConstant} wrapping the {@link java.lang.Class} mirror for {@code type}.
*/
native HotSpotObjectConstantImpl getJavaMirror(HotSpotResolvedJavaType type);
/**
* Returns the length of the array if {@code object} represents an array or -1 otherwise.
*/
native int getArrayLength(HotSpotObjectConstantImpl object);
/**
* Reads the element at {@code index} if {@code object} is an array. Elements of an object array
* are returned as {@link JavaConstant}s and primitives are returned as boxed values. The value
* {@code null} is returned if the {@code index} is out of range or object is not an array.
*/
native Object readArrayElement(HotSpotObjectConstantImpl object, int index);
/**
* Reads a byte sized value from {@code displacement} in {@code object}.
*/
native byte getByte(HotSpotObjectConstantImpl object, long displacement);
/**
* Reads a short sized value from {@code displacement} in {@code object}.
*/
native short getShort(HotSpotObjectConstantImpl object, long displacement);
/**
* Reads an int sized value from {@code displacement} in {@code object}.
*/
native int getInt(HotSpotObjectConstantImpl object, long displacement);
/**
* Reads a long sized value from {@code displacement} in {@code object}.
*/
native long getLong(HotSpotObjectConstantImpl object, long displacement);
/**
* Reads a Java object from {@code displacement} in {@code object}.
*/
native HotSpotObjectConstantImpl getObject(HotSpotObjectConstantImpl object, long displacement);
/**
* @see HotSpotJVMCIRuntime#registerNativeMethods
*/
native long[] registerNativeMethods(Class<?> clazz);
/**
* @see HotSpotJVMCIRuntime#translate(Object)
*/
native long translate(Object obj);
/**
* @see HotSpotJVMCIRuntime#unhand(Class, long)
*/
native Object unhand(long handle);
/**
* Updates {@code address} and {@code entryPoint} fields of {@code nmethodMirror} based on the
* current state of the {@code nmethod} identified by {@code address} and
* {@code nmethodMirror.compileId} in the code cache.
*/
native void updateHotSpotNmethod(HotSpotNmethod nmethodMirror);
/**
* @see InstalledCode#getCode()
*/
native byte[] getCode(HotSpotInstalledCode code);
/**
* Gets a {@link Executable} corresponding to {@code method}.
*/
@ -671,4 +906,45 @@ final class CompilerToVM {
* @param fieldIndex the {@code fieldDescriptor::index()} denoting the field
*/
native Field asReflectionField(HotSpotResolvedObjectTypeImpl holder, int fieldIndex);
/**
* @see HotSpotJVMCIRuntime#getIntrinsificationTrustPredicate(Class...)
*/
native boolean isTrustedForIntrinsics(HotSpotResolvedObjectTypeImpl type);
/**
* Releases the resources backing the global JNI {@code handle}. This is equivalent to the
* {@code DeleteGlobalRef} JNI function.
*/
native void deleteGlobalHandle(long handle);
/**
* Gets the failed speculations pointed to by {@code *failedSpeculationsAddress}.
*
* @param currentFailures the known failures at {@code failedSpeculationsAddress}
* @return the list of failed speculations with each entry being a single speculation in the
* format emitted by {@link HotSpotSpeculationEncoding#toByteArray()}
*/
native byte[][] getFailedSpeculations(long failedSpeculationsAddress, byte[][] currentFailures);
/**
* Gets the address of the {@code MethodData::_failed_speculations} field in the
* {@code MethodData} associated with {@code method}. This will create and install the
* {@code MethodData} if it didn't already exist.
*/
native long getFailedSpeculationsAddress(HotSpotResolvedJavaMethodImpl method);
/**
* Frees the failed speculations pointed to by {@code *failedSpeculationsAddress}.
*/
native void releaseFailedSpeculations(long failedSpeculationsAddress);
/**
* Adds a speculation to the failed speculations pointed to by
* {@code *failedSpeculationsAddress}.
*
* @return {@code false} if the speculation could not be appended to the list
*/
native boolean addFailedSpeculation(long failedSpeculationsAddress, byte[] speculation);
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.JavaConstant;
final class DirectHotSpotObjectConstantImpl extends HotSpotObjectConstantImpl {
static JavaConstant forObject(Object object, boolean compressed) {
if (object == null) {
return compressed ? HotSpotCompressedNullConstant.COMPRESSED_NULL : JavaConstant.NULL_POINTER;
} else {
return new DirectHotSpotObjectConstantImpl(object, compressed);
}
}
static HotSpotObjectConstantImpl forNonNullObject(Object object, boolean compressed) {
if (object == null) {
throw new NullPointerException();
}
return new DirectHotSpotObjectConstantImpl(object, compressed);
}
private DirectHotSpotObjectConstantImpl(Object object, boolean compressed) {
super(compressed);
assert object != null;
this.object = object;
}
final Object object;
@Override
public JavaConstant compress() {
assert !compressed;
return new DirectHotSpotObjectConstantImpl(object, true);
}
@Override
public JavaConstant uncompress() {
assert compressed;
return new DirectHotSpotObjectConstantImpl(object, false);
}
@Override
public int getIdentityHashCode() {
return System.identityHashCode(object);
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
/**
* This class manages a set of {@code jobject} and {@code jmetadata} handles whose lifetimes are
* dependent on associated {@link IndirectHotSpotObjectConstantImpl} and
* {@link MetaspaceHandleObject} wrapper objects respectively.
*
* The general theory of operation is that all wrappers are created by calling into the VM which
* calls back out to actually create the wrapper instance. During the call the VM keeps the object
* or metadata reference alive through the use of handles. Once the call completes the wrapper
* object is registered here and will be scanned during metadata scanning. The weakness of the
* reference to the wrapper object allows the handles to be reclaimed when they are no longer used.
*/
final class HandleCleaner extends Cleaner {
/**
* A {@code jmetadata} or {@code jobject} handle.
*/
private final long handle;
/**
* Specifies if {@link #handle} is a {@code jobject} or {@code jmetadata}.
*/
private final boolean isJObject;
private HandleCleaner(Object wrapper, long handle, boolean isJObject) {
super(wrapper);
this.handle = handle;
this.isJObject = isJObject;
}
/**
* Releases the resource associated with {@code this.handle}.
*/
@Override
void doCleanup() {
if (isJObject) {
// The sentinel value used to denote a free handle is
// an object on the HotSpot heap so we call into the
// VM to set the target of an object handle to this value.
CompilerToVM.compilerToVM().deleteGlobalHandle(handle);
} else {
// Setting the target of a jmetadata handle to 0 enables
// the handle to be reused. See MetadataHandleBlock in
// jvmciRuntime.cpp for more info.
long value = UNSAFE.getLong(null, handle);
UNSAFE.compareAndSetLong(null, handle, value, 0);
}
}
/**
* Registers a cleaner for {@code handle}. The cleaner will release the handle some time after
* {@code wrapper} is detected as unreachable by the garbage collector.
*/
@SuppressWarnings("unused")
static void create(Object wrapper, long handle) {
assert wrapper instanceof IndirectHotSpotObjectConstantImpl || wrapper instanceof MetaspaceHandleObject;
new HandleCleaner(wrapper, handle, wrapper instanceof IndirectHotSpotObjectConstantImpl);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -23,6 +23,7 @@
package jdk.vm.ci.hotspot;
import java.util.Map;
import java.util.Objects;
import jdk.vm.ci.code.BailoutException;
import jdk.vm.ci.code.BytecodeFrame;
@ -102,25 +103,42 @@ public class HotSpotCodeCacheProvider implements CodeCacheProvider {
@Override
public InstalledCode installCode(ResolvedJavaMethod method, CompiledCode compiledCode, InstalledCode installedCode, SpeculationLog log, boolean isDefault) {
InstalledCode resultInstalledCode;
if (installedCode == null) {
if (method == null) {
// Must be a stub
resultInstalledCode = new HotSpotRuntimeStub(((HotSpotCompiledCode) compiledCode).getName());
} else {
resultInstalledCode = new HotSpotNmethod((HotSpotResolvedJavaMethod) method, ((HotSpotCompiledCode) compiledCode).getName(), isDefault);
}
if (installedCode != null) {
throw new IllegalArgumentException("InstalledCode argument must be null");
}
HotSpotCompiledCode hsCompiledCode = (HotSpotCompiledCode) compiledCode;
String name = hsCompiledCode.getName();
HotSpotCompiledNmethod hsCompiledNmethod = null;
if (method == null) {
// Must be a stub
resultInstalledCode = new HotSpotRuntimeStub(name);
} else {
resultInstalledCode = installedCode;
hsCompiledNmethod = (HotSpotCompiledNmethod) hsCompiledCode;
HotSpotResolvedJavaMethodImpl hsMethod = (HotSpotResolvedJavaMethodImpl) method;
resultInstalledCode = new HotSpotNmethod(hsMethod, name, isDefault, hsCompiledNmethod.id);
}
HotSpotSpeculationLog speculationLog = (log != null && log.hasSpeculations()) ? (HotSpotSpeculationLog) log : null;
HotSpotSpeculationLog speculationLog = null;
if (log != null) {
if (log.hasSpeculations()) {
speculationLog = (HotSpotSpeculationLog) log;
}
}
int result = runtime.getCompilerToVM().installCode(target, (HotSpotCompiledCode) compiledCode, resultInstalledCode, speculationLog);
byte[] speculations;
long failedSpeculationsAddress;
if (speculationLog != null) {
speculations = speculationLog.getFlattenedSpeculations(true);
failedSpeculationsAddress = speculationLog.getFailedSpeculationsAddress();
} else {
speculations = new byte[0];
failedSpeculationsAddress = 0L;
}
int result = runtime.getCompilerToVM().installCode(target, (HotSpotCompiledCode) compiledCode, resultInstalledCode, failedSpeculationsAddress, speculations);
if (result != config.codeInstallResultOk) {
String resultDesc = config.getCodeInstallResultDescription(result);
if (compiledCode instanceof HotSpotCompiledNmethod) {
HotSpotCompiledNmethod compiledNmethod = (HotSpotCompiledNmethod) compiledCode;
String msg = compiledNmethod.getInstallationFailureMessage();
if (hsCompiledNmethod != null) {
String msg = hsCompiledNmethod.getInstallationFailureMessage();
if (msg != null) {
msg = String.format("Code installation failed: %s%n%s", resultDesc, msg);
} else {
@ -139,7 +157,11 @@ public class HotSpotCodeCacheProvider implements CodeCacheProvider {
@Override
public void invalidateInstalledCode(InstalledCode installedCode) {
runtime.getCompilerToVM().invalidateInstalledCode(installedCode);
if (installedCode instanceof HotSpotNmethod) {
runtime.getCompilerToVM().invalidateHotSpotNmethod((HotSpotNmethod) installedCode);
} else {
throw new IllegalArgumentException("Cannot invalidate a " + Objects.requireNonNull(installedCode).getClass().getName());
}
}
@Override

Some files were not shown because too many files have changed in this diff Show More