From e675075ee377219409e6253be968d3d66cd93d48 Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Wed, 20 Feb 2019 11:39:20 +0100 Subject: [PATCH] jdk: C1 compiler for x86_64 and arm JIT compiler version of OpenJDK 9 issue #136 --- lib/mk/jvm.inc | 12 +- ports/jdk.hash | 2 +- ports/jdk.port | 3 +- run/java.run | 24 +++- src/app/jdk/lib/jvm/os_genode.cpp | 31 +++-- .../jdk/lib/jvm/spec/arm/os_genode_arm.cpp | 6 +- src/app/jdk/patches/id.patch | 43 ++++++ src/app/jdk/patches/lir.patch | 122 ++++++++++++++++++ src/app/jdk/patches/mutex.patch | 13 ++ src/app/jdk/patches/verified_entry.patch | 50 +++++++ src/app/jdk/patches/vfp.patch | 63 +++++++++ 11 files changed, 341 insertions(+), 28 deletions(-) create mode 100644 src/app/jdk/patches/id.patch create mode 100644 src/app/jdk/patches/lir.patch create mode 100644 src/app/jdk/patches/mutex.patch create mode 100644 src/app/jdk/patches/verified_entry.patch create mode 100644 src/app/jdk/patches/vfp.patch diff --git a/lib/mk/jvm.inc b/lib/mk/jvm.inc index 1b53356..fb3d50d 100644 --- a/lib/mk/jvm.inc +++ b/lib/mk/jvm.inc @@ -18,7 +18,9 @@ CC_OPT += -D__GENODE__ CC_OPT += -DINCLUDE_SUFFIX_OS=_bsd -DTARGET_COMPILER_gcc -D_ALLBSD_SOURCE -DUSE_LIBRARY_BASED_TLS_ONLY \ -DVM_LITTLE_ENDIAN -CC_OLEVEL = -O0 +CC_OPT += -DCOMPILER1 -DCOMPILER2 + +CC_OLEVEL = -O2 ## DEBUGGING ## #CC_OPT += -DASSERT @@ -138,14 +140,9 @@ SRC_CTWO += share/vm/ci/bcEscapeAnalyzer.cpp \ share/vm/opto/vectornode.cpp \ share/vm/prims/jvm.cpp \ share/vm/runtime/globals.cpp \ + share/vm/runtime/vframe.cpp \ share/vm/runtime/sharedRuntime.cpp -# -# create CC_OPT_file for c1/c2 compiler -# -$(foreach FILE, $(SRC_CONE:.cpp=), $(eval CC_OPT_$(FILE) = -DCOMPILER1)) -$(foreach FILE, $(SRC_CTWO:.cpp=), $(eval CC_OPT_$(FILE) = -DCOMPILER2)) - CC_OPT_share/vm/runtime/vm_version += $(JDK_VERSION) \ -DHOTSPOT_VERSION_STRING='"9-internal+0-adhoc.genode.openjdk-jdk9-jdk9"'\ -DDEBUG_LEVEL='"release"' -DHOTSPOT_VM_DISTRO='"OpenJDK"' \ @@ -609,7 +606,6 @@ SRC_CC += $(SRC_CONE) $(SRC_CTWO) \ share/vm/runtime/timerTrace.cpp \ share/vm/runtime/unhandledOops.cpp \ share/vm/runtime/vframeArray.cpp \ - share/vm/runtime/vframe.cpp \ share/vm/runtime/vframe_hp.cpp \ share/vm/runtime/vm_operations.cpp \ share/vm/runtime/vmStructs.cpp \ diff --git a/ports/jdk.hash b/ports/jdk.hash index a2e3f15..6cee769 100644 --- a/ports/jdk.hash +++ b/ports/jdk.hash @@ -1 +1 @@ -e878af950a95fe36270ae12dcfb2bb0b7d6c12e7 +65138302b9644d4da43119dd63ac44a6c27cfc3b diff --git a/ports/jdk.port b/ports/jdk.port index 82c433c..0fe9c09 100644 --- a/ports/jdk.port +++ b/ports/jdk.port @@ -9,7 +9,8 @@ TAR_OPT(jdk) := --strip-components=1 --files-from=$(REP_DIR)/src/app/jdk/files.l DIR(jdk) := src/app/jdk PATCHES := $(addprefix src/app/jdk/patches/,jdk.patch arm.patch \ - icache.patch size.patch) + icache.patch size.patch id.patch lir.patch mutex.patch \ + verified_entry.patch vfp.patch) # This patch has to be applied to JDK when building the standard Java library # pollselectorprovider.patch diff --git a/run/java.run b/run/java.run index 211ec61..4431238 100644 --- a/run/java.run +++ b/run/java.run @@ -41,6 +41,12 @@ set config { + + + + + + @@ -85,8 +91,24 @@ set boot_modules { classes.tar tzdb.dat management.lib.so } + +# return jdk_generated port path +proc jdk_generated { } { + set ::env(MAKEFLAGS) s + set jdk_generated_path [exec [genode_dir]/tool/ports/current jdk_generated] + return $jdk_generated_path +} + +file copy -force [jdk_generated]/src/app/jdk/bin/classes.tar bin +file copy -force [jdk_generated]/src/app/jdk/bin/tzdb.dat bin +file copy -force [jdk_generated]/src/app/jdk/bin/hello.tar bin + build_boot_image $boot_modules append qemu_args " -nographic -serial mon:stdio " -run_genode_until forever +run_genode_until "child \"java\" exited with exit value 0" 60 + +file delete -force bin/classes.tar +file delete -force bin/tzdb.dat +file delete -force bin/hello.tar diff --git a/src/app/jdk/lib/jvm/os_genode.cpp b/src/app/jdk/lib/jvm/os_genode.cpp index e017ec0..33376b4 100644 --- a/src/app/jdk/lib/jvm/os_genode.cpp +++ b/src/app/jdk/lib/jvm/os_genode.cpp @@ -2323,7 +2323,7 @@ bool os::dont_yield() { } void os::naked_yield() { - sched_yield(); + //sched_yield(); } //////////////////////////////////////////////////////////////////////////////// @@ -3204,14 +3204,13 @@ extern "C" { } } +static void polling_page_handler(); +unsigned long polling_page_readable = 1; + // this is called _after_ the global arguments have been parsed jint os::init_2(void) { - // Allocate a single page and mark it as readable for safepoint polling - address polling_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); - guarantee(polling_page != MAP_FAILED, "os::init_2: failed to allocate polling page"); - os::set_polling_page(polling_page); - log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page)); + os::set_polling_page((address)&polling_page_readable); if (!UseMembar) { address mem_serialize_page = (address) ::mmap(NULL, Bsd::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); @@ -3292,20 +3291,24 @@ jint os::init_2(void) { return JNI_OK; } +void os::garbage_collector() +{ + return; + + /* TODO: enable gargabe collector + if (polling_page_readable) return; + SafepointSynchronize::handle_polling_page_exception(c); + SafepointSynchronize::block(c); */ +} + // Mark the polling page as unreadable void os::make_polling_page_unreadable(void) { - //if (!guard_memory((char*)_polling_page, Bsd::page_size())) { - // fatal("Could not disable polling page"); - //} - NOT_IMPL; + polling_page_readable = 0; } // Mark the polling page as readable void os::make_polling_page_readable(void) { - //if (!bsd_mprotect((char *)_polling_page, Bsd::page_size(), PROT_READ)) { - // fatal("Could not enable polling page"); - //} - NOT_IMPL; + polling_page_readable = 1; } int os::active_processor_count() { diff --git a/src/app/jdk/lib/jvm/spec/arm/os_genode_arm.cpp b/src/app/jdk/lib/jvm/spec/arm/os_genode_arm.cpp index b369803..183005b 100644 --- a/src/app/jdk/lib/jvm/spec/arm/os_genode_arm.cpp +++ b/src/app/jdk/lib/jvm/spec/arm/os_genode_arm.cpp @@ -172,8 +172,9 @@ void os::verify_stack_alignment() address os::current_stack_pointer() { - address dummy = (address)&dummy; - return dummy; + address sp = 0; + asm volatile ("mov %0, sp\n" : "=r" (sp) : :); + return sp; } @@ -204,7 +205,6 @@ address os::current_stack_base() pthread_attr_getstack(&attr, &addr, &size); pthread_attr_destroy(&attr); - return (address)addr + size; } diff --git a/src/app/jdk/patches/id.patch b/src/app/jdk/patches/id.patch new file mode 100644 index 0000000..3b3075e --- /dev/null +++ b/src/app/jdk/patches/id.patch @@ -0,0 +1,43 @@ +diff --git a/hotspot/src/share/vm/c1/c1_Instruction.hpp b/hotspot/src/share/vm/c1/c1_Instruction.hpp +index c71b561..984dc3e 100644 +--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp ++++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp +@@ -349,7 +349,7 @@ class Instruction: public CompilationResourceObj { + void* operator new(size_t size) throw() { + Compilation* c = Compilation::current(); + void* res = c->arena()->Amalloc(size); +- ((Instruction*)res)->_id = c->get_next_id(); ++ //((Instruction *)res)->_id = c->get_next_id(); + return res; + } + +@@ -410,7 +410,8 @@ class Instruction: public CompilationResourceObj { + + // creation + Instruction(ValueType* type, ValueStack* state_before = NULL, bool type_is_constant = false) +- : _use_count(0) ++ : _id(Compilation::current()->get_next_id()) ++ , _use_count(0) + #ifndef PRODUCT + , _printable_bci(-99) + #endif +@@ -1648,8 +1649,9 @@ LEAF(BlockBegin, StateSplit) + void* operator new(size_t size) throw() { + Compilation* c = Compilation::current(); + void* res = c->arena()->Amalloc(size); +- ((BlockBegin*)res)->_id = c->get_next_id(); +- ((BlockBegin*)res)->_block_id = c->get_next_block_id(); ++ ++ //((BlockBegin*)res)->_id = c->get_next_id(); ++ //((BlockBegin*)res)->_block_id = c->get_next_block_id(); + return res; + } + +@@ -1661,6 +1663,7 @@ LEAF(BlockBegin, StateSplit) + // creation + BlockBegin(int bci) + : StateSplit(illegalType) ++ , _block_id(Compilation::current()->get_next_block_id()) + , _bci(bci) + , _depth_first_number(-1) + , _linear_scan_number(-1) diff --git a/src/app/jdk/patches/lir.patch b/src/app/jdk/patches/lir.patch new file mode 100644 index 0000000..f6786c2 --- /dev/null +++ b/src/app/jdk/patches/lir.patch @@ -0,0 +1,122 @@ +diff --git a/hotspot/src/cpu/arm/vm/c1_LIRAssembler_arm.cpp b/hotspot/src/cpu/arm/vm/c1_LIRAssembler_arm.cpp +index caf0071..e5b8d87 100644 +--- a/hotspot/src/cpu/arm/vm/c1_LIRAssembler_arm.cpp ++++ b/hotspot/src/cpu/arm/vm/c1_LIRAssembler_arm.cpp +@@ -352,6 +352,7 @@ void LIR_Assembler::return_op(LIR_Opr result) { + __ ret(); + } + ++#if 0 + + int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { + __ mov_address(Rtemp, os::get_polling_page(), symbolic_Relocation::polling_page_reference); +@@ -364,6 +365,27 @@ int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { + return offset; + } + ++#else ++ ++int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { ++ __ mov_address(Rtemp, os::get_polling_page(), symbolic_Relocation::polling_page_reference); ++ if (info != NULL) { ++ add_debug_info_for_branch(info); ++ } ++ int offset = __ offset(); ++ Label out; ++ __ relocate(relocInfo::poll_type); ++ __ ldr(Rtemp, Address(Rtemp)); ++ __ cmp(Rtemp, 1); ++ __ b(out, eq); ++ __ save_all_registers(); ++ __ call((address)os::garbage_collector, relocInfo::runtime_call_type); ++ __ restore_all_registers(); ++ __ bind(out); ++ ++ return offset; ++} ++#endif + + void LIR_Assembler::move_regs(Register from_reg, Register to_reg) { + if (from_reg != to_reg) { +diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +index 8aa4aec..6c04b06 100644 +--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp ++++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp +@@ -526,6 +526,7 @@ void LIR_Assembler::return_op(LIR_Opr result) { + + // Note: we do not need to round double result; float result has the right precision + // the poll sets the condition code, but no data registers ++#if 1 + AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type); + + if (Assembler::is_polling_page_far()) { +@@ -535,10 +536,13 @@ void LIR_Assembler::return_op(LIR_Opr result) { + } else { + __ testl(rax, polling_page); + } ++#endif ++ //__ call(RuntimeAddress(os::get_polling_page(), relocInfo::poll_return_type); ++ //__ call_VM(noreg, os::get_polling_page()); + __ ret(0); + } + +- ++#if 0 + int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { + AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type); + guarantee(info != NULL, "Shouldn't be NULL"); +@@ -555,7 +559,42 @@ int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { + } + return offset; + } ++#endif ++#if 1 ++int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) { ++ guarantee(info != NULL, "Shouldn't be NULL"); ++ AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type); ++ const Register thread = LP64_ONLY(r15_thread); ++ int offset = __ offset(); ++ Label out; ++ __ enter(); ++ ++ /* check polling page variable */ ++ __ push(rax); ++ __ lea(rax, polling_page); ++ __ movptr(rax, Address(rax, 0)); ++ __ testl(rax, rax); ++ __ jcc(Assembler::notZero, out); ++ ++ /* polling page unmapped (zero), start GC */ ++ __ pushf(); ++ __ pusha(); ++ __ push(rax); ++ __ set_last_Java_frame(rsp, rbp, __ pc()); ++ __ call(RuntimeAddress((address)os::garbage_collector)); ++ __ reset_last_Java_frame(true); ++ __ pop(rax); ++ __ popa(); ++ __ popf(); ++ ++ /* leave */ ++ __ bind(out); ++ __ pop(rax); ++ __ leave(); + ++ return offset; ++} ++#endif + + void LIR_Assembler::move_regs(Register from_reg, Register to_reg) { + if (from_reg != to_reg) __ mov(to_reg, from_reg); +diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp +index ac5919a..fe3bb83 100644 +--- a/hotspot/src/share/vm/runtime/os.hpp ++++ b/hotspot/src/share/vm/runtime/os.hpp +@@ -381,6 +381,7 @@ class os: AllStatic { + static bool is_poll_address(address addr) { return addr >= _polling_page && addr < (_polling_page + os::vm_page_size()); } + static void make_polling_page_unreadable(); + static void make_polling_page_readable(); ++ static void garbage_collector(); + + // Routines used to serialize the thread state without using membars + static void serialize_thread_states(); diff --git a/src/app/jdk/patches/mutex.patch b/src/app/jdk/patches/mutex.patch new file mode 100644 index 0000000..5556b44 --- /dev/null +++ b/src/app/jdk/patches/mutex.patch @@ -0,0 +1,13 @@ +diff --git a/hotspot/src/share/vm/runtime/mutex.cpp b/hotspot/src/share/vm/runtime/mutex.cpp +index 675dbfb..3b1ba0a 100644 +--- a/hotspot/src/share/vm/runtime/mutex.cpp ++++ b/hotspot/src/share/vm/runtime/mutex.cpp +@@ -1398,8 +1398,6 @@ void Monitor::check_prelock_state(Thread *thread) { + void Monitor::check_block_state(Thread *thread) { + if (!_allow_vm_block && thread->is_VM_thread()) { + warning("VM thread blocked on lock"); +- print(); +- BREAKPOINT; + } + assert(_owner != thread, "deadlock: blocking on monitor owned by current thread"); + } diff --git a/src/app/jdk/patches/verified_entry.patch b/src/app/jdk/patches/verified_entry.patch new file mode 100644 index 0000000..19c43af --- /dev/null +++ b/src/app/jdk/patches/verified_entry.patch @@ -0,0 +1,50 @@ +diff --git a/hotspot/src/cpu/arm/vm/nativeInst_arm_32.cpp b/hotspot/src/cpu/arm/vm/nativeInst_arm_32.cpp +index 77694f6..bce8843 100644 +--- a/hotspot/src/cpu/arm/vm/nativeInst_arm_32.cpp ++++ b/hotspot/src/cpu/arm/vm/nativeInst_arm_32.cpp +@@ -287,12 +287,45 @@ void NativeMovConstReg::set_pc_relative_offset(address addr, address pc) { + void RawNativeJump::check_verified_entry_alignment(address entry, address verified_entry) { + } + ++#if 0 + void RawNativeJump::patch_verified_entry(address entry, address verified_entry, address dest) { + assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "should be"); + int *a = (int *)verified_entry; + a[0] = zombie_illegal_instruction; // always illegal ++ printf("%s:%d called dest %x verf %x\n", __func__, __LINE__, dest, verified_entry); ++ + ICache::invalidate_range((address)&a[0], sizeof a[0]); + } ++#endif ++ ++void RawNativeJump::patch_verified_entry(address entry, address verified_entry, address dest) { ++ assert(dest == SharedRuntime::get_handle_wrong_method_stub(), "should be"); ++ ++ printf("%s:%d called dest %x verf %x\n", __func__, __LINE__, dest, verified_entry); ++ ++ /* jump to 'dest' */ ++ unsigned *instruction = (unsigned *)verified_entry; ++ unsigned constexpr opcode = 0xea << 24; // 'b' (branch) ++ unsigned constexpr opcode_mask = ~(0xff << 24); ++ ++ /* ++ * Lower 24 bits are the sign extented PC relative target shifted by 2. ++ * Since the PC is always 8 bytes ahead, we have to subtract them. ++ */ ++ int displacement = (int)(dest - verified_entry - 8) >> 2; ++ ++ int constexpr limit = (32 * 1024 * 1024) - 4; ++ if (displacement > limit || displacement < -limit) { ++ printf("%s -> ERROR: displacement larger than 32 MB\n", __PRETTY_FUNCTION__); ++ while (1); ++ } ++ ++ /* patch machine code */ ++ *instruction = (displacement & opcode_mask) | opcode; ++ ++ /* flush instruction cache so the CPU sees correct things */ ++ ICache::invalidate_range(verified_entry, sizeof(unsigned)); ++} + + void NativeGeneralJump::insert_unconditional(address code_pos, address entry) { + int offset = (int)(entry - code_pos - 8); diff --git a/src/app/jdk/patches/vfp.patch b/src/app/jdk/patches/vfp.patch new file mode 100644 index 0000000..a5caed6 --- /dev/null +++ b/src/app/jdk/patches/vfp.patch @@ -0,0 +1,63 @@ +vfp.patch + +From: Christian Prochaska + + +--- + hotspot/src/cpu/arm/vm/vm_version_arm_32.cpp | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/hotspot/src/cpu/arm/vm/vm_version_arm_32.cpp b/hotspot/src/cpu/arm/vm/vm_version_arm_32.cpp +index b35d68f..7ffd771 100644 +--- a/hotspot/src/cpu/arm/vm/vm_version_arm_32.cpp ++++ b/hotspot/src/cpu/arm/vm/vm_version_arm_32.cpp +@@ -126,28 +126,28 @@ void VM_Version::initialize() { + address check_vfp_pc = g.generate_check_vfp(); + check_vfp_t check_vfp = CAST_TO_FN_PTR(check_vfp_t, check_vfp_pc); + +- check_vfp_fault_instr = (address)check_vfp; +- double dummy; +- if (check_vfp(&dummy)) { ++ //check_vfp_fault_instr = (address)check_vfp; ++ //double dummy; ++ //if (check_vfp(&dummy)) { + _features |= vfp_m; +- } ++ //} + + #ifdef COMPILER2 + if (has_vfp()) { + address check_vfp3_32_pc = g.generate_check_vfp3_32(); + check_vfp_t check_vfp3_32 = CAST_TO_FN_PTR(check_vfp_t, check_vfp3_32_pc); +- check_vfp3_32_fault_instr = (address)check_vfp3_32; ++ //check_vfp3_32_fault_instr = (address)check_vfp3_32; + double dummy; +- if (check_vfp3_32(&dummy)) { +- _features |= vfp3_32_m; +- } ++ //if (check_vfp3_32(&dummy)) { ++ //_features |= vfp3_32_m; ++ //} + + address check_simd_pc =g.generate_check_simd(); + check_simd_t check_simd = CAST_TO_FN_PTR(check_simd_t, check_simd_pc); +- check_simd_fault_instr = (address)check_simd; +- if (check_simd()) { +- _features |= simd_m; +- } ++ //check_simd_fault_instr = (address)check_simd; ++ //if (check_simd()) { ++ //_features |= simd_m; ++ //} + } + #endif + #endif +@@ -226,7 +226,7 @@ void VM_Version::initialize() { + #ifdef COMPILER2 + // C2 is only supported on v7+ VFP at this time + if (_arm_arch < 7 || !has_vfp()) { +- vm_exit_during_initialization("Server VM is only supported on ARMv7+ VFP"); ++ //vm_exit_during_initialization("Server VM is only supported on ARMv7+ VFP"); + } + #endif +