atom feed22 messages in net.java.openjdk.bsd-port-devPatch to build 64 bit VM
FromSent OnAttachments
Xiaobin LuDec 17, 2008 9:13 pm 
Xiaobin LuDec 17, 2008 9:22 pm 
Greg LewisDec 22, 2008 6:09 am 
Xiaobin LuDec 22, 2008 11:05 am.Other
Landon FullerDec 22, 2008 11:25 am 
Greg LewisDec 25, 2008 11:23 pm 
Xiaobin LuDec 25, 2008 11:34 pm 
Greg LewisDec 26, 2008 9:26 am 
Greg LewisDec 28, 2008 12:28 am 
Greg LewisDec 28, 2008 12:54 pm.diff
Xiaobin LuDec 28, 2008 1:35 pm 
Greg LewisDec 29, 2008 8:45 am 
Xiaobin LuDec 31, 2008 8:32 pm 
Michael FranzJan 2, 2009 7:58 pm 
Kelly O'HairJan 3, 2009 10:59 am 
Greg LewisJan 4, 2009 9:18 pm 
Michael FranzJan 5, 2009 4:42 am 
Xiaobin LuJan 5, 2009 11:14 am 
Michael FranzJan 5, 2009 4:43 pm 
Greg LewisJan 5, 2009 10:11 pm 
Dalibor TopicJan 6, 2009 4:45 am 
Michael FranzJan 6, 2009 7:36 am 
Subject:Patch to build 64 bit VM
From:Xiaobin Lu (Xiao@Sun.COM)
Date:Dec 17, 2008 9:13:36 pm
List:net.java.openjdk.bsd-port-dev

I am attaching the patch for building 64 bit VM. They are BSD specific files. Would someone review it and help me check it in?

Thanks, -Xiaobin

diff -r de4c58dbee8f src/cpu/x86/vm/stubGenerator_x86_32.cpp --- a/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Nov 26 05:05:13 2008 -0800 +++ b/src/cpu/x86/vm/stubGenerator_x86_64.cpp Wed Dec 17 21:06:49 2008 -0800 @@ -954,9 +954,9 @@ class StubGenerator: public StubCodeGene __ jcc(Assembler::zero, exit); // if obj is NULL it is OK // Check if the oop is in the right area of memory __ movptr(c_rarg2, rax); - __ movptr(c_rarg3, (int64_t) Universe::verify_oop_mask()); + __ movptr(c_rarg3, (intptr_t) Universe::verify_oop_mask()); __ andptr(c_rarg2, c_rarg3); - __ movptr(c_rarg3, (int64_t) Universe::verify_oop_bits()); + __ movptr(c_rarg3, (intptr_t) Universe::verify_oop_bits()); __ cmpptr(c_rarg2, c_rarg3); __ jcc(Assembler::notZero, error);

@@ -969,9 +969,9 @@ class StubGenerator: public StubCodeGene __ jcc(Assembler::zero, error); // if klass is NULL it is broken // Check if the klass is in the right area of memory __ mov(c_rarg2, rax); - __ movptr(c_rarg3, (int64_t) Universe::verify_klass_mask()); + __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_mask()); __ andptr(c_rarg2, c_rarg3); - __ movptr(c_rarg3, (int64_t) Universe::verify_klass_bits()); + __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_bits()); __ cmpptr(c_rarg2, c_rarg3); __ jcc(Assembler::notZero, error);

@@ -980,9 +980,9 @@ class StubGenerator: public StubCodeGene __ testptr(rax, rax); __ jcc(Assembler::zero, error); // if klass' klass is NULL it is broken // Check if the klass' klass is in the right area of memory - __ movptr(c_rarg3, (int64_t) Universe::verify_klass_mask()); + __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_mask()); __ andptr(rax, c_rarg3); - __ movptr(c_rarg3, (int64_t) Universe::verify_klass_bits()); + __ movptr(c_rarg3, (intptr_t) Universe::verify_klass_bits()); __ cmpptr(rax, c_rarg3); __ jcc(Assembler::notZero, error);

diff -r de4c58dbee8f src/os_cpu/bsd_x86/vm/bytes_bsd_x86.inline.hpp --- a/src/os_cpu/bsd_x86/vm/bytes_bsd_x86.inline.hpp Wed Nov 26 05:05:13 2008
-0800 +++ b/src/os_cpu/bsd_x86/vm/bytes_bsd_x86.inline.hpp Wed Dec 17 21:06:49 2008
-0800 @@ -32,9 +32,9 @@

