8139170: JVMCI refresh

Reviewed-by: kvn
This commit is contained in:
Christian Thalinger 2015-11-04 07:23:23 -10:00
parent a4e16dd190
commit a38ea495d6
246 changed files with 4445 additions and 2901 deletions

View File

@ -11,3 +11,12 @@
^.hgtip
.DS_Store
\.class$
^\.?mx.jvmci/
^src/jdk.vm.ci/share/classes/\w[\w\.]*/.*\.xml
^src/jdk.vm.ci/share/classes/\w[\w\.]*/.*\.iml
^src/jdk.vm.ci/share/classes/\w[\w\.]*/nbproject
^src/jdk.vm.ci/share/classes/\w[\w\.]*/\..*
^test/compiler/jvmci/\w[\w\.]*/.*\.xml
^test/compiler/jvmci/\w[\w\.]*/.*\.iml
^test/compiler/jvmci/\w[\w\.]*/nbproject
^test/compiler/jvmci/\w[\w\.]*/\..*

View File

@ -56,10 +56,10 @@ $(eval $(call SetupJavaCompilation, BUILD_JVMCI_SERVICE, \
################################################################################
PROC_SRC_SUBDIRS := \
jdk.vm.ci.compiler \
jdk.vm.ci.hotspot \
jdk.vm.ci.hotspot.amd64 \
jdk.vm.ci.hotspot.sparc \
jdk.vm.ci.runtime \
#
PROC_SRC_DIRS := $(patsubst %, $(SRC_DIR)/%/src, $(PROC_SRC_SUBDIRS))
@ -94,11 +94,7 @@ TARGETS += $(GENSRC_DIR)/_gensrc_proc_done
$(GENSRC_DIR)/META-INF/services/jdk.vm.ci.options.OptionDescriptors: \
$(GENSRC_DIR)/_gensrc_proc_done
$(MKDIR) -p $(@D)
($(CD) $(GENSRC_DIR)/META-INF/jvmci.options && \
$(RM) -f $@; \
for i in $$(ls); do \
echo $${i}_OptionDescriptors >> $@; \
done)
$(FIND) $(GENSRC_DIR) -name '*_OptionDescriptors.java' | $(SED) 's:.*/jdk\.vm\.ci/\(.*\)\.java:\1:' | $(TR) '/' '.' > $@
TARGETS += $(GENSRC_DIR)/META-INF/services/jdk.vm.ci.options.OptionDescriptors

View File

@ -38,11 +38,11 @@ void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) {
Unimplemented();
}
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle& constant) {
Unimplemented();
}
void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
Unimplemented();
}

View File

@ -38,11 +38,11 @@ void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) {
Unimplemented();
}
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle& constant) {
Unimplemented();
}
void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
Unimplemented();
}

View File

