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:
parent
f9bbbb6e27
commit
e9c523ae5f
@ -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"
|
||||
|
@ -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"],
|
||||
},
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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") \
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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)) {
|
||||
|
@ -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.
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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());
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ class ScavengeRootsTask : public GCTask {
|
||||
management = 7,
|
||||
jvmti = 8,
|
||||
code_cache = 9
|
||||
JVMCI_ONLY(COMMA jvmci = 10)
|
||||
};
|
||||
private:
|
||||
RootType _root_type;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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);)
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
49
src/hotspot/share/jvmci/jniAccessMark.inline.hpp
Normal file
49
src/hotspot/share/jvmci/jniAccessMark.inline.hpp
Normal 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
|
151
src/hotspot/share/jvmci/jvmci.cpp
Normal file
151
src/hotspot/share/jvmci/jvmci.cpp
Normal 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;
|
||||
}
|
106
src/hotspot/share/jvmci/jvmci.hpp
Normal file
106
src/hotspot/share/jvmci/jvmci.hpp
Normal 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
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
@ -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;
|
||||
|
@ -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
@ -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
|
||||
|
79
src/hotspot/share/jvmci/jvmciExceptions.hpp
Normal file
79
src/hotspot/share/jvmci/jvmciExceptions.hpp
Normal 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
|
@ -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
|
||||
|
@ -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
|
||||
|
94
src/hotspot/share/jvmci/jvmciObject.hpp
Normal file
94
src/hotspot/share/jvmci/jvmciObject.hpp
Normal 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
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
158
src/hotspot/share/jvmci/metadataHandleBlock.cpp
Normal file
158
src/hotspot/share/jvmci/metadataHandleBlock.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
170
src/hotspot/share/jvmci/metadataHandleBlock.hpp
Normal file
170
src/hotspot/share/jvmci/metadataHandleBlock.hpp
Normal 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
|
@ -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
|
@ -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) \
|
||||
|
@ -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
|
||||
|
@ -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 */ \
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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})
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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<>();
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user