#if defined(AMD64) # if defined(__APPLE__) -# define bswap16(x) OSSwapInt16(x) -# define bswap32(x) OSSwapInt32(x) -# define bswap64(x) OSSwapInt64(x) +# define bswap_16(x) OSSwapInt16(x) +# define bswap_32(x) OSSwapInt32(x) +# define bswap_64(x) OSSwapInt64(x) # elif defined(__OpenBSD__) # define bswap_16(x) swap16(x) # define bswap_32(x) swap32(x) diff -r de4c58dbee8f src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp --- a/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Wed Nov 26 05:05:13 2008 -0800 +++ b/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp Wed Dec 17 21:06:49 2008 -0800 @@ -456,197 +456,191 @@ JVM_handle_bsd_signal(int sig, if (nm != NULL && nm->has_unsafe_access()) { stub = StubRoutines::handler_for_unsafe_access(); } + } else { +#if defined(AMD64) && !defined(__APPLE__) + if (sig == SIGFPE && + (info->si_code == FPE_INTDIV || info->si_code == FPE_FLTDIV)) { + stub = + SharedRuntime:: + continuation_for_implicit_exception(thread, + pc, + SharedRuntime:: + IMPLICIT_DIVIDE_BY_ZERO); +#else + if (sig == SIGFPE /* && info->si_code == FPE_INTDIV */) { + // HACK: si_code does not work on bsd 2.2.12-20!!! + int op = pc[0]; +# ifdef AMD64 + // Skip REX + if ((pc[0] & 0xf0) == 0x40) { + op = pc[1]; +# endif + if (op == 0xDB) { + // FIST + // TODO: The encoding of D2I in i486.ad can cause an exception + // prior to the fist instruction if there was an invalid operation + // pending. We want to dismiss that exception. From the win_32 + // side it also seems that if it really was the fist causing + // the exception that we do the d2i by hand with different + // rounding. Seems kind of weird. + // NOTE: that we take the exception at the NEXT floating point
instruction. + assert(pc[0] == 0xDB, "not a FIST opcode"); + assert(pc[1] == 0x14, "not a FIST opcode"); + assert(pc[2] == 0x24, "not a FIST opcode"); + return true; + } else if (op == 0xF7) { + // IDIV + stub = SharedRuntime::continuation_for_implicit_exception(thread,
pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); + } else { + // TODO: handle more cases if we are using other x86 instructions + // that can generate SIGFPE signal on bsd. + tty->print_cr("unknown opcode 0x%X with SIGFPE.", op); + fatal("please update this code."); + } +#endif // AMD64 + } else if ((sig == SIGSEGV || sig == SIGBUS) && +
!MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { + // Determination of interpreter/vtable stub/compiled code null
exception + stub = SharedRuntime::continuation_for_implicit_exception(thread,
pc, SharedRuntime::IMPLICIT_NULL); + } + } else if (thread->thread_state() == _thread_in_vm && + sig == SIGBUS && /* info->si_code == BUS_OBJERR && */ + thread->doing_unsafe_access()) { + stub = StubRoutines::handler_for_unsafe_access(); + } + + // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks
in + // and the heap gets shrunk before the field access. + if ((sig == SIGSEGV) || (sig == SIGBUS)) { + address addr = JNI_FastGetField::find_slowcase_pc(pc); + if (addr != (address)-1) { + stub = addr; + } + } + + // Check to see if we caught the safepoint code in the + // process of write protecting the memory serialization page. + // It write enables the page immediately after protecting it + // so we can just return to retry the write. + if ((sig == SIGSEGV || sig == SIGBUS) && + os::is_memory_serialize_page(thread, (address) info->si_addr)) { + // Block current thread until the memory serialize page permission
restored. + os::block_on_serialize_page_trap(); + return true; + } } - else +#ifndef AMD64 + // Execution protection violation + // + // This should be kept as the last step in the triage. We don't + // have a dedicated trap number for a no-execute fault, so be + // conservative and allow other handlers the first shot. + // + // Note: We don't test that info->si_code == SEGV_ACCERR here. + // this si_code is so generic that it is almost meaningless; and + // the si_code for this condition may change in the future. + // Furthermore, a false-positive should be harmless. + if (UnguardOnExecutionViolation > 0 && + (sig == SIGSEGV || sig == SIGBUS) && + uc->context_trapno == trap_page_fault) { + int page_size = os::vm_page_size(); + address addr = (address) info->si_addr; + address pc = os::Bsd::ucontext_get_pc(uc); + // Make sure the pc and the faulting address are sane. + // + // If an instruction spans a page boundary, and the page containing + // the beginning of the instruction is executable but the following + // page is not, the pc and the faulting address might be slightly + // different - we still want to unguard the 2nd page in this case. + // + // 15 bytes seems to be a (very) safe value for max instruction size. + bool pc_is_near_addr = + (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15); + bool instr_spans_page_boundary = + (align_size_down((intptr_t) pc ^ (intptr_t) addr, + (intptr_t) page_size) > 0);

