From 554de1133e465119398ce259bf78ab472994c864 Mon Sep 17 00:00:00 2001 From: TheShermanTanker Date: Sun, 7 Jul 2024 21:18:52 +0800 Subject: [PATCH] Windows/Zero Port Signed-off-by: TheShermanTanker --- make/modules/java.base/Lib.gmk | 3 +- src/hotspot/os/windows/os_windows.cpp | 12 +- .../windows_zero/atomic_windows_zero.hpp | 103 ++++++ .../windows_zero/globals_windows_zero.hpp | 47 +++ .../windows_zero/javaThread_windows_zero.cpp | 66 ++++ .../windows_zero/javaThread_windows_zero.hpp | 79 +++++ .../windows_zero/orderAccess_windows_zero.hpp | 53 +++ .../os_cpu/windows_zero/os_windows_zero.cpp | 310 ++++++++++++++++++ .../windows_zero/os_windows_zero.inline.hpp | 42 +++ .../prefetch_windows_zero.inline.hpp | 33 ++ .../windows_zero/vmStructs_windows_zero.hpp | 40 +++ .../interpreter/zero/bytecodeInterpreter.cpp | 144 -------- 12 files changed, 786 insertions(+), 146 deletions(-) create mode 100644 src/hotspot/os_cpu/windows_zero/atomic_windows_zero.hpp create mode 100644 src/hotspot/os_cpu/windows_zero/globals_windows_zero.hpp create mode 100644 src/hotspot/os_cpu/windows_zero/javaThread_windows_zero.cpp create mode 100644 src/hotspot/os_cpu/windows_zero/javaThread_windows_zero.hpp create mode 100644 src/hotspot/os_cpu/windows_zero/orderAccess_windows_zero.hpp create mode 100644 src/hotspot/os_cpu/windows_zero/os_windows_zero.cpp create mode 100644 src/hotspot/os_cpu/windows_zero/os_windows_zero.inline.hpp create mode 100644 src/hotspot/os_cpu/windows_zero/prefetch_windows_zero.inline.hpp create mode 100644 src/hotspot/os_cpu/windows_zero/vmStructs_windows_zero.hpp diff --git a/make/modules/java.base/Lib.gmk b/make/modules/java.base/Lib.gmk index 967b93d682a2d..e3455be65175f 100644 --- a/make/modules/java.base/Lib.gmk +++ b/make/modules/java.base/Lib.gmk @@ -186,7 +186,8 @@ ifeq ($(ENABLE_FALLBACK_LINKER), true) CFLAGS := $(LIBFFI_CFLAGS), \ DISABLED_WARNINGS_gcc := implicit-function-declaration unused-variable, \ LIBS := $(LIBFFI_LIBS), \ - LIBS_windows := ws2_32.lib, \ + LIBS_microsoft_windows := ws2_32.lib, \ + LIBS_gcc_windows := -lws2_32, \ )) TARGETS += $(BUILD_LIBFALLBACKLINKER) diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 88ab05ace8f33..e3e1f959b09ae 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -2535,6 +2535,7 @@ const char* os::exception_name(int exception_code, char *buf, size_t size) { return nullptr; } +#ifndef ZERO //----------------------------------------------------------------------------- LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { // handle exception caused by idiv; should only happen for -MinInt/-1 @@ -2572,6 +2573,7 @@ LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) { #endif return EXCEPTION_CONTINUE_EXECUTION; } +#endif #if defined(_M_AMD64) //----------------------------------------------------------------------------- @@ -2628,7 +2630,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { #endif Thread* t = Thread::current_or_null_safe(); -#if defined(_M_AMD64) +#if defined(_M_AMD64) && !defined(ZERO) if ((exception_code == EXCEPTION_ACCESS_VIOLATION) && VM_Version::is_cpuinfo_segv_addr(pc)) { // Verify that OS save/restore AVX registers. @@ -2663,6 +2665,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { if (exception_code == EXCEPTION_STACK_OVERFLOW) { StackOverflow* overflow_state = thread->stack_overflow_state(); if (overflow_state->stack_guards_enabled()) { +#ifndef ZERO if (in_java) { frame fr; if (os::win32::get_frame_at_stack_banging_point(thread, exceptionInfo, pc, &fr)) { @@ -2670,6 +2673,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { SharedRuntime::look_for_reserved_stack_annotated_method(thread, fr); } } +#endif // Yellow zone violation. The o/s has unprotected the first yellow // zone page for us. Note: must call disable_stack_yellow_zone to // update the enabled status, even if the zone contains only one page. @@ -2719,11 +2723,13 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { !ExecMem); return EXCEPTION_CONTINUE_EXECUTION; } +#ifndef ZERO // Null pointer exception. if (MacroAssembler::uses_implicit_null_check((void*)addr)) { address stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); if (stub != nullptr) return Handle_Exception(exceptionInfo, stub); } +#endif report_error(t, exception_code, pc, exception_record, exceptionInfo->ContextRecord); return EXCEPTION_CONTINUE_SEARCH; @@ -2753,6 +2759,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { nm = (cb != nullptr) ? cb->as_nmethod_or_null() : nullptr; } +#ifndef ZERO bool is_unsafe_memory_access = (in_native || in_java) && UnsafeMemoryAccess::contains_pc(pc); if (((in_vm || in_native || is_unsafe_memory_access) && thread->doing_unsafe_access()) || (nm != nullptr && nm->has_unsafe_access())) { @@ -2762,6 +2769,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { } return Handle_Exception(exceptionInfo, SharedRuntime::handle_unsafe_access(thread, next_pc)); } +#endif } #ifdef _M_ARM64 @@ -2782,8 +2790,10 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { case EXCEPTION_INT_DIVIDE_BY_ZERO: return Handle_Exception(exceptionInfo, SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO)); +#ifndef ZERO case EXCEPTION_INT_OVERFLOW: return Handle_IDiv_Exception(exceptionInfo); +#endif } // switch } diff --git a/src/hotspot/os_cpu/windows_zero/atomic_windows_zero.hpp b/src/hotspot/os_cpu/windows_zero/atomic_windows_zero.hpp new file mode 100644 index 0000000000000..8d8df31a391ae --- /dev/null +++ b/src/hotspot/os_cpu/windows_zero/atomic_windows_zero.hpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_ZERO_ATOMIC_WINDOWS_ZERO_HPP +#define OS_CPU_WINDOWS_ZERO_ATOMIC_WINDOWS_ZERO_HPP + +#include +#include "runtime/os.hpp" + +template +struct Atomic::PlatformAdd { + template + D add_then_fetch(D volatile* dest, I add_value, atomic_memory_order order) const; + + template + D fetch_then_add(D volatile* dest, I add_value, atomic_memory_order order) const { + return add_then_fetch(dest, add_value, order) - add_value; + } +}; + +// The Interlocked* APIs only take long and will not accept __int32. That is +// acceptable on Windows, since long is a 32-bits integer type. + +#define DEFINE_INTRINSIC_ADD(IntrinsicName, IntrinsicType) \ + template<> \ + template \ + inline D Atomic::PlatformAdd::add_then_fetch(D volatile* dest, \ + I add_value, \ + atomic_memory_order order) const { \ + STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(D)); \ + return PrimitiveConversions::cast( \ + IntrinsicName(reinterpret_cast(dest), \ + PrimitiveConversions::cast(add_value))); \ + } + +DEFINE_INTRINSIC_ADD(InterlockedAdd, long) +DEFINE_INTRINSIC_ADD(InterlockedAdd64, long long) + +#undef DEFINE_INTRINSIC_ADD + +#define DEFINE_INTRINSIC_XCHG(IntrinsicName, IntrinsicType) \ + template<> \ + template \ + inline T Atomic::PlatformXchg::operator()(T volatile* dest, \ + T exchange_value, \ + atomic_memory_order order) const { \ + STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \ + return PrimitiveConversions::cast( \ + IntrinsicName(reinterpret_cast(dest), \ + PrimitiveConversions::cast(exchange_value))); \ + } + +DEFINE_INTRINSIC_XCHG(InterlockedExchange, long) +DEFINE_INTRINSIC_XCHG(InterlockedExchange64, long long) + +#undef DEFINE_INTRINSIC_XCHG + +// Note: the order of the parameters is different between +// Atomic::PlatformCmpxchg<*>::operator() and the +// InterlockedCompareExchange* API. + +#define DEFINE_INTRINSIC_CMPXCHG(IntrinsicName, IntrinsicType) \ + template<> \ + template \ + inline T Atomic::PlatformCmpxchg::operator()(T volatile* dest, \ + T compare_value, \ + T exchange_value, \ + atomic_memory_order order) const { \ + STATIC_ASSERT(sizeof(IntrinsicType) == sizeof(T)); \ + return PrimitiveConversions::cast( \ + IntrinsicName(reinterpret_cast(dest), \ + PrimitiveConversions::cast(exchange_value), \ + PrimitiveConversions::cast(compare_value))); \ + } + +DEFINE_INTRINSIC_CMPXCHG(_InterlockedCompareExchange8, char) // Use the intrinsic as InterlockedCompareExchange8 does not exist +DEFINE_INTRINSIC_CMPXCHG(InterlockedCompareExchange, long) +DEFINE_INTRINSIC_CMPXCHG(InterlockedCompareExchange64, long long) + +#undef DEFINE_INTRINSIC_CMPXCHG + +#endif // OS_CPU_WINDOWS_ZERO_ATOMIC_WINDOWS_ZERO_HPP diff --git a/src/hotspot/os_cpu/windows_zero/globals_windows_zero.hpp b/src/hotspot/os_cpu/windows_zero/globals_windows_zero.hpp new file mode 100644 index 0000000000000..b2c7ce4033f2c --- /dev/null +++ b/src/hotspot/os_cpu/windows_zero/globals_windows_zero.hpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_ZERO_GLOBALS_WINDOWS_ZERO_HPP +#define OS_CPU_WINDOWS_ZERO_GLOBALS_WINDOWS_ZERO_HPP + +// Sets the default values for platform dependent flags used by the runtime system. +// (see globals.hpp) + +define_pd_global(bool, DontYieldALot, false); + +// Default stack size on Windows is determined by the executable (java.exe +// has a default value of 320K/1MB [32bit/64bit]). Depending on Windows version, changing +// ThreadStackSize to non-zero may have significant impact on memory usage. +// See comments in os_windows.cpp. +define_pd_global(intx, ThreadStackSize, 0); // 0 => use system default +define_pd_global(intx, VMThreadStackSize, 0); // 0 => use system default + +define_pd_global(intx, CompilerThreadStackSize, 0); + +define_pd_global(size_t, JVMInvokeMethodSlack, 8192); + +// Used on 64 bit platforms for UseCompressedOops base address +define_pd_global(size_t, HeapBaseMinAddress, 2*G); + +#endif // OS_CPU_WINDOWS_ZERO_GLOBALS_WINDOWS_ZERO_HPP diff --git a/src/hotspot/os_cpu/windows_zero/javaThread_windows_zero.cpp b/src/hotspot/os_cpu/windows_zero/javaThread_windows_zero.cpp new file mode 100644 index 0000000000000..7428aeb1cfc49 --- /dev/null +++ b/src/hotspot/os_cpu/windows_zero/javaThread_windows_zero.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "runtime/frame.inline.hpp" +#include "runtime/javaThread.hpp" + +frame JavaThread::pd_last_frame() { + assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); + return frame(last_Java_fp(), last_Java_sp()); +} + +bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, + void* ucontext, + bool isInJava) { + if (has_last_Java_frame()) { + *fr_addr = pd_last_frame(); + return true; + } + + if (isInJava) { + // We know we are in Java, but there is no frame? + // Try to find the top-most Java frame on Zero stack then. + intptr_t* sp = stack.sp(); + ZeroFrame* zf = top; + while (zf != nullptr) { + if (zf->is_interpreter_frame()) { + interpreterState istate = zf->as_interpreter_frame()->interpreter_state(); + if (istate->self_link() == istate) { + // Valid interpreter state found, this is our frame. + *fr_addr = frame(zf, sp); + return true; + } + } + sp = reinterpret_cast(zf) + 1; + zf = zf->next(); + } + } + + // No dice. + return false; +} + +void JavaThread::cache_global_variables() { +} diff --git a/src/hotspot/os_cpu/windows_zero/javaThread_windows_zero.hpp b/src/hotspot/os_cpu/windows_zero/javaThread_windows_zero.hpp new file mode 100644 index 0000000000000..88e939b65740c --- /dev/null +++ b/src/hotspot/os_cpu/windows_zero/javaThread_windows_zero.hpp @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_ZERO_JAVATHREAD_WINDOWS_ZERO_HPP +#define OS_CPU_WINDOWS_ZERO_JAVATHREAD_WINDOWS_ZERO_HPP + + ZeroStack* zero_stack() noexcept { + return &stack; + } + + ZeroFrame* top_zero_frame() const noexcept { + return top; + } + + void push_zero_frame(ZeroFrame* frame) noexcept { + *reinterpret_cast(frame) = top; + top = frame; + } + + void pop_zero_frame() { + stack.set_sp(reinterpret_cast(top) + 1); + top = *reinterpret_cast(top); + } + + void set_last_Java_frame() { + set_last_Java_frame(top, stack.sp()); + } + + void reset_last_Java_frame() { + frame_anchor()->zap(); + } + void set_last_Java_frame(ZeroFrame* fp, intptr_t* sp) { + frame_anchor()->set(sp, nullptr, fp); + } + + ZeroFrame* last_Java_fp() { + return frame_anchor()->last_Java_fp(); + } + + bool has_special_condition_for_native_trans() const noexcept { + return _suspend_flags != 0; + } + + bool pd_get_top_frame_for_signal_handler(frame* fr_addr, + void* ucontext, + bool isInJava); + + private: + void pd_initialize() noexcept { + top = nullptr; + } + + frame pd_last_frame(); + + ZeroStack stack; + ZeroFrame* top; + +#endif // OS_CPU_WINDOWS_ZERO_JAVATHREAD_WINDOWS_ZERO_HPP diff --git a/src/hotspot/os_cpu/windows_zero/orderAccess_windows_zero.hpp b/src/hotspot/os_cpu/windows_zero/orderAccess_windows_zero.hpp new file mode 100644 index 0000000000000..3f4782b228ee1 --- /dev/null +++ b/src/hotspot/os_cpu/windows_zero/orderAccess_windows_zero.hpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_ZERO_ORDERACCESS_WINDOWS_ZERO_HPP +#define OS_CPU_WINDOWS_ZERO_ORDERACCESS_WINDOWS_ZERO_HPP + +// Included in orderAccess.hpp header file. +#include + +// Implementation of class OrderAccess. + +inline void OrderAccess::loadload() { acquire(); } +inline void OrderAccess::storestore() { release(); } +inline void OrderAccess::loadstore() { acquire(); } +inline void OrderAccess::storeload() { fence(); } + +inline void OrderAccess::acquire() { + std::atomic_thread_fence(std::memory_order_acquire); +} + +inline void OrderAccess::release() { + std::atomic_thread_fence(std::memory_order_release); +} + +inline void OrderAccess::fence() { + std::atomic_thread_fence(std::memory_order_seq_cst); +} + +inline void OrderAccess::cross_modify_fence_impl() { +} + +#endif // OS_CPU_WINDOWS_ZERO_ORDERACCESS_WINDOWS_ZERO_HPP diff --git a/src/hotspot/os_cpu/windows_zero/os_windows_zero.cpp b/src/hotspot/os_cpu/windows_zero/os_windows_zero.cpp new file mode 100644 index 0000000000000..e5671cc100ae2 --- /dev/null +++ b/src/hotspot/os_cpu/windows_zero/os_windows_zero.cpp @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "jvm.h" +#include "os_windows.hpp" +#include "runtime/frame.inline.hpp" +#include "runtime/os.inline.hpp" +#include "symbolengine.hpp" +#include "windbghelp.hpp" + +#undef REG_SP +#undef REG_FP +#undef REG_PC +#ifdef _M_AMD64 +#define REG_SP Rsp +#define REG_FP Rbp +#define REG_PC Rip +#elif defined(_M_ARM64) +#define REG_SP Sp +#define REG_FP Fp +#define REG_PC Pc +#endif // AMD64 + +JNIEXPORT +extern LONG topLevelExceptionFilter(PEXCEPTION_POINTERS); + +// Install a win32 structured exception handler around thread. +void os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method, JavaCallArguments* args, JavaThread* thread) { + WIN32_TRY { + f(value, method, args, thread); + } WIN32_EXCEPT (topLevelExceptionFilter(GetExceptionInformation())) { + // Nothing to do. + } +} + +#ifdef HAVE_PLATFORM_PRINT_NATIVE_STACK +/* + * Windows/x64 does not use stack frames the way expected by Java: + * [1] in most cases, there is no frame pointer. All locals are addressed via RSP + * [2] in rare cases, when alloca() is used, a frame pointer is used, but this may + * not be RBP. + * See http://msdn.microsoft.com/en-us/library/ew5tede7.aspx + * + * So it's not possible to print the native stack using the + * while (...) {... fr = os::get_sender_for_C_frame(&fr); } + * loop in vmError.cpp. We need to roll our own loop. + */ +bool os::win32::platform_print_native_stack(outputStream* st, const void* context, + char *buf, int buf_size, address& lastpc) +{ + CONTEXT ctx; + if (context != nullptr) { + memcpy(&ctx, context, sizeof(ctx)); + } else { + RtlCaptureContext(&ctx); + } + + st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)"); + + STACKFRAME stk; + memset(&stk, 0, sizeof(stk)); + stk.AddrStack.Offset = ctx.Rsp; + stk.AddrStack.Mode = AddrModeFlat; + stk.AddrFrame.Offset = ctx.Rbp; + stk.AddrFrame.Mode = AddrModeFlat; + stk.AddrPC.Offset = ctx.Rip; + stk.AddrPC.Mode = AddrModeFlat; + + // Ensure we consider dynamically loaded dll's + SymbolEngine::refreshModuleList(); + + int count = 0; + address lastpc_internal = 0; + while (count++ < StackPrintLimit) { + intptr_t* sp = (intptr_t*)stk.AddrStack.Offset; + intptr_t* fp = (intptr_t*)stk.AddrFrame.Offset; // NOT necessarily the same as ctx.Rbp! + address pc = (address)stk.AddrPC.Offset; + + if (pc != nullptr) { + if (count == 2 && lastpc_internal == pc) { + // Skip it -- StackWalk64() may return the same PC + // (but different SP) on the first try. + } else { + // Don't try to create a frame(sp, fp, pc) -- on WinX64, stk.AddrFrame + // may not contain what Java expects, and may cause the frame() constructor + // to crash. Let's just print out the symbolic address. + frame::print_C_frame(st, buf, buf_size, pc); + // print source file and line, if available + char buf[128]; + int line_no; + if (SymbolEngine::get_source_info(pc, buf, sizeof(buf), &line_no)) { + st->print(" (%s:%d)", buf, line_no); + } else { + st->print(" (no source info available)"); + } + st->cr(); + } + lastpc_internal = pc; + } + + PVOID p = WindowsDbgHelp::symFunctionTableAccess64(GetCurrentProcess(), stk.AddrPC.Offset); + if (!p) { + // StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash. + lastpc = lastpc_internal; + break; + } + + BOOL result = WindowsDbgHelp::stackWalk64( + IMAGE_FILE_MACHINE_AMD64, // __in DWORD MachineType, + GetCurrentProcess(), // __in HANDLE hProcess, + GetCurrentThread(), // __in HANDLE hThread, + &stk, // __inout LP STACKFRAME64 StackFrame, + &ctx); // __inout PVOID ContextRecord, + + if (!result) { + break; + } + } + if (count > StackPrintLimit) { + st->print_cr("......"); + } + st->cr(); + + return true; +} +#endif // HAVE_PLATFORM_PRINT_NATIVE_STACK + +address os::fetch_frame_from_context(const void* ucVoid, + intptr_t** ret_sp, intptr_t** ret_fp) { + + address epc; + CONTEXT* uc = (CONTEXT*)ucVoid; + + if (uc != nullptr) { + epc = reinterpret_cast
(uc->REG_PC); + if (ret_sp) *ret_sp = reinterpret_cast(uc->REG_SP); + if (ret_fp) *ret_fp = reinterpret_cast(uc->REG_FP); + } else { + epc = nullptr; + if (ret_sp) *ret_sp = static_cast(nullptr); + if (ret_fp) *ret_fp = static_cast(nullptr); + } + + return epc; +} + +frame os::fetch_frame_from_context(const void* ucVoid) { + // This code is only called from error handler to get PC and SP. + // We don't have the ready ZeroFrame* at this point, so fake the + // frame with bare minimum. + if (ucVoid != nullptr) { + intptr_t* sp; + intptr_t* fp; + address epc = fetch_frame_from_context(ucVoid, &sp, &fp); + frame dummy = frame(); + dummy.set_pc(epc); + dummy.set_sp(sp); + return dummy; + } else { + return frame(nullptr, nullptr); + } +} + +PRAGMA_DIAG_PUSH +PRAGMA_DISABLE_GCC_WARNING("-Wreturn-local-addr") +PRAGMA_DISABLE_MSVC_WARNING(4172) +// Returns an estimate of the current stack pointer. Result must be guaranteed +// to point into the calling threads stack, and be no lower than the current +// stack pointer. +address os::current_stack_pointer() { + address dummy = reinterpret_cast
(&dummy); + return dummy; +} +PRAGMA_DIAG_POP + +frame os::get_sender_for_C_frame(frame* fr) { + ShouldNotCallThis(); + return frame(nullptr, nullptr); // silence compile warning. +} + +frame os::current_frame() { + // The only thing that calls this is the stack printing code in + // VMError::report: + // - Step 110 (printing stack bounds) uses the sp in the frame + // to determine the amount of free space on the stack. We + // set the sp to a close approximation of the real value in + // order to allow this step to complete. + // - Step 120 (printing native stack) tries to walk the stack. + // The frame we create has a null pc, which is ignored as an + // invalid frame. + frame dummy = frame(); + dummy.set_sp(reinterpret_cast(current_stack_pointer())); + return dummy; +} + +void os::print_context(outputStream* st, const void* ucVoid) { + st->print_cr("No context information."); +} + +void os::print_register_info(outputStream *st, const void *context, int& continuation) { + st->print_cr("No register info."); +} + +void os::setup_fpu() { +} + +#ifndef PRODUCT +void os::verify_stack_alignment() { +} +#endif + +extern "C" { + int SpinPause() { +#ifdef AMD64 + YieldProcessor(); + return 1; +#else + return 0; +#endif + } + + void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { + if (from > to) { + const jshort *end = from + count; + while (from < end) + *(to++) = *(from++); + } + else if (from < to) { + const jshort *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + *(to--) = *(from--); + } + } + void _Copy_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { + if (from > to) { + const jint *end = from + count; + while (from < end) + *(to++) = *(from++); + } + else if (from < to) { + const jint *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + *(to--) = *(from--); + } + } + void _Copy_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { + if (from > to) { + const jlong *end = from + count; + while (from < end) + [] (const volatile void *src, volatile void *dst) noexcept -> void { + *reinterpret_cast(dst) = *(const jlong *) src; + } (from++, to++); + } + else if (from < to) { + const jlong *end = from; + from += count - 1; + to += count - 1; + while (from >= end) + [] (const volatile void *src, volatile void *dst) noexcept -> void { + *reinterpret_cast(dst) = *(const jlong *) src; + } (from--, to--); + } + } + + void _Copy_arrayof_conjoint_bytes(const HeapWord* from, + HeapWord* to, + size_t count) { + memmove(to, from, count); + } + void _Copy_arrayof_conjoint_jshorts(const HeapWord* from, + HeapWord* to, + size_t count) { + memmove(to, from, count * 2); + } + void _Copy_arrayof_conjoint_jints(const HeapWord* from, + HeapWord* to, + size_t count) { + memmove(to, from, count * 4); + } + void _Copy_arrayof_conjoint_jlongs(const HeapWord* from, + HeapWord* to, + size_t count) { + memmove(to, from, count * 8); + } +} diff --git a/src/hotspot/os_cpu/windows_zero/os_windows_zero.inline.hpp b/src/hotspot/os_cpu/windows_zero/os_windows_zero.inline.hpp new file mode 100644 index 0000000000000..1dfab6f3f99df --- /dev/null +++ b/src/hotspot/os_cpu/windows_zero/os_windows_zero.inline.hpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_ZERO_OS_WINDOWS_ZERO_INLINE_HPP +#define OS_CPU_WINDOWS_ZERO_OS_WINDOWS_ZERO_INLINE_HPP + +#include "os_windows.hpp" + +#ifdef _MSC_VER +#define HAVE_PLATFORM_PRINT_NATIVE_STACK 1 +inline bool os::platform_print_native_stack(outputStream* st, const void* context, + char *buf, int buf_size, address& lastpc) { + return os::win32::platform_print_native_stack(st, context, buf, buf_size, lastpc); +} +#endif + +inline bool os::register_code_area(char *low, char *high) { + return true; +} + +#endif // OS_CPU_WINDOWS_ZERO_OS_WINDOWS_ZERO_INLINE_HPP diff --git a/src/hotspot/os_cpu/windows_zero/prefetch_windows_zero.inline.hpp b/src/hotspot/os_cpu/windows_zero/prefetch_windows_zero.inline.hpp new file mode 100644 index 0000000000000..e9eb099d42d69 --- /dev/null +++ b/src/hotspot/os_cpu/windows_zero/prefetch_windows_zero.inline.hpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_ZERO_PREFETCH_WINDOWS_ZERO_INLINE_HPP +#define OS_CPU_WINDOWS_ZERO_PREFETCH_WINDOWS_ZERO_INLINE_HPP + +#include "runtime/prefetch.hpp" + +inline void Prefetch::read (const void *loc, intx interval) {} +inline void Prefetch::write(void *loc, intx interval) {} + +#endif // OS_CPU_WINDOWS_ZERO_PREFETCH_WINDOWS_ZERO_INLINE_HPP diff --git a/src/hotspot/os_cpu/windows_zero/vmStructs_windows_zero.hpp b/src/hotspot/os_cpu/windows_zero/vmStructs_windows_zero.hpp new file mode 100644 index 0000000000000..4df8aaf73a257 --- /dev/null +++ b/src/hotspot/os_cpu/windows_zero/vmStructs_windows_zero.hpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef OS_CPU_WINDOWS_ZERO_VMSTRUCTS_WINDOWS_ZERO_HPP +#define OS_CPU_WINDOWS_ZERO_VMSTRUCTS_WINDOWS_ZERO_HPP + +// These are the OS and CPU-specific fields, types and integer +// constants required by the Serviceability Agent. This file is +// referenced by vmStructs.cpp. + +#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) + +#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) + +#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) + +#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) + +#endif // OS_CPU_WINDOWS_ZERO_VMSTRUCTS_WINDOWS_ZERO_HPP diff --git a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp index 3f3632c0eea5d..2f8c7208cf655 100644 --- a/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp +++ b/src/hotspot/share/interpreter/zero/bytecodeInterpreter.cpp @@ -66,32 +66,10 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" -/* - * USELABELS - If using GCC, then use labels for the opcode dispatching - * rather -then a switch statement. This improves performance because it - * gives us the opportunity to have the instructions that calculate the - * next opcode to jump to be intermixed with the rest of the instructions - * that implement the opcode (see UPDATE_PC_AND_TOS_AND_CONTINUE macro). - */ -#undef USELABELS -#ifdef __GNUC__ -/* - ASSERT signifies debugging. It is much easier to step thru bytecodes if we - don't use the computed goto approach. -*/ -#ifndef ASSERT -#define USELABELS -#endif -#endif #undef CASE -#ifdef USELABELS -#define CASE(opcode) opc ## opcode -#define DEFAULT opc_default -#else #define CASE(opcode) case Bytecodes:: opcode #define DEFAULT default -#endif /* * PREFETCH_OPCCODE - Some compilers do better if you prefetch the next @@ -205,17 +183,6 @@ JRT_END * CONTINUE - Macro for executing the next opcode. */ #undef CONTINUE -#ifdef USELABELS -// Have to do this dispatch this way in C++ because otherwise gcc complains about crossing an -// initialization (which is is the initialization of the table pointer...) -#define DISPATCH(opcode) goto *(void*)dispatch_table[opcode] -#define CONTINUE { \ - opcode = *pc; \ - DO_UPDATE_INSTRUCTION_COUNT(opcode); \ - DEBUGGER_SINGLE_STEP_NOTIFY(); \ - DISPATCH(opcode); \ - } -#else #ifdef PREFETCH_OPCCODE #define CONTINUE { \ opcode = *pc; \ @@ -230,7 +197,6 @@ JRT_END continue; \ } #endif -#endif #define UPDATE_PC(opsize) {pc += opsize; } @@ -247,21 +213,6 @@ JRT_END * of UPDATE_PC_AND_TOS and CONTINUE, but with some minor optimizations. */ #undef UPDATE_PC_AND_TOS_AND_CONTINUE -#ifdef USELABELS -#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \ - pc += opsize; opcode = *pc; MORE_STACK(stack); \ - DO_UPDATE_INSTRUCTION_COUNT(opcode); \ - DEBUGGER_SINGLE_STEP_NOTIFY(); \ - DISPATCH(opcode); \ - } - -#define UPDATE_PC_AND_CONTINUE(opsize) { \ - pc += opsize; opcode = *pc; \ - DO_UPDATE_INSTRUCTION_COUNT(opcode); \ - DEBUGGER_SINGLE_STEP_NOTIFY(); \ - DISPATCH(opcode); \ - } -#else #ifdef PREFETCH_OPCCODE #define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \ pc += opsize; opcode = *pc; MORE_STACK(stack); \ @@ -291,7 +242,6 @@ JRT_END goto do_continue; \ } #endif /* PREFETCH_OPCCODE */ -#endif /* USELABELS */ // About to call a new method, update the save the adjusted pc and return to frame manager #define UPDATE_PC_AND_RETURN(opsize) \ @@ -518,91 +468,6 @@ void BytecodeInterpreter::run(interpreterState istate) { interpreterState orig = istate; #endif -#ifdef USELABELS - const static void* const opclabels_data[256] = { -/* 0x00 */ &&opc_nop, &&opc_aconst_null, &&opc_iconst_m1, &&opc_iconst_0, -/* 0x04 */ &&opc_iconst_1, &&opc_iconst_2, &&opc_iconst_3, &&opc_iconst_4, -/* 0x08 */ &&opc_iconst_5, &&opc_lconst_0, &&opc_lconst_1, &&opc_fconst_0, -/* 0x0C */ &&opc_fconst_1, &&opc_fconst_2, &&opc_dconst_0, &&opc_dconst_1, - -/* 0x10 */ &&opc_bipush, &&opc_sipush, &&opc_ldc, &&opc_ldc_w, -/* 0x14 */ &&opc_ldc2_w, &&opc_iload, &&opc_lload, &&opc_fload, -/* 0x18 */ &&opc_dload, &&opc_aload, &&opc_iload_0, &&opc_iload_1, -/* 0x1C */ &&opc_iload_2, &&opc_iload_3, &&opc_lload_0, &&opc_lload_1, - -/* 0x20 */ &&opc_lload_2, &&opc_lload_3, &&opc_fload_0, &&opc_fload_1, -/* 0x24 */ &&opc_fload_2, &&opc_fload_3, &&opc_dload_0, &&opc_dload_1, -/* 0x28 */ &&opc_dload_2, &&opc_dload_3, &&opc_aload_0, &&opc_aload_1, -/* 0x2C */ &&opc_aload_2, &&opc_aload_3, &&opc_iaload, &&opc_laload, - -/* 0x30 */ &&opc_faload, &&opc_daload, &&opc_aaload, &&opc_baload, -/* 0x34 */ &&opc_caload, &&opc_saload, &&opc_istore, &&opc_lstore, -/* 0x38 */ &&opc_fstore, &&opc_dstore, &&opc_astore, &&opc_istore_0, -/* 0x3C */ &&opc_istore_1, &&opc_istore_2, &&opc_istore_3, &&opc_lstore_0, - -/* 0x40 */ &&opc_lstore_1, &&opc_lstore_2, &&opc_lstore_3, &&opc_fstore_0, -/* 0x44 */ &&opc_fstore_1, &&opc_fstore_2, &&opc_fstore_3, &&opc_dstore_0, -/* 0x48 */ &&opc_dstore_1, &&opc_dstore_2, &&opc_dstore_3, &&opc_astore_0, -/* 0x4C */ &&opc_astore_1, &&opc_astore_2, &&opc_astore_3, &&opc_iastore, - -/* 0x50 */ &&opc_lastore, &&opc_fastore, &&opc_dastore, &&opc_aastore, -/* 0x54 */ &&opc_bastore, &&opc_castore, &&opc_sastore, &&opc_pop, -/* 0x58 */ &&opc_pop2, &&opc_dup, &&opc_dup_x1, &&opc_dup_x2, -/* 0x5C */ &&opc_dup2, &&opc_dup2_x1, &&opc_dup2_x2, &&opc_swap, - -/* 0x60 */ &&opc_iadd, &&opc_ladd, &&opc_fadd, &&opc_dadd, -/* 0x64 */ &&opc_isub, &&opc_lsub, &&opc_fsub, &&opc_dsub, -/* 0x68 */ &&opc_imul, &&opc_lmul, &&opc_fmul, &&opc_dmul, -/* 0x6C */ &&opc_idiv, &&opc_ldiv, &&opc_fdiv, &&opc_ddiv, - -/* 0x70 */ &&opc_irem, &&opc_lrem, &&opc_frem, &&opc_drem, -/* 0x74 */ &&opc_ineg, &&opc_lneg, &&opc_fneg, &&opc_dneg, -/* 0x78 */ &&opc_ishl, &&opc_lshl, &&opc_ishr, &&opc_lshr, -/* 0x7C */ &&opc_iushr, &&opc_lushr, &&opc_iand, &&opc_land, - -/* 0x80 */ &&opc_ior, &&opc_lor, &&opc_ixor, &&opc_lxor, -/* 0x84 */ &&opc_iinc, &&opc_i2l, &&opc_i2f, &&opc_i2d, -/* 0x88 */ &&opc_l2i, &&opc_l2f, &&opc_l2d, &&opc_f2i, -/* 0x8C */ &&opc_f2l, &&opc_f2d, &&opc_d2i, &&opc_d2l, - -/* 0x90 */ &&opc_d2f, &&opc_i2b, &&opc_i2c, &&opc_i2s, -/* 0x94 */ &&opc_lcmp, &&opc_fcmpl, &&opc_fcmpg, &&opc_dcmpl, -/* 0x98 */ &&opc_dcmpg, &&opc_ifeq, &&opc_ifne, &&opc_iflt, -/* 0x9C */ &&opc_ifge, &&opc_ifgt, &&opc_ifle, &&opc_if_icmpeq, - -/* 0xA0 */ &&opc_if_icmpne, &&opc_if_icmplt, &&opc_if_icmpge, &&opc_if_icmpgt, -/* 0xA4 */ &&opc_if_icmple, &&opc_if_acmpeq, &&opc_if_acmpne, &&opc_goto, -/* 0xA8 */ &&opc_jsr, &&opc_ret, &&opc_tableswitch, &&opc_lookupswitch, -/* 0xAC */ &&opc_ireturn, &&opc_lreturn, &&opc_freturn, &&opc_dreturn, - -/* 0xB0 */ &&opc_areturn, &&opc_return, &&opc_getstatic, &&opc_putstatic, -/* 0xB4 */ &&opc_getfield, &&opc_putfield, &&opc_invokevirtual, &&opc_invokespecial, -/* 0xB8 */ &&opc_invokestatic, &&opc_invokeinterface, &&opc_invokedynamic, &&opc_new, -/* 0xBC */ &&opc_newarray, &&opc_anewarray, &&opc_arraylength, &&opc_athrow, - -/* 0xC0 */ &&opc_checkcast, &&opc_instanceof, &&opc_monitorenter, &&opc_monitorexit, -/* 0xC4 */ &&opc_wide, &&opc_multianewarray, &&opc_ifnull, &&opc_ifnonnull, -/* 0xC8 */ &&opc_goto_w, &&opc_jsr_w, &&opc_breakpoint, &&opc_fast_agetfield, -/* 0xCC */ &&opc_fast_bgetfield,&&opc_fast_cgetfield, &&opc_fast_dgetfield, &&opc_fast_fgetfield, - -/* 0xD0 */ &&opc_fast_igetfield,&&opc_fast_lgetfield, &&opc_fast_sgetfield, &&opc_fast_aputfield, -/* 0xD4 */ &&opc_fast_bputfield,&&opc_fast_zputfield, &&opc_fast_cputfield, &&opc_fast_dputfield, -/* 0xD8 */ &&opc_fast_fputfield,&&opc_fast_iputfield, &&opc_fast_lputfield, &&opc_fast_sputfield, -/* 0xDC */ &&opc_fast_aload_0, &&opc_fast_iaccess_0, &&opc_fast_aaccess_0, &&opc_fast_faccess_0, - -/* 0xE0 */ &&opc_fast_iload, &&opc_fast_iload2, &&opc_fast_icaload, &&opc_fast_invokevfinal, -/* 0xE4 */ &&opc_default, &&opc_default, &&opc_fast_aldc, &&opc_fast_aldc_w, -/* 0xE8 */ &&opc_return_register_finalizer, - &&opc_invokehandle, &&opc_nofast_getfield,&&opc_nofast_putfield, -/* 0xEC */ &&opc_nofast_aload_0,&&opc_nofast_iload, &&opc_default, &&opc_default, - -/* 0xF0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -/* 0xF4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -/* 0xF8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -/* 0xFC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default - }; - uintptr_t *dispatch_table = (uintptr_t*)&opclabels_data[0]; -#endif /* USELABELS */ switch (istate->msg()) { case initialize: { @@ -763,9 +628,7 @@ void BytecodeInterpreter::run(interpreterState istate) { opcode = *pc; /* prefetch first opcode */ #endif -#ifndef USELABELS while (1) -#endif { #ifndef PREFETCH_OPCCODE opcode = *pc; @@ -782,11 +645,7 @@ void BytecodeInterpreter::run(interpreterState istate) { assert(topOfStack >= istate->stack_limit(), "Stack overrun"); assert(topOfStack < istate->stack_base(), "Stack underrun"); -#ifdef USELABELS - DISPATCH(opcode); -#else switch (opcode) -#endif { CASE(_nop): UPDATE_PC_AND_CONTINUE(1); @@ -2927,9 +2786,6 @@ void BytecodeInterpreter::run(interpreterState istate) { } /* switch(opc) */ -#ifdef USELABELS - check_for_exception: -#endif { if (!THREAD->has_pending_exception()) { CONTINUE;