@ -66,6 +66,25 @@ void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) {
}
}
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle& constant) {
address pc = _instructions->start() + pc_offset;
if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
#ifdef _LP64
NativeMovConstReg32* move = nativeMovConstReg32_at(pc);
narrowKlass narrowOop = record_narrow_metadata_reference(constant);
move->set_data((intptr_t)narrowOop);
TRACE_jvmci_3("relocating (narrow metaspace constant) at %p/%p", pc, narrowOop);
#else
fatal("compressed Klass* on 32bit");
#endif
} else {
NativeMovConstReg* move = nativeMovConstReg_at(pc);
Metadata* reference = record_metadata_reference(constant);
move->set_data((intptr_t)reference);
TRACE_jvmci_3("relocating (metaspace constant) at %p/%p", pc, reference);
}
}
void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset) {
address pc = _instructions->start() + pc_offset;
NativeInstruction* inst = nativeInstruction_at(pc);
@ -87,10 +106,6 @@ void CodeInstaller::pd_patch_DataSectionReference(int pc_offset, int data_offset
}
}
void CodeInstaller::pd_relocate_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
fatal("CodeInstaller::pd_relocate_CodeBlob - sparc unimp");
}
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
address pc = (address) inst;
if (inst->is_call()) {
@ -168,16 +183,25 @@ void CodeInstaller::pd_relocate_poll(address pc, jint mark) {
// convert JVMCI register indices (as used in oop maps) to HotSpot registers
VMReg CodeInstaller::get_hotspot_reg(jint jvmci_reg) {
if (jvmci_reg < RegisterImpl::number_of_registers) {
// JVMCI Registers are numbered as follows:
// 0..31: Thirty-two General Purpose registers (CPU Registers)
// 32..63: Thirty-two single precision float registers
// 64..95: Thirty-two double precision float registers
// 96..111: Sixteen quad precision float registers
if (jvmci_reg < 32) {
return as_Register(jvmci_reg)->as_VMReg();
} else {
jint floatRegisterNumber = jvmci_reg - RegisterImpl::number_of_registers;
floatRegisterNumber += MAX2(0, floatRegisterNumber-32); // Beginning with f32, only every second register is going to be addressed
if (floatRegisterNumber < FloatRegisterImpl::number_of_registers) {
return as_FloatRegister(floatRegisterNumber)->as_VMReg();
jint floatRegisterNumber;
if(jvmci_reg < 64) { // Single precision
floatRegisterNumber = jvmci_reg - 32;
} else if(jvmci_reg < 96) {
floatRegisterNumber = 2 * (jvmci_reg - 64);
} else if(jvmci_reg < 112) {
floatRegisterNumber = 4 * (jvmci_reg - 96);
} else {
fatal("Unknown jvmci register");
}
ShouldNotReachHere();
return NULL;
return as_FloatRegister(floatRegisterNumber)->as_VMReg();
}
}

View File

@ -417,6 +417,67 @@ void NativeMovConstReg::test() {
//-------------------------------------------------------------------
void NativeMovConstReg32::verify() {
NativeInstruction::verify();
// make sure code pattern is actually a "set_metadata" synthetic instruction
// see MacroAssembler::set_oop()
int i0 = long_at(sethi_offset);
int i1 = long_at(add_offset);
// verify the pattern "sethi %hi22(imm), reg ; add reg, %lo10(imm), reg"
Register rd = inv_rd(i0);
if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) {
fatal("not a set_metadata");
}
}
void NativeMovConstReg32::print() {
tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, instruction_address(), data());
}
intptr_t NativeMovConstReg32::data() const {
return data32(long_at(sethi_offset), long_at(add_offset));
}
void NativeMovConstReg32::set_data(intptr_t x) {
set_long_at(sethi_offset, set_data32_sethi( long_at(sethi_offset), x));
set_long_at(add_offset, set_data32_simm13( long_at(add_offset), x));
// also store the value into an oop_Relocation cell, if any
CodeBlob* cb = CodeCache::find_blob(instruction_address());
nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL;
if (nm != NULL) {
RelocIterator iter(nm, instruction_address(), next_instruction_address());
oop* oop_addr = NULL;
Metadata** metadata_addr = NULL;
while (iter.next()) {
if (iter.type() == relocInfo::oop_type) {
oop_Relocation *r = iter.oop_reloc();
if (oop_addr == NULL) {
oop_addr = r->oop_addr();
*oop_addr = cast_to_oop(x);
} else {
assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
}
}
if (iter.type() == relocInfo::metadata_type) {
metadata_Relocation *r = iter.metadata_reloc();
if (metadata_addr == NULL) {
metadata_addr = r->metadata_addr();
*metadata_addr = (Metadata*)x;
} else {
assert(metadata_addr == r->metadata_addr(), "must be only one set-metadata here");
}
}
}
}
}
//-------------------------------------------------------------------
void NativeMovConstRegPatching::verify() {
NativeInstruction::verify();
// Make sure code pattern is sethi/nop/add.

View File

@ -518,6 +518,46 @@ class NativeFarCall: public NativeInstruction {
#endif // _LP64
// An interface for accessing/manipulating 32 bit native set_metadata imm, reg instructions
// (used to manipulate inlined data references, etc.)
// set_metadata imm, reg
// == sethi %hi22(imm), reg ; add reg, %lo10(imm), reg
class NativeMovConstReg32;
inline NativeMovConstReg32* nativeMovConstReg32_at(address address);
class NativeMovConstReg32: public NativeInstruction {
public:
enum Sparc_specific_constants {
sethi_offset = 0,
add_offset = 4,
instruction_size = 8
};
address instruction_address() const { return addr_at(0); }
address next_instruction_address() const { return addr_at(instruction_size); }
// (The [set_]data accessor respects oop_type relocs also.)
intptr_t data() const;
void set_data(intptr_t x);
// report the destination register
Register destination() { return inv_rd(long_at(sethi_offset)); }
void verify();
void print();
// unit test stuff
static void test();
// Creation
friend inline NativeMovConstReg32* nativeMovConstReg32_at(address address) {
NativeMovConstReg32* test = (NativeMovConstReg32*)address;
#ifdef ASSERT
test->verify();
#endif
return test;
}
};
// An interface for accessing/manipulating native set_metadata imm, reg instructions.
// (used to manipulate inlined data references, etc.)
// set_metadata imm, reg

View File

@ -83,7 +83,26 @@
declare_constant(VM_Version::vis1_instructions_m) \
declare_constant(VM_Version::vis2_instructions_m) \
declare_constant(VM_Version::vis3_instructions_m) \
declare_constant(VM_Version::cbcond_instructions_m)
declare_constant(VM_Version::cbcond_instructions_m) \
declare_constant(VM_Version::v8_instructions_m) \
declare_constant(VM_Version::hardware_mul32_m) \
declare_constant(VM_Version::hardware_div32_m) \
declare_constant(VM_Version::hardware_fsmuld_m) \
declare_constant(VM_Version::hardware_popc_m) \
declare_constant(VM_Version::v9_instructions_m) \
declare_constant(VM_Version::sun4v_m) \
declare_constant(VM_Version::blk_init_instructions_m) \
declare_constant(VM_Version::fmaf_instructions_m) \
declare_constant(VM_Version::fmau_instructions_m) \
declare_constant(VM_Version::sparc64_family_m) \
declare_constant(VM_Version::M_family_m) \
declare_constant(VM_Version::T_family_m) \
declare_constant(VM_Version::T1_model_m) \
declare_constant(VM_Version::sparc5_instructions_m) \
declare_constant(VM_Version::aes_instructions_m) \
declare_constant(VM_Version::sha1_instruction_m) \
declare_constant(VM_Version::sha256_instruction_m) \
declare_constant(VM_Version::sha512_instruction_m)
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)

View File

@ -85,6 +85,23 @@ void CodeInstaller::pd_patch_OopConstant(int pc_offset, Handle& constant) {
}
}
void CodeInstaller::pd_patch_MetaspaceConstant(int pc_offset, Handle& constant) {
address pc = _instructions->start() + pc_offset;
if (HotSpotMetaspaceConstantImpl::compressed(constant)) {
#ifdef _LP64
address operand = Assembler::locate_operand(pc, Assembler::narrow_oop_operand);
*((narrowKlass*) operand) = record_narrow_metadata_reference(constant);
TRACE_jvmci_3("relocating (narrow metaspace constant) at " PTR_FORMAT "/" PTR_FORMAT, p2i(pc), p2i(operand));
#else
fatal("compressed Klass* on 32bit");
#endif
} else {
address operand = Assembler::locate_operand(pc, Assembler::imm_operand);
*((Metadata**) operand) = record_metadata_reference(constant);
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) {
address pc = _instructions->start() + pc_offset;
@ -100,16 +117,6 @@ 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_CodeBlob(CodeBlob* cb, NativeInstruction* inst) {
if (cb->is_nmethod()) {
nmethod* nm = (nmethod*) cb;
nativeJump_at((address)inst)->set_jump_destination(nm->verified_entry_point());
} else {
nativeJump_at((address)inst)->set_jump_destination(cb->code_begin());
}
_instructions->relocate((address)inst, runtime_call_Relocation::spec(), Assembler::call32_operand);
}
void CodeInstaller::pd_relocate_ForeignCall(NativeInstruction* inst, jlong foreign_call_destination) {
address pc = (address) inst;
if (inst->is_call()) {

View File

@ -82,6 +82,7 @@
declare_constant(VM_Version::CPU_AVX512CD) \
declare_constant(VM_Version::CPU_AVX512BW)
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant)
#define VM_LONG_CONSTANTS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) \
declare_preprocessor_constant("VM_Version::CPU_AVX512VL", CPU_AVX512VL)
#endif // CPU_X86_VM_VMSTRUCTS_X86_HPP

View File

@ -22,15 +22,18 @@
*/
package jdk.vm.ci.amd64;
import static jdk.vm.ci.code.MemoryBarriers.*;
import static jdk.vm.ci.code.Register.*;
import static jdk.vm.ci.code.MemoryBarriers.LOAD_STORE;
import static jdk.vm.ci.code.MemoryBarriers.STORE_STORE;
import static jdk.vm.ci.code.Register.SPECIAL;
import java.nio.*;
import java.util.*;
import java.nio.ByteOrder;
import java.util.EnumSet;
import jdk.vm.ci.code.*;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.PlatformKind;
/**
* Represents the AMD64 architecture.
@ -65,9 +68,7 @@ public class AMD64 extends Architecture {
r8, r9, r10, r11, r12, r13, r14, r15
};
private static final int XMM_REFERENCE_MAP_SHIFT = 2;
public static final RegisterCategory XMM = new RegisterCategory("XMM", cpuRegisters.length, XMM_REFERENCE_MAP_SHIFT);
public static final RegisterCategory XMM = new RegisterCategory("XMM");
// XMM registers
public static final Register xmm0 = new Register(16, 0, "xmm0", XMM);
@ -79,8 +80,8 @@ public class AMD64 extends Architecture {
public static final Register xmm6 = new Register(22, 6, "xmm6", XMM);
public static final Register xmm7 = new Register(23, 7, "xmm7", XMM);
public static final Register xmm8 = new Register(24, 8, "xmm8", XMM);
public static final Register xmm9 = new Register(25, 9, "xmm9", XMM);
public static final Register xmm8 = new Register(24, 8, "xmm8", XMM);
public static final Register xmm9 = new Register(25, 9, "xmm9", XMM);
public static final Register xmm10 = new Register(26, 10, "xmm10", XMM);
public static final Register xmm11 = new Register(27, 11, "xmm11", XMM);
public static final Register xmm12 = new Register(28, 12, "xmm12", XMM);
@ -88,28 +89,77 @@ public class AMD64 extends Architecture {
public static final Register xmm14 = new Register(30, 14, "xmm14", XMM);
public static final Register xmm15 = new Register(31, 15, "xmm15", XMM);
public static final Register[] xmmRegisters = {
public static final Register xmm16 = new Register(32, 16, "xmm16", XMM);
public static final Register xmm17 = new Register(33, 17, "xmm17", XMM);
public static final Register xmm18 = new Register(34, 18, "xmm18", XMM);
public static final Register xmm19 = new Register(35, 19, "xmm19", XMM);
public static final Register xmm20 = new Register(36, 20, "xmm20", XMM);
public static final Register xmm21 = new Register(37, 21, "xmm21", XMM);
public static final Register xmm22 = new Register(38, 22, "xmm22", XMM);
public static final Register xmm23 = new Register(39, 23, "xmm23", XMM);
public static final Register xmm24 = new Register(40, 24, "xmm24", XMM);
public static final Register xmm25 = new Register(41, 25, "xmm25", XMM);
public static final Register xmm26 = new Register(42, 26, "xmm26", XMM);
public static final Register xmm27 = new Register(43, 27, "xmm27", XMM);
public static final Register xmm28 = new Register(44, 28, "xmm28", XMM);
public static final Register xmm29 = new Register(45, 29, "xmm29", XMM);
public static final Register xmm30 = new Register(46, 30, "xmm30", XMM);
public static final Register xmm31 = new Register(47, 31, "xmm31", XMM);
public static final Register[] xmmRegistersSSE = {
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
};
public static final Register[] cpuxmmRegisters = {
public static final Register[] xmmRegistersAVX512 = {
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23,
xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31
};
public static final RegisterCategory MASK = new RegisterCategory("MASK", false);
public static final Register k0 = new Register(48, 0, "k0", MASK);
public static final Register k1 = new Register(49, 1, "k1", MASK);
public static final Register k2 = new Register(50, 2, "k2", MASK);
public static final Register k3 = new Register(51, 3, "k3", MASK);
public static final Register k4 = new Register(52, 4, "k4", MASK);
public static final Register k5 = new Register(53, 5, "k5", MASK);
public static final Register k6 = new Register(54, 6, "k6", MASK);
public static final Register k7 = new Register(55, 7, "k7", MASK);
public static final Register[] valueRegistersSSE = {
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
};
public static final Register[] valueRegistersAVX512 = {
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23,
xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31,
k0, k1, k2, k3, k4, k5, k6, k7
};
/**
* Register used to construct an instruction-relative address.
*/
public static final Register rip = new Register(32, -1, "rip", SPECIAL);
public static final Register rip = new Register(56, -1, "rip", SPECIAL);
public static final Register[] allRegisters = {
rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi,
r8, r9, r10, r11, r12, r13, r14, r15,
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15,
xmm16, xmm17, xmm18, xmm19, xmm20, xmm21, xmm22, xmm23,
xmm24, xmm25, xmm26, xmm27, xmm28, xmm29, xmm30, xmm31,
k0, k1, k2, k3, k4, k5, k6, k7,
rip
};
@ -151,7 +201,8 @@ public class AMD64 extends Architecture {
AVX512PF,
AVX512ER,
AVX512CD,
AVX512BW
AVX512BW,
AVX512VL
}
private final EnumSet<CPUFeature> features;
@ -166,11 +217,21 @@ public class AMD64 extends Architecture {
private final EnumSet<Flag> flags;
private final AMD64Kind largestKind;
public AMD64(EnumSet<CPUFeature> features, EnumSet<Flag> flags) {
super("AMD64", JavaKind.Long, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, cpuRegisters.length + (xmmRegisters.length << XMM_REFERENCE_MAP_SHIFT), 8);
super("AMD64", AMD64Kind.QWORD, ByteOrder.LITTLE_ENDIAN, true, allRegisters, LOAD_STORE | STORE_STORE, 1, 8);
this.features = features;
this.flags = flags;
assert features.contains(CPUFeature.SSE2) : "minimum config for x64";
if (features.contains(CPUFeature.AVX512F)) {
largestKind = AMD64Kind.V512_QWORD;
} else if (features.contains(CPUFeature.AVX)) {
largestKind = AMD64Kind.V256_QWORD;
} else {
largestKind = AMD64Kind.V128_QWORD;
}
}
public EnumSet<CPUFeature> getFeatures() {
@ -182,50 +243,60 @@ public class AMD64 extends Architecture {
}
@Override
public PlatformKind getPlatformKind(JavaKind javaKind) {
if (javaKind.isObject()) {
return getWordKind();
public Register[] getAvailableValueRegisters() {
if (features.contains(CPUFeature.AVX512F)) {
return valueRegistersAVX512;
} else {
return javaKind;
return valueRegistersSSE;
}
}
@Override
public PlatformKind getPlatformKind(JavaKind javaKind) {
switch (javaKind) {
case Boolean:
case Byte:
return AMD64Kind.BYTE;
case Short:
case Char:
return AMD64Kind.WORD;
case Int:
return AMD64Kind.DWORD;
case Long:
case Object:
return AMD64Kind.QWORD;
case Float:
return AMD64Kind.SINGLE;
case Double:
return AMD64Kind.DOUBLE;
default:
return null;
}
}
@Override
public boolean canStoreValue(RegisterCategory category, PlatformKind platformKind) {
if (!(platformKind instanceof JavaKind)) {
return false;
AMD64Kind kind = (AMD64Kind) platformKind;
if (kind.isInteger()) {
return category.equals(CPU);
} else if (kind.isXMM()) {
return category.equals(XMM);
} else {
assert kind.isMask();
return category.equals(MASK);
}
JavaKind kind = (JavaKind) platformKind;
if (category.equals(CPU)) {
switch (kind) {
case Boolean:
case Byte:
case Char:
case Short:
case Int:
case Long:
return true;
}
} else if (category.equals(XMM)) {
switch (kind) {
case Float:
case Double:
return true;
}
}
return false;
}
@Override
public PlatformKind getLargestStorableKind(RegisterCategory category) {
public AMD64Kind getLargestStorableKind(RegisterCategory category) {
if (category.equals(CPU)) {
return JavaKind.Long;
return AMD64Kind.QWORD;
} else if (category.equals(XMM)) {
return JavaKind.Double;
return largestKind;
} else if (category.equals(MASK)) {
return AMD64Kind.MASK64;
} else {
return JavaKind.Illegal;
return null;
}
}
}

View File

@ -0,0 +1,214 @@
/*
* Copyright (c) 2015, 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.amd64;
import jdk.vm.ci.meta.PlatformKind;
public enum AMD64Kind implements PlatformKind {
// scalar
BYTE(1),
WORD(2),
DWORD(4),
QWORD(8),
SINGLE(4),
DOUBLE(8),
// SSE2
V32_BYTE(4, BYTE),
V32_WORD(4, WORD),
V64_BYTE(8, BYTE),
V64_WORD(8, WORD),
V64_DWORD(8, DWORD),
V128_BYTE(16, BYTE),
V128_WORD(16, WORD),
V128_DWORD(16, DWORD),
V128_QWORD(16, QWORD),
V128_SINGLE(16, SINGLE),
V128_DOUBLE(16, DOUBLE),
// AVX
V256_BYTE(32, BYTE),
V256_WORD(32, WORD),
V256_DWORD(32, DWORD),
V256_QWORD(32, QWORD),
V256_SINGLE(32, SINGLE),
V256_DOUBLE(32, DOUBLE),
// AVX512
V512_BYTE(64, BYTE),
V512_WORD(64, WORD),
V512_DWORD(64, DWORD),
V512_QWORD(64, QWORD),
V512_SINGLE(64, SINGLE),
V512_DOUBLE(64, DOUBLE),
MASK8(1),
MASK16(2),
MASK32(4),
MASK64(8);
private final int size;
private final int vectorLength;
private final AMD64Kind scalar;
private final EnumKey<AMD64Kind> key = new EnumKey<>(this);
private AMD64Kind(int size) {
this.size = size;
this.scalar = this;
this.vectorLength = 1;
}
private AMD64Kind(int size, AMD64Kind scalar) {
this.size = size;
this.scalar = scalar;
assert size % scalar.size == 0;
this.vectorLength = size / scalar.size;
}
public AMD64Kind getScalar() {
return scalar;
}
public int getSizeInBytes() {
return size;
}
public int getVectorLength() {
return vectorLength;
}
public Key getKey() {
return key;
}
public boolean isInteger() {
switch (this) {
case BYTE:
case WORD:
case DWORD:
case QWORD:
return true;
default:
return false;
}
}
public boolean isXMM() {
switch (this) {
case SINGLE:
case DOUBLE:
case V32_BYTE:
case V32_WORD:
case V64_BYTE:
case V64_WORD:
case V64_DWORD:
case V128_BYTE:
case V128_WORD:
case V128_DWORD:
case V128_QWORD:
case V128_SINGLE:
case V128_DOUBLE:
case V256_BYTE:
case V256_WORD:
case V256_DWORD:
case V256_QWORD:
case V256_SINGLE:
case V256_DOUBLE:
case V512_BYTE:
case V512_WORD:
case V512_DWORD:
case V512_QWORD:
case V512_SINGLE:
case V512_DOUBLE:
return true;
default:
return false;
}
}
public boolean isMask() {
switch (this) {
case MASK8:
case MASK16:
case MASK32:
case MASK64:
return true;
default:
return false;
}
}
public char getTypeChar() {
switch (this) {
case BYTE:
return 'b';
case WORD:
return 'w';
case DWORD:
return 'd';
case QWORD:
return 'q';
case SINGLE:
return 'S';
case DOUBLE:
return 'D';
case V32_BYTE:
case V32_WORD:
case V64_BYTE:
case V64_WORD:
case V64_DWORD:
return 'v';
case V128_BYTE:
case V128_WORD:
case V128_DWORD:
case V128_QWORD:
case V128_SINGLE:
case V128_DOUBLE:
return 'x';
case V256_BYTE:
case V256_WORD:
case V256_DWORD:
case V256_QWORD:
case V256_SINGLE:
case V256_DOUBLE:
return 'y';
case V512_BYTE:
case V512_WORD:
case V512_DWORD:
case V512_QWORD:
case V512_SINGLE:
case V512_DOUBLE:
return 'z';
case MASK8:
case MASK16:
case MASK32:
case MASK64:
return 'k';
default:
return '-';
}
}
}

View File

@ -22,11 +22,12 @@
*/
package jdk.vm.ci.code;
import java.nio.*;
import java.util.*;
import java.nio.ByteOrder;
import java.util.Arrays;
import jdk.vm.ci.code.Register.RegisterCategory;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.PlatformKind;
/**
* Represents a CPU architecture, including information such as its endianness, CPU registers, word
@ -34,13 +35,6 @@ import jdk.vm.ci.meta.*;
*/
public abstract class Architecture {
/**
* The number of entries required in a {@link ReferenceMap} covering all the registers that may
* store references. The index of a register in the reference map is given by
* {@link Register#getReferenceMapIndex()}.
*/
private final int registerReferenceMapSize;
/**
* The architecture specific type of a native word.
*/
@ -85,7 +79,7 @@ public abstract class Architecture {
private final int returnAddressSize;
protected Architecture(String name, PlatformKind wordKind, ByteOrder byteOrder, boolean unalignedMemoryAccess, Register[] registers, int implicitMemoryBarriers, int nativeCallDisplacementOffset,
int registerReferenceMapSize, int returnAddressSize) {
int returnAddressSize) {
this.name = name;
this.registers = registers;
this.wordKind = wordKind;
@ -93,7 +87,6 @@ public abstract class Architecture {
this.unalignedMemoryAccess = unalignedMemoryAccess;
this.implicitMemoryBarriers = implicitMemoryBarriers;
this.machineCodeCallDisplacementOffset = nativeCallDisplacementOffset;
this.registerReferenceMapSize = registerReferenceMapSize;
this.returnAddressSize = returnAddressSize;
}
@ -107,10 +100,6 @@ public abstract class Architecture {
return getName().toLowerCase();
}
public int getRegisterReferenceMapSize() {
return registerReferenceMapSize;
}
/**
* Gets the natural size of words (typically registers and pointers) of this architecture, in
* bytes.
@ -131,13 +120,23 @@ public abstract class Architecture {
}
/**
* Gets an array of all available registers on this architecture. The index of each register in
* this array is equal to its {@linkplain Register#number number}.
* Gets an array of all registers that exist on this architecture. This contains all registers
* that exist in the specification of this architecture. Not all of them may be available on
* this particular architecture instance. The index of each register in this array is equal to
* its {@linkplain Register#number number}.
*/
public Register[] getRegisters() {
return registers.clone();
}
/**
* Gets an array of all registers available for storing values on this architecture. This may be
* a subset of {@link #getRegisters()}, depending on the capabilities of this particular CPU.
*/
public Register[] getAvailableValueRegisters() {
return getRegisters();
}
public ByteOrder getByteOrder() {
return byteOrder;
}
@ -207,7 +206,6 @@ public abstract class Architecture {
assert this.byteOrder.equals(that.byteOrder);
assert this.implicitMemoryBarriers == that.implicitMemoryBarriers;
assert this.machineCodeCallDisplacementOffset == that.machineCodeCallDisplacementOffset;
assert this.registerReferenceMapSize == that.registerReferenceMapSize;
assert Arrays.equals(this.registers, that.registers);
assert this.returnAddressSize == that.returnAddressSize;
assert this.unalignedMemoryAccess == that.unalignedMemoryAccess;

View File

@ -22,7 +22,7 @@
*/
package jdk.vm.ci.code;
import java.util.*;
import java.util.Locale;
/**
* Exception thrown when the compiler refuses to compile a method because of problems with the

View File

@ -22,9 +22,12 @@
*/
package jdk.vm.ci.code;
import java.util.*;
import java.util.Arrays;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaValue;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Value;
/**
* Represents the Java bytecode frame state(s) at a given position including {@link Value locations}

View File

@ -22,9 +22,9 @@
*/
package jdk.vm.ci.code;
import java.util.*;
import java.util.Objects;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Represents a code position, that is, a chain of inlined methods with bytecode locations, that is

View File

@ -22,9 +22,10 @@
*/
package jdk.vm.ci.code;
import static jdk.vm.ci.code.ValueUtil.*;
import jdk.vm.ci.meta.*;
import static jdk.vm.ci.code.ValueUtil.isAllocatableValue;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Value;
/**
* A calling convention describes the locations in which the arguments for a call are placed and the

View File

@ -22,9 +22,14 @@
*/
package jdk.vm.ci.code;
import jdk.vm.ci.code.CompilationResult.*;
import jdk.vm.ci.code.DataSection.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.code.CompilationResult.Call;
import jdk.vm.ci.code.CompilationResult.DataPatch;
import jdk.vm.ci.code.CompilationResult.Mark;
import jdk.vm.ci.code.DataSection.Data;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.SpeculationLog;
/**
* Access to code cache related details and requirements.
@ -32,26 +37,62 @@ import jdk.vm.ci.meta.*;
public interface CodeCacheProvider {
/**
* Adds the given compilation result as an implementation of the given method without making it
* the default implementation.
* Installs code for a given method based on a given compilation result without making it the
* default implementation of the method.
*
* @param method a method to which the executable code is begin added
* @param method a method implemented by the installed code
* @param compResult the compilation result to be added
* @param speculationLog the speculation log to be used
* @return a reference to the compiled and ready-to-run code or throws a
* {@link BailoutException} if the code installation failed
* @param log the speculation log to be used
* @param installedCode a predefined {@link InstalledCode} object to use as a reference to the
* installed code. If {@code null}, a new {@link InstalledCode} object will be
* created.
* @return a reference to the ready-to-run code
* @throws BailoutException if the code installation failed
*/
InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog speculationLog, InstalledCode predefinedInstalledCode);
default InstalledCode addCode(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log, InstalledCode installedCode) {
return installCode(new CompilationRequest(method), compResult, installedCode, log, false);
}
/**
* Sets the given compilation result as the default implementation of the given method.
* Installs code for a given method based on a given compilation result and makes it the default
* implementation of the method.
*
* @param method a method to which the executable code is begin added
* @param method a method implemented by the installed code and for which the installed code
* becomes the default implementation
* @param compResult the compilation result to be added
* @return a reference to the compiled and ready-to-run code or null if the code installation
* failed
* @return a reference to the ready-to-run code
* @throws BailoutException if the code installation failed
*/
InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult);
default InstalledCode setDefaultCode(ResolvedJavaMethod method, CompilationResult compResult) {
return installCode(new CompilationRequest(method), compResult, null, null, true);
}
/**
* Installs code based on a given compilation result.
*
* @param compRequest details of the method compiled to produce {@code compResult} or
* {@code null} if the input to {@code compResult} was not a
* {@link ResolvedJavaMethod}
* @param compResult the compilation result to be added
* @param installedCode a pre-allocated {@link InstalledCode} object to use as a reference to
* the installed code. If {@code null}, a new {@link InstalledCode} object will be
* created.
* @param log the speculation log to be used
* @param isDefault specifies if the installed code should be made the default implementation of
* {@code compRequest.getMethod()}. The default implementation for a method is the
* code executed for standard calls to the method. This argument is ignored if
* {@code compRequest == null}.
* @return a reference to the compiled and ready-to-run installed code
* @throws BailoutException if the code installation failed
*/
InstalledCode installCode(CompilationRequest compRequest, CompilationResult compResult, InstalledCode installedCode, SpeculationLog log, boolean isDefault);
/**
* Invalidates {@code installedCode} such that {@link InvalidInstalledCodeException} will be
* raised the next time {@code installedCode} is
* {@linkplain InstalledCode#executeVarargs(Object...) executed}.
*/
void invalidateInstalledCode(InstalledCode installedCode);
/**
* Gets a name for a {@link Mark} mark.
@ -102,4 +143,16 @@ public interface CodeCacheProvider {
* Create a new speculation log for the target runtime.
*/
SpeculationLog createSpeculationLog();
/**
* Returns the maximum absolute offset of a PC relative call to a given address from any
* position in the code cache or -1 when not applicable. Intended for determining the required
* size of address/offset fields.
*/
long getMaxCallTargetOffset(long address);
/**
* Determines if debug info should also be emitted at non-safepoint locations.
*/
boolean shouldDebugNonSafepoints();
}

View File

@ -22,9 +22,15 @@
*/
package jdk.vm.ci.code;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.MetaUtil;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.Signature;
/**
* Miscellaneous collection of utility methods used by {@code jdk.vm.ci.code} and its clients.
@ -323,49 +329,12 @@ public class CodeUtil {
public interface RefMapFormatter {
String formatStackSlot(int frameRefMapIndex);
String formatRegister(int regRefMapIndex);
}
/**
* Formats a location in a register reference map.
* Formats a location present in a reference map.
*/
public static class DefaultRegFormatter implements RefMapFormatter {
private final Register[] registers;
public DefaultRegFormatter(Architecture arch) {
registers = new Register[arch.getRegisterReferenceMapSize()];
for (Register r : arch.getRegisters()) {
if (r.getReferenceMapIndex() >= 0) {
registers[r.getReferenceMapIndex()] = r;
}
}
}
public String formatStackSlot(int frameRefMapIndex) {
return null;
}
public String formatRegister(int regRefMapIndex) {
int i = regRefMapIndex;
int idx = 0;
while (registers[i] == null) {
i--;
idx++;
}
if (idx == 0) {
return registers[i].toString();
} else {
return String.format("%s+%d", registers[i].toString(), idx);
}
}
}
/**
* Formats a location present in a register or frame reference map.
*/
public static class DefaultRefMapFormatter extends DefaultRegFormatter {
public static class DefaultRefMapFormatter implements RefMapFormatter {
/**
* The size of a stack slot.
@ -383,8 +352,7 @@ public class CodeUtil {
*/
public final int refMapToFPOffset;
public DefaultRefMapFormatter(Architecture arch, int slotSize, Register fp, int refMapToFPOffset) {
super(arch);
public DefaultRefMapFormatter(int slotSize, Register fp, int refMapToFPOffset) {
this.slotSize = slotSize;
this.fp = fp;
this.refMapToFPOffset = refMapToFPOffset;

View File

@ -0,0 +1,78 @@
/*
* Copyright (c) 2015, 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.code;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Represents a request to compile a method.
*/
public class CompilationRequest {
private final ResolvedJavaMethod method;
private final int entryBCI;
/**
* Creates a request to compile a method starting at its entry point.
*
* @param method the method to be compiled
*/
public CompilationRequest(ResolvedJavaMethod method) {
this(method, -1);
}
/**
* Creates a request to compile a method starting at a given BCI.
*
* @param method the method to be compiled
* @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the
* method's entry point
*/
public CompilationRequest(ResolvedJavaMethod method, int entryBCI) {
assert method != null;
this.method = method;
this.entryBCI = entryBCI;
}
/**
* Gets the method to be compiled.
*/
public ResolvedJavaMethod getMethod() {
return method;
}
/**
* Gets the bytecode index (BCI) at which to start compiling where -1 denotes a non-OSR
* compilation request and all other values denote an on stack replacement (OSR) compilation
* request.
*/
public int getEntryBCI() {
return entryBCI;
}
@Override
public String toString() {
return method.format("%H.%n(%p)@" + entryBCI);
}
}

View File

@ -22,13 +22,24 @@
*/
package jdk.vm.ci.code;
import static java.util.Collections.*;
import static jdk.vm.ci.meta.MetaUtil.*;
import static java.util.Collections.emptyList;
import static java.util.Collections.unmodifiableList;
import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.Assumptions.*;
import jdk.vm.ci.meta.Assumptions.Assumption;
import jdk.vm.ci.meta.InvokeTarget;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.MetaUtil;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.VMConstant;
/**
* Represents the output from compiling a method, including the compiled machine code, associated
@ -115,8 +126,8 @@ public class CompilationResult {
public enum MetaSpaceAccessType {
Move,
Store, // store only works for compressed oops (memory <- 32bit value). Compressed oops is
// not supported using AOT. TODO: Look at HotSpotStoreConstantOp
Store, // store only works for compressed oops (memory <- 32bit value). Compressed oops is
// not supported using AOT. TODO: Look at HotSpotStoreConstantOp
Compare; // HotSpotCompareMemoryConstantOp, HotSpotCompareConstantOp
private MetaSpaceAccessType() {
@ -128,13 +139,11 @@ public class CompilationResult {
*/
public static final class MetaSpaceAccess extends Infopoint {
private static final long serialVersionUID = 1701958512608684706L;
/**
* Metaspace reference.
*/
public final Object reference; // Object here is a HotSpotResolvedObjectType or a
// HotSpotMetaSpaceConstant
// HotSpotMetaSpaceConstant
public final MetaSpaceAccessType type;
@ -296,6 +305,15 @@ public class CompilationResult {
}
return false;
}
@Override
public String toString() {
if (initialized) {
return String.format("DataSection[0x%x]", offset);
} else {
return "DataSection[?]";
}
}
}
/**
@ -528,8 +546,6 @@ public class CompilationResult {
}
}
private int id = -1;
/**
* Specifies whether this compilation is a {@code +ImmutableCode} {@code +GeneratePIC}
* compilation.
@ -612,7 +628,6 @@ public class CompilationResult {
CompilationResult that = (CompilationResult) obj;
// @formatter:off
if (this.entryBCI == that.entryBCI &&
this.id == that.id &&
this.customStackAreaOffset == that.customStackAreaOffset &&
this.totalFrameSize == that.totalFrameSize &&
this.targetCodeSize == that.targetCodeSize &&
@ -632,20 +647,6 @@ public class CompilationResult {
return false;
}
/**
* @return the compile id
*/
public int getId() {
return id;
}
/**
* @param id the compile id to set
*/
public void setId(int id) {
this.id = id;
}
/**
* @return true is this is a {@code +ImmutableCode} {@code +GeneratePIC} compilation, false
* otherwise.

View File

@ -22,15 +22,18 @@
*/
package jdk.vm.ci.code;
import static jdk.vm.ci.meta.MetaUtil.*;
import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
import java.nio.*;
import java.util.*;
import java.util.function.*;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Objects;
import java.util.function.Consumer;
import jdk.vm.ci.code.CompilationResult.*;
import jdk.vm.ci.code.DataSection.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.code.CompilationResult.DataPatch;
import jdk.vm.ci.code.CompilationResult.DataSectionReference;
import jdk.vm.ci.code.DataSection.Data;
import jdk.vm.ci.meta.SerializableConstant;
public final class DataSection implements Iterable<Data> {
@ -176,11 +179,27 @@ public final class DataSection implements Iterable<Data> {
*/
public DataSectionReference insertData(Data data) {
assert !finalLayout;
if (data.ref == null) {
data.ref = new DataSectionReference();
synchronized (data) {
if (data.ref == null) {
data.ref = new DataSectionReference();
dataItems.add(data);
}
return data.ref;
}
}
/**
* Transfers all {@link Data} from the provided other {@link DataSection} to this
* {@link DataSection}, and empties the other section.
*/
public void addAll(DataSection other) {
assert !finalLayout && !other.finalLayout;
for (Data data : other.dataItems) {
assert data.ref != null;
dataItems.add(data);
}
return data.ref;
other.dataItems.clear();
}
/**
@ -195,14 +214,16 @@ public final class DataSection implements Iterable<Data> {
dataItems.sort((a, b) -> a.alignment - b.alignment);
int position = 0;
int alignment = 1;
for (Data d : dataItems) {
sectionAlignment = lcm(sectionAlignment, d.alignment);
alignment = lcm(alignment, d.alignment);
position = align(position, d.alignment);
d.ref.setOffset(position);
position += d.size;
}
sectionAlignment = alignment;
sectionSize = position;
}

View File

@ -22,7 +22,7 @@
*/
package jdk.vm.ci.code;
import java.util.*;
import java.util.Objects;
/**
* Represents the debugging information for a particular point of execution. This information

View File

@ -29,14 +29,19 @@ package jdk.vm.ci.code;
public class InstalledCode {
/**
* Raw address of this code blob.
* Raw address address of entity representing this installed code.
*/
private long address;
protected long address;
/**
* Raw address of entryPoint of this installed code.
*/
protected long entryPoint;
/**
* Counts how often the address field was reassigned.
*/
private long version;
protected long version;
protected final String name;
@ -44,27 +49,29 @@ public class InstalledCode {
this.name = name;
}
public final void setAddress(long address) {
this.address = address;
version++;
}
/**
* @return the address of this code blob
* @return the address of entity representing this installed code.
*/
public final long getAddress() {
return address;
}
/**
* @return the address of this code blob
* @return the address of the normal entry point of the installed code.
*/
public final long getEntryPoint() {
return entryPoint;
}
/**
* @return the version number of this installed code
*/
public final long getVersion() {
return version;
}
/**
* Returns the name of this code blob.
* Returns the name of this installed code.
*/
public String getName() {
return name;
@ -79,10 +86,19 @@ public class InstalledCode {
}
/**
* Returns the number of instruction bytes for this code.
* @return true if the code represented by this object is still valid for invocation, false
* otherwise (may happen due to deopt, etc.)
*/
public long getCodeSize() {
return 0;
public boolean isValid() {
return entryPoint != 0;
}
/**
* @return true if the code represented by this object still exists and might have live
* activations, false otherwise (may happen due to deopt, etc.)
*/
public boolean isAlive() {
return address != 0;
}
/**
@ -92,18 +108,10 @@ public class InstalledCode {
return null;
}
/**
* @return true if the code represented by this object is still valid, false otherwise (may
* happen due to deopt, etc.)
*/
public boolean isValid() {
return address != 0;
}
/**
* Invalidates this installed code such that any subsequent
* {@linkplain #executeVarargs(Object...) invocation} will throw an
* {@link InvalidInstalledCodeException}.
* {@link InvalidInstalledCodeException} and all existing invocations will be deoptimized.
*/
public void invalidate() {
throw new UnsupportedOperationException();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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

View File

@ -22,7 +22,8 @@
*/
package jdk.vm.ci.code;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.LIRKind;
/**
* Represents a target machine register.
@ -80,22 +81,15 @@ public final class Register implements Comparable<Register> {
public static class RegisterCategory {
private final String name;
private final int referenceMapOffset;
private final int referenceMapShift;
private final boolean mayContainReference;
public RegisterCategory(String name) {
this(name, 0, 0);
this(name, true);
}
public RegisterCategory(String name, int referenceMapOffset) {
this(name, referenceMapOffset, 0);
}
public RegisterCategory(String name, int referenceMapOffset, int referenceMapShift) {
public RegisterCategory(String name, boolean mayContainReference) {
this.name = name;
this.referenceMapOffset = referenceMapOffset;
this.referenceMapShift = referenceMapShift;
this.mayContainReference = mayContainReference;
}
@Override
@ -112,7 +106,7 @@ public final class Register implements Comparable<Register> {
public boolean equals(Object obj) {
if (obj instanceof RegisterCategory) {
RegisterCategory that = (RegisterCategory) obj;
return this.referenceMapOffset == that.referenceMapOffset && this.referenceMapShift == that.referenceMapShift && this.name.equals(that.name);
return this.name.equals(that.name);
}
return false;
}
@ -138,10 +132,10 @@ public final class Register implements Comparable<Register> {
}
/**
* Get the start index of this register in the {@link ReferenceMap}.
* Determine whether this register needs to be part of the reference map.
*/
public int getReferenceMapIndex() {
return (encoding << registerCategory.referenceMapShift) + registerCategory.referenceMapOffset;
public boolean mayContainReference() {
return registerCategory.mayContainReference;
}
/**

View File

@ -22,7 +22,7 @@
*/
package jdk.vm.ci.code;
import java.util.*;
import java.util.Arrays;
/**
* A collection of register attributes. The specific attribute values for a register may be local to

View File

@ -22,8 +22,10 @@
*/
package jdk.vm.ci.code;
import jdk.vm.ci.code.CallingConvention.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.code.CallingConvention.Type;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.PlatformKind;
/**
* A register configuration binds roles and {@linkplain RegisterAttributes attributes} to physical

View File

@ -22,7 +22,11 @@
*/
package jdk.vm.ci.code;
import java.util.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.TreeMap;
/**
* A map from registers to frame slots. This can be used to describe where callee saved registers

View File

@ -22,7 +22,9 @@
*/
package jdk.vm.ci.code;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.LIRKind;
/**
* Denotes a register that stores a value of a fixed kind. There is exactly one (canonical) instance

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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

View File

@ -22,9 +22,9 @@
*/
package jdk.vm.ci.code;
import static jdk.vm.ci.code.ValueUtil.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaValue;
import jdk.vm.ci.meta.Value;
/**
* Represents lock information in the debug information.
@ -32,10 +32,10 @@ import jdk.vm.ci.meta.*;
public final class StackLockValue implements JavaValue {
private JavaValue owner;
private StackSlotValue slot;
private AllocatableValue slot;
private final boolean eliminated;
public StackLockValue(JavaValue object, StackSlotValue slot, boolean eliminated) {
public StackLockValue(JavaValue object, AllocatableValue slot, boolean eliminated) {
this.owner = object;
this.slot = slot;
this.eliminated = eliminated;
@ -81,8 +81,7 @@ public final class StackLockValue implements JavaValue {
return false;
}
public void setSlot(StackSlotValue stackSlot) {
assert slot == null || (isVirtualStackSlot(slot) && (slot.equals(stackSlot) || isStackSlot(stackSlot))) : String.format("Can not set slot for %s to %s", this, stackSlot);
public void setSlot(AllocatableValue stackSlot) {
slot = stackSlot;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2015, 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
@ -22,13 +22,14 @@
*/
package jdk.vm.ci.code;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.LIRKind;
/**
* Represents a compiler spill slot or an outgoing stack-based argument in a method's frame or an
* incoming stack-based argument in a method's {@linkplain #isInCallerFrame() caller's frame}.
*/
public final class StackSlot extends StackSlotValue {
public final class StackSlot extends AllocatableValue {
private final int offset;
private final boolean addFrameSize;

View File

@ -1,37 +0,0 @@
/*
* Copyright (c) 2014, 2014, 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.code;
import jdk.vm.ci.meta.*;
/**
* Common base class for {@linkplain StackSlot real} and {@linkplain VirtualStackSlot virtual} stack
* slots.
*/
public abstract class StackSlotValue extends AllocatableValue {
public StackSlotValue(LIRKind lirKind) {
super(lirKind);
}
}

View File

@ -22,9 +22,10 @@
*/
package jdk.vm.ci.code;
import static jdk.vm.ci.meta.MetaUtil.*;
import jdk.vm.ci.meta.*;
import static jdk.vm.ci.meta.MetaUtil.identityHashCodeString;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.PlatformKind;
/**
* Represents the target machine for a compiler, including the CPU architecture, the size of
@ -50,9 +51,9 @@ public class TargetDescription {
public final int wordSize;
/**
* The kind to be used for representing raw pointers and CPU registers.
* The {@link JavaKind} to be used for representing raw pointers and CPU registers in Java code.
*/
public final JavaKind wordKind;
public final JavaKind wordJavaKind;
/**
* The stack alignment requirement of the platform. For example, from Appendix D of <a
@ -78,10 +79,12 @@ public class TargetDescription {
this.arch = arch;
this.isMP = isMP;
this.wordSize = arch.getWordSize();
this.wordKind = JavaKind.fromWordSize(wordSize);
this.wordJavaKind = JavaKind.fromWordSize(wordSize);
this.stackAlignment = stackAlignment;
this.implicitNullCheckLimit = implicitNullCheckLimit;
this.inlineObjects = inlineObjects;
assert arch.getPlatformKind(wordJavaKind).equals(arch.getWordKind());
}
@Override
@ -101,7 +104,7 @@ public class TargetDescription {
this.inlineObjects == that.inlineObjects &&
this.isMP == that.isMP &&
this.stackAlignment == that.stackAlignment &&
this.wordKind.equals(that.wordKind) &&
this.wordJavaKind.equals(that.wordJavaKind) &&
this.wordSize == that.wordSize &&
this.arch.equals(that.arch)) {
return true;
@ -116,10 +119,6 @@ public class TargetDescription {
return identityHashCodeString(this);
}
public int getSizeInBytes(PlatformKind kind) {
return kind.getSizeInBytes();
}
public LIRKind getLIRKind(JavaKind javaKind) {
PlatformKind platformKind = arch.getPlatformKind(javaKind);
if (javaKind.isObject()) {

View File

@ -1,124 +0,0 @@
/*
* Copyright (c) 2011, 2011, 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.code;
import java.math.*;
//JaCoCo Exclude
/**
* Utilities for unsigned comparisons. All methods have correct, but slow, standard Java
* implementations so that they can be used with compilers not supporting the intrinsics.
*/
public class UnsignedMath {
private static final long MASK = 0xffffffffL;
/**
* Unsigned comparison aboveThan for two numbers.
*/
public static boolean aboveThan(int a, int b) {
return (a & MASK) > (b & MASK);
}
/**
* Unsigned comparison aboveOrEqual for two numbers.
*/
public static boolean aboveOrEqual(int a, int b) {
return (a & MASK) >= (b & MASK);
}
/**
* Unsigned comparison belowThan for two numbers.
*/
public static boolean belowThan(int a, int b) {
return (a & MASK) < (b & MASK);
}
/**
* Unsigned comparison belowOrEqual for two numbers.
*/
public static boolean belowOrEqual(int a, int b) {
return (a & MASK) <= (b & MASK);
}
/**
* Unsigned comparison aboveThan for two numbers.
*/
public static boolean aboveThan(long a, long b) {
return (a > b) ^ ((a < 0) != (b < 0));
}
/**
* Unsigned comparison aboveOrEqual for two numbers.
*/
public static boolean aboveOrEqual(long a, long b) {
return (a >= b) ^ ((a < 0) != (b < 0));
}
/**
* Unsigned comparison belowThan for two numbers.
*/
public static boolean belowThan(long a, long b) {
return (a < b) ^ ((a < 0) != (b < 0));
}
/**
* Unsigned comparison belowOrEqual for two numbers.
*/
public static boolean belowOrEqual(long a, long b) {
return (a <= b) ^ ((a < 0) != (b < 0));
}
/**
* Unsigned division for two numbers.
*/
public static int divide(int a, int b) {
return (int) ((a & MASK) / (b & MASK));
}
/**
* Unsigned remainder for two numbers.
*/
public static int remainder(int a, int b) {
return (int) ((a & MASK) % (b & MASK));
}
/**
* Unsigned division for two numbers.
*/
public static long divide(long a, long b) {
return bi(a).divide(bi(b)).longValue();
}
/**
* Unsigned remainder for two numbers.
*/
public static long remainder(long a, long b) {
return bi(a).remainder(bi(b)).longValue();
}
private static BigInteger bi(long unsigned) {
return unsigned >= 0 ? BigInteger.valueOf(unsigned) : BigInteger.valueOf(unsigned & 0x7fffffffffffffffL).setBit(63);
}
}

View File

@ -22,9 +22,14 @@
*/
package jdk.vm.ci.code;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaValue;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.meta.Value;
/**
* Utility class for working with the {@link Value} class and its subclasses.
@ -60,6 +65,11 @@ public final class ValueUtil {
return value instanceof JavaConstant;
}
public static JavaConstant asConstantJavaValue(JavaValue value) {
assert value != null;
return (JavaConstant) value;
}
public static boolean isAllocatableValue(Value value) {
assert value != null;
return value instanceof AllocatableValue;
@ -80,26 +90,6 @@ public final class ValueUtil {
return (StackSlot) value;
}
public static boolean isStackSlotValue(Value value) {
assert value != null;
return value instanceof StackSlotValue;
}
public static StackSlotValue asStackSlotValue(Value value) {
assert value != null;
return (StackSlotValue) value;
}
public static boolean isVirtualStackSlot(Value value) {
assert value != null;
return value instanceof VirtualStackSlot;
}
public static VirtualStackSlot asVirtualStackSlot(Value value) {
assert value != null;
return (VirtualStackSlot) value;
}
public static boolean isRegister(Value value) {
assert value != null;
return value instanceof RegisterValue;

View File

@ -22,9 +22,15 @@
*/
package jdk.vm.ci.code;
import java.util.*;
import java.util.Arrays;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.Set;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaValue;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaType;
/**
* An instance of this class represents an object whose allocation was removed by escape analysis.
@ -134,45 +140,6 @@ public final class VirtualObject implements JavaValue {
return id;
}
private boolean checkValues() {
assert (values == null) == (slotKinds == null);
if (values != null) {
assert values.length == slotKinds.length;
if (!type.isArray()) {
ResolvedJavaField[] fields = type.getInstanceFields(true);
int fieldIndex = 0;
for (int i = 0; i < values.length; i++) {
ResolvedJavaField field = fields[fieldIndex++];
JavaKind valKind = slotKinds[i].getStackKind();
if (field.getJavaKind() == JavaKind.Object) {
assert valKind.isObject() : field + ": " + valKind + " != " + field.getJavaKind();
} else {
if ((valKind == JavaKind.Double || valKind == JavaKind.Long) && field.getJavaKind() == JavaKind.Int) {
assert fields[fieldIndex].getJavaKind() == JavaKind.Int;
fieldIndex++;
} else {
assert valKind == field.getJavaKind().getStackKind() : field + ": " + valKind + " != " + field.getJavaKind();
}
}
}
assert fields.length == fieldIndex : type + ": fields=" + Arrays.toString(fields) + ", field values=" + Arrays.toString(values);
} else {
JavaKind componentKind = type.getComponentType().getJavaKind().getStackKind();
if (componentKind == JavaKind.Object) {
for (int i = 0; i < values.length; i++) {
assert slotKinds[i].isObject() : slotKinds[i] + " != " + componentKind;
}
} else {
for (int i = 0; i < values.length; i++) {
assert slotKinds[i] == componentKind || componentKind.getBitCount() >= slotKinds[i].getBitCount() ||
(componentKind == JavaKind.Int && slotKinds[i].getBitCount() >= JavaKind.Int.getBitCount()) : slotKinds[i] + " != " + componentKind;
}
}
}
}
return true;
}
/**
* Overwrites the current set of values with a new one.
*
@ -183,7 +150,6 @@ public final class VirtualObject implements JavaValue {
public void setValues(JavaValue[] values, JavaKind[] slotKinds) {
this.values = values;
this.slotKinds = slotKinds;
assert checkValues();
}
@Override

View File

@ -1,75 +0,0 @@
/*
* Copyright (c) 2014, 2014, 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.code;
import jdk.vm.ci.meta.*;
/**
* {@link VirtualStackSlot}s are stack slots that are not yet fixed to specific frame offset. They
* are replaced by real {@link StackSlot}s with a fixed position in the frame before code emission.
*/
public abstract class VirtualStackSlot extends StackSlotValue {
private final int id;
public VirtualStackSlot(int id, LIRKind lirKind) {
super(lirKind);
this.id = id;
}
public int getId() {
return id;
}
@Override
public String toString() {
return "vstack:" + id + getKindSuffix();
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + id;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
VirtualStackSlot other = (VirtualStackSlot) obj;
if (id != other.id) {
return false;
}
return true;
}
}

View File

@ -18,10 +18,10 @@
* if you need additional information or have any questions.
*/
/**
* Package that defines the interface between a Java application that wants to install code and the
* runtime. The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider}
* interface. The method
* {@link jdk.vm.ci.code.CodeCacheProvider#addMethod(jdk.vm.ci.meta.ResolvedJavaMethod, CompilationResult, jdk.vm.ci.meta.SpeculationLog, InstalledCode)}
* can be used to install code for a given method.
* Package that defines the interface between a Java application that wants to install code and the runtime.
* The runtime provides in implementation of the {@link jdk.vm.ci.code.CodeCacheProvider} interface.
* The method {@link jdk.vm.ci.code.CodeCacheProvider#addCode(jdk.vm.ci.meta.ResolvedJavaMethod, CompilationResult, jdk.vm.ci.meta.SpeculationLog, InstalledCode)}
* can be used to install code.
*/
package jdk.vm.ci.code;

View File

@ -22,7 +22,7 @@
*/
package jdk.vm.ci.code.stack;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public interface InspectedFrame {

View File

@ -22,7 +22,7 @@
*/
package jdk.vm.ci.code.stack;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public interface StackIntrospection {

View File

@ -22,7 +22,8 @@
*/
package jdk.vm.ci.common;
import java.util.*;
import java.util.ArrayList;
import java.util.Locale;
/**
* Indicates a condition in JVMCI related code that should never occur during normal operation.

View File

@ -1,50 +0,0 @@
/*
* Copyright (c) 2015, 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.compiler;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.options.*;
public interface Compiler {
int INVOCATION_ENTRY_BCI = -1;
@Option(help = "", type = OptionType.Debug) OptionValue<String> PrintFilter = new OptionValue<>(null);
@Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintCompilation = new OptionValue<>(false);
@Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintAfterCompilation = new OptionValue<>(false);
@Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintBailout = new OptionValue<>(false);
@Option(help = "", type = OptionType.Debug) OptionValue<Boolean> ExitVMOnBailout = new OptionValue<>(false);
@Option(help = "", type = OptionType.Debug) OptionValue<Boolean> ExitVMOnException = new OptionValue<>(true);
@Option(help = "", type = OptionType.Debug) OptionValue<Boolean> PrintStackTraceOnException = new OptionValue<>(false);
/**
* Request the compilation of a method by this JVMCI compiler. The compiler should compile the
* method to machine code and install it in the code cache if the compilation is successful.
*
* @param method the method that should be compiled
* @param entryBCI the BCI at which to start compiling where -1 denotes a non-OSR compilation
* request and all other values denote an OSR compilation request
* @param jvmciEnv pointer to native {@code JVMCIEnv} object
* @param id a unique identifier for this compilation
*/
void compileMethod(ResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id);
}

View File

@ -22,18 +22,26 @@
*/
package jdk.vm.ci.hotspot.amd64;
import static jdk.vm.ci.inittimer.InitTimer.*;
import static jdk.vm.ci.inittimer.InitTimer.timer;
import java.util.*;
import java.util.EnumSet;
import jdk.vm.ci.amd64.*;
import jdk.vm.ci.code.*;
import jdk.vm.ci.compiler.*;
import jdk.vm.ci.hotspot.*;
import jdk.vm.ci.inittimer.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.runtime.*;
import jdk.vm.ci.service.*;
import jdk.vm.ci.amd64.AMD64;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.code.stack.StackIntrospection;
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.inittimer.InitTimer;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.runtime.JVMCIBackend;
import jdk.vm.ci.service.ServiceProvider;
@ServiceProvider(HotSpotJVMCIBackendFactory.class)
public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory {
@ -68,6 +76,9 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
if ((config.x86CPUFeatures & config.cpuLZCNT) != 0) {
features.add(AMD64.CPUFeature.LZCNT);
}
if ((config.x86CPUFeatures & config.cpuERMS) != 0) {
features.add(AMD64.CPUFeature.ERMS);
}
if ((config.x86CPUFeatures & config.cpuAVX) != 0) {
features.add(AMD64.CPUFeature.AVX);
}
@ -77,12 +88,42 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
if ((config.x86CPUFeatures & config.cpuAES) != 0) {
features.add(AMD64.CPUFeature.AES);
}
if ((config.x86CPUFeatures & config.cpuERMS) != 0) {
features.add(AMD64.CPUFeature.ERMS);
if ((config.x86CPUFeatures & config.cpu3DNOWPREFETCH) != 0) {
features.add(AMD64.CPUFeature.AMD_3DNOW_PREFETCH);
}
if ((config.x86CPUFeatures & config.cpuBMI1) != 0) {
features.add(AMD64.CPUFeature.BMI1);
}
if ((config.x86CPUFeatures & config.cpuBMI2) != 0) {
features.add(AMD64.CPUFeature.BMI2);
}
if ((config.x86CPUFeatures & config.cpuRTM) != 0) {
features.add(AMD64.CPUFeature.RTM);
}
if ((config.x86CPUFeatures & config.cpuADX) != 0) {
features.add(AMD64.CPUFeature.ADX);
}
if ((config.x86CPUFeatures & config.cpuAVX512F) != 0) {
features.add(AMD64.CPUFeature.AVX512F);
}
if ((config.x86CPUFeatures & config.cpuAVX512DQ) != 0) {
features.add(AMD64.CPUFeature.AVX512DQ);
}
if ((config.x86CPUFeatures & config.cpuAVX512PF) != 0) {
features.add(AMD64.CPUFeature.AVX512PF);
}
if ((config.x86CPUFeatures & config.cpuAVX512ER) != 0) {
features.add(AMD64.CPUFeature.AVX512ER);
}
if ((config.x86CPUFeatures & config.cpuAVX512CD) != 0) {
features.add(AMD64.CPUFeature.AVX512CD);
}
if ((config.x86CPUFeatures & config.cpuAVX512BW) != 0) {
features.add(AMD64.CPUFeature.AVX512BW);
}
if ((config.x86CPUFeatures & config.cpuAVX512VL) != 0) {
features.add(AMD64.CPUFeature.AVX512VL);
}
return features;
}
@ -97,12 +138,12 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
return flags;
}
protected TargetDescription createTarget(HotSpotVMConfig config, CompilerFactory compilerFactory) {
protected TargetDescription createTarget(HotSpotVMConfig config) {
final int stackFrameAlignment = 16;
final int implicitNullCheckLimit = 4096;
final boolean inlineObjects = true;
Architecture arch = new AMD64(computeFeatures(config), computeFlags(config));
return new TargetDescription(compilerFactory.initializeArchitecture(arch), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
return new TargetDescription(arch, true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
}
protected HotSpotConstantReflectionProvider createConstantReflection(HotSpotJVMCIRuntimeProvider runtime) {
@ -132,15 +173,16 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
}
@SuppressWarnings("try")
public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, CompilerFactory compilerFactory, JVMCIBackend host) {
public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, JVMCIBackend host) {
assert host == null;
TargetDescription target = createTarget(runtime.getConfig(), compilerFactory);
TargetDescription target = createTarget(runtime.getConfig());
RegisterConfig regConfig;
HotSpotCodeCacheProvider codeCache;
ConstantReflectionProvider constantReflection;
HotSpotMetaAccessProvider metaAccess;
StackIntrospection stackIntrospection;
try (InitTimer t = timer("create providers")) {
try (InitTimer rt = timer("create MetaAccess provider")) {
metaAccess = createMetaAccess(runtime);
@ -154,13 +196,16 @@ public class AMD64HotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
try (InitTimer rt = timer("create ConstantReflection provider")) {
constantReflection = createConstantReflection(runtime);
}
try (InitTimer rt = timer("create StackIntrospection provider")) {
stackIntrospection = new HotSpotStackIntrospection(runtime);
}
}
try (InitTimer rt = timer("instantiate backend")) {
return createBackend(metaAccess, codeCache, constantReflection);
return createBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}
protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection) {
return new JVMCIBackend(metaAccess, codeCache, constantReflection);
protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, ConstantReflectionProvider constantReflection, StackIntrospection stackIntrospection) {
return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}

View File

@ -22,16 +22,47 @@
*/
package jdk.vm.ci.hotspot.amd64;
import static jdk.vm.ci.amd64.AMD64.*;
import static jdk.vm.ci.amd64.AMD64.r12;
import static jdk.vm.ci.amd64.AMD64.r15;
import static jdk.vm.ci.amd64.AMD64.r8;
import static jdk.vm.ci.amd64.AMD64.r9;
import static jdk.vm.ci.amd64.AMD64.rax;
import static jdk.vm.ci.amd64.AMD64.rcx;
import static jdk.vm.ci.amd64.AMD64.rdi;
import static jdk.vm.ci.amd64.AMD64.rdx;
import static jdk.vm.ci.amd64.AMD64.rsi;
import static jdk.vm.ci.amd64.AMD64.rsp;
import static jdk.vm.ci.amd64.AMD64.xmm0;
import static jdk.vm.ci.amd64.AMD64.xmm1;
import static jdk.vm.ci.amd64.AMD64.xmm2;
import static jdk.vm.ci.amd64.AMD64.xmm3;
import static jdk.vm.ci.amd64.AMD64.xmm4;
import static jdk.vm.ci.amd64.AMD64.xmm5;
import static jdk.vm.ci.amd64.AMD64.xmm6;
import static jdk.vm.ci.amd64.AMD64.xmm7;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import jdk.vm.ci.amd64.*;
import jdk.vm.ci.code.*;
import jdk.vm.ci.code.CallingConvention.*;
import jdk.vm.ci.common.*;
import jdk.vm.ci.hotspot.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.CallingConvention.Type;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterAttributes;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.meta.Value;
public class AMD64HotSpotRegisterConfig implements RegisterConfig {
@ -86,28 +117,30 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
*/
private final boolean needsNativeStackHomeSpace;
private static Register[] initAllocatable(boolean reserveForHeapBase) {
Register[] registers = null;
// @formatter:off
if (reserveForHeapBase) {
registers = new Register[] {
rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, r10, r11, /*r12,*/ r13, r14, /*r15, */
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
};
} else {
registers = new Register[] {
rax, rbx, rcx, rdx, /*rsp,*/ rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, /*r15, */
xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7,
xmm8, xmm9, xmm10, xmm11, xmm12, xmm13, xmm14, xmm15
};
private static Register[] initAllocatable(Architecture arch, boolean reserveForHeapBase) {
Register[] allRegisters = arch.getAvailableValueRegisters();
Register[] registers = new Register[allRegisters.length - (reserveForHeapBase ? 3 : 2)];
int idx = 0;
for (Register reg : allRegisters) {
if (reg.equals(rsp) || reg.equals(r15)) {
// skip stack pointer and thread register
continue;
}
if (reserveForHeapBase && reg.equals(r12)) {
// skip heap base register
continue;
}
registers[idx++] = reg;
}
// @formatter:on
assert idx == registers.length;
return registers;
}
public AMD64HotSpotRegisterConfig(Architecture architecture, HotSpotVMConfig config) {
this(architecture, config, initAllocatable(config.useCompressedOops));
this(architecture, config, initAllocatable(architecture, config.useCompressedOops));
assert callerSaved.length >= allocatable.length;
}
@ -125,7 +158,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
this.needsNativeStackHomeSpace = false;
}
this.allocatable = allocatable.clone();
this.allocatable = allocatable;
Set<Register> callerSaveSet = new HashSet<>();
Collections.addAll(callerSaveSet, allocatable);
Collections.addAll(callerSaveSet, xmmParameterRegisters);
@ -134,7 +167,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
callerSaved = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
allAllocatableAreCallerSaved = true;
attributesMap = RegisterAttributes.createMap(this, AMD64.allRegisters);
attributesMap = RegisterAttributes.createMap(this, architecture.getRegisters());
}
@Override
@ -221,7 +254,7 @@ public class AMD64HotSpotRegisterConfig implements RegisterConfig {
if (locations[i] == null) {
LIRKind lirKind = target.getLIRKind(kind);
locations[i] = StackSlot.get(lirKind, currentStackOffset, !type.out);
currentStackOffset += Math.max(target.getSizeInBytes(lirKind.getPlatformKind()), target.wordSize);
currentStackOffset += Math.max(lirKind.getPlatformKind().getSizeInBytes(), target.wordSize);
}
}

View File

@ -22,28 +22,36 @@
*/
package jdk.vm.ci.hotspot.sparc;
import static jdk.vm.ci.inittimer.InitTimer.*;
import static jdk.vm.ci.inittimer.InitTimer.timer;
import java.util.*;
import java.util.EnumSet;
import jdk.vm.ci.code.*;
import jdk.vm.ci.compiler.*;
import jdk.vm.ci.hotspot.*;
import jdk.vm.ci.inittimer.*;
import jdk.vm.ci.runtime.*;
import jdk.vm.ci.service.*;
import jdk.vm.ci.sparc.*;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.code.stack.StackIntrospection;
import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
import jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider;
import jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider;
import jdk.vm.ci.hotspot.HotSpotMetaAccessProvider;
import jdk.vm.ci.hotspot.HotSpotStackIntrospection;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.inittimer.InitTimer;
import jdk.vm.ci.runtime.JVMCIBackend;
import jdk.vm.ci.service.ServiceProvider;
import jdk.vm.ci.sparc.SPARC;
import jdk.vm.ci.sparc.SPARC.CPUFeature;
@ServiceProvider(HotSpotJVMCIBackendFactory.class)
public class SPARCHotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFactory {
protected TargetDescription createTarget(HotSpotVMConfig config, CompilerFactory compilerFactory) {
protected TargetDescription createTarget(HotSpotVMConfig config) {
final int stackFrameAlignment = 16;
final int implicitNullCheckLimit = 4096;
final boolean inlineObjects = false;
Architecture arch = new SPARC(computeFeatures(config));
return new TargetDescription(compilerFactory.initializeArchitecture(arch), true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
return new TargetDescription(arch, true, stackFrameAlignment, implicitNullCheckLimit, inlineObjects);
}
protected HotSpotCodeCacheProvider createCodeCache(HotSpotJVMCIRuntimeProvider runtime, TargetDescription target, RegisterConfig regConfig) {
@ -64,8 +72,62 @@ public class SPARCHotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
if ((config.sparcFeatures & config.cbcondInstructions) != 0) {
features.add(CPUFeature.CBCOND);
}
if (config.useBlockZeroing) {
features.add(CPUFeature.BLOCK_ZEROING);
if ((config.sparcFeatures & config.v8Instructions) != 0) {
features.add(CPUFeature.V8);
}
if ((config.sparcFeatures & config.hardwareMul32) != 0) {
features.add(CPUFeature.HARDWARE_MUL32);
}
if ((config.sparcFeatures & config.hardwareDiv32) != 0) {
features.add(CPUFeature.HARDWARE_DIV32);
}
if ((config.sparcFeatures & config.hardwareFsmuld) != 0) {
features.add(CPUFeature.HARDWARE_FSMULD);
}
if ((config.sparcFeatures & config.hardwarePopc) != 0) {
features.add(CPUFeature.HARDWARE_POPC);
}
if ((config.sparcFeatures & config.v9Instructions) != 0) {
features.add(CPUFeature.V9);
}
if ((config.sparcFeatures & config.sun4v) != 0) {
features.add(CPUFeature.SUN4V);
}
if ((config.sparcFeatures & config.blkInitInstructions) != 0) {
features.add(CPUFeature.BLK_INIT_INSTRUCTIONS);
}
if ((config.sparcFeatures & config.fmafInstructions) != 0) {
features.add(CPUFeature.FMAF);
}
if ((config.sparcFeatures & config.fmauInstructions) != 0) {
features.add(CPUFeature.FMAU);
}
if ((config.sparcFeatures & config.sparc64Family) != 0) {
features.add(CPUFeature.SPARC64_FAMILY);
}
if ((config.sparcFeatures & config.mFamily) != 0) {
features.add(CPUFeature.M_FAMILY);
}
if ((config.sparcFeatures & config.tFamily) != 0) {
features.add(CPUFeature.T_FAMILY);
}
if ((config.sparcFeatures & config.t1Model) != 0) {
features.add(CPUFeature.T1_MODEL);
}
if ((config.sparcFeatures & config.sparc5Instructions) != 0) {
features.add(CPUFeature.SPARC5);
}
if ((config.sparcFeatures & config.aesInstructions) != 0) {
features.add(CPUFeature.SPARC64_FAMILY);
}
if ((config.sparcFeatures & config.sha1Instruction) != 0) {
features.add(CPUFeature.SHA1);
}
if ((config.sparcFeatures & config.sha256Instruction) != 0) {
features.add(CPUFeature.SHA256);
}
if ((config.sparcFeatures & config.sha512Instruction) != 0) {
features.add(CPUFeature.SHA512);
}
return features;
}
@ -81,20 +143,22 @@ public class SPARCHotSpotJVMCIBackendFactory implements HotSpotJVMCIBackendFacto
}
@SuppressWarnings("try")
public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, CompilerFactory compilerFactory, JVMCIBackend host) {
public JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, JVMCIBackend host) {
assert host == null;
TargetDescription target = createTarget(runtime.getConfig(), compilerFactory);
TargetDescription target = createTarget(runtime.getConfig());
HotSpotMetaAccessProvider metaAccess = new HotSpotMetaAccessProvider(runtime);
RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target, runtime.getConfig());
RegisterConfig regConfig = new SPARCHotSpotRegisterConfig(target.arch, runtime.getConfig());
HotSpotCodeCacheProvider codeCache = createCodeCache(runtime, target, regConfig);
HotSpotConstantReflectionProvider constantReflection = new HotSpotConstantReflectionProvider(runtime);
StackIntrospection stackIntrospection = new HotSpotStackIntrospection(runtime);
try (InitTimer rt = timer("instantiate backend")) {
return createBackend(metaAccess, codeCache, constantReflection);
return createBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}
protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, HotSpotConstantReflectionProvider constantReflection) {
return new JVMCIBackend(metaAccess, codeCache, constantReflection);
protected JVMCIBackend createBackend(HotSpotMetaAccessProvider metaAccess, HotSpotCodeCacheProvider codeCache, HotSpotConstantReflectionProvider constantReflection,
StackIntrospection stackIntrospection) {
return new JVMCIBackend(metaAccess, codeCache, constantReflection, stackIntrospection);
}
}

View File

@ -22,16 +22,72 @@
*/
package jdk.vm.ci.hotspot.sparc;
import static jdk.vm.ci.sparc.SPARC.*;
import static jdk.vm.ci.code.CallingConvention.Type.JavaCall;
import static jdk.vm.ci.code.CallingConvention.Type.JavaCallee;
import static jdk.vm.ci.code.CallingConvention.Type.NativeCall;
import static jdk.vm.ci.meta.JavaKind.Void;
import static jdk.vm.ci.meta.Value.ILLEGAL;
import static jdk.vm.ci.sparc.SPARC.REGISTER_SAFE_AREA_SIZE;
import static jdk.vm.ci.sparc.SPARC.d0;
import static jdk.vm.ci.sparc.SPARC.d2;
import static jdk.vm.ci.sparc.SPARC.d4;
import static jdk.vm.ci.sparc.SPARC.d6;
import static jdk.vm.ci.sparc.SPARC.f0;
import static jdk.vm.ci.sparc.SPARC.f1;
import static jdk.vm.ci.sparc.SPARC.f2;
import static jdk.vm.ci.sparc.SPARC.f3;
import static jdk.vm.ci.sparc.SPARC.f4;
import static jdk.vm.ci.sparc.SPARC.f5;
import static jdk.vm.ci.sparc.SPARC.f6;
import static jdk.vm.ci.sparc.SPARC.f7;
import static jdk.vm.ci.sparc.SPARC.g0;
import static jdk.vm.ci.sparc.SPARC.g2;
import static jdk.vm.ci.sparc.SPARC.g6;
import static jdk.vm.ci.sparc.SPARC.i0;
import static jdk.vm.ci.sparc.SPARC.i1;
import static jdk.vm.ci.sparc.SPARC.i2;
import static jdk.vm.ci.sparc.SPARC.i3;
import static jdk.vm.ci.sparc.SPARC.i4;
import static jdk.vm.ci.sparc.SPARC.i5;
import static jdk.vm.ci.sparc.SPARC.i6;
import static jdk.vm.ci.sparc.SPARC.i7;
import static jdk.vm.ci.sparc.SPARC.l0;
import static jdk.vm.ci.sparc.SPARC.l1;
import static jdk.vm.ci.sparc.SPARC.l2;
import static jdk.vm.ci.sparc.SPARC.l3;
import static jdk.vm.ci.sparc.SPARC.l4;
import static jdk.vm.ci.sparc.SPARC.l5;
import static jdk.vm.ci.sparc.SPARC.l6;
import static jdk.vm.ci.sparc.SPARC.l7;
import static jdk.vm.ci.sparc.SPARC.o0;
import static jdk.vm.ci.sparc.SPARC.o1;
import static jdk.vm.ci.sparc.SPARC.o2;
import static jdk.vm.ci.sparc.SPARC.o3;
import static jdk.vm.ci.sparc.SPARC.o4;
import static jdk.vm.ci.sparc.SPARC.o5;
import static jdk.vm.ci.sparc.SPARC.sp;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import jdk.vm.ci.code.*;
import jdk.vm.ci.code.CallingConvention.*;
import jdk.vm.ci.common.*;
import jdk.vm.ci.hotspot.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.sparc.*;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CallingConvention;
import jdk.vm.ci.code.CallingConvention.Type;
import jdk.vm.ci.code.Register;
import jdk.vm.ci.code.RegisterAttributes;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotVMConfig;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.PlatformKind;
import jdk.vm.ci.sparc.SPARC;
public class SPARCHotSpotRegisterConfig implements RegisterConfig {
@ -41,6 +97,11 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
private final RegisterAttributes[] attributesMap;
/**
* Does native code (C++ code) spill arguments in registers to the parent frame?
*/
private final boolean addNativeRegisterArgumentSlots;
@Override
public Register[] getAllocatableRegisters() {
return allocatable.clone();
@ -50,22 +111,9 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
ArrayList<Register> list = new ArrayList<>();
for (Register reg : registers) {
if (architecture.canStoreValue(reg.getRegisterCategory(), kind)) {
// Special treatment for double precision
// TODO: This is wasteful it uses only half of the registers as float.
if (kind == JavaKind.Double) {
if (reg.getRegisterCategory().equals(FPUd)) {
list.add(reg);
}
} else if (kind == JavaKind.Float) {
if (reg.getRegisterCategory().equals(FPUs)) {
list.add(reg);
}
} else {
list.add(reg);
}
list.add(reg);
}
}
Register[] ret = list.toArray(new Register[list.size()]);
return ret;
}
@ -78,76 +126,57 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
private final Register[] cpuCallerParameterRegisters = {o0, o1, o2, o3, o4, o5};
private final Register[] cpuCalleeParameterRegisters = {i0, i1, i2, i3, i4, i5};
private final Register[] fpuParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
private final Register[] fpuFloatParameterRegisters = {f0, f1, f2, f3, f4, f5, f6, f7};
private final Register[] fpuDoubleParameterRegisters = {d0, null, d2, null, d4, null, d6, null};
// @formatter:off
private final Register[] callerSaveRegisters =
{g1, g2, g3, g4, g5, g6, g7,
o0, o1, o2, o3, o4, o5, o7,
f0, f1, f2, f3, f4, f5, f6, f7,
f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23,
f24, f25, f26, f27, f28, f29, f30, f31,
d32, d34, d36, d38, d40, d42, d44, d46,
d48, d50, d52, d54, d56, d58, d60, d62};
// @formatter:on
private final Register[] callerSaveRegisters;
/**
* Registers saved by the callee. This lists all L and I registers which are saved in the
* register window.
*/
private final Register[] calleeSaveRegisters = {l0, l1, l2, l3, l4, l5, l6, l7, i0, i1, i2, i3, i4, i5, i6, i7};
private final Register[] calleeSaveRegisters = {
l0, l1, l2, l3, l4, l5, l6, l7,
i0, i1, i2, i3, i4, i5, i6, i7};
// @formatter:on
private static Register[] initAllocatable(boolean reserveForHeapBase) {
Register[] registers = null;
if (reserveForHeapBase) {
// @formatter:off
registers = new Register[]{
// TODO this is not complete
// o7 cannot be used as register because it is always overwritten on call
// and the current register handler would ignore this fact if the called
// method still does not modify registers, in fact o7 is modified by the Call instruction
// There would be some extra handlin necessary to be able to handle the o7 properly for local usage
g1, g4, g5,
o0, o1, o2, o3, o4, o5, /*o6,o7,*/
l0, l1, l2, l3, l4, l5, l6, l7,
i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/
//f0, f1, f2, f3, f4, f5, f6, f7,
f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23,
f24, f25, f26, f27, f28, f29, f30, f31,
d32, d34, d36, d38, d40, d42, d44, d46,
d48, d50, d52, d54, d56, d58, d60, d62
};
// @formatter:on
} else {
// @formatter:off
registers = new Register[]{
// TODO this is not complete
g1, g4, g5,
o0, o1, o2, o3, o4, o5, /*o6, o7,*/
l0, l1, l2, l3, l4, l5, l6, l7,
i0, i1, i2, i3, i4, i5, /*i6,*/ /*i7,*/
// f0, f1, f2, f3, f4, f5, f6, f7
f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, f18, f19, f20, f21, f22, f23,
f24, f25, f26, f27, f28, f29, f30, f31,
d32, d34, d36, d38, d40, d42, d44, d46,
d48, d50, d52, d54, d56, d58, d60, d62
};
// @formatter:on
private static Register[] initAllocatable(Architecture arch, boolean reserveForHeapBase) {
Register[] allRegisters = arch.getAvailableValueRegisters();
Register[] registers = new Register[allRegisters.length - (reserveForHeapBase ? 4 : 3)];
int idx = 0;
for (Register reg : allRegisters) {
if (reg.equals(sp) || reg.equals(g2) || reg.equals(g0)) {
// skip g0, stack pointer and thread register
continue;
}
if (reserveForHeapBase && reg.equals(g6)) {
// skip heap base register
continue;
}
registers[idx++] = reg;
}
assert idx == registers.length;
return registers;
}
public SPARCHotSpotRegisterConfig(TargetDescription target, HotSpotVMConfig config) {
this(target, initAllocatable(config.useCompressedOops));
public SPARCHotSpotRegisterConfig(Architecture arch, HotSpotVMConfig config) {
this(arch, initAllocatable(arch, config.useCompressedOops), config);
}
public SPARCHotSpotRegisterConfig(TargetDescription target, Register[] allocatable) {
this.architecture = target.arch;
public SPARCHotSpotRegisterConfig(Architecture arch, Register[] allocatable, HotSpotVMConfig config) {
this.architecture = arch;
this.allocatable = allocatable.clone();
this.addNativeRegisterArgumentSlots = config.linuxOs;
HashSet<Register> callerSaveSet = new HashSet<>();
Collections.addAll(callerSaveSet, arch.getAvailableValueRegisters());
for (Register cs : calleeSaveRegisters) {
callerSaveSet.remove(cs);
}
this.callerSaveRegisters = callerSaveSet.toArray(new Register[callerSaveSet.size()]);
attributesMap = RegisterAttributes.createMap(this, SPARC.allRegisters);
}
@ -172,21 +201,31 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
@Override
public CallingConvention getCallingConvention(Type type, JavaType returnType, JavaType[] parameterTypes, TargetDescription target, boolean stackOnly) {
if (type == Type.JavaCall || type == Type.NativeCall) {
if (type == JavaCall || type == NativeCall) {
return callingConvention(cpuCallerParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
}
if (type == Type.JavaCallee) {
if (type == JavaCallee) {
return callingConvention(cpuCalleeParameterRegisters, returnType, parameterTypes, type, target, stackOnly);
}
throw JVMCIError.shouldNotReachHere();
}
public Register[] getCallingConventionRegisters(Type type, JavaKind kind) {
if (architecture.canStoreValue(FPUs, kind) || architecture.canStoreValue(FPUd, kind)) {
return fpuParameterRegisters;
switch (kind) {
case Boolean:
case Byte:
case Short:
case Char:
case Int:
case Long:
case Object:
return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
case Double:
case Float:
return fpuFloatParameterRegisters;
default:
throw JVMCIError.shouldNotReachHere("Unknown JavaKind " + kind);
}
assert architecture.canStoreValue(CPU, kind);
return type == Type.JavaCallee ? cpuCalleeParameterRegisters : cpuCallerParameterRegisters;
}
private CallingConvention callingConvention(Register[] generalParameterRegisters, JavaType returnType, JavaType[] parameterTypes, Type type, TargetDescription target, boolean stackOnly) {
@ -213,7 +252,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
}
break;
case Double:
if (!stackOnly && currentFloating < fpuParameterRegisters.length) {
if (!stackOnly && currentFloating < fpuFloatParameterRegisters.length) {
if (currentFloating % 2 != 0) {
// Make register number even to be a double reg
currentFloating++;
@ -224,8 +263,8 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
}
break;
case Float:
if (!stackOnly && currentFloating < fpuParameterRegisters.length) {
Register register = fpuParameterRegisters[currentFloating++];
if (!stackOnly && currentFloating < fpuFloatParameterRegisters.length) {
Register register = fpuFloatParameterRegisters[currentFloating++];
locations[i] = register.asValue(target.getLIRKind(kind));
}
break;
@ -234,20 +273,27 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
}
if (locations[i] == null) {
LIRKind lirKind = target.getLIRKind(kind);
// Stack slot is always aligned to its size in bytes but minimum wordsize
int typeSize = SPARC.spillSlotSize(target, kind);
int typeSize = lirKind.getPlatformKind().getSizeInBytes();
currentStackOffset = roundUp(currentStackOffset, typeSize);
int slotOffset = currentStackOffset + SPARC.REGISTER_SAFE_AREA_SIZE;
locations[i] = StackSlot.get(target.getLIRKind(kind.getStackKind()), slotOffset, !type.out);
int slotOffset = currentStackOffset + REGISTER_SAFE_AREA_SIZE;
locations[i] = StackSlot.get(lirKind, slotOffset, !type.out);
currentStackOffset += typeSize;
}
}
JavaKind returnKind = returnType == null ? JavaKind.Void : returnType.getJavaKind();
AllocatableValue returnLocation = returnKind == JavaKind.Void ? Value.ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
// Space where callee may spill outgoing parameters o0...o5
int lowerOutgoingSpace = Math.min(locations.length, 6) * target.wordSize;
return new CallingConvention(currentStackOffset + lowerOutgoingSpace, returnLocation, locations);
JavaKind returnKind = returnType == null ? Void : returnType.getJavaKind();
AllocatableValue returnLocation = returnKind == Void ? ILLEGAL : getReturnRegister(returnKind, type).asValue(target.getLIRKind(returnKind.getStackKind()));
int outArgSpillArea;
if (type == NativeCall && addNativeRegisterArgumentSlots) {
// Space for native callee which may spill our outgoing arguments
outArgSpillArea = Math.min(locations.length, generalParameterRegisters.length) * target.wordSize;
} else {
outArgSpillArea = 0;
}
return new CallingConvention(currentStackOffset + outArgSpillArea, returnLocation, locations);
}
private static int roundUp(int number, int mod) {
@ -256,7 +302,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
@Override
public Register getReturnRegister(JavaKind kind) {
return getReturnRegister(kind, Type.JavaCallee);
return getReturnRegister(kind, JavaCallee);
}
private static Register getReturnRegister(JavaKind kind, Type type) {
@ -268,7 +314,7 @@ public class SPARCHotSpotRegisterConfig implements RegisterConfig {
case Int:
case Long:
case Object:
return type == Type.JavaCallee ? i0 : o0;
return type == JavaCallee ? i0 : o0;
case Float:
return f0;
case Double:

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015, 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 static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.inittimer.InitTimer.timer;
import java.lang.reflect.Constructor;
@ -36,7 +37,6 @@ import jdk.vm.ci.inittimer.InitTimer;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.SpeculationLog;
import sun.misc.Unsafe;
/**
@ -44,7 +44,7 @@ import sun.misc.Unsafe;
* pointer as an argument (e.g., {@link #getSymbol(long)}) is undefined if the argument does not
* denote a valid native object.
*/
public final class CompilerToVM {
final class CompilerToVM {
/**
* Initializes the native part of the JVMCI runtime.
*/
@ -61,6 +61,14 @@ public final class CompilerToVM {
}
}
/**
* Gets the {@link CompilerToVM} instance associated with the singleton
* {@link HotSpotJVMCIRuntime} instance.
*/
public static CompilerToVM compilerToVM() {
return runtime().getCompilerToVM();
}
/**
* Copies the original bytecode of {@code method} into a new byte array and returns it.
*
@ -301,7 +309,7 @@ public final class CompilerToVM {
* {@link HotSpotVMConfig#codeInstallResultDependenciesFailed} or
* {@link HotSpotVMConfig#codeInstallResultDependenciesInvalid}.
*/
public native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog);
native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, HotSpotSpeculationLog speculationLog);
public native int getMetadata(TargetDescription target, HotSpotCompiledCode compiledCode, HotSpotMetaData metaData);
@ -317,18 +325,18 @@ public final class CompilerToVM {
* @param timeUnitsPerSecond the granularity of the units for the {@code time} value
* @param installedCode the nmethod installed as a result of the compilation
*/
public synchronized native void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethodImpl method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond,
synchronized native void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethodImpl method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond,
InstalledCode installedCode);
/**
* Resets all compilation statistics.
*/
public native void resetCompilationStatistics();
native void resetCompilationStatistics();
/**
* Initializes the fields of {@code config}.
*/
native long initializeConfiguration();
native long initializeConfiguration(HotSpotVMConfig config);
/**
* Resolves the implementation of {@code method} for virtual dispatches on objects of dynamic
@ -367,7 +375,7 @@ public final class CompilerToVM {
* @param address an address that may be called from any code in the code cache
* @return -1 if {@code address == 0}
*/
public native long getMaxCallTargetOffset(long address);
native long getMaxCallTargetOffset(long address);
/**
* Gets a textual disassembly of {@code codeBlob}.
@ -376,7 +384,7 @@ public final class CompilerToVM {
* {@code codeBlob} could not be disassembled for some reason
*/
// The HotSpot disassembler seems not to be thread safe so it's better to synchronize its usage
public synchronized native String disassembleCodeBlob(long codeBlob);
synchronized native String disassembleCodeBlob(InstalledCode installedCode);
/**
* Gets a stack trace element for {@code method} at bytecode index {@code bci}.
@ -454,12 +462,12 @@ public final class CompilerToVM {
* Invalidates {@code installedCode} such that {@link InvalidInstalledCodeException} will be
* raised the next time {@code installedCode} is executed.
*/
public native void invalidateInstalledCode(InstalledCode installedCode);
native void invalidateInstalledCode(InstalledCode installedCode);
/**
* Collects the current values of all JVMCI benchmark counters, summed up over all threads.
*/
public native long[] collectCounters();
native long[] collectCounters();
/**
* Determines if {@code metaspaceMethodData} is mature.
@ -489,7 +497,7 @@ public final class CompilerToVM {
* @param methods the methods to look for, where {@code null} means that any frame is returned
* @return the frame, or {@code null} if the end of the stack was reached during the search
*/
public native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, HotSpotResolvedJavaMethodImpl[] methods, int initialSkip);
native HotSpotStackFrameReference getNextStackFrame(HotSpotStackFrameReference frame, ResolvedJavaMethod[] methods, int initialSkip);
/**
* Materializes all virtual objects within {@code stackFrame} updates its locals.
@ -512,30 +520,34 @@ public final class CompilerToVM {
/**
* Determines if debug info should also be emitted at non-safepoint locations.
*/
public native boolean shouldDebugNonSafepoints();
native boolean shouldDebugNonSafepoints();
/**
* Writes {@code length} bytes from {@code bytes} starting at offset {@code offset} to the
* HotSpot's log stream.
*
* @exception NullPointerException if <code>bytes</code> is <code>null</code>.
* @exception NullPointerException if {@code bytes == null}
* @exception IndexOutOfBoundsException if copying would cause access of data outside array
* bounds.
* bounds
*/
public native void writeDebugOutput(byte[] bytes, int offset, int length);
native void writeDebugOutput(byte[] bytes, int offset, int length);
/**
* Flush HotSpot's log stream.
*/
public native void flushDebugOutput();
native void flushDebugOutput();
/**
* Read a value representing a metaspace Method* and return the
* {@link HotSpotResolvedJavaMethodImpl} wrapping it. This method does no checking that the
* location actually contains a valid Method*. If the {@code base} object is a
* Read a HotSpot Method* value from the memory location described by {@code base} plus
* {@code displacement} and return the {@link HotSpotResolvedJavaMethodImpl} wrapping it. This
* method does no checking that the memory location actually contains a valid pointer and may
* crash the VM if an invalid location is provided. If the {@code base} is null then
* {@code displacement} is used by itself. If {@code base} is a
* {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
* {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
* and used as the base. Otherwise the object itself is used as the base.
* and added to {@code displacement}. Any other non-null object type causes an
* {@link IllegalArgumentException} to be thrown.
*
* @param base an object to read from or null
* @param displacement
@ -544,12 +556,14 @@ public final class CompilerToVM {
native HotSpotResolvedJavaMethodImpl getResolvedJavaMethod(Object base, long displacement);
/**
* Read a value representing a metaspace ConstantPool* and return the
* {@link HotSpotConstantPool} wrapping it. This method does no checking that the location
* actually contains a valid ConstantPool*. If the {@code base} object is a
* {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
* {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
* and used as the base. Otherwise the object itself is used as the base.
* Read a HotSpot ConstantPool* value from the memory location described by {@code base} plus
* {@code displacement} and return the {@link HotSpotConstantPool} wrapping it. This method does
* no checking that the memory location actually contains a valid pointer and may crash the VM
* if an invalid location is provided. If the {@code base} is null then {@code displacement} is
* used by itself. If {@code base} is a {@link HotSpotResolvedJavaMethodImpl},
* {@link HotSpotConstantPool} or {@link HotSpotResolvedObjectTypeImpl} then the metaspace
* pointer is fetched from that object and added to {@code displacement}. Any other non-null
* object type causes an {@link IllegalArgumentException} to be thrown.
*
* @param base an object to read from or null
* @param displacement
@ -558,12 +572,15 @@ public final class CompilerToVM {
native HotSpotConstantPool getConstantPool(Object base, long displacement);
/**
* Read a value representing a metaspace Klass* and return the
* {@link HotSpotResolvedObjectTypeImpl} wrapping it. The method does no checking that the
* location actually contains a valid Klass*. If the {@code base} object is a
* Read a HotSpot Klass* value from the memory location described by {@code base} plus
* {@code displacement} and return the {@link HotSpotResolvedObjectTypeImpl} wrapping it. This
* method does no checking that the memory location actually contains a valid pointer and may
* crash the VM if an invalid location is provided. If the {@code base} is null then
* {@code displacement} is used by itself. If {@code base} is a
* {@link HotSpotResolvedJavaMethodImpl}, {@link HotSpotConstantPool} or
* {@link HotSpotResolvedObjectTypeImpl} then the metaspace pointer is fetched from that object
* and used as the base. Otherwise the object itself is used as the base.
* and added to {@code displacement}. Any other non-null object type causes an
* {@link IllegalArgumentException} to be thrown.
*
* @param base an object to read from or null
* @param displacement
@ -571,4 +588,17 @@ public final class CompilerToVM {
* @return null or the resolved method for this location
*/
native HotSpotResolvedObjectTypeImpl getResolvedJavaType(Object base, long displacement, boolean compressed);
/**
* Return the size of the HotSpot ProfileData* pointed at by {@code position}. If
* {@code position} is outside the space of the MethodData then an
* {@link IllegalArgumentException} is thrown. A {@code position} inside the MethodData but that
* isn't pointing at a valid ProfileData will crash the VM.
*
* @param metaspaceMethodData
* @param position
* @return the size of the ProfileData item pointed at by {@code position}
* @throws IllegalArgumentException if an out of range position is given
*/
native int methodDataProfileDataSize(long metaspaceMethodData, int position);
}

View File

@ -22,15 +22,30 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotCompressedNullConstant.*;
import static jdk.vm.ci.hotspot.HotSpotCompressedNullConstant.COMPRESSED_NULL;
import java.lang.reflect.*;
import java.lang.reflect.Field;
import jdk.vm.ci.code.*;
import jdk.vm.ci.code.CompilationResult.*;
import jdk.vm.ci.code.DataSection.*;
import jdk.vm.ci.common.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.code.BailoutException;
import jdk.vm.ci.code.CodeCacheProvider;
import jdk.vm.ci.code.CompilationRequest;
import jdk.vm.ci.code.CompilationResult;
import jdk.vm.ci.code.CompilationResult.Call;
import jdk.vm.ci.code.CompilationResult.ConstantReference;
import jdk.vm.ci.code.CompilationResult.DataPatch;
import jdk.vm.ci.code.CompilationResult.Mark;
import jdk.vm.ci.code.DataSection;
import jdk.vm.ci.code.DataSection.Data;
import jdk.vm.ci.code.DataSection.DataBuilder;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.RegisterConfig;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.SerializableConstant;
import jdk.vm.ci.meta.SpeculationLog;
import jdk.vm.ci.meta.VMConstant;
/**
* HotSpot implementation of {@link CodeCacheProvider}.
@ -98,72 +113,64 @@ public class HotSpotCodeCacheProvider implements CodeCacheProvider {
return runtime.getConfig().runtimeCallStackSize;
}
public InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) {
HotSpotJVMCIRuntime.runtime().notifyInstall(this, installedCode, compResult);
private InstalledCode logOrDump(InstalledCode installedCode, CompilationResult compResult) {
((HotSpotJVMCIRuntime) runtime).notifyInstall(this, installedCode, compResult);
return installedCode;
}
private InstalledCode installCode(CompilationResult compResult, HotSpotCompiledNmethod compiledCode, InstalledCode installedCode, SpeculationLog log) {
int result = runtime.getCompilerToVM().installCode(target, compiledCode, installedCode, log);
if (result != config.codeInstallResultOk) {
String msg = compiledCode.getInstallationFailureMessage();
String resultDesc = config.getCodeInstallResultDescription(result);
if (msg != null) {
msg = String.format("Code installation failed: %s%n%s", resultDesc, msg);
} else {
msg = String.format("Code installation failed: %s", resultDesc);
}
if (result == config.codeInstallResultDependenciesInvalid) {
throw new AssertionError(resultDesc + " " + msg);
}
throw new BailoutException(result != config.codeInstallResultDependenciesFailed, msg);
}
return logOrDump(installedCode, compResult);
}
public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long jvmciEnv, boolean isDefault) {
if (compResult.getId() == -1) {
compResult.setId(method.allocateCompileId(compResult.getEntryBCI()));
}
HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), isDefault);
HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(method, compResult, jvmciEnv);
return installCode(compResult, compiledCode, installedCode, method.getSpeculationLog());
}
@Override
public InstalledCode addMethod(ResolvedJavaMethod method, CompilationResult compResult, SpeculationLog log, InstalledCode predefinedInstalledCode) {
HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
if (compResult.getId() == -1) {
compResult.setId(hotspotMethod.allocateCompileId(compResult.getEntryBCI()));
}
InstalledCode installedCode = predefinedInstalledCode;
public InstalledCode installCode(CompilationRequest compRequest, CompilationResult compResult, InstalledCode installedCode, SpeculationLog log, boolean isDefault) {
HotSpotResolvedJavaMethod method = compRequest != null ? (HotSpotResolvedJavaMethod) compRequest.getMethod() : null;
InstalledCode resultInstalledCode;
if (installedCode == null) {
HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false);
installedCode = code;
if (method == null) {
// Must be a stub
resultInstalledCode = new HotSpotRuntimeStub(compResult.getName());
} else {
resultInstalledCode = new HotSpotNmethod(method, compResult.getName(), isDefault);
}
} else {
resultInstalledCode = installedCode;
}
HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(hotspotMethod, compResult);
return installCode(compResult, compiledCode, installedCode, log);
HotSpotCompiledCode compiledCode;
if (method != null) {
final int id;
final long jvmciEnv;
if (compRequest instanceof HotSpotCompilationRequest) {
HotSpotCompilationRequest hsCompRequest = (HotSpotCompilationRequest) compRequest;
id = hsCompRequest.getId();
jvmciEnv = hsCompRequest.getJvmciEnv();
} else {
id = method.allocateCompileId(compRequest.getEntryBCI());
jvmciEnv = 0L;
}
compiledCode = new HotSpotCompiledNmethod(method, compResult, id, jvmciEnv);
} else {
compiledCode = new HotSpotCompiledCode(compResult);
}
int result = runtime.getCompilerToVM().installCode(target, compiledCode, resultInstalledCode, (HotSpotSpeculationLog) log);
if (result != config.codeInstallResultOk) {
String resultDesc = config.getCodeInstallResultDescription(result);
if (compiledCode instanceof HotSpotCompiledNmethod) {
HotSpotCompiledNmethod compiledNmethod = (HotSpotCompiledNmethod) compiledCode;
String msg = compiledNmethod.getInstallationFailureMessage();
if (msg != null) {
msg = String.format("Code installation failed: %s%n%s", resultDesc, msg);
} else {
msg = String.format("Code installation failed: %s", resultDesc);
}
if (result == config.codeInstallResultDependenciesInvalid) {
throw new AssertionError(resultDesc + " " + msg);
}
throw new BailoutException(result != config.codeInstallResultDependenciesFailed, msg);
} else {
throw new BailoutException("Error installing %s: %s", compResult.getName(), resultDesc);
}
}
return logOrDump(resultInstalledCode, compResult);
}
@Override
public InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult) {
HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method;
return installMethod(hotspotMethod, compResult, 0L, true);
}
public HotSpotNmethod addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) {
HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) method;
if (compResult.getId() == -1) {
compResult.setId(javaMethod.allocateCompileId(compResult.getEntryBCI()));
}
HotSpotNmethod code = new HotSpotNmethod(javaMethod, compResult.getName(), false, true);
HotSpotCompiledNmethod compiled = new HotSpotCompiledNmethod(javaMethod, compResult);
CompilerToVM vm = runtime.getCompilerToVM();
int result = vm.installCode(target, compiled, code, null);
if (result != runtime.getConfig().codeInstallResultOk) {
return null;
}
return code;
public void invalidateInstalledCode(InstalledCode installedCode) {
runtime.getCompilerToVM().invalidateInstalledCode(installedCode);
}
public boolean needsDataPatch(JavaConstant constant) {
@ -176,35 +183,29 @@ public class HotSpotCodeCacheProvider implements CodeCacheProvider {
if (constant instanceof VMConstant) {
VMConstant vmConstant = (VMConstant) constant;
boolean compressed;
long raw;
if (constant instanceof HotSpotObjectConstant) {
HotSpotObjectConstant c = (HotSpotObjectConstant) vmConstant;
if (constant instanceof HotSpotConstant) {
HotSpotConstant c = (HotSpotConstant) vmConstant;
compressed = c.isCompressed();
raw = 0xDEADDEADDEADDEADL;
} else if (constant instanceof HotSpotMetaspaceConstant) {
HotSpotMetaspaceConstant meta = (HotSpotMetaspaceConstant) constant;
compressed = meta.isCompressed();
raw = meta.rawValue();
} else {
throw new JVMCIError(String.valueOf(constant));
}
size = target.getSizeInBytes(compressed ? JavaKind.Int : target.wordKind);
size = compressed ? 4 : target.wordSize;
if (size == 4) {
builder = (buffer, patch) -> {
patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant)));
buffer.putInt((int) raw);
buffer.putInt(0xDEADDEAD);
};
} else {
assert size == 8;
builder = (buffer, patch) -> {
patch.accept(new DataPatch(buffer.position(), new ConstantReference(vmConstant)));
buffer.putLong(raw);
buffer.putLong(0xDEADDEADDEADDEADL);
};
}
} else if (JavaConstant.isNull(constant)) {
boolean compressed = COMPRESSED_NULL.equals(constant);
size = target.getSizeInBytes(compressed ? JavaKind.Int : target.wordKind);
size = compressed ? 4 : target.wordSize;
builder = DataBuilder.zero(size);
} else if (constant instanceof SerializableConstant) {
SerializableConstant s = (SerializableConstant) constant;
@ -250,8 +251,7 @@ public class HotSpotCodeCacheProvider implements CodeCacheProvider {
public String disassemble(InstalledCode code) {
if (code.isValid()) {
long codeBlob = code.getAddress();
return runtime.getCompilerToVM().disassembleCodeBlob(codeBlob);
return runtime.getCompilerToVM().disassembleCodeBlob(code);
}
return null;
}
@ -259,4 +259,35 @@ public class HotSpotCodeCacheProvider implements CodeCacheProvider {
public SpeculationLog createSpeculationLog() {
return new HotSpotSpeculationLog();
}
public long getMaxCallTargetOffset(long address) {
return runtime.getCompilerToVM().getMaxCallTargetOffset(address);
}
public boolean shouldDebugNonSafepoints() {
return runtime.getCompilerToVM().shouldDebugNonSafepoints();
}
/**
* Notifies the VM of statistics for a completed compilation.
*
* @param id the identifier of the compilation
* @param method the method compiled
* @param osr specifies if the compilation was for on-stack-replacement
* @param processedBytecodes the number of bytecodes processed during the compilation, including
* the bytecodes of all inlined methods
* @param time the amount time spent compiling {@code method}
* @param timeUnitsPerSecond the granularity of the units for the {@code time} value
* @param installedCode the nmethod installed as a result of the compilation
*/
public void notifyCompilationStatistics(int id, HotSpotResolvedJavaMethod method, boolean osr, int processedBytecodes, long time, long timeUnitsPerSecond, InstalledCode installedCode) {
runtime.getCompilerToVM().notifyCompilationStatistics(id, (HotSpotResolvedJavaMethodImpl) method, osr, processedBytecodes, time, timeUnitsPerSecond, installedCode);
}
/**
* Resets all compilation statistics.
*/
public void resetCompilationStatistics() {
runtime.getCompilerToVM().resetCompilationStatistics();
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2015, 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.code.CompilationRequest;
/**
* A compilation request with extra HotSpot specific context such as a compilation identifier and
* the address of a {@code JVMCIEnv} object that provides native context for a compilation.
*/
public class HotSpotCompilationRequest extends CompilationRequest {
private final long jvmciEnv;
private final int id;
/**
* Creates a request to compile a method starting at a given BCI and allocates an identifier to
* the request.
*
* @param method the method to be compiled
* @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the
* method's entry point
* @param jvmciEnv address of a native {@code JVMCIEnv} object or 0L
*/
public HotSpotCompilationRequest(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv) {
this(method, entryBCI, jvmciEnv, method.allocateCompileId(entryBCI));
}
/**
* Creates a request to compile a method starting at a given BCI.
*
* @param method the method to be compiled
* @param entryBCI the bytecode index (BCI) at which to start compiling where -1 denotes the
* method's entry point
* @param jvmciEnv address of a native {@code JVMCIEnv} object or 0L
* @param id an identifier for the request
*/
public HotSpotCompilationRequest(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
super(method, entryBCI);
this.jvmciEnv = jvmciEnv;
this.id = id;
}
@Override
public HotSpotResolvedJavaMethod getMethod() {
return (HotSpotResolvedJavaMethod) super.getMethod();
}
/**
* Gets the address of the native {@code JVMCIEnv} object or 0L if no such object exists.
*/
public long getJvmciEnv() {
return jvmciEnv;
}
/**
* Gets the VM allocated identifier for this compilation.
*/
public int getId() {
return id;
}
}

View File

@ -22,12 +22,16 @@
*/
package jdk.vm.ci.hotspot;
import java.nio.*;
import java.util.*;
import java.util.stream.*;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Stream;
import java.util.stream.Stream.Builder;
import jdk.vm.ci.code.*;
import jdk.vm.ci.code.BytecodeFrame;
import jdk.vm.ci.code.CompilationResult;
import jdk.vm.ci.code.CompilationResult.CodeAnnotation;
import jdk.vm.ci.code.CompilationResult.CodeComment;
import jdk.vm.ci.code.CompilationResult.DataPatch;
@ -36,14 +40,15 @@ import jdk.vm.ci.code.CompilationResult.Infopoint;
import jdk.vm.ci.code.CompilationResult.JumpTable;
import jdk.vm.ci.code.CompilationResult.Mark;
import jdk.vm.ci.code.CompilationResult.Site;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.code.DataSection;
import jdk.vm.ci.meta.Assumptions.Assumption;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* A {@link CompilationResult} with additional HotSpot-specific information required for installing
* the code in HotSpot's code cache.
*/
public abstract class HotSpotCompiledCode {
public class HotSpotCompiledCode {
public final String name;
public final Site[] sites;
@ -113,9 +118,7 @@ public abstract class HotSpotCompiledCode {
targetCodeSize = compResult.getTargetCodeSize();
DataSection data = compResult.getDataSection();
if (!data.isFinalized()) {
data.finalizeLayout();
}
data.finalizeLayout();
dataSection = new byte[data.getSectionSize()];
ByteBuffer buffer = ByteBuffer.wrap(dataSection).order(ByteOrder.nativeOrder());
@ -176,4 +179,9 @@ public abstract class HotSpotCompiledCode {
Arrays.sort(result, new SiteComparator());
return result;
}
@Override
public String toString() {
return name;
}
}

View File

@ -22,8 +22,8 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.*;
import jdk.vm.ci.inittimer.*;
import jdk.vm.ci.code.CompilationResult;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
/**
* {@link HotSpotCompiledCode} destined for installation as an nmethod.
@ -32,8 +32,17 @@ public final class HotSpotCompiledNmethod extends HotSpotCompiledCode {
public final HotSpotResolvedJavaMethod method;
public final int entryBCI;
/**
* Compilation identifier.
*/
public final int id;
/**
* Address of a native {@code JVMCIEnv} object or 0L if no such object exists.
*/
public final long jvmciEnv;
public final boolean hasUnsafeAccess;
/**
@ -42,15 +51,11 @@ public final class HotSpotCompiledNmethod extends HotSpotCompiledCode {
*/
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "set by the VM") private String installationFailureMessage;
public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) {
this(method, compResult, 0L);
}
public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long jvmciEnv) {
public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, int id, long jvmciEnv) {
super(compResult);
this.method = method;
this.entryBCI = compResult.getEntryBCI();
this.id = compResult.getId();
this.id = id;
this.jvmciEnv = jvmciEnv;
this.hasUnsafeAccess = compResult.hasUnsafeAccess();
}

View File

@ -22,7 +22,9 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
/**
* The compressed representation of the {@link JavaConstant#NULL_POINTER null constant}.
@ -48,6 +50,14 @@ public final class HotSpotCompressedNullConstant implements JavaConstant, HotSpo
return true;
}
public Constant compress() {
throw new IllegalArgumentException();
}
public Constant uncompress() {
return NULL_POINTER;
}
@Override
public boolean isDefaultForKind() {
return true;

View File

@ -22,7 +22,7 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.Constant;
/**
* Marker interface for hotspot specific constants.
@ -30,4 +30,8 @@ import jdk.vm.ci.meta.*;
public interface HotSpotConstant extends Constant {
boolean isCompressed();
Constant compress();
Constant uncompress();
}

View File

@ -22,18 +22,27 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
import java.lang.invoke.*;
import java.lang.invoke.MethodHandle;
import jdk.vm.ci.common.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaField;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.Signature;
/**
* Implementation of {@link ConstantPool} for HotSpot.
*/
public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, MetaspaceWrapperObject {
final class HotSpotConstantPool implements ConstantPool, HotSpotProxified, MetaspaceWrapperObject {
/**
* Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}.
@ -121,10 +130,6 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
this.tag = tag;
}
private static HotSpotVMConfig config() {
return runtime().getConfig();
}
/**
* Maps JVM_CONSTANT tags to {@link JVM_CONSTANT} values. Using a separate class for lazy
* initialization.
@ -204,7 +209,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
* @return holder for this constant pool
*/
private HotSpotResolvedObjectType getHolder() {
return runtime().getCompilerToVM().getResolvedJavaType(this, runtime().getConfig().constantPoolHolderOffset, false);
return compilerToVM().getResolvedJavaType(this, config().constantPoolHolderOffset, false);
}
/**
@ -224,7 +229,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
} else {
assert opcode == Bytecodes.GETFIELD || opcode == Bytecodes.PUTFIELD || opcode == Bytecodes.GETSTATIC || opcode == Bytecodes.PUTSTATIC || opcode == Bytecodes.INVOKEINTERFACE ||
opcode == Bytecodes.INVOKEVIRTUAL || opcode == Bytecodes.INVOKESPECIAL || opcode == Bytecodes.INVOKESTATIC : "unexpected invoke opcode " + opcode;
index = rawIndex + runtime().getConfig().constantPoolCpCacheIndexTag;
index = rawIndex + config().constantPoolCpCacheIndexTag;
}
return index;
}
@ -241,7 +246,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
if (isInvokedynamicIndex(index)) {
return decodeInvokedynamicIndex(index);
} else {
return index - runtime().getConfig().constantPoolCpCacheIndexTag;
return index - config().constantPoolCpCacheIndexTag;
}
}
@ -260,7 +265,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
return ~i;
}
public long getMetaspaceConstantPool() {
long getMetaspaceConstantPool() {
return metaspaceConstantPool;
}
@ -276,7 +281,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
*/
private JVM_CONSTANT getTagAt(int index) {
assertBounds(index);
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
final long metaspaceConstantPoolTags = UNSAFE.getAddress(getMetaspaceConstantPool() + config.constantPoolTagsOffset);
final int tag = UNSAFE.getByteVolatile(null, metaspaceConstantPoolTags + config.arrayU1DataOffset + index);
if (tag == 0) {
@ -293,7 +298,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
*/
private long getEntryAt(int index) {
assertBounds(index);
return UNSAFE.getAddress(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
return UNSAFE.getAddress(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@ -304,7 +309,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
*/
private int getIntAt(int index) {
assertTag(index, JVM_CONSTANT.Integer);
return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@ -315,7 +320,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
*/
private long getLongAt(int index) {
assertTag(index, JVM_CONSTANT.Long);
return UNSAFE.getLong(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
return UNSAFE.getLong(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@ -326,7 +331,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
*/
private float getFloatAt(int index) {
assertTag(index, JVM_CONSTANT.Float);
return UNSAFE.getFloat(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
return UNSAFE.getFloat(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@ -337,7 +342,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
*/
private double getDoubleAt(int index) {
assertTag(index, JVM_CONSTANT.Double);
return UNSAFE.getDouble(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
return UNSAFE.getDouble(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@ -348,7 +353,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
*/
private int getNameAndTypeAt(int index) {
assertTag(index, JVM_CONSTANT.NameAndType);
return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
}
/**
@ -359,7 +364,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
* @return {@code JVM_CONSTANT_NameAndType} reference constant pool entry
*/
private int getNameAndTypeRefIndexAt(int index) {
return runtime().getCompilerToVM().lookupNameAndTypeRefIndexInPool(this, index);
return compilerToVM().lookupNameAndTypeRefIndexInPool(this, index);
}
/**
@ -370,7 +375,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
* @return name as {@link String}
*/
private String getNameOf(int which) {
return runtime().getCompilerToVM().lookupNameInPool(this, which);
return compilerToVM().lookupNameInPool(this, which);
}
/**
@ -394,7 +399,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
* @return signature as {@link String}
*/
private String getSignatureOf(int which) {
return runtime().getCompilerToVM().lookupSignatureInPool(this, which);
return compilerToVM().lookupSignatureInPool(this, which);
}
/**
@ -417,7 +422,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
* @return klass reference index
*/
private int getKlassRefIndexAt(int index) {
return runtime().getCompilerToVM().lookupKlassRefIndexInPool(this, index);
return compilerToVM().lookupKlassRefIndexInPool(this, index);
}
/**
@ -427,22 +432,11 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
* @param index constant pool index
* @return klass reference index
*/
private int getUncachedKlassRefIndexAt(int index, JVM_CONSTANT tag) {
int resultIndex;
if (tag == JVM_CONSTANT.MethodRef || tag == JVM_CONSTANT.Fieldref || tag == JVM_CONSTANT.InterfaceMethodref) {
assertTagIsFieldOrMethod(index);
final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
// klass ref index is in the low 16-bits.
resultIndex = refIndex & 0xFFFF;
} else {
resultIndex = index;
}
// Read the tag only once because it could change between multiple reads.
final JVM_CONSTANT klassTag = getTagAt(resultIndex);
assert klassTag == JVM_CONSTANT.Class || klassTag == JVM_CONSTANT.UnresolvedClass || klassTag == JVM_CONSTANT.UnresolvedClassInError : klassTag;
return resultIndex;
private int getUncachedKlassRefIndexAt(int index) {
assertTagIsFieldOrMethod(index);
final int refIndex = UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolSize + index * runtime().getHostJVMCIBackend().getTarget().wordSize);
// klass ref index is in the low 16-bits.
return refIndex & 0xFFFF;
}
/**
@ -478,7 +472,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
@Override
public int length() {
return UNSAFE.getInt(getMetaspaceConstantPool() + runtime().getConfig().constantPoolLengthOffset);
return UNSAFE.getInt(getMetaspaceConstantPool() + config().constantPoolLengthOffset);
}
@Override
@ -505,13 +499,13 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
* "pseudo strings" (arbitrary live objects) patched into a String entry. Such
* entries do not have a symbol in the constant pool slot.
*/
Object string = runtime().getCompilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
Object string = compilerToVM().resolvePossiblyCachedConstantInPool(this, cpi);
return HotSpotObjectConstantImpl.forObject(string);
case MethodHandle:
case MethodHandleInError:
case MethodType:
case MethodTypeInError:
Object obj = runtime().getCompilerToVM().resolveConstantInPool(this, cpi);
Object obj = compilerToVM().resolveConstantInPool(this, cpi);
return HotSpotObjectConstantImpl.forObject(obj);
default:
throw new JVMCIError("Unknown constant pool tag %s", tag);
@ -521,7 +515,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
@Override
public String lookupUtf8(int cpi) {
assertTag(cpi, JVM_CONSTANT.Utf8);
return runtime().getCompilerToVM().getSymbol(getEntryAt(cpi));
return compilerToVM().getSymbol(getEntryAt(cpi));
}
@Override
@ -533,7 +527,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
public JavaConstant lookupAppendix(int cpi, int opcode) {
assert Bytecodes.isInvoke(opcode);
final int index = rawIndexToConstantPoolIndex(cpi, opcode);
Object appendix = runtime().getCompilerToVM().lookupAppendixInPool(this, index);
Object appendix = compilerToVM().lookupAppendixInPool(this, index);
if (appendix == null) {
return null;
} else {
@ -558,7 +552,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
@Override
public JavaMethod lookupMethod(int cpi, int opcode) {
final int index = rawIndexToConstantPoolIndex(cpi, opcode);
final HotSpotResolvedJavaMethod method = runtime().getCompilerToVM().lookupMethodInPool(this, index, (byte) opcode);
final HotSpotResolvedJavaMethod method = compilerToVM().lookupMethodInPool(this, index, (byte) opcode);
if (method != null) {
return method;
} else {
@ -570,7 +564,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
return new HotSpotMethodUnresolved(name, signature, holder);
} else {
final int klassIndex = getKlassRefIndexAt(index);
final Object type = runtime().getCompilerToVM().lookupKlassInPool(this, klassIndex);
final Object type = compilerToVM().lookupKlassInPool(this, klassIndex);
JavaType holder = getJavaType(type);
return new HotSpotMethodUnresolved(name, signature, holder);
}
@ -583,7 +577,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
if (elem != null && elem.lastCpi == cpi) {
return elem.javaType;
} else {
final Object type = runtime().getCompilerToVM().lookupKlassInPool(this, cpi);
final Object type = compilerToVM().lookupKlassInPool(this, cpi);
JavaType result = getJavaType(type);
if (result instanceof ResolvedJavaType) {
this.lastLookupType = new LookupTypeCacheElement(cpi, result);
@ -609,7 +603,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
long[] info = new long[2];
HotSpotResolvedObjectTypeImpl resolvedHolder;
try {
resolvedHolder = runtime().getCompilerToVM().resolveFieldInPool(this, index, (byte) opcode, info);
resolvedHolder = compilerToVM().resolveFieldInPool(this, index, (byte) opcode, info);
} catch (Throwable t) {
/*
* If there was an exception resolving the field we give up and return an unresolved
@ -643,8 +637,8 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
break;
case Bytecodes.INVOKEDYNAMIC: {
// invokedynamic instructions point to a constant pool cache entry.
index = decodeConstantPoolCacheIndex(cpi) + runtime().getConfig().constantPoolCpCacheIndexTag;
index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
index = decodeConstantPoolCacheIndex(cpi) + config().constantPoolCpCacheIndexTag;
index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
break;
}
case Bytecodes.GETSTATIC:
@ -657,7 +651,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
case Bytecodes.INVOKEINTERFACE: {
// invoke and field instructions point to a constant pool cache entry.
index = rawIndexToConstantPoolIndex(cpi, opcode);
index = runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
index = compilerToVM().constantPoolRemapInstructionOperandFromCache(this, index);
break;
}
default:
@ -673,11 +667,15 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
case MethodRef:
case Fieldref:
case InterfaceMethodref:
index = getUncachedKlassRefIndexAt(index);
// Read the tag only once because it could change between multiple reads.
final JVM_CONSTANT klassTag = getTagAt(index);
assert klassTag == JVM_CONSTANT.Class || klassTag == JVM_CONSTANT.UnresolvedClass || klassTag == JVM_CONSTANT.UnresolvedClassInError : klassTag;
// fall through
case Class:
case UnresolvedClass:
case UnresolvedClassInError:
index = getUncachedKlassRefIndexAt(index, tag);
final HotSpotResolvedObjectTypeImpl type = runtime().getCompilerToVM().resolveTypeInPool(this, index);
final HotSpotResolvedObjectTypeImpl type = compilerToVM().resolveTypeInPool(this, index);
Class<?> klass = type.mirror();
if (!klass.isPrimitive() && !klass.isArray()) {
UNSAFE.ensureClassInitialized(klass);
@ -687,14 +685,14 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
if (Bytecodes.isInvokeHandleAlias(opcode)) {
final int methodRefCacheIndex = rawIndexToConstantPoolIndex(cpi, opcode);
if (isInvokeHandle(methodRefCacheIndex, type)) {
runtime().getCompilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
compilerToVM().resolveInvokeHandleInPool(this, methodRefCacheIndex);
}
}
}
break;
case InvokeDynamic:
if (isInvokedynamicIndex(cpi)) {
runtime().getCompilerToVM().resolveInvokeDynamicInPool(this, cpi);
compilerToVM().resolveInvokeDynamicInPool(this, cpi);
}
break;
default:
@ -704,7 +702,7 @@ public final class HotSpotConstantPool implements ConstantPool, HotSpotProxified
}
private boolean isInvokeHandle(int methodRefCacheIndex, HotSpotResolvedObjectTypeImpl klass) {
assertTag(runtime().getCompilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef);
assertTag(compilerToVM().constantPoolRemapInstructionOperandFromCache(this, methodRefCacheIndex), JVM_CONSTANT.MethodRef);
return ResolvedJavaMethod.isSignaturePolymorphic(klass, getNameOf(methodRefCacheIndex), runtime().getHostJVMCIBackend().getMetaAccess());
}

View File

@ -22,12 +22,24 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotConstantReflectionProvider.Options.*;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
import java.lang.reflect.*;
import java.lang.reflect.Array;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.options.*;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaField;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.MemoryAccessProvider;
import jdk.vm.ci.meta.MethodHandleAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.options.Option;
import jdk.vm.ci.options.OptionType;
import jdk.vm.ci.options.OptionValue;
import jdk.vm.ci.options.StableOptionValue;
/**
* HotSpot implementation of {@link ConstantReflectionProvider}.
@ -60,11 +72,6 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
return memoryAccess;
}
@Override
public boolean isEmbeddable(Constant constant) {
return true;
}
@Override
public Boolean constantEquals(Constant x, Constant y) {
if (x == y) {
@ -110,8 +117,8 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
}
Class<?> componentType = ((HotSpotObjectConstantImpl) array).object().getClass().getComponentType();
JavaKind kind = runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType(componentType).getJavaKind();
int arraybase = runtime.getArrayBaseOffset(kind);
int scale = runtime.getArrayIndexScale(kind);
int arraybase = getArrayBaseOffset(kind);
int scale = getArrayIndexScale(kind);
if (offset < arraybase) {
return -1;
}
@ -207,6 +214,10 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
return HotSpotObjectConstantImpl.forObject(value);
}
public JavaConstant forObject(Object value) {
return HotSpotObjectConstantImpl.forObject(value);
}
@Override
public ResolvedJavaType asJavaType(Constant constant) {
if (constant instanceof HotSpotObjectConstant) {
@ -216,7 +227,7 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
}
}
if (constant instanceof HotSpotMetaspaceConstant) {
Object obj = HotSpotMetaspaceConstantImpl.getMetaspaceObject(constant);
MetaspaceWrapperObject obj = HotSpotMetaspaceConstantImpl.getMetaspaceObject(constant);
if (obj instanceof HotSpotResolvedObjectTypeImpl) {
return (ResolvedJavaType) obj;
}
@ -251,7 +262,7 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
* {@code value} was read
*/
protected boolean isFinalInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
return !value.isDefaultForKind() || TrustFinalDefaultFields.getValue();
return !value.isDefaultForKind() || Options.TrustFinalDefaultFields.getValue();
}
/**
@ -327,7 +338,7 @@ public class HotSpotConstantReflectionProvider implements ConstantReflectionProv
if (!hotspotField.isStable()) {
return readNonStableFieldValue(field, receiver);
} else {
return readStableFieldValue(field, receiver, false);
return readStableFieldValue(field, receiver, hotspotField.isDefaultStable());
}
}

View File

@ -23,7 +23,6 @@
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
import sun.misc.Unsafe;
@ -59,18 +58,6 @@ public abstract class HotSpotInstalledCode extends InstalledCode {
return size;
}
/**
* @return a copy of this code blob if it is {@linkplain #isValid() valid}, null otherwise.
*/
public byte[] getBlob() {
if (!isValid()) {
return null;
}
byte[] blob = new byte[size];
UNSAFE.copyMemory(null, getAddress(), blob, Unsafe.ARRAY_BYTE_BASE_OFFSET, size);
return blob;
}
@Override
public abstract String toString();
@ -79,7 +66,6 @@ public abstract class HotSpotInstalledCode extends InstalledCode {
return codeStart;
}
@Override
public long getCodeSize() {
return codeSize;
}

View File

@ -22,12 +22,11 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.compiler.*;
import jdk.vm.ci.runtime.*;
import jdk.vm.ci.runtime.JVMCIBackend;
public interface HotSpotJVMCIBackendFactory {
JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, CompilerFactory compilerFactory, JVMCIBackend host);
JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, JVMCIBackend host);
/**
* Gets the CPU architecture of this backend.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 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
@ -22,19 +22,18 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.*;
import jdk.vm.ci.common.*;
import jdk.vm.ci.compiler.*;
import jdk.vm.ci.compiler.Compiler;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.runtime.*;
import jdk.vm.ci.service.*;
import jdk.vm.ci.code.CompilationRequest;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.runtime.JVMCICompiler;
import jdk.vm.ci.runtime.JVMCICompilerFactory;
import jdk.vm.ci.runtime.JVMCIRuntime;
import jdk.vm.ci.service.Services;
final class HotSpotJVMCICompilerConfig {
private static class DummyCompilerFactory implements CompilerFactory, Compiler {
private static class DummyCompilerFactory implements JVMCICompilerFactory, JVMCICompiler {
public void compileMethod(ResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
public void compileMethod(CompilationRequest request) {
throw new JVMCIError("no JVMCI compiler selected");
}
@ -42,16 +41,12 @@ final class HotSpotJVMCICompilerConfig {
return "<none>";
}
public Architecture initializeArchitecture(Architecture arch) {
return arch;
}
public Compiler createCompiler(JVMCIRuntime runtime) {
public JVMCICompiler createCompiler(JVMCIRuntime runtime) {
return this;
}
}
private static CompilerFactory compilerFactory;
private static JVMCICompilerFactory compilerFactory;
/**
* Selects the system compiler.
@ -61,7 +56,7 @@ final class HotSpotJVMCICompilerConfig {
*/
static Boolean selectCompiler(String compilerName) {
assert compilerFactory == null;
for (CompilerFactory factory : Services.load(CompilerFactory.class)) {
for (JVMCICompilerFactory factory : Services.load(JVMCICompilerFactory.class)) {
if (factory.getCompilerName().equals(compilerName)) {
compilerFactory = factory;
return Boolean.TRUE;
@ -71,7 +66,7 @@ final class HotSpotJVMCICompilerConfig {
throw new JVMCIError("JVMCI compiler '%s' not found", compilerName);
}
static CompilerFactory getCompilerFactory() {
static JVMCICompilerFactory getCompilerFactory() {
if (compilerFactory == null) {
compilerFactory = new DummyCompilerFactory();
}

View File

@ -22,10 +22,17 @@
*/
package jdk.vm.ci.hotspot;
import java.lang.ref.*;
import java.util.*;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.WeakHashMap;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaType;
/**
* This class manages the set of metadata roots that must be scanned during garbage collection.

View File

@ -22,54 +22,55 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.inittimer.InitTimer.*;
import static jdk.vm.ci.inittimer.InitTimer.timer;
import java.util.*;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import jdk.vm.ci.code.*;
import jdk.vm.ci.common.*;
import jdk.vm.ci.compiler.*;
import jdk.vm.ci.compiler.Compiler;
import jdk.vm.ci.inittimer.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.runtime.*;
import jdk.vm.ci.service.*;
import jdk.vm.ci.code.Architecture;
import jdk.vm.ci.code.CompilationResult;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.inittimer.InitTimer;
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.runtime.JVMCI;
import jdk.vm.ci.runtime.JVMCIBackend;
import jdk.vm.ci.runtime.JVMCICompiler;
import jdk.vm.ci.service.Services;
//JaCoCo Exclude
/**
* HotSpot implementation of a JVMCI runtime.
*
* The initialization of this class is very fragile since it's initialized both through
* {@link JVMCI#initialize()} or through calling {@link HotSpotJVMCIRuntime#runtime()} and
* {@link HotSpotJVMCIRuntime#runtime()} is also called by {@link JVMCI#initialize()}. So this class
* can't have a static initializer and any required initialization must be done as part of
* {@link #runtime()}. This allows the initialization to funnel back through
* {@link JVMCI#initialize()} without deadlocking.
*/
public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, HotSpotProxified {
/**
* The proper initialization of this class is complex because it's tangled up with the
* initialization of the JVMCI and really should only ever be triggered through
* {@link JVMCI#getRuntime}. However since {@link #runtime} can also be called directly it
* should also trigger proper initialization. To ensure proper ordering, the static initializer
* of this class initializes {@link JVMCI} and then access to {@link DelayedInit#instance}
* triggers the final initialization of the {@link HotSpotJVMCIRuntime}.
*/
static {
JVMCI.initialize();
}
@SuppressWarnings("try")
static class DelayedInit {
private static final HotSpotJVMCIRuntime instance;
static {
try (InitTimer t0 = timer("HotSpotJVMCIRuntime.<clinit>")) {
try (InitTimer t = timer("StartupEventListener.beforeJVMCIStartup")) {
for (StartupEventListener l : Services.load(StartupEventListener.class)) {
l.beforeJVMCIStartup();
}
}
try (InitTimer t = timer("HotSpotJVMCIRuntime.<init>")) {
instance = new HotSpotJVMCIRuntime();
}
try (InitTimer t = timer("HotSpotJVMCIRuntime.completeInitialization")) {
instance.completeInitialization();
}
try (InitTimer t = timer("HotSpotJVMCIRuntime.<init>")) {
instance = new HotSpotJVMCIRuntime();
}
}
}
@ -78,20 +79,10 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
* Gets the singleton {@link HotSpotJVMCIRuntime} object.
*/
public static HotSpotJVMCIRuntime runtime() {
assert DelayedInit.instance != null;
JVMCI.initialize();
return DelayedInit.instance;
}
/**
* Do deferred initialization.
*/
public void completeInitialization() {
compiler = HotSpotJVMCICompilerConfig.getCompilerFactory().createCompiler(this);
for (HotSpotVMEventListener vmEventListener : vmEventListeners) {
vmEventListener.completeInitialization(this);
}
}
public static HotSpotJVMCIBackendFactory findFactory(String architecture) {
for (HotSpotJVMCIBackendFactory factory : Services.load(HotSpotJVMCIBackendFactory.class)) {
if (factory.getArchitecture().equalsIgnoreCase(architecture)) {
@ -106,7 +97,7 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
* Gets the kind of a word value on the {@linkplain #getHostJVMCIBackend() host} backend.
*/
public static JavaKind getHostWordKind() {
return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordKind;
return runtime().getHostJVMCIBackend().getCodeCache().getTarget().wordJavaKind;
}
protected final CompilerToVM compilerToVm;
@ -114,16 +105,19 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
protected final HotSpotVMConfig config;
private final JVMCIBackend hostBackend;
private Compiler compiler;
private volatile JVMCICompiler compiler;
protected final JVMCIMetaAccessContext metaAccessContext;
private final Map<Class<? extends Architecture>, JVMCIBackend> backends = new HashMap<>();
private final Iterable<HotSpotVMEventListener> vmEventListeners;
@SuppressWarnings("unused") private final String[] trivialPrefixes;
@SuppressWarnings("try")
private HotSpotJVMCIRuntime() {
compilerToVm = new CompilerToVM();
try (InitTimer t = timer("HotSpotVMConfig<init>")) {
config = new HotSpotVMConfig(compilerToVm);
}
@ -135,10 +129,8 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
factory = findFactory(hostArchitecture);
}
CompilerFactory compilerFactory = HotSpotJVMCICompilerConfig.getCompilerFactory();
try (InitTimer t = timer("create JVMCI backend:", hostArchitecture)) {
hostBackend = registerBackend(factory.createJVMCIBackend(this, compilerFactory, null));
hostBackend = registerBackend(factory.createJVMCIBackend(this, null));
}
vmEventListeners = Services.load(HotSpotVMEventListener.class);
@ -154,6 +146,12 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
context = new HotSpotJVMCIMetaAccessContext();
}
metaAccessContext = context;
if (Boolean.valueOf(System.getProperty("jvmci.printconfig"))) {
printConfig(config, compilerToVm);
}
trivialPrefixes = HotSpotJVMCICompilerConfig.getCompilerFactory().getTrivialPrefixes();
}
private JVMCIBackend registerBackend(JVMCIBackend backend) {
@ -179,7 +177,14 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
return metaAccessContext;
}
public Compiler getCompiler() {
public JVMCICompiler getCompiler() {
if (compiler == null) {
synchronized (this) {
if (compiler == null) {
compiler = HotSpotJVMCICompilerConfig.getCompilerFactory().createCompiler(this);
}
}
}
return compiler;
}
@ -211,7 +216,7 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
return backends.get(arch);
}
public Map<Class<? extends Architecture>, JVMCIBackend> getBackends() {
public Map<Class<? extends Architecture>, JVMCIBackend> getJVMCIBackends() {
return Collections.unmodifiableMap(backends);
}
@ -220,7 +225,7 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
*/
@SuppressWarnings({"unused"})
private void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long jvmciEnv, int id) {
compiler.compileMethod(method, entryBCI, jvmciEnv, id);
getCompiler().compileMethod(new HotSpotCompilationRequest(method, entryBCI, jvmciEnv, id));
}
/**
@ -247,4 +252,105 @@ public final class HotSpotJVMCIRuntime implements HotSpotJVMCIRuntimeProvider, H
vmEventListener.notifyInstall(hotSpotCodeCacheProvider, installedCode, compResult);
}
}
private static void printConfig(HotSpotVMConfig config, CompilerToVM vm) {
Field[] fields = config.getClass().getDeclaredFields();
Map<String, Field> sortedFields = new TreeMap<>();
for (Field f : fields) {
if (!f.isSynthetic() && !Modifier.isStatic(f.getModifiers())) {
f.setAccessible(true);
sortedFields.put(f.getName(), f);
}
}
for (Field f : sortedFields.values()) {
try {
String line = String.format("%9s %-40s = %s%n", f.getType().getSimpleName(), f.getName(), pretty(f.get(config)));
byte[] lineBytes = line.getBytes();
vm.writeDebugOutput(lineBytes, 0, lineBytes.length);
vm.flushDebugOutput();
} catch (Exception e) {
}
}
}
private static String pretty(Object value) {
if (value == null) {
return "null";
}
Class<?> klass = value.getClass();
if (value instanceof String) {
return "\"" + value + "\"";
} else if (value instanceof Method) {
return "method \"" + ((Method) value).getName() + "\"";
} else if (value instanceof Class<?>) {
return "class \"" + ((Class<?>) value).getSimpleName() + "\"";
} else if (value instanceof Integer) {
if ((Integer) value < 10) {
return value.toString();
}
return value + " (0x" + Integer.toHexString((Integer) value) + ")";
} else if (value instanceof Long) {
if ((Long) value < 10 && (Long) value > -10) {
return value + "l";
}
return value + "l (0x" + Long.toHexString((Long) value) + "l)";
} else if (klass.isArray()) {
StringBuilder str = new StringBuilder();
int dimensions = 0;
while (klass.isArray()) {
dimensions++;
klass = klass.getComponentType();
}
int length = Array.getLength(value);
str.append(klass.getSimpleName()).append('[').append(length).append(']');
for (int i = 1; i < dimensions; i++) {
str.append("[]");
}
str.append(" {");
for (int i = 0; i < length; i++) {
str.append(pretty(Array.get(value, i)));
if (i < length - 1) {
str.append(", ");
}
}
str.append('}');
return str.toString();
}
return value.toString();
}
public OutputStream getLogStream() {
return new OutputStream() {
@Override
public void write(byte[] b, int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if (off < 0 || off > b.length || len < 0 || (off + len) > b.length || (off + len) < 0) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
compilerToVm.writeDebugOutput(b, off, len);
}
@Override
public void write(int b) throws IOException {
write(new byte[]{(byte) b}, 0, 1);
}
@Override
public void flush() throws IOException {
compilerToVm.flushDebugOutput();
}
};
}
/**
* Collects the current values of all JVMCI benchmark counters, summed up over all threads.
*/
public long[] collectCounters() {
return compilerToVm.collectCounters();
}
}

View File

@ -22,11 +22,15 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.common.*;
import jdk.vm.ci.compiler.Compiler;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.runtime.*;
import sun.misc.*;
import java.io.OutputStream;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.runtime.JVMCIRuntime;
import sun.misc.Unsafe;
//JaCoCo Exclude
@ -39,7 +43,10 @@ public interface HotSpotJVMCIRuntimeProvider extends JVMCIRuntime {
CompilerToVM getCompilerToVM();
Compiler getCompiler();
/**
* Gets an output stream that writes to the HotSpot's {@code tty} stream.
*/
OutputStream getLogStream();
/**
* Converts a name to a Java type. This method attempts to resolve {@code name} to a
@ -70,7 +77,7 @@ public interface HotSpotJVMCIRuntimeProvider extends JVMCIRuntime {
*
* @return the offset in bytes
*/
default int getArrayBaseOffset(JavaKind kind) {
static int getArrayBaseOffset(JavaKind kind) {
switch (kind) {
case Boolean:
return Unsafe.ARRAY_BOOLEAN_BASE_OFFSET;
@ -100,7 +107,7 @@ public interface HotSpotJVMCIRuntimeProvider extends JVMCIRuntime {
*
* @return the scale in order to convert the index into a byte offset
*/
default int getArrayIndexScale(JavaKind kind) {
static int getArrayIndexScale(JavaKind kind) {
switch (kind) {
case Boolean:
return Unsafe.ARRAY_BOOLEAN_INDEX_SCALE;

View File

@ -22,7 +22,7 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaType;
/**
* Common base class for all HotSpot {@link JavaType} implementations.
@ -39,5 +39,4 @@ public abstract class HotSpotJavaType implements JavaType {
public final String getName() {
return name;
}
}

View File

@ -22,8 +22,10 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.hotspot.HotSpotVMConfig.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.hotspot.HotSpotVMConfig.CompressEncoding;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.MemoryAccessProvider;
/**
* HotSpot specific extension of {@link MemoryAccessProvider}.

View File

@ -23,8 +23,6 @@
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspot.HotSpotVMConfig.CompressEncoding;
import jdk.vm.ci.meta.Constant;
@ -36,7 +34,7 @@ import jdk.vm.ci.meta.PrimitiveConstant;
/**
* HotSpot implementation of {@link MemoryAccessProvider}.
*/
public class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, HotSpotProxified {
class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvider, HotSpotProxified {
protected final HotSpotJVMCIRuntimeProvider runtime;
@ -54,7 +52,7 @@ public class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvi
private boolean isValidObjectFieldDisplacement(Constant base, long displacement) {
if (base instanceof HotSpotMetaspaceConstant) {
Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
if (displacement == runtime.getConfig().classMirrorOffset) {
// Klass::_java_mirror is valid for all Klass* values
@ -68,8 +66,9 @@ public class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvi
}
private static long asRawPointer(Constant base) {
if (base instanceof HotSpotMetaspaceConstant) {
return ((HotSpotMetaspaceConstant) base).rawValue();
if (base instanceof HotSpotMetaspaceConstantImpl) {
MetaspaceWrapperObject meta = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
return meta.getMetaspacePointer();
} else if (base instanceof PrimitiveConstant) {
PrimitiveConstant prim = (PrimitiveConstant) base;
if (prim.getJavaKind().isNumericInteger()) {
@ -119,7 +118,7 @@ public class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvi
}
}
if (base instanceof HotSpotMetaspaceConstant) {
Object metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
MetaspaceWrapperObject metaspaceObject = HotSpotMetaspaceConstantImpl.getMetaspaceObject(base);
if (metaspaceObject instanceof HotSpotResolvedObjectTypeImpl) {
if (displacement == runtime.getConfig().classMirrorOffset) {
assert expected == ((HotSpotResolvedObjectTypeImpl) metaspaceObject).mirror();
@ -211,8 +210,7 @@ public class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvi
if (klass == null) {
return JavaConstant.NULL_POINTER;
}
TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, klass.getMetaspaceKlass(), klass, false);
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, false);
}
@Override
@ -221,15 +219,14 @@ public class HotSpotMemoryAccessProviderImpl implements HotSpotMemoryAccessProvi
if (klass == null) {
return HotSpotCompressedNullConstant.COMPRESSED_NULL;
}
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(JavaKind.Int, encoding.compress(klass.getMetaspaceKlass()), klass, true);
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(klass, true);
}
@Override
public Constant readMethodPointerConstant(Constant base, long displacement) {
TargetDescription target = runtime.getHostJVMCIBackend().getCodeCache().getTarget();
assert (base instanceof HotSpotObjectConstantImpl);
Object baseObject = ((HotSpotObjectConstantImpl) base).object();
HotSpotResolvedJavaMethodImpl method = runtime.getCompilerToVM().getResolvedJavaMethod(baseObject, displacement);
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(target.wordKind, method.getMetaspaceMethod(), method, false);
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(method, false);
}
}

View File

@ -22,14 +22,31 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.*;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayBaseOffset;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider.getArrayIndexScale;
import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
import java.lang.reflect.*;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import jdk.vm.ci.code.*;
import jdk.vm.ci.common.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.code.CodeUtil;
import jdk.vm.ci.code.TargetDescription;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.DeoptimizationAction;
import jdk.vm.ci.meta.DeoptimizationReason;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.Signature;
// JaCoCo Exclude
@ -292,9 +309,9 @@ public class HotSpotMetaAccessProvider implements MetaAccessProvider, HotSpotPro
int length = Array.getLength(((HotSpotObjectConstantImpl) constant).object());
ResolvedJavaType elementType = lookupJavaType.getComponentType();
JavaKind elementKind = elementType.getJavaKind();
final int headerSize = runtime.getArrayBaseOffset(elementKind);
final int headerSize = getArrayBaseOffset(elementKind);
TargetDescription target = runtime.getHostJVMCIBackend().getTarget();
int sizeOfElement = target.getSizeInBytes(elementKind);
int sizeOfElement = getArrayIndexScale(elementKind);
int alignment = target.wordSize;
int log2ElementSize = CodeUtil.log2(sizeOfElement);
return computeArrayAllocationSize(length, alignment, headerSize, log2ElementSize);

View File

@ -22,6 +22,8 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
public class HotSpotMetaData {
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] pcDescBytes;
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private byte[] scopesDescBytes;

View File

@ -22,18 +22,11 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.hotspot.HotSpotVMConfig.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.VMConstant;
public interface HotSpotMetaspaceConstant extends HotSpotConstant, VMConstant {
Constant compress(CompressEncoding encoding);
Constant uncompress(CompressEncoding encoding);
HotSpotResolvedObjectType asResolvedJavaType();
HotSpotResolvedJavaMethod asResolvedJavaMethod();
long rawValue();
}

View File

@ -22,59 +22,75 @@
*/
package jdk.vm.ci.hotspot;
import java.util.*;
import java.util.Objects;
import jdk.vm.ci.hotspot.HotSpotVMConfig.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.VMConstant;
public final class HotSpotMetaspaceConstantImpl extends PrimitiveConstant implements HotSpotMetaspaceConstant, VMConstant, HotSpotProxified {
final class HotSpotMetaspaceConstantImpl implements HotSpotMetaspaceConstant, VMConstant, HotSpotProxified {
static HotSpotMetaspaceConstantImpl forMetaspaceObject(JavaKind kind, long primitive, Object metaspaceObject, boolean compressed) {
return new HotSpotMetaspaceConstantImpl(kind, primitive, metaspaceObject, compressed);
static HotSpotMetaspaceConstantImpl forMetaspaceObject(MetaspaceWrapperObject metaspaceObject, boolean compressed) {
return new HotSpotMetaspaceConstantImpl(metaspaceObject, compressed);
}
static Object getMetaspaceObject(Constant constant) {
static MetaspaceWrapperObject getMetaspaceObject(Constant constant) {
return ((HotSpotMetaspaceConstantImpl) constant).metaspaceObject;
}
private final Object metaspaceObject;
private final MetaspaceWrapperObject metaspaceObject;
private final boolean compressed;
private HotSpotMetaspaceConstantImpl(JavaKind kind, long primitive, Object metaspaceObject, boolean compressed) {
super(kind, primitive);
private HotSpotMetaspaceConstantImpl(MetaspaceWrapperObject metaspaceObject, boolean compressed) {
this.metaspaceObject = metaspaceObject;
this.compressed = compressed;
}
@Override
public int hashCode() {
return super.hashCode() ^ System.identityHashCode(metaspaceObject);
return System.identityHashCode(metaspaceObject) ^ (compressed ? 1 : 2);
}
@Override
public boolean equals(Object o) {
return o == this || (o instanceof HotSpotMetaspaceConstantImpl && super.equals(o) && Objects.equals(metaspaceObject, ((HotSpotMetaspaceConstantImpl) o).metaspaceObject));
if (o == this) {
return true;
}
if (!(o instanceof HotSpotMetaspaceConstantImpl)) {
return false;
}
HotSpotMetaspaceConstantImpl other = (HotSpotMetaspaceConstantImpl) o;
return Objects.equals(this.metaspaceObject, other.metaspaceObject) && this.compressed == other.compressed;
}
@Override
public String toValueString() {
return String.format("meta{%s%s}", metaspaceObject, compressed ? ";compressed" : "");
}
@Override
public String toString() {
return super.toString() + "{" + metaspaceObject + (compressed ? ";compressed}" : "}");
return toValueString();
}
public boolean isDefaultForKind() {
return false;
}
public boolean isCompressed() {
return compressed;
}
public JavaConstant compress(CompressEncoding encoding) {
public Constant compress() {
assert !isCompressed();
HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(JavaKind.Int, encoding.compress(asLong()), metaspaceObject, true);
HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, true);
assert res.isCompressed();
return res;
}
public JavaConstant uncompress(CompressEncoding encoding) {
public Constant uncompress() {
assert isCompressed();
HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(JavaKind.Long, encoding.uncompress(asInt()), metaspaceObject, false);
HotSpotMetaspaceConstantImpl res = HotSpotMetaspaceConstantImpl.forMetaspaceObject(metaspaceObject, false);
assert !res.isCompressed();
return res;
}
@ -92,8 +108,4 @@ public final class HotSpotMetaspaceConstantImpl extends PrimitiveConstant implem
}
return null;
}
public long rawValue() {
return asLong();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015, 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
@ -22,12 +22,17 @@
*/
package jdk.vm.ci.hotspot;
import static java.util.FormattableFlags.*;
import java.util.*;
import static java.util.FormattableFlags.ALTERNATE;
import static java.util.FormattableFlags.LEFT_JUSTIFY;
import static java.util.FormattableFlags.UPPERCASE;
import jdk.vm.ci.meta.*;
import java.util.Formattable;
import java.util.Formatter;
public abstract class HotSpotMethod implements JavaMethod, Formattable /* , JavaMethodContex */{
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.ResolvedJavaMethod;
abstract class HotSpotMethod implements JavaMethod, Formattable /* , JavaMethodContex */{
public static String applyFormattingFlagsAndWidth(String s, int flags, int width) {
if (flags == 0 && width < 0) {

View File

@ -22,24 +22,31 @@
*/
package jdk.vm.ci.hotspot;
import static java.lang.String.*;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
import static java.lang.String.format;
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
import java.util.*;
import java.util.Arrays;
import jdk.vm.ci.hotspot.HotSpotMethodDataAccessor.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaMethodProfile.*;
import jdk.vm.ci.meta.JavaTypeProfile.*;
import sun.misc.*;
import jdk.vm.ci.hotspot.HotSpotMethodDataAccessor.Tag;
import jdk.vm.ci.meta.DeoptimizationReason;
import jdk.vm.ci.meta.JavaMethodProfile;
import jdk.vm.ci.meta.JavaMethodProfile.ProfiledMethod;
import jdk.vm.ci.meta.JavaTypeProfile;
import jdk.vm.ci.meta.JavaTypeProfile.ProfiledType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.TriState;
import sun.misc.Unsafe;
/**
* Access to a HotSpot MethodData structure (defined in methodData.hpp).
*/
public final class HotSpotMethodData {
private static final HotSpotVMConfig config = runtime().getConfig();
private static final HotSpotVMConfig config = config();
private static final HotSpotMethodDataAccessor NO_DATA_NO_EXCEPTION_ACCESSOR = new NoMethodData(TriState.FALSE);
private static final HotSpotMethodDataAccessor NO_DATA_EXCEPTION_POSSIBLY_NOT_RECORDED_ACCESSOR = new NoMethodData(TriState.UNKNOWN);
@ -50,16 +57,16 @@ public final class HotSpotMethodData {
new BitData(),
new CounterData(),
new JumpData(),
new TypeCheckData(),
new ReceiverTypeData(),
new VirtualCallData(),
new RetData(),
new BranchData(),
new MultiBranchData(),
new ArgInfoData(),
null, // call_type_data_tag
null, // virtual_call_type_data_tag
null, // parameters_type_data_tag
null, // speculative_trap_data_tag
new UnknownProfileData(Tag.CallTypeData),
new VirtualCallTypeData(),
new UnknownProfileData(Tag.ParametersTypeData),
new UnknownProfileData(Tag.SpeculativeTrapData),
};
// @formatter:on
@ -127,7 +134,8 @@ public final class HotSpotMethodData {
}
HotSpotMethodDataAccessor result = getData(position);
assert result != null : "NO_DATA tag is not allowed";
final Tag tag = AbstractMethodData.readTag(this, position);
assert result != null : "NO_DATA tag is not allowed " + tag;
return result;
}
@ -193,12 +201,12 @@ public final class HotSpotMethodData {
private HotSpotResolvedJavaMethod readMethod(int position, int offsetInBytes) {
long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
return runtime().compilerToVm.getResolvedJavaMethod(null, metaspaceMethodData + fullOffsetInBytes);
return compilerToVM().getResolvedJavaMethod(null, metaspaceMethodData + fullOffsetInBytes);
}
private HotSpotResolvedObjectTypeImpl readKlass(int position, int offsetInBytes) {
long fullOffsetInBytes = computeFullOffset(position, offsetInBytes);
return runtime().compilerToVm.getResolvedJavaType(null, metaspaceMethodData + fullOffsetInBytes, false);
return compilerToVM().getResolvedJavaType(null, metaspaceMethodData + fullOffsetInBytes, false);
}
private static int truncateLongToInt(long value) {
@ -266,10 +274,10 @@ public final class HotSpotMethodData {
/**
* Corresponds to {@code exception_seen_flag}.
*/
private static final int EXCEPTIONS_MASK = 0x2;
private static final int EXCEPTIONS_MASK = 1 << config.bitDataExceptionSeenFlag;
private final Tag tag;
private final int staticSize;
protected final int staticSize;
protected AbstractMethodData(Tag tag, int staticSize) {
this.tag = tag;
@ -291,8 +299,12 @@ public final class HotSpotMethodData {
}
@Override
public int getSize(HotSpotMethodData data, int position) {
return staticSize + getDynamicSize(data, position);
public final int getSize(HotSpotMethodData data, int position) {
int size = staticSize + getDynamicSize(data, position);
// Sanity check against VM
int vmSize = HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position);
assert size == vmSize : size + " != " + vmSize;
return size;
}
@Override
@ -375,7 +387,7 @@ public final class HotSpotMethodData {
private static class BitData extends AbstractMethodData {
private static final int BIT_DATA_SIZE = cellIndexToOffset(0);
private static final int BIT_DATA_NULL_SEEN_FLAG = 0x01;
private static final int BIT_DATA_NULL_SEEN_FLAG = 1 << config.bitDataNullSeenFlag;
private BitData() {
super(Tag.BitData, BIT_DATA_SIZE);
@ -399,7 +411,7 @@ public final class HotSpotMethodData {
private static class CounterData extends BitData {
private static final int COUNTER_DATA_SIZE = cellIndexToOffset(1);
private static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(0);
private static final int COUNTER_DATA_COUNT_OFFSET = cellIndexToOffset(config.methodDataCountOffset);
public CounterData() {
super(Tag.CounterData, COUNTER_DATA_SIZE);
@ -427,8 +439,8 @@ public final class HotSpotMethodData {
private static class JumpData extends AbstractMethodData {
private static final int JUMP_DATA_SIZE = cellIndexToOffset(2);
protected static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(0);
protected static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(1);
protected static final int TAKEN_COUNT_OFFSET = cellIndexToOffset(config.jumpDataTakenOffset);
protected static final int TAKEN_DISPLACEMENT_OFFSET = cellIndexToOffset(config.jumpDataDisplacementOffset);
public JumpData() {
super(Tag.JumpData, JUMP_DATA_SIZE);
@ -474,11 +486,11 @@ public final class HotSpotMethodData {
private abstract static class AbstractTypeData extends CounterData {
protected static final int TYPE_DATA_ROW_SIZE = cellsToBytes(2);
protected static final int TYPE_DATA_ROW_SIZE = cellsToBytes(config.receiverTypeDataReceiverTypeRowCellCount);
protected static final int NONPROFILED_COUNT_OFFSET = cellIndexToOffset(1);
protected static final int TYPE_DATA_FIRST_TYPE_OFFSET = cellIndexToOffset(2);
protected static final int TYPE_DATA_FIRST_TYPE_COUNT_OFFSET = cellIndexToOffset(3);
protected static final int NONPROFILED_COUNT_OFFSET = cellIndexToOffset(config.receiverTypeDataNonprofiledCountOffset);
protected static final int TYPE_DATA_FIRST_TYPE_OFFSET = cellIndexToOffset(config.receiverTypeDataReceiver0Offset);
protected static final int TYPE_DATA_FIRST_TYPE_COUNT_OFFSET = cellIndexToOffset(config.receiverTypeDataCount0Offset);
protected AbstractTypeData(Tag tag, int staticSize) {
super(tag, staticSize);
@ -571,14 +583,18 @@ public final class HotSpotMethodData {
}
}
private static class TypeCheckData extends AbstractTypeData {
private static class ReceiverTypeData extends AbstractTypeData {
private static final int TYPE_CHECK_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
public TypeCheckData() {
public ReceiverTypeData() {
super(Tag.ReceiverTypeData, TYPE_CHECK_DATA_SIZE);
}
protected ReceiverTypeData(Tag tag, int staticSize) {
super(tag, staticSize);
}
@Override
public int getExecutionCount(HotSpotMethodData data, int position) {
return -1;
@ -590,7 +606,7 @@ public final class HotSpotMethodData {
}
}
private static class VirtualCallData extends AbstractTypeData {
private static class VirtualCallData extends ReceiverTypeData {
private static final int VIRTUAL_CALL_DATA_SIZE = cellIndexToOffset(2) + TYPE_DATA_ROW_SIZE * (config.typeProfileWidth + config.methodProfileWidth);
private static final int VIRTUAL_CALL_DATA_FIRST_METHOD_OFFSET = TYPE_DATA_FIRST_TYPE_OFFSET + TYPE_DATA_ROW_SIZE * config.typeProfileWidth;
@ -600,6 +616,10 @@ public final class HotSpotMethodData {
super(Tag.VirtualCallData, VIRTUAL_CALL_DATA_SIZE);
}
protected VirtualCallData(Tag tag, int staticSize) {
super(tag, staticSize);
}
@Override
public int getExecutionCount(HotSpotMethodData data, int position) {
final int typeProfileWidth = config.typeProfileWidth;
@ -692,6 +712,19 @@ public final class HotSpotMethodData {
}
}
private static class VirtualCallTypeData extends VirtualCallData {
public VirtualCallTypeData() {
super(Tag.VirtualCallTypeData, 0);
}
@Override
protected int getDynamicSize(HotSpotMethodData data, int position) {
assert staticSize == 0;
return HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position);
}
}
private static class RetData extends CounterData {
private static final int RET_DATA_ROW_SIZE = cellsToBytes(3);
@ -705,7 +738,7 @@ public final class HotSpotMethodData {
private static class BranchData extends JumpData {
private static final int BRANCH_DATA_SIZE = cellIndexToOffset(3);
private static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(2);
private static final int NOT_TAKEN_COUNT_OFFSET = cellIndexToOffset(config.branchDataNotTakenOffset);
public BranchData() {
super(Tag.BranchData, BRANCH_DATA_SIZE);
@ -737,8 +770,8 @@ public final class HotSpotMethodData {
private static class ArrayData extends AbstractMethodData {
private static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(0);
protected static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(1);
private static final int ARRAY_DATA_LENGTH_OFFSET = cellIndexToOffset(config.arrayDataArrayLenOffset);
protected static final int ARRAY_DATA_START_OFFSET = cellIndexToOffset(config.arrayDataArrayStartOffset);
public ArrayData(Tag tag, int staticSize) {
super(tag, staticSize);
@ -762,7 +795,7 @@ public final class HotSpotMethodData {
private static class MultiBranchData extends ArrayData {
private static final int MULTI_BRANCH_DATA_SIZE = cellIndexToOffset(1);
private static final int MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS = 2;
private static final int MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS = config.multiBranchDataPerCaseCellCount;
private static final int MULTI_BRANCH_DATA_ROW_SIZE = cellsToBytes(MULTI_BRANCH_DATA_ROW_SIZE_IN_CELLS);
private static final int MULTI_BRANCH_DATA_FIRST_COUNT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(0);
private static final int MULTI_BRANCH_DATA_FIRST_DISPLACEMENT_OFFSET = ARRAY_DATA_START_OFFSET + cellsToBytes(1);
@ -854,6 +887,24 @@ public final class HotSpotMethodData {
}
}
private static class UnknownProfileData extends AbstractMethodData {
public UnknownProfileData(Tag tag) {
super(tag, 0);
}
@Override
protected int getDynamicSize(HotSpotMethodData data, int position) {
assert staticSize == 0;
return HotSpotJVMCIRuntime.runtime().compilerToVm.methodDataProfileDataSize(data.metaspaceMethodData, position);
}
@Override
public StringBuilder appendTo(StringBuilder sb, HotSpotMethodData data, int pos) {
// TODO Auto-generated method stub
return null;
}
}
public void setCompiledIRSize(int size) {
UNSAFE.putInt(metaspaceMethodData + config.methodDataIRSizeOffset, size);
}

View File

@ -22,9 +22,11 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
import jdk.vm.ci.meta.*;
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import jdk.vm.ci.meta.JavaMethodProfile;
import jdk.vm.ci.meta.JavaTypeProfile;
import jdk.vm.ci.meta.ProfilingInfo;
import jdk.vm.ci.meta.TriState;
/**
* Interface for accessor objects that encapsulate the logic for accessing the different kinds of
@ -62,10 +64,6 @@ public interface HotSpotMethodDataAccessor {
return value;
}
private static HotSpotVMConfig config() {
return runtime().getConfig();
}
public static Tag getEnum(int value) {
Tag result = values()[value];
assert value == result.value;

View File

@ -22,11 +22,16 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.*;
import jdk.vm.ci.common.*;
import jdk.vm.ci.meta.*;
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.MethodHandleAccessProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProvider, HotSpotProxified {
@ -155,6 +160,6 @@ public class HotSpotMethodHandleAccessProvider implements MethodHandleAccessProv
Object object = ((HotSpotObjectConstantImpl) memberName).object();
/* Read the ResolvedJavaMethod from the injected field MemberName.vmtarget */
return runtime().compilerToVm.getResolvedJavaMethod(object, LazyInitialization.memberNameVmtargetField.offset());
return compilerToVM().getResolvedJavaMethod(object, LazyInitialization.memberNameVmtargetField.offset());
}
}

View File

@ -22,12 +22,14 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.Signature;
/**
* Implementation of {@link JavaMethod} for unresolved HotSpot methods.
*/
public final class HotSpotMethodUnresolved extends HotSpotMethod {
final class HotSpotMethodUnresolved extends HotSpotMethod {
private final Signature signature;
protected JavaType holder;

View File

@ -22,10 +22,12 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
import jdk.vm.ci.code.*;
import jdk.vm.ci.meta.*;
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.InvalidInstalledCodeException;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Implementation of {@link InstalledCode} for code installed as an nmethod. The nmethod stores a
@ -45,34 +47,24 @@ public class HotSpotNmethod extends HotSpotInstalledCode {
private final HotSpotResolvedJavaMethod method;
private final boolean isDefault;
private final boolean isExternal;
public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault) {
this(method, name, isDefault, false);
}
public HotSpotNmethod(HotSpotResolvedJavaMethod method, String name, boolean isDefault, boolean isExternal) {
super(name);
this.method = method;
this.isDefault = isDefault;
this.isExternal = isExternal;
}
public boolean isDefault() {
return isDefault;
}
public boolean isExternal() {
return isExternal;
}
public ResolvedJavaMethod getMethod() {
return method;
}
@Override
public void invalidate() {
runtime().getCompilerToVM().invalidateInstalledCode(this);
compilerToVM().invalidateInstalledCode(this);
}
@Override
@ -105,8 +97,7 @@ public class HotSpotNmethod extends HotSpotInstalledCode {
@Override
public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
assert checkArgs(args);
assert !isExternal();
return runtime().getCompilerToVM().executeInstalledCode(args, this);
return compilerToVM().executeInstalledCode(args, this);
}
@Override

View File

@ -22,10 +22,13 @@
*/
package jdk.vm.ci.hotspot;
import java.lang.invoke.*;
import java.util.*;
import java.lang.invoke.CallSite;
import java.util.Objects;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.Assumptions;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.VMConstant;
/**
* Represents a constant non-{@code null} object reference, within the compiler and across the

View File

@ -22,20 +22,26 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.*;
import static jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.fromObjectClass;
import java.lang.invoke.*;
import java.lang.invoke.CallSite;
import java.lang.invoke.ConstantCallSite;
import java.lang.invoke.MethodHandle;
import jdk.vm.ci.inittimer.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
import jdk.vm.ci.meta.Assumptions;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Represents a constant non-{@code null} object reference, within the compiler and across the
* compiler/runtime interface.
*/
public final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotProxified {
final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, HotSpotProxified {
public static JavaConstant forObject(Object object) {
static JavaConstant forObject(Object object) {
return forObject(object, false);
}
@ -106,21 +112,6 @@ public final class HotSpotObjectConstantImpl implements HotSpotObjectConstant, H
return object;
}
/**
* Determines if the object represented by this constant is {@link Object#equals(Object) equal}
* to a given object.
*/
public boolean isEqualTo(Object obj) {
return object.equals(obj);
}
/**
* Gets the class of the object represented by this constant.
*/
public Class<?> getObjectClass() {
return object.getClass();
}
public boolean isCompressed() {
return compressed;
}

View File

@ -22,6 +22,8 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.inittimer.SuppressFBWarnings;
public class HotSpotOopMap {
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int offset;
@SuppressFBWarnings(value = "UWF_UNWRITTEN_FIELD", justification = "field is set by the native part") private int count;

View File

@ -22,7 +22,11 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.DeoptimizationReason;
import jdk.vm.ci.meta.JavaMethodProfile;
import jdk.vm.ci.meta.JavaTypeProfile;
import jdk.vm.ci.meta.ProfilingInfo;
import jdk.vm.ci.meta.TriState;
public final class HotSpotProfilingInfo implements ProfilingInfo, HotSpotProxified {

View File

@ -22,9 +22,10 @@
*/
package jdk.vm.ci.hotspot;
import java.util.*;
import java.util.Arrays;
import jdk.vm.ci.code.*;
import jdk.vm.ci.code.Location;
import jdk.vm.ci.code.ReferenceMap;
public final class HotSpotReferenceMap extends ReferenceMap {

View File

@ -22,7 +22,7 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.ResolvedJavaField;
/**
* Represents a field in a HotSpot type.
@ -45,4 +45,12 @@ public interface HotSpotResolvedJavaField extends ResolvedJavaField {
* @return true if field has {@link Stable} annotation, false otherwise
*/
boolean isStable();
/**
* If this field is stable, checks if default values (0, null, etc.) should be considered stable
* as well.
*
* @return true if default values should be considered stable, false otherwise
*/
boolean isDefaultStable();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015, 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
@ -22,20 +22,27 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
import static jdk.vm.ci.hotspot.HotSpotResolvedJavaFieldImpl.Options.*;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import jdk.vm.ci.common.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.options.*;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.LocationIdentity;
import jdk.vm.ci.meta.MetaAccessProvider;
import jdk.vm.ci.meta.ModifiersProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.options.Option;
import jdk.vm.ci.options.OptionType;
import jdk.vm.ci.options.OptionValue;
/**
* Represents a field in a HotSpot type.
*/
public class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
static class Options {
//@formatter:off
@ -91,7 +98,7 @@ public class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, H
}
}
public HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, String name, JavaType type, long offset, int modifiers) {
HotSpotResolvedJavaFieldImpl(HotSpotResolvedObjectTypeImpl holder, String name, JavaType type, long offset, int modifiers) {
this.holder = holder;
this.name = name;
this.type = type;
@ -130,7 +137,7 @@ public class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, H
@Override
public boolean isInternal() {
return (modifiers & runtime().getConfig().jvmAccFieldInternal) != 0;
return (modifiers & config().jvmAccFieldInternal) != 0;
}
/**
@ -183,7 +190,7 @@ public class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, H
@Override
public boolean isSynthetic() {
return (runtime().getConfig().syntheticFlag & modifiers) != 0;
return (config().syntheticFlag & modifiers) != 0;
}
/**
@ -192,11 +199,11 @@ public class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, H
* @return true if field has {@link Stable} annotation, false otherwise
*/
public boolean isStable() {
if ((runtime().getConfig().jvmAccFieldStable & modifiers) != 0) {
if ((config().jvmAccFieldStable & modifiers) != 0) {
return true;
}
assert getAnnotation(Stable.class) == null;
if (ImplicitStableValues.getValue() && isImplicitStableField()) {
if (Options.ImplicitStableValues.getValue() && isImplicitStableField()) {
return true;
}
return false;
@ -243,19 +250,25 @@ public class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, H
}
private boolean isImplicitStableField() {
if (isSynthetic()) {
if (isSyntheticImplicitStableField()) {
return true;
}
} else if (isWellKnownImplicitStableField()) {
if (isSyntheticEnumSwitchMap()) {
return true;
}
if (isWellKnownImplicitStableField()) {
return true;
}
return false;
}
private boolean isSyntheticImplicitStableField() {
assert this.isSynthetic();
if (isStatic() && isArray()) {
public boolean isDefaultStable() {
assert this.isStable();
if (isSyntheticEnumSwitchMap()) {
return true;
}
return false;
}
private boolean isSyntheticEnumSwitchMap() {
if (isSynthetic() && isStatic() && isArray()) {
if (isFinal() && name.equals("$VALUES") || name.equals("ENUM$VALUES")) {
// generated int[] field for EnumClass::values()
return true;
@ -281,6 +294,7 @@ public class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, H
}
private static final ResolvedJavaField STRING_VALUE_FIELD;
static {
try {
MetaAccessProvider metaAccess = runtime().getHostJVMCIBackend().getMetaAccess();

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015, 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
@ -22,15 +22,27 @@
*/
package jdk.vm.ci.hotspot;
import java.lang.reflect.*;
import java.lang.reflect.Modifier;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.options.Option;
import jdk.vm.ci.options.OptionType;
import jdk.vm.ci.options.OptionValue;
/**
* Implementation of {@link JavaMethod} for resolved HotSpot methods.
*/
public interface HotSpotResolvedJavaMethod extends ResolvedJavaMethod {
public static class Options {
// @formatter:off
@Option(help = "", type = OptionType.Debug)
public static final OptionValue<Boolean> UseProfilingInformation = new OptionValue<>(true);
// @formatter:on
}
/**
* Returns true if this method has a {@code CallerSensitive} annotation.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2015, 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
@ -22,29 +22,47 @@
*/
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
import static jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl.Options.*;
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod.Options.UseProfilingInformation;
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Executable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
import jdk.vm.ci.common.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.options.*;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.meta.DefaultProfilingInfo;
import jdk.vm.ci.meta.ExceptionHandler;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaMethod;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.LineNumberTable;
import jdk.vm.ci.meta.LineNumberTableImpl;
import jdk.vm.ci.meta.Local;
import jdk.vm.ci.meta.LocalImpl;
import jdk.vm.ci.meta.LocalVariableTable;
import jdk.vm.ci.meta.LocalVariableTableImpl;
import jdk.vm.ci.meta.ModifiersProvider;
import jdk.vm.ci.meta.ProfilingInfo;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.Signature;
import jdk.vm.ci.meta.SpeculationLog;
import jdk.vm.ci.meta.TriState;
/**
* Implementation of {@link JavaMethod} for resolved HotSpot methods.
*/
public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MetaspaceWrapperObject {
public static class Options {
// @formatter:off
@Option(help = "", type = OptionType.Debug)
public static final OptionValue<Boolean> UseProfilingInformation = new OptionValue<>(true);
// @formatter:on
}
final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSpotResolvedJavaMethod, HotSpotProxified, MetaspaceWrapperObject {
/**
* Reference to metaspace Method object.
@ -56,7 +74,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
private final HotSpotSignature signature;
private HotSpotMethodData methodData;
private byte[] code;
private Member toJavaCache;
private Executable toJavaCache;
/**
* Gets the holder of a HotSpot metaspace method native object.
@ -66,10 +84,10 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
* {@code metaspaceMethod}
*/
private static HotSpotResolvedObjectTypeImpl getHolder(long metaspaceMethod) {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
final long metaspaceConstMethod = UNSAFE.getAddress(metaspaceMethod + config.methodConstMethodOffset);
final long metaspaceConstantPool = UNSAFE.getAddress(metaspaceConstMethod + config.constMethodConstantsOffset);
return runtime().getCompilerToVM().getResolvedJavaType(null, metaspaceConstantPool + config.constantPoolHolderOffset, false);
return compilerToVM().getResolvedJavaType(null, metaspaceConstantPool + config.constantPoolHolderOffset, false);
}
/**
@ -94,7 +112,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
this.metaspaceMethod = metaspaceMethod;
this.holder = holder;
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
final long constMethod = getConstMethod();
/*
@ -106,7 +124,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
if (metaspaceConstantPool == holder.getConstantPool().getMetaspaceConstantPool()) {
this.constantPool = holder.getConstantPool();
} else {
this.constantPool = runtime().getCompilerToVM().getConstantPool(null, constMethod + config.constMethodConstantsOffset);
this.constantPool = compilerToVM().getConstantPool(null, constMethod + config.constMethodConstantsOffset);
}
final int nameIndex = UNSAFE.getChar(constMethod + config.constMethodNameIndexOffset);
@ -126,7 +144,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
*/
private long getConstMethod() {
assert metaspaceMethod != 0;
return UNSAFE.getAddress(metaspaceMethod + runtime().getConfig().methodConstMethodOffset);
return UNSAFE.getAddress(metaspaceMethod + config().methodConstMethodOffset);
}
@Override
@ -152,7 +170,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
* @return flags of this method
*/
private int getFlags() {
return UNSAFE.getByte(metaspaceMethod + runtime().getConfig().methodFlagsOffset);
return UNSAFE.getByte(metaspaceMethod + config().methodFlagsOffset);
}
/**
@ -161,7 +179,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
* @return flags of this method's ConstMethod
*/
private int getConstMethodFlags() {
return UNSAFE.getChar(getConstMethod() + runtime().getConfig().constMethodFlagsOffset);
return UNSAFE.getChar(getConstMethod() + config().constMethodFlagsOffset);
}
@Override
@ -172,20 +190,16 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
/**
* Gets the address of the C++ Method object for this method.
*/
public JavaConstant getMetaspaceMethodConstant() {
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(getHostWordKind(), metaspaceMethod, this, false);
}
public long getMetaspaceMethod() {
return metaspaceMethod;
public Constant getMetaspaceMethodConstant() {
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false);
}
public long getMetaspacePointer() {
return getMetaspaceMethod();
return metaspaceMethod;
}
@Override
public JavaConstant getEncoding() {
public Constant getEncoding() {
return getMetaspaceMethodConstant();
}
@ -194,7 +208,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
* modifiers as well as the HotSpot internal modifiers.
*/
public int getAllModifiers() {
return UNSAFE.getInt(metaspaceMethod + runtime().getConfig().methodAccessFlagsOffset);
return UNSAFE.getInt(metaspaceMethod + config().methodAccessFlagsOffset);
}
@Override
@ -213,7 +227,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
return null;
}
if (code == null && holder.isLinked()) {
code = runtime().getCompilerToVM().getBytecode(this);
code = compilerToVM().getBytecode(this);
assert code.length == getCodeSize() : "expected: " + getCodeSize() + ", actual: " + code.length;
}
return code;
@ -221,20 +235,20 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
@Override
public int getCodeSize() {
return UNSAFE.getChar(getConstMethod() + runtime().getConfig().constMethodCodeSizeOffset);
return UNSAFE.getChar(getConstMethod() + config().constMethodCodeSizeOffset);
}
@Override
public ExceptionHandler[] getExceptionHandlers() {
final boolean hasExceptionTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasExceptionTable) != 0;
final boolean hasExceptionTable = (getConstMethodFlags() & config().constMethodHasExceptionTable) != 0;
if (!hasExceptionTable) {
return new ExceptionHandler[0];
}
HotSpotVMConfig config = runtime().getConfig();
final int exceptionTableLength = runtime().getCompilerToVM().getExceptionTableLength(this);
HotSpotVMConfig config = config();
final int exceptionTableLength = compilerToVM().getExceptionTableLength(this);
ExceptionHandler[] handlers = new ExceptionHandler[exceptionTableLength];
long exceptionTableElement = runtime().getCompilerToVM().getExceptionTableStart(this);
long exceptionTableElement = compilerToVM().getExceptionTableStart(this);
for (int i = 0; i < exceptionTableLength; i++) {
final int startPc = UNSAFE.getChar(exceptionTableElement + config.exceptionTableElementStartPcOffset);
@ -273,7 +287,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
* @return true if CallerSensitive annotation present, false otherwise
*/
public boolean isCallerSensitive() {
return (getFlags() & runtime().getConfig().methodFlagsCallerSensitive) != 0;
return (getFlags() & config().methodFlagsCallerSensitive) != 0;
}
/**
@ -282,7 +296,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
* @return true if ForceInline annotation present, false otherwise
*/
public boolean isForceInline() {
return (getFlags() & runtime().getConfig().methodFlagsForceInline) != 0;
return (getFlags() & config().methodFlagsForceInline) != 0;
}
/**
@ -291,14 +305,14 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
* @return true if DontInline annotation present, false otherwise
*/
public boolean isDontInline() {
return (getFlags() & runtime().getConfig().methodFlagsDontInline) != 0;
return (getFlags() & config().methodFlagsDontInline) != 0;
}
/**
* Manually adds a DontInline annotation to this method.
*/
public void setNotInlineable() {
runtime().getCompilerToVM().doNotInlineOrCompile(this);
compilerToVM().doNotInlineOrCompile(this);
}
/**
@ -308,7 +322,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
* @return true if special method ignored by security stack walks, false otherwise
*/
public boolean ignoredBySecurityStackWalk() {
return runtime().getCompilerToVM().methodIsIgnoredBySecurityStackWalk(this);
return compilerToVM().methodIsIgnoredBySecurityStackWalk(this);
}
@Override
@ -326,7 +340,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
if (isAbstract() || isNative()) {
return 0;
}
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
return UNSAFE.getChar(getConstMethod() + config.methodMaxLocalsOffset);
}
@ -335,7 +349,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
if (isAbstract() || isNative()) {
return 0;
}
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
return config.extraStackEntries + UNSAFE.getChar(getConstMethod() + config.constMethodMaxStackOffset);
}
@ -343,10 +357,10 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
public StackTraceElement asStackTraceElement(int bci) {
if (bci < 0 || bci >= getCodeSize()) {
// HotSpot code can only construct stack trace elements for valid bcis
StackTraceElement ste = runtime().getCompilerToVM().getStackTraceElement(this, 0);
StackTraceElement ste = compilerToVM().getStackTraceElement(this, 0);
return new StackTraceElement(ste.getClassName(), ste.getMethodName(), ste.getFileName(), -1);
}
return runtime().getCompilerToVM().getStackTraceElement(this, bci);
return compilerToVM().getStackTraceElement(this, bci);
}
public ResolvedJavaMethod uniqueConcreteMethod(HotSpotResolvedObjectType receiver) {
@ -361,7 +375,11 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
// seeing A.foo().
return null;
}
return runtime().getCompilerToVM().findUniqueConcreteMethod(((HotSpotResolvedObjectTypeImpl) receiver), this);
if (this.isDefault()) {
// CHA for default methods doesn't work and may crash the VM
return null;
}
return compilerToVM().findUniqueConcreteMethod(((HotSpotResolvedObjectTypeImpl) receiver), this);
}
@Override
@ -375,7 +393,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
* @return the value of {@code Method::_code}
*/
private long getCompiledCode() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
return UNSAFE.getAddress(metaspaceMethod + config.methodCodeOffset);
}
@ -395,7 +413,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
public boolean hasCompiledCodeAtLevel(int level) {
long compiledCode = getCompiledCode();
if (compiledCode != 0) {
return UNSAFE.getInt(compiledCode + runtime().getConfig().nmethodCompLevelOffset) == level;
return UNSAFE.getInt(compiledCode + config().nmethodCompLevelOffset) == level;
}
return false;
}
@ -407,7 +425,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
ProfilingInfo info;
if (UseProfilingInformation.getValue() && methodData == null) {
long metaspaceMethodData = UNSAFE.getAddress(metaspaceMethod + runtime().getConfig().methodDataOffset);
long metaspaceMethodData = UNSAFE.getAddress(metaspaceMethod + config().methodDataOffset);
if (metaspaceMethodData != 0) {
methodData = new HotSpotMethodData(metaspaceMethodData, this);
if (TraceMethodDataFilter != null && this.format("%H.%n").contains(TraceMethodDataFilter)) {
@ -429,7 +447,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
@Override
public void reprofile() {
runtime().getCompilerToVM().reprofile(this);
compilerToVM().reprofile(this);
}
@Override
@ -439,31 +457,19 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
@Override
public Annotation[][] getParameterAnnotations() {
if (isConstructor()) {
Constructor<?> javaConstructor = toJavaConstructor();
return javaConstructor == null ? null : javaConstructor.getParameterAnnotations();
}
Method javaMethod = toJava();
Executable javaMethod = toJava();
return javaMethod == null ? null : javaMethod.getParameterAnnotations();
}
@Override
public Annotation[] getAnnotations() {
if (isConstructor()) {
Constructor<?> javaConstructor = toJavaConstructor();
return javaConstructor == null ? new Annotation[0] : javaConstructor.getAnnotations();
}
Method javaMethod = toJava();
Executable javaMethod = toJava();
return javaMethod == null ? new Annotation[0] : javaMethod.getAnnotations();
}
@Override
public <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
if (isConstructor()) {
Constructor<?> javaConstructor = toJavaConstructor();
return javaConstructor == null ? null : javaConstructor.getAnnotation(annotationClass);
}
Method javaMethod = toJava();
Executable javaMethod = toJava();
return javaMethod == null ? null : javaMethod.getAnnotation(annotationClass);
}
@ -478,11 +484,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
@Override
public Type[] getGenericParameterTypes() {
if (isConstructor()) {
Constructor<?> javaConstructor = toJavaConstructor();
return javaConstructor == null ? null : javaConstructor.getGenericParameterTypes();
}
Method javaMethod = toJava();
Executable javaMethod = toJava();
return javaMethod == null ? null : javaMethod.getGenericParameterTypes();
}
@ -498,25 +500,13 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
return result;
}
private Method toJava() {
private Executable toJava() {
if (toJavaCache != null) {
return (Method) toJavaCache;
return toJavaCache;
}
try {
Method result = holder.mirror().getDeclaredMethod(name, signatureToTypes());
toJavaCache = result;
return result;
} catch (NoSuchMethodException | NoClassDefFoundError e) {
return null;
}
}
private Constructor<?> toJavaConstructor() {
if (toJavaCache != null) {
return (Constructor<?>) toJavaCache;
}
try {
Constructor<?> result = holder.mirror().getDeclaredConstructor(signatureToTypes());
Class<?>[] parameterTypes = signatureToTypes();
Executable result = isConstructor() ? holder.mirror().getDeclaredConstructor(parameterTypes) : holder.mirror().getDeclaredMethod(name, parameterTypes);
toJavaCache = result;
return result;
} catch (NoSuchMethodException | NoClassDefFoundError e) {
@ -529,7 +519,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
if (isDontInline()) {
return false;
}
return runtime().getCompilerToVM().canInlineMethod(this);
return compilerToVM().canInlineMethod(this);
}
@Override
@ -537,17 +527,17 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
if (isForceInline()) {
return true;
}
return runtime().getCompilerToVM().shouldInlineMethod(this);
return compilerToVM().shouldInlineMethod(this);
}
@Override
public LineNumberTable getLineNumberTable() {
final boolean hasLineNumberTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLineNumberTable) != 0;
final boolean hasLineNumberTable = (getConstMethodFlags() & config().constMethodHasLineNumberTable) != 0;
if (!hasLineNumberTable) {
return null;
}
long[] values = runtime().getCompilerToVM().getLineNumberTable(this);
long[] values = compilerToVM().getLineNumberTable(this);
if (values == null || values.length == 0) {
// Empty table so treat is as non-existent
return null;
@ -566,14 +556,14 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
@Override
public LocalVariableTable getLocalVariableTable() {
final boolean hasLocalVariableTable = (getConstMethodFlags() & runtime().getConfig().constMethodHasLocalVariableTable) != 0;
final boolean hasLocalVariableTable = (getConstMethodFlags() & config().constMethodHasLocalVariableTable) != 0;
if (!hasLocalVariableTable) {
return null;
}
HotSpotVMConfig config = runtime().getConfig();
long localVariableTableElement = runtime().getCompilerToVM().getLocalVariableTableStart(this);
final int localVariableTableLength = runtime().getCompilerToVM().getLocalVariableTableLength(this);
HotSpotVMConfig config = config();
long localVariableTableElement = compilerToVM().getLocalVariableTableStart(this);
final int localVariableTableLength = compilerToVM().getLocalVariableTableLength(this);
Local[] locals = new Local[localVariableTableLength];
for (int i = 0; i < localVariableTableLength; i++) {
@ -606,7 +596,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
if (!isInVirtualMethodTable(resolved)) {
throw new JVMCIError("%s does not have a vtable entry in type %s", this, resolved);
}
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
final int vtableIndex = getVtableIndex((HotSpotResolvedObjectTypeImpl) resolved);
return config.instanceKlassVtableStartOffset() + vtableIndex * config.vtableEntrySize + config.vtableEntryMethodOffset;
}
@ -623,11 +613,11 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
private int getVtableIndex(HotSpotResolvedObjectTypeImpl resolved) {
if (!holder.isLinked()) {
return runtime().getConfig().invalidVtableIndex;
return config().invalidVtableIndex;
}
if (holder.isInterface()) {
if (resolved.isInterface()) {
return runtime().getConfig().invalidVtableIndex;
return config().invalidVtableIndex;
}
return getVtableIndexForInterfaceMethod(resolved);
}
@ -640,8 +630,8 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
* @return virtual table index
*/
private int getVtableIndex() {
assert!holder.isInterface();
HotSpotVMConfig config = runtime().getConfig();
assert !holder.isInterface();
HotSpotVMConfig config = config();
int result = UNSAFE.getInt(metaspaceMethod + config.methodVtableIndexOffset);
assert result >= config.nonvirtualVtableIndex : "must be linked";
return result;
@ -649,7 +639,7 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
private int getVtableIndexForInterfaceMethod(ResolvedJavaType resolved) {
HotSpotResolvedObjectTypeImpl hotspotType = (HotSpotResolvedObjectTypeImpl) resolved;
return runtime().getCompilerToVM().getVtableIndexForInterfaceMethod(hotspotType, this);
return compilerToVM().getVtableIndexForInterfaceMethod(hotspotType, this);
}
/**
@ -682,14 +672,14 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
}
public int intrinsicId() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
return UNSAFE.getChar(metaspaceMethod + config.methodIntrinsicIdOffset);
}
@Override
public JavaConstant invoke(JavaConstant receiver, JavaConstant[] arguments) {
assert!isConstructor();
Method javaMethod = toJava();
assert !isConstructor();
Method javaMethod = (Method) toJava();
javaMethod.setAccessible(true);
Object[] objArguments = new Object[arguments.length];
@ -714,13 +704,13 @@ public final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implement
* @return compile id
*/
public int allocateCompileId(int entryBCI) {
return runtime().getCompilerToVM().allocateCompileId(this, entryBCI);
return compilerToVM().allocateCompileId(this, entryBCI);
}
public boolean hasCodeAtLevel(int entryBCI, int level) {
if (entryBCI == runtime().getConfig().invocationEntryBci) {
if (entryBCI == config().invocationEntryBci) {
return hasCompiledCodeAtLevel(level);
}
return runtime().getCompilerToVM().hasCompiledCodeForOSR(this, entryBCI, level);
return compilerToVM().hasCompiledCodeForOSR(this, entryBCI, level);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015, 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
@ -22,11 +22,11 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.ResolvedJavaType;
public abstract class HotSpotResolvedJavaType extends HotSpotJavaType implements ResolvedJavaType {
public HotSpotResolvedJavaType(String name) {
HotSpotResolvedJavaType(String name) {
super(name);
}

View File

@ -22,14 +22,30 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.Assumptions.*;
import jdk.vm.ci.meta.Assumptions.AssumptionResult;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
*/
public interface HotSpotResolvedObjectType extends ResolvedJavaType {
/**
* Gets the JVMCI mirror for a {@link Class} object.
*
* @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
*/
static HotSpotResolvedObjectType fromObjectClass(Class<?> javaClass) {
return HotSpotResolvedObjectTypeImpl.fromObjectClass(javaClass);
}
HotSpotResolvedObjectType getArrayClass();
ResolvedJavaType getComponentType();

View File

@ -22,24 +22,44 @@
*/
package jdk.vm.ci.hotspot;
import static java.util.Objects.*;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.*;
import static java.util.Objects.requireNonNull;
import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.HotSpotVMConfig.config;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.net.*;
import java.nio.*;
import java.util.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import jdk.vm.ci.common.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.Assumptions.*;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.Assumptions.AssumptionResult;
import jdk.vm.ci.meta.Assumptions.ConcreteMethod;
import jdk.vm.ci.meta.Assumptions.ConcreteSubtype;
import jdk.vm.ci.meta.Assumptions.LeafType;
import jdk.vm.ci.meta.Assumptions.NoFinalizableSubclass;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.MetaUtil;
import jdk.vm.ci.meta.ModifiersProvider;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.TrustedInterface;
/**
* Implementation of {@link JavaType} for resolved non-primitive HotSpot classes.
*/
public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, HotSpotProxified, MetaspaceWrapperObject {
final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType implements HotSpotResolvedObjectType, HotSpotProxified, MetaspaceWrapperObject {
/**
* The Java class this type represents.
@ -58,7 +78,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
*
* @return the {@link HotSpotResolvedJavaType} corresponding to {@code javaClass}
*/
public static HotSpotResolvedObjectTypeImpl fromObjectClass(Class<?> javaClass) {
static HotSpotResolvedObjectTypeImpl fromObjectClass(Class<?> javaClass) {
return (HotSpotResolvedObjectTypeImpl) runtime().fromClass(javaClass);
}
@ -108,11 +128,11 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
/**
* Gets the metaspace Klass for this type.
*/
public long getMetaspaceKlass() {
long getMetaspaceKlass() {
if (HotSpotJVMCIRuntime.getHostWordKind() == JavaKind.Long) {
return UNSAFE.getLong(javaClass, (long) runtime().getConfig().klassOffset);
return UNSAFE.getLong(javaClass, (long) config().klassOffset);
}
return UNSAFE.getInt(javaClass, (long) runtime().getConfig().klassOffset) & 0xFFFFFFFFL;
return UNSAFE.getInt(javaClass, (long) config().klassOffset) & 0xFFFFFFFFL;
}
public long getMetaspacePointer() {
@ -129,7 +149,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
}
public int getAccessFlags() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
return UNSAFE.getInt(getMetaspaceKlass() + config.klassAccessFlagsOffset);
}
@ -149,7 +169,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
@Override
public AssumptionResult<ResolvedJavaType> findLeafConcreteSubtype() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
if (isArray()) {
return getElementalType().isLeaf() ? new AssumptionResult<>(this) : null;
} else if (isInterface()) {
@ -214,7 +234,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
* @return value of the subklass field as metaspace klass pointer
*/
private HotSpotResolvedObjectTypeImpl getSubklass() {
return runtime().getCompilerToVM().getResolvedJavaType(this, runtime().getConfig().subklassOffset, false);
return compilerToVM().getResolvedJavaType(this, config().subklassOffset, false);
}
@Override
@ -241,7 +261,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
if (!isInterface()) {
throw new JVMCIError("Cannot call getSingleImplementor() on a non-interface type: %s", this);
}
return runtime().getCompilerToVM().getImplementor(this);
return compilerToVM().getImplementor(this);
}
public HotSpotResolvedObjectTypeImpl getSupertype() {
@ -289,14 +309,14 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
}
@Override
public JavaConstant getObjectHub() {
public Constant getObjectHub() {
return klass();
}
@Override
public AssumptionResult<Boolean> hasFinalizableSubclass() {
assert !isArray();
if (!runtime().getCompilerToVM().hasFinalizableSubclass(this)) {
if (!compilerToVM().hasFinalizableSubclass(this)) {
return new AssumptionResult<>(false, new NoFinalizableSubclass(this));
}
return new AssumptionResult<>(true);
@ -304,7 +324,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
@Override
public boolean hasFinalizer() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
return (getAccessFlags() & config.klassHasFinalizerFlag) != 0;
}
@ -320,12 +340,12 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
@Override
public boolean isInitialized() {
return isArray() ? true : getInitState() == runtime().getConfig().instanceKlassStateFullyInitialized;
return isArray() ? true : getInitState() == config().instanceKlassStateFullyInitialized;
}
@Override
public boolean isLinked() {
return isArray() ? true : getInitState() >= runtime().getConfig().instanceKlassStateLinked;
return isArray() ? true : getInitState() >= config().instanceKlassStateLinked;
}
/**
@ -336,7 +356,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
*/
private int getInitState() {
assert !isArray() : "_init_state only exists in InstanceKlass";
return UNSAFE.getByte(getMetaspaceKlass() + runtime().getConfig().instanceKlassInitStateOffset) & 0xFF;
return UNSAFE.getByte(getMetaspaceKlass() + config().instanceKlassInitStateOffset) & 0xFF;
}
@Override
@ -405,12 +425,12 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
}
HotSpotResolvedJavaMethodImpl hotSpotMethod = (HotSpotResolvedJavaMethodImpl) method;
HotSpotResolvedObjectTypeImpl hotSpotCallerType = (HotSpotResolvedObjectTypeImpl) callerType;
return runtime().getCompilerToVM().resolveMethod(this, hotSpotMethod, hotSpotCallerType);
return compilerToVM().resolveMethod(this, hotSpotMethod, hotSpotCallerType);
}
public HotSpotConstantPool getConstantPool() {
if (constantPool == null) {
constantPool = runtime().getCompilerToVM().getConstantPool(this, runtime().getConfig().instanceKlassConstantsOffset);
constantPool = compilerToVM().getConstantPool(this, config().instanceKlassConstantsOffset);
}
return constantPool;
}
@ -424,7 +444,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
assert !isArray();
assert !isInterface();
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
final int layoutHelper = layoutHelper();
assert layoutHelper > config.klassLayoutHelperNeutralValue : "must be instance";
@ -438,7 +458,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
}
public int layoutHelper() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
return UNSAFE.getInt(getMetaspaceKlass() + config.klassLayoutHelperOffset);
}
@ -458,7 +478,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
}
public int getVtableLength() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
if (isInterface() || isArray()) {
/* Everything has the core vtable of java.lang.Object */
return config.baseVtableLength();
@ -547,7 +567,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
* @param index index to the fields array
*/
public FieldInfo(int index) {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
// Get Klass::_fields
final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
assert config.fieldInfoFieldSlots == 6 : "revisit the field parsing code";
@ -555,19 +575,19 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
}
private int getAccessFlags() {
return readFieldSlot(runtime().getConfig().fieldInfoAccessFlagsOffset);
return readFieldSlot(config().fieldInfoAccessFlagsOffset);
}
private int getNameIndex() {
return readFieldSlot(runtime().getConfig().fieldInfoNameIndexOffset);
return readFieldSlot(config().fieldInfoNameIndexOffset);
}
private int getSignatureIndex() {
return readFieldSlot(runtime().getConfig().fieldInfoSignatureIndexOffset);
return readFieldSlot(config().fieldInfoSignatureIndexOffset);
}
public int getOffset() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
final int lowPacked = readFieldSlot(config.fieldInfoLowPackedOffset);
final int highPacked = readFieldSlot(config.fieldInfoHighPackedOffset);
final int offset = ((highPacked << Short.SIZE) | lowPacked) >> config.fieldInfoTagSize;
@ -606,7 +626,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
}
private boolean isInternal() {
return (getAccessFlags() & runtime().getConfig().jvmAccFieldInternal) != 0;
return (getAccessFlags() & config().jvmAccFieldInternal) != 0;
}
public boolean isStatic() {
@ -614,7 +634,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
}
public boolean hasGenericSignature() {
return (getAccessFlags() & runtime().getConfig().jvmAccFieldHasGenericSignature) != 0;
return (getAccessFlags() & config().jvmAccFieldHasGenericSignature) != 0;
}
}
@ -707,7 +727,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
* See {@code FieldStreamBase::init_generic_signature_start_slot}
*/
private int getFieldCount() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
final long metaspaceFields = UNSAFE.getAddress(getMetaspaceKlass() + config.instanceKlassFieldsOffset);
int metaspaceFieldsLength = UNSAFE.getInt(metaspaceFields + config.arrayU1LengthOffset);
int fieldCount = 0;
@ -729,7 +749,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
@Override
public String getSourceFileName() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
final int sourceFileNameIndex = UNSAFE.getChar(getMetaspaceKlass() + config.instanceKlassSourceFileNameIndexOffset);
if (sourceFileNameIndex == 0) {
return null;
@ -784,21 +804,21 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
/**
* Gets the metaspace Klass boxed in a {@link JavaConstant}.
*/
public JavaConstant klass() {
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(runtime().getHostJVMCIBackend().getTarget().wordKind, getMetaspaceKlass(), this, false);
public Constant klass() {
return HotSpotMetaspaceConstantImpl.forMetaspaceObject(this, false);
}
public boolean isPrimaryType() {
return runtime().getConfig().secondarySuperCacheOffset != superCheckOffset();
return config().secondarySuperCacheOffset != superCheckOffset();
}
public int superCheckOffset() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
return UNSAFE.getInt(getMetaspaceKlass() + config.superCheckOffsetOffset);
}
public long prototypeMarkWord() {
HotSpotVMConfig config = runtime().getConfig();
HotSpotVMConfig config = config();
if (isArray()) {
return config.arrayPrototypeMarkWord();
} else {
@ -874,7 +894,7 @@ public final class HotSpotResolvedObjectTypeImpl extends HotSpotResolvedJavaType
}
public ResolvedJavaMethod getClassInitializer() {
return runtime().getCompilerToVM().getClassInitializer(this);
return compilerToVM().getClassInitializer(this);
}
@Override

View File

@ -22,15 +22,21 @@
*/
package jdk.vm.ci.hotspot;
import static java.util.Objects.*;
import static java.util.Objects.requireNonNull;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.net.*;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
import java.lang.reflect.Modifier;
import java.net.URL;
import jdk.vm.ci.common.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.Assumptions.AssumptionResult;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaField;
import jdk.vm.ci.meta.ResolvedJavaMethod;
import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Implementation of {@link JavaType} for primitive HotSpot types.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 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
@ -22,19 +22,39 @@
*/
package jdk.vm.ci.hotspot;
/**
* Used to suppress <a href="http://findbugs.sourceforge.net">FindBugs</a> warnings.
*/
public @interface SuppressFBWarnings {
/**
* The set of FindBugs <a
* href="http://findbugs.sourceforge.net/bugDescriptions.html">warnings</a> that are to be
* suppressed in annotated element. The value can be a bug category, kind or pattern.
*/
String[] value();
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.code.InvalidInstalledCodeException;
import jdk.vm.ci.meta.ResolvedJavaMethod;
/**
* Reason why the warning is suppressed.
*/
String justification();
/**
* Implementation of {@link InstalledCode} for code installed as a RuntimeStub.
*/
public class HotSpotRuntimeStub extends HotSpotInstalledCode {
public HotSpotRuntimeStub(String name) {
super(name);
}
public ResolvedJavaMethod getMethod() {
return null;
}
@Override
public boolean isValid() {
return true;
}
@Override
public void invalidate() {
}
@Override
public String toString() {
return String.format("InstalledRuntimeStub[stub=%s, codeBlob=0x%x]", name, getAddress());
}
@Override
public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
throw new InternalError("Cannot call stub " + name);
}
}

View File

@ -22,16 +22,23 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.LIRKind;
import jdk.vm.ci.meta.VMConstant;
import jdk.vm.ci.meta.Value;
public final class HotSpotSentinelConstant extends Value implements JavaConstant, VMConstant {
public HotSpotSentinelConstant(JavaKind kind) {
super(LIRKind.reference(kind));
private final JavaKind javaKind;
public HotSpotSentinelConstant(LIRKind lirKind, JavaKind javaKind) {
super(lirKind);
this.javaKind = javaKind;
}
public JavaKind getJavaKind() {
return (JavaKind) getLIRKind().getPlatformKind();
return javaKind;
}
@Override

View File

@ -22,10 +22,14 @@
*/
package jdk.vm.ci.hotspot;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import jdk.vm.ci.common.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaType;
import jdk.vm.ci.meta.Signature;
/**
* Represents a method signature.
@ -131,7 +135,7 @@ public class HotSpotSignature implements Signature {
JavaKind kind = JavaKind.fromPrimitiveOrVoidTypeChar(name.charAt(0));
return runtime.getHostJVMCIBackend().getMetaAccess().lookupJavaType(kind.toJavaClass());
}
return new HotSpotUnresolvedJavaType(name, runtime);
return HotSpotUnresolvedJavaType.create(runtime, name);
}
@Override

View File

@ -22,13 +22,63 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
public class HotSpotSpeculationLog extends SpeculationLog {
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.SpeculationLog;
public class HotSpotSpeculationLog implements SpeculationLog {
/** Written by the C++ code that performs deoptimization. */
private volatile Object lastFailed;
/** All speculations that have been a deoptimization reason. */
private Set<SpeculationReason> failedSpeculations;
/** Strong references to all reasons embededded in the current nmethod. */
private volatile Collection<SpeculationReason> speculations;
@Override
public JavaConstant speculate(Object reason) {
addSpeculation(reason);
public synchronized void collectFailedSpeculations() {
if (lastFailed != null) {
if (failedSpeculations == null) {
failedSpeculations = new HashSet<>(2);
}
failedSpeculations.add((SpeculationReason) lastFailed);
lastFailed = null;
speculations = null;
}
}
@Override
public boolean maySpeculate(SpeculationReason reason) {
if (failedSpeculations != null && failedSpeculations.contains(reason)) {
return false;
}
return true;
}
@Override
public JavaConstant speculate(SpeculationReason reason) {
assert maySpeculate(reason);
/*
* Objects referenced from nmethods are weak references. We need a strong reference to the
* reason objects that are embedded in nmethods, so we add them to the speculations
* collection.
*/
if (speculations == null) {
synchronized (this) {
if (speculations == null) {
speculations = new ConcurrentLinkedQueue<>();
}
}
}
speculations.add(reason);
return HotSpotObjectConstantImpl.forObject(reason);
}
}

View File

@ -22,10 +22,10 @@
*/
package jdk.vm.ci.hotspot;
import java.util.*;
import java.util.Arrays;
import jdk.vm.ci.code.stack.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.code.stack.InspectedFrame;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public class HotSpotStackFrameReference implements InspectedFrame {

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, 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.code.stack.InspectedFrameVisitor;
import jdk.vm.ci.code.stack.StackIntrospection;
import jdk.vm.ci.meta.ResolvedJavaMethod;
public class HotSpotStackIntrospection implements StackIntrospection {
protected final HotSpotJVMCIRuntimeProvider runtime;
public HotSpotStackIntrospection(HotSpotJVMCIRuntimeProvider runtime) {
this.runtime = runtime;
}
@Override
public <T> T iterateFrames(ResolvedJavaMethod[] initialMethods, ResolvedJavaMethod[] matchingMethods, int initialSkip, InspectedFrameVisitor<T> visitor) {
CompilerToVM compilerToVM = runtime.getCompilerToVM();
HotSpotStackFrameReference current = compilerToVM.getNextStackFrame(null, initialMethods, initialSkip);
while (current != null) {
T result = visitor.visitFrame(current);
if (result != null) {
return result;
}
current = compilerToVM.getNextStackFrame(current, matchingMethods, 0);
}
return null;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2015, 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
@ -22,18 +22,19 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaField;
import jdk.vm.ci.meta.JavaType;
/**
* A implementation of {@link JavaField} for an unresolved field.
*/
public class HotSpotUnresolvedField implements JavaField {
class HotSpotUnresolvedField implements JavaField {
private final String name;
private final JavaType holder;
private final JavaType type;
public HotSpotUnresolvedField(JavaType holder, String name, JavaType type) {
HotSpotUnresolvedField(JavaType holder, String name, JavaType type) {
this.name = name;
this.type = type;
this.holder = holder;

View File

@ -22,16 +22,18 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.meta.JavaKind;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.ResolvedJavaType;
/**
* Implementation of {@link JavaType} for unresolved HotSpot classes.
*/
public class HotSpotUnresolvedJavaType extends HotSpotJavaType {
final class HotSpotUnresolvedJavaType extends HotSpotJavaType {
private final HotSpotJVMCIRuntimeProvider runtime;
public HotSpotUnresolvedJavaType(String name, HotSpotJVMCIRuntimeProvider runtime) {
private HotSpotUnresolvedJavaType(String name, HotSpotJVMCIRuntimeProvider runtime) {
super(name);
assert name.charAt(0) == '[' || name.charAt(name.length() - 1) == ';' : name;
this.runtime = runtime;
@ -40,7 +42,7 @@ public class HotSpotUnresolvedJavaType extends HotSpotJavaType {
/**
* Creates an unresolved type for a valid {@link JavaType#getName() type name}.
*/
public static HotSpotUnresolvedJavaType create(HotSpotJVMCIRuntimeProvider runtime, String name) {
static HotSpotUnresolvedJavaType create(HotSpotJVMCIRuntimeProvider runtime, String name) {
return new HotSpotUnresolvedJavaType(name, runtime);
}

View File

@ -23,14 +23,23 @@
package jdk.vm.ci.hotspot;
import static jdk.vm.ci.common.UnsafeUtil.readCString;
import static jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.runtime;
import static jdk.vm.ci.hotspot.UnsafeAccess.UNSAFE;
import java.lang.reflect.*;
import java.util.*;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Iterator;
import sun.misc.*;
import jdk.vm.ci.common.*;
import jdk.vm.ci.hotspotvmconfig.*;
import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMAddress;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMConstant;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMData;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMField;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMFlag;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMManual;
import jdk.vm.ci.hotspotvmconfig.HotSpotVMType;
import sun.misc.Unsafe;
//JaCoCo Exclude
@ -41,6 +50,13 @@ import jdk.vm.ci.hotspotvmconfig.*;
*/
public class HotSpotVMConfig {
/**
* Gets the configuration associated with the singleton {@link HotSpotJVMCIRuntime}.
*/
public static HotSpotVMConfig config() {
return runtime().getConfig();
}
/**
* Maximum allowed size of allocated area for a frame.
*/
@ -48,7 +64,7 @@ public class HotSpotVMConfig {
public HotSpotVMConfig(CompilerToVM compilerToVm) {
// Get raw pointer to the array that contains all gHotSpotVM values.
final long gHotSpotVMData = compilerToVm.initializeConfiguration();
final long gHotSpotVMData = compilerToVm.initializeConfiguration(this);
assert gHotSpotVMData != 0;
// Make FindBugs happy.
@ -106,6 +122,8 @@ public class HotSpotVMConfig {
handleDeoptStub = deoptBlob + UNSAFE.getInt(deoptBlob + codeBlobCodeOffsetOffset) + UNSAFE.getInt(deoptBlob + deoptimizationBlobUnpackOffsetOffset);
uncommonTrapStub = deoptBlob + UNSAFE.getInt(deoptBlob + codeBlobCodeOffsetOffset) + UNSAFE.getInt(deoptBlob + deoptimizationBlobUncommonTrapOffsetOffset);
tlabAlignmentReserve = roundUp(threadLocalAllocBufferEndReserve(), minObjAlignment());
assert check();
assert HotSpotVMConfigVerifier.check();
}
@ -844,6 +862,7 @@ public class HotSpotVMConfig {
@HotSpotVMConstant(name = "ASSERT") @Stable public boolean cAssertions;
public final boolean windowsOs = System.getProperty("os.name", "").startsWith("Windows");
public final boolean linuxOs = System.getProperty("os.name", "").startsWith("Linux");
@HotSpotVMFlag(name = "CodeEntryAlignment") @Stable public int codeEntryAlignment;
@HotSpotVMFlag(name = "VerifyOops") @Stable public boolean verifyOops;
@ -938,6 +957,16 @@ public class HotSpotVMConfig {
@HotSpotVMConstant(name = "VM_Version::CPU_ERMS", archs = {"amd64"}) @Stable public long cpuERMS;
@HotSpotVMConstant(name = "VM_Version::CPU_CLMUL", archs = {"amd64"}) @Stable public long cpuCLMUL;
@HotSpotVMConstant(name = "VM_Version::CPU_BMI1", archs = {"amd64"}) @Stable public long cpuBMI1;
@HotSpotVMConstant(name = "VM_Version::CPU_BMI2", archs = {"amd64"}) @Stable public long cpuBMI2;
@HotSpotVMConstant(name = "VM_Version::CPU_RTM", archs = {"amd64"}) @Stable public long cpuRTM;
@HotSpotVMConstant(name = "VM_Version::CPU_ADX", archs = {"amd64"}) @Stable public long cpuADX;
@HotSpotVMConstant(name = "VM_Version::CPU_AVX512F", archs = {"amd64"}) @Stable public long cpuAVX512F;
@HotSpotVMConstant(name = "VM_Version::CPU_AVX512DQ", archs = {"amd64"}) @Stable public long cpuAVX512DQ;
@HotSpotVMConstant(name = "VM_Version::CPU_AVX512PF", archs = {"amd64"}) @Stable public long cpuAVX512PF;
@HotSpotVMConstant(name = "VM_Version::CPU_AVX512ER", archs = {"amd64"}) @Stable public long cpuAVX512ER;
@HotSpotVMConstant(name = "VM_Version::CPU_AVX512CD", archs = {"amd64"}) @Stable public long cpuAVX512CD;
@HotSpotVMConstant(name = "VM_Version::CPU_AVX512BW", archs = {"amd64"}) @Stable public long cpuAVX512BW;
@HotSpotVMConstant(name = "VM_Version::CPU_AVX512VL", archs = {"amd64"}) @Stable public long cpuAVX512VL;
// SPARC specific values
@HotSpotVMField(name = "VM_Version::_features", type = "int", get = HotSpotVMField.Type.VALUE, archs = {"sparc"}) @Stable public int sparcFeatures;
@ -945,6 +974,26 @@ public class HotSpotVMConfig {
@HotSpotVMConstant(name = "VM_Version::vis2_instructions_m", archs = {"sparc"}) @Stable public int vis2Instructions;
@HotSpotVMConstant(name = "VM_Version::vis1_instructions_m", archs = {"sparc"}) @Stable public int vis1Instructions;
@HotSpotVMConstant(name = "VM_Version::cbcond_instructions_m", archs = {"sparc"}) @Stable public int cbcondInstructions;
@HotSpotVMConstant(name = "VM_Version::v8_instructions_m", archs = {"sparc"}) @Stable public int v8Instructions;
@HotSpotVMConstant(name = "VM_Version::hardware_mul32_m", archs = {"sparc"}) @Stable public int hardwareMul32;
@HotSpotVMConstant(name = "VM_Version::hardware_div32_m", archs = {"sparc"}) @Stable public int hardwareDiv32;
@HotSpotVMConstant(name = "VM_Version::hardware_fsmuld_m", archs = {"sparc"}) @Stable public int hardwareFsmuld;
@HotSpotVMConstant(name = "VM_Version::hardware_popc_m", archs = {"sparc"}) @Stable public int hardwarePopc;
@HotSpotVMConstant(name = "VM_Version::v9_instructions_m", archs = {"sparc"}) @Stable public int v9Instructions;
@HotSpotVMConstant(name = "VM_Version::sun4v_m", archs = {"sparc"}) @Stable public int sun4v;
@HotSpotVMConstant(name = "VM_Version::blk_init_instructions_m", archs = {"sparc"}) @Stable public int blkInitInstructions;
@HotSpotVMConstant(name = "VM_Version::fmaf_instructions_m", archs = {"sparc"}) @Stable public int fmafInstructions;
@HotSpotVMConstant(name = "VM_Version::fmau_instructions_m", archs = {"sparc"}) @Stable public int fmauInstructions;
@HotSpotVMConstant(name = "VM_Version::sparc64_family_m", archs = {"sparc"}) @Stable public int sparc64Family;
@HotSpotVMConstant(name = "VM_Version::M_family_m", archs = {"sparc"}) @Stable public int mFamily;
@HotSpotVMConstant(name = "VM_Version::T_family_m", archs = {"sparc"}) @Stable public int tFamily;
@HotSpotVMConstant(name = "VM_Version::T1_model_m", archs = {"sparc"}) @Stable public int t1Model;
@HotSpotVMConstant(name = "VM_Version::sparc5_instructions_m", archs = {"sparc"}) @Stable public int sparc5Instructions;
@HotSpotVMConstant(name = "VM_Version::aes_instructions_m", archs = {"sparc"}) @Stable public int aesInstructions;
@HotSpotVMConstant(name = "VM_Version::sha1_instruction_m", archs = {"sparc"}) @Stable public int sha1Instruction;
@HotSpotVMConstant(name = "VM_Version::sha256_instruction_m", archs = {"sparc"}) @Stable public int sha256Instruction;
@HotSpotVMConstant(name = "VM_Version::sha512_instruction_m", archs = {"sparc"}) @Stable public int sha512Instruction;
@HotSpotVMFlag(name = "UseBlockZeroing", archs = {"sparc"}) @Stable public boolean useBlockZeroing;
@HotSpotVMFlag(name = "BlockZeroingLowLimit", archs = {"sparc"}) @Stable public int blockZeroingLowLimit;
@ -1396,6 +1445,7 @@ public class HotSpotVMConfig {
@HotSpotVMField(name = "Thread::_allocated_bytes", type = "jlong", get = HotSpotVMField.Type.OFFSET) @Stable public int threadAllocatedBytesOffset;
@HotSpotVMFlag(name = "TLABWasteIncrement") @Stable public int tlabRefillWasteIncrement;
@HotSpotVMManual(name = "ThreadLocalAllocBuffer::alignment_reserve()") @Stable public int tlabAlignmentReserve;
@HotSpotVMField(name = "ThreadLocalAllocBuffer::_start", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferStartOffset;
@HotSpotVMField(name = "ThreadLocalAllocBuffer::_end", type = "HeapWord*", get = HotSpotVMField.Type.OFFSET) @Stable private int threadLocalAllocBufferEndOffset;
@ -1453,13 +1503,6 @@ public class HotSpotVMConfig {
return Integer.max(reserveSize, abstractVmVersionReserveForAllocationPrefetch);
}
/**
* See: {@code ThreadLocalAllocBuffer::alignment_reserve()}.
*/
public final int tlabAlignmentReserve() {
return roundUp(threadLocalAllocBufferEndReserve(), minObjAlignment());
}
@HotSpotVMFlag(name = "TLABStats") @Stable public boolean tlabStats;
// FIXME This is only temporary until the GC code is changed.
@ -1688,6 +1731,7 @@ public class HotSpotVMConfig {
@HotSpotVMConstant(name = "CodeInstaller::POLL_RETURN_NEAR") @Stable public int MARKID_POLL_RETURN_NEAR;
@HotSpotVMConstant(name = "CodeInstaller::POLL_FAR") @Stable public int MARKID_POLL_FAR;
@HotSpotVMConstant(name = "CodeInstaller::POLL_RETURN_FAR") @Stable public int MARKID_POLL_RETURN_FAR;
@HotSpotVMConstant(name = "CodeInstaller::CARD_TABLE_SHIFT") @Stable public int MARKID_CARD_TABLE_SHIFT;
@HotSpotVMConstant(name = "CodeInstaller::CARD_TABLE_ADDRESS") @Stable public int MARKID_CARD_TABLE_ADDRESS;
@HotSpotVMConstant(name = "CodeInstaller::HEAP_TOP_ADDRESS") @Stable public int MARKID_HEAP_TOP_ADDRESS;
@HotSpotVMConstant(name = "CodeInstaller::HEAP_END_ADDRESS") @Stable public int MARKID_HEAP_END_ADDRESS;
@ -1695,6 +1739,20 @@ public class HotSpotVMConfig {
@HotSpotVMConstant(name = "CodeInstaller::CRC_TABLE_ADDRESS") @Stable public int MARKID_CRC_TABLE_ADDRESS;
@HotSpotVMConstant(name = "CodeInstaller::INVOKE_INVALID") @Stable public int MARKID_INVOKE_INVALID;
@HotSpotVMConstant(name = "BitData::exception_seen_flag") @Stable public int bitDataExceptionSeenFlag;
@HotSpotVMConstant(name = "BitData::null_seen_flag") @Stable public int bitDataNullSeenFlag;
@HotSpotVMConstant(name = "CounterData::count_off") @Stable public int methodDataCountOffset;
@HotSpotVMConstant(name = "JumpData::taken_off_set") @Stable public int jumpDataTakenOffset;
@HotSpotVMConstant(name = "JumpData::displacement_off_set") @Stable public int jumpDataDisplacementOffset;
@HotSpotVMConstant(name = "ReceiverTypeData::nonprofiled_count_off_set") @Stable public int receiverTypeDataNonprofiledCountOffset;
@HotSpotVMConstant(name = "ReceiverTypeData::receiver_type_row_cell_count") @Stable public int receiverTypeDataReceiverTypeRowCellCount;
@HotSpotVMConstant(name = "ReceiverTypeData::receiver0_offset") @Stable public int receiverTypeDataReceiver0Offset;
@HotSpotVMConstant(name = "ReceiverTypeData::count0_offset") @Stable public int receiverTypeDataCount0Offset;
@HotSpotVMConstant(name = "BranchData::not_taken_off_set") @Stable public int branchDataNotTakenOffset;
@HotSpotVMConstant(name = "ArrayData::array_len_off_set") @Stable public int arrayDataArrayLenOffset;
@HotSpotVMConstant(name = "ArrayData::array_start_off_set") @Stable public int arrayDataArrayStartOffset;
@HotSpotVMConstant(name = "MultiBranchData::per_case_cell_count") @Stable public int multiBranchDataPerCaseCellCount;
// Checkstyle: resume
private boolean check() {

View File

@ -22,16 +22,25 @@
*/
package jdk.vm.ci.hotspot;
import static java.lang.String.*;
import static java.lang.String.format;
import java.io.*;
import java.lang.reflect.*;
import java.util.*;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Objects;
import jdk.internal.org.objectweb.asm.*;
import jdk.vm.ci.common.JVMCIError;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.org.objectweb.asm.Type;
import jdk.vm.ci.common.*;
import sun.misc.*;
import sun.misc.Unsafe;
/**
* A {@link ClassVisitor} that verifies {@link HotSpotVMConfig} does not access {@link Unsafe} from

View File

@ -22,8 +22,10 @@
*/
package jdk.vm.ci.hotspot;
import jdk.vm.ci.code.*;
import jdk.vm.ci.meta.*;
import jdk.vm.ci.code.CompilationResult;
import jdk.vm.ci.code.InstalledCode;
import jdk.vm.ci.meta.JVMCIMetaAccessContext;
import jdk.vm.ci.meta.ResolvedJavaType;
public interface HotSpotVMEventListener {
@ -34,7 +36,7 @@ public interface HotSpotVMEventListener {
}
/**
* Notify on successful install into the CodeCache.
* Notify on successful install into the code cache.
*
* @param hotSpotCodeCacheProvider
* @param installedCode
@ -43,14 +45,6 @@ public interface HotSpotVMEventListener {
default void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompilationResult compResult) {
}
/**
* Perform any extra initialization required.
*
* @param runtime
*/
default void completeInitialization(HotSpotJVMCIRuntime runtime) {
}
/**
* Create a custom {@link JVMCIMetaAccessContext} to be used for managing the lifetime of loaded
* metadata. It a custom one isn't created then the default implementation will be a single

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