-#if defined(AMD64) && !defined(__APPLE__) - if (sig == SIGFPE && - (info->si_code == FPE_INTDIV || info->si_code == FPE_FLTDIV)) { - stub = - SharedRuntime:: - continuation_for_implicit_exception(thread, - pc, - SharedRuntime:: - IMPLICIT_DIVIDE_BY_ZERO); + if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) { + static volatile address last_addr = + (address) os::non_memory_address_word();

-#else - if (sig == SIGFPE /* && info->si_code == FPE_INTDIV */) { - // HACK: si_code does not work on bsd 2.2.12-20!!! - int op = pc[0]; + // In conservative mode, don't unguard unless the address is in the
VM + if (addr != last_addr && + (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr)))
{ + + // Unguard and retry + address page_start = + (address) align_size_down((intptr_t) addr, (intptr_t) page_size); + bool res = os::unguard_memory((char*) page_start, page_size); + + if (PrintMiscellaneous && Verbose) { + char buf[256]; + jio_snprintf(buf, sizeof(buf), "Execution protection violation " + "at " INTPTR_FORMAT + ", unguarding " INTPTR_FORMAT ": %s, errno=%d",
addr, + page_start, (res ? "success" : "failed"), errno); + tty->print_raw_cr(buf); + } + stub = pc; + + // Set last_addr so if we fault again at the same address, we don't
end + // up in an endless loop. + // + // There are two potential complications here. Two threads
trapping at + // the same address at the same time could cause one of the threads
to + // think it already unguarded, and abort the VM. Likely very rare. + // + // The other race involves two threads alternately trapping at + // different addresses and failing to unguard the page, resulting
in + // an endless loop. This condition is probably even more unlikely
than + // the first. + // + // Although both cases could be avoided by using locks or thread
local + // last_addr, these solutions are unnecessary complication: this + // handler is a best-effort safety net, not a complete solution.
It is + // disabled by default and should only be used as a workaround in
case + // we missed any no-execute-unsafe VM code. + + last_addr = addr; + } + } + } +#endif // !AMD64 + if (stub != NULL) { + // save all thread context in case we need to restore it + if (thread != NULL) thread->set_saved_exception_pc(pc);

-# ifdef AMD64 - // Skip REX - if ((pc[0] & 0xf0) == 0x40) { - op = pc[1]; -# endif - - if (op == 0xDB) { - // FIST - // TODO: The encoding of D2I in i486.ad can cause an exception - // prior to the fist instruction if there was an invalid operation - // pending. We want to dismiss that exception. From the win_32 - // side it also seems that if it really was the fist causing - // the exception that we do the d2i by hand with different - // rounding. Seems kind of weird. - // NOTE: that we take the exception at the NEXT floating point
instruction. - assert(pc[0] == 0xDB, "not a FIST opcode"); - assert(pc[1] == 0x14, "not a FIST opcode"); - assert(pc[2] == 0x24, "not a FIST opcode"); - return true; - } else if (op == 0xF7) { - // IDIV - stub = SharedRuntime::continuation_for_implicit_exception(thread, pc,
SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); - } else { - // TODO: handle more cases if we are using other x86 instructions - // that can generate SIGFPE signal on bsd. - tty->print_cr("unknown opcode 0x%X with SIGFPE.", op); - fatal("please update this code."); - } -#endif // AMD64 - } else if ((sig == SIGSEGV || sig == SIGBUS) && -
!MacroAssembler::needs_explicit_null_check((intptr_t)info->si_addr)) { - // Determination of interpreter/vtable stub/compiled code null
exception - stub = SharedRuntime::continuation_for_implicit_exception(thread, pc,
SharedRuntime::IMPLICIT_NULL); + uc->context_pc = (intptr_t)stub; + return true; } - } else if (thread->thread_state() == _thread_in_vm && - sig == SIGBUS && /* info->si_code == BUS_OBJERR && */ - thread->doing_unsafe_access()) { - stub = StubRoutines::handler_for_unsafe_access(); - }

- // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in - // and the heap gets shrunk before the field access. - if ((sig == SIGSEGV) || (sig == SIGBUS)) { - address addr = JNI_FastGetField::find_slowcase_pc(pc); - if (addr != (address)-1) { - stub = addr; + // signal-chaining + if (os::Bsd::chained_handler(sig, info, ucVoid)) { + return true; } - }

- // Check to see if we caught the safepoint code in the - // process of write protecting the memory serialization page. - // It write enables the page immediately after protecting it - // so we can just return to retry the write. - if ((sig == SIGSEGV || sig == SIGBUS) && - os::is_memory_serialize_page(thread, (address) info->si_addr)) { - // Block current thread until the memory serialize page permission
restored. - os::block_on_serialize_page_trap(); - return true; + if (!abort_if_unrecognized) { + // caller wants another chance, so give it to him + return false; + } + + if (pc == NULL && uc != NULL) { + pc = os::Bsd::ucontext_get_pc(uc); + } + + // unmask current signal + sigset_t newset; + sigemptyset(&newset); + sigaddset(&newset, sig); + sigprocmask(SIG_UNBLOCK, &newset, NULL); + + VMError err(t, sig, pc, info, ucVoid); + err.report_and_die(); + + ShouldNotReachHere(); } } - -#ifndef AMD64 - // Execution protection violation - // - // This should be kept as the last step in the triage. We don't - // have a dedicated trap number for a no-execute fault, so be - // conservative and allow other handlers the first shot. - // - // Note: We don't test that info->si_code == SEGV_ACCERR here. - // this si_code is so generic that it is almost meaningless; and - // the si_code for this condition may change in the future. - // Furthermore, a false-positive should be harmless. - if (UnguardOnExecutionViolation > 0 && - (sig == SIGSEGV || sig == SIGBUS) && - uc->context_trapno == trap_page_fault) { - int page_size = os::vm_page_size(); - address addr = (address) info->si_addr; - address pc = os::Bsd::ucontext_get_pc(uc); - // Make sure the pc and the faulting address are sane. - // - // If an instruction spans a page boundary, and the page containing - // the beginning of the instruction is executable but the following - // page is not, the pc and the faulting address might be slightly - // different - we still want to unguard the 2nd page in this case. - // - // 15 bytes seems to be a (very) safe value for max instruction size. - bool pc_is_near_addr = - (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15); - bool instr_spans_page_boundary = - (align_size_down((intptr_t) pc ^ (intptr_t) addr, - (intptr_t) page_size) > 0); - - if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) { - static volatile address last_addr = - (address) os::non_memory_address_word(); - - // In conservative mode, don't unguard unless the address is in the VM - if (addr != last_addr && - (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) { - - // Unguard and retry - address page_start = - (address) align_size_down((intptr_t) addr, (intptr_t) page_size); - bool res = os::unguard_memory((char*) page_start, page_size); - - if (PrintMiscellaneous && Verbose) { - char buf[256]; - jio_snprintf(buf, sizeof(buf), "Execution protection violation " - "at " INTPTR_FORMAT - ", unguarding " INTPTR_FORMAT ": %s, errno=%d", addr, - page_start, (res ? "success" : "failed"), errno); - tty->print_raw_cr(buf); - } - stub = pc; - - // Set last_addr so if we fault again at the same address, we don't end - // up in an endless loop. - // - // There are two potential complications here. Two threads trapping at - // the same address at the same time could cause one of the threads to - // think it already unguarded, and abort the VM. Likely very rare. - // - // The other race involves two threads alternately trapping at - // different addresses and failing to unguard the page, resulting in - // an endless loop. This condition is probably even more unlikely than - // the first. - // - // Although both cases could be avoided by using locks or thread local - // last_addr, these solutions are unnecessary complication: this - // handler is a best-effort safety net, not a complete solution. It is - // disabled by default and should only be used as a workaround in case - // we missed any no-execute-unsafe VM code. - - last_addr = addr; - } - } - } -#endif // !AMD64 - - if (stub != NULL) { - // save all thread context in case we need to restore it - if (thread != NULL) thread->set_saved_exception_pc(pc); - - uc->context_pc = (intptr_t)stub; - return true; - } - - // signal-chaining - if (os::Bsd::chained_handler(sig, info, ucVoid)) { - return true; - } - - if (!abort_if_unrecognized) { - // caller wants another chance, so give it to him - return false; - } - - if (pc == NULL && uc != NULL) { - pc = os::Bsd::ucontext_get_pc(uc); - } - - // unmask current signal - sigset_t newset; - sigemptyset(&newset); - sigaddset(&newset, sig); - sigprocmask(SIG_UNBLOCK, &newset, NULL); - - VMError err(t, sig, pc, info, ucVoid); - err.report_and_die(); - - ShouldNotReachHere(); } - #ifdef _ALLBSD_SOURCE // From solaris_i486.s ported to bsd_i486.s extern "C" void fixcw();