--- a/doc/building.html Wed Oct 18 16:06:39 2017 +0200
+++ b/doc/building.html Sun Oct 15 22:54:03 2017 +0200
@@ -463,7 +463,7 @@
<li><code>--with-native-debug-symbols=<method></code> - Specify if and how native debug symbols should be built. Available methods are <code>none</code>, <code>internal</code>, <code>external</code>, <code>zipped</code>. Default behavior depends on platform. See <a href="#native-debug-symbols">Native Debug Symbols</a> for more details.</li>
<li><code>--with-version-string=<string></code> - Specify the version string this build will be identified with.</li>
<li><code>--with-version-<part>=<value></code> - A group of options, where <code><part></code> can be any of <code>pre</code>, <code>opt</code>, <code>build</code>, <code>major</code>, <code>minor</code>, <code>security</code> or <code>patch</code>. Use these options to modify just the corresponding part of the version string from the default, or the value provided by <code>--with-version-string</code>.</li>
-<li><code>--with-jvm-variants=<variant>[,<variant>...]</code> - Build the specified variant (or variants) of Hotspot. Valid variants are: <code>server</code>, <code>client</code>, <code>minimal</code>, <code>core</code>, <code>zero</code>, <code>zeroshark</code>, <code>custom</code>. Note that not all variants are possible to combine in a single build.</li>
+<li><code>--with-jvm-variants=<variant>[,<variant>...]</code> - Build the specified variant (or variants) of Hotspot. Valid variants are: <code>server</code>, <code>client</code>, <code>minimal</code>, <code>core</code>, <code>zero</code>, <code>custom</code>. Note that not all variants are possible to combine in a single build.</li>
<li><code>--with-jvm-features=<feature>[,<feature>...]</code> - Use the specified JVM features when building Hotspot. The list of features will be enabled on top of the default list. For the <code>custom</code> JVM variant, this default list is empty. A complete list of available JVM features can be found using <code>bash configure --help</code>.</li>
<li><code>--with-target-bits=<bits></code> - Create a target binary suitable for running on a <code><bits></code> platform. Use this to create 32-bit output on a 64-bit build platform, instead of doing a full cross-compile. (This is known as a <em>reduced</em> build.)</li>
</ul>
--- a/doc/building.md Wed Oct 18 16:06:39 2017 +0200
+++ b/doc/building.md Sun Oct 15 22:54:03 2017 +0200
@@ -668,7 +668,7 @@
from the default, or the value provided by `--with-version-string`.
* `--with-jvm-variants=<variant>[,<variant>...]` - Build the specified variant
(or variants) of Hotspot. Valid variants are: `server`, `client`,
- `minimal`, `core`, `zero`, `zeroshark`, `custom`. Note that not all
+ `minimal`, `core`, `zero`, `custom`. Note that not all
variants are possible to combine in a single build.
* `--with-jvm-features=<feature>[,<feature>...]` - Use the specified JVM
features when building Hotspot. The list of features will be enabled on top
--- a/make/autoconf/flags.m4 Wed Oct 18 16:06:39 2017 +0200
+++ b/make/autoconf/flags.m4 Sun Oct 15 22:54:03 2017 +0200
@@ -1097,7 +1097,7 @@
]
)
fi
- if ! HOTSPOT_CHECK_JVM_VARIANT(zero) && ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+ if ! HOTSPOT_CHECK_JVM_VARIANT(zero); then
# Non-zero builds have stricter warnings
$2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wreturn-type -Wundef -Wformat=2"
else
--- a/make/autoconf/hotspot.m4 Wed Oct 18 16:06:39 2017 +0200
+++ b/make/autoconf/hotspot.m4 Sun Oct 15 22:54:03 2017 +0200
@@ -24,12 +24,12 @@
#
# All valid JVM features, regardless of platform
-VALID_JVM_FEATURES="compiler1 compiler2 zero shark minimal dtrace jvmti jvmci \
+VALID_JVM_FEATURES="compiler1 compiler2 zero minimal dtrace jvmti jvmci \
graal vm-structs jni-check services management all-gcs nmt cds \
static-build link-time-opt aot"
# All valid JVM variants
-VALID_JVM_VARIANTS="server client minimal core zero zeroshark custom"
+VALID_JVM_VARIANTS="server client minimal core zero custom"
###############################################################################
# Check if the specified JVM variant should be built. To be used in shell if
@@ -62,13 +62,12 @@
# minimal: reduced form of client with optional features stripped out
# core: normal interpreter only, no compiler
# zero: C++ based interpreter only, no compiler
-# zeroshark: C++ based interpreter, and a llvm-based compiler
# custom: baseline JVM with no default features
#
AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_VARIANTS],
[
AC_ARG_WITH([jvm-variants], [AS_HELP_STRING([--with-jvm-variants],
- [JVM variants (separated by commas) to build (server,client,minimal,core,zero,zeroshark,custom) @<:@server@:>@])])
+ [JVM variants (separated by commas) to build (server,client,minimal,core,zero,custom) @<:@server@:>@])])
SETUP_HOTSPOT_TARGET_CPU_PORT
@@ -132,7 +131,7 @@
AC_SUBST(VALID_JVM_VARIANTS)
AC_SUBST(JVM_VARIANT_MAIN)
- if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+ if HOTSPOT_CHECK_JVM_VARIANT(zero); then
# zero behaves as a platform and rewrites these values. This is really weird. :(
# We are guaranteed that we do not build any other variants when building zero.
HOTSPOT_TARGET_CPU=zero
@@ -325,15 +324,9 @@
fi
fi
- if ! HOTSPOT_CHECK_JVM_VARIANT(zero) && ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+ if ! HOTSPOT_CHECK_JVM_VARIANT(zero); then
if HOTSPOT_CHECK_JVM_FEATURE(zero); then
- AC_MSG_ERROR([To enable zero/zeroshark, you must use --with-jvm-variants=zero/zeroshark])
- fi
- fi
-
- if ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
- if HOTSPOT_CHECK_JVM_FEATURE(shark); then
- AC_MSG_ERROR([To enable shark, you must use --with-jvm-variants=zeroshark])
+ AC_MSG_ERROR([To enable zero, you must use --with-jvm-variants=zero])
fi
fi
@@ -408,7 +401,6 @@
JVM_FEATURES_core="$NON_MINIMAL_FEATURES $JVM_FEATURES"
JVM_FEATURES_minimal="compiler1 minimal $JVM_FEATURES $JVM_FEATURES_link_time_opt"
JVM_FEATURES_zero="zero $NON_MINIMAL_FEATURES $JVM_FEATURES"
- JVM_FEATURES_zeroshark="zero shark $NON_MINIMAL_FEATURES $JVM_FEATURES"
JVM_FEATURES_custom="$JVM_FEATURES"
AC_SUBST(JVM_FEATURES_server)
@@ -416,7 +408,6 @@
AC_SUBST(JVM_FEATURES_core)
AC_SUBST(JVM_FEATURES_minimal)
AC_SUBST(JVM_FEATURES_zero)
- AC_SUBST(JVM_FEATURES_zeroshark)
AC_SUBST(JVM_FEATURES_custom)
# Used for verification of Makefiles by check-jvm-feature
@@ -437,7 +428,6 @@
JVM_FEATURES_core="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_core | $SORT -u))"
JVM_FEATURES_minimal="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_minimal | $SORT -u))"
JVM_FEATURES_zero="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zero | $SORT -u))"
- JVM_FEATURES_zeroshark="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_zeroshark | $SORT -u))"
JVM_FEATURES_custom="$($ECHO $($PRINTF '%s\n' $JVM_FEATURES_custom | $SORT -u))"
# Validate features
--- a/make/autoconf/jdk-options.m4 Wed Oct 18 16:06:39 2017 +0200
+++ b/make/autoconf/jdk-options.m4 Sun Oct 15 22:54:03 2017 +0200
@@ -232,7 +232,7 @@
# Should we build the serviceability agent (SA)?
INCLUDE_SA=true
- if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+ if HOTSPOT_CHECK_JVM_VARIANT(zero); then
INCLUDE_SA=false
fi
if test "x$OPENJDK_TARGET_OS" = xaix ; then
--- a/make/autoconf/lib-std.m4 Wed Oct 18 16:06:39 2017 +0200
+++ b/make/autoconf/lib-std.m4 Sun Oct 15 22:54:03 2017 +0200
@@ -65,8 +65,7 @@
# If dynamic was requested, it's available since it would fail above otherwise.
# If dynamic wasn't requested, go with static unless it isn't available.
AC_MSG_CHECKING([how to link with libstdc++])
- if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno \
- || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+ if test "x$with_stdc__lib" = xdynamic || test "x$has_static_libstdcxx" = xno ; then
AC_MSG_RESULT([dynamic])
else
LIBCXX="$LIBCXX $STATIC_STDCXX_FLAGS"
--- a/make/autoconf/libraries.m4 Wed Oct 18 16:06:39 2017 +0200
+++ b/make/autoconf/libraries.m4 Sun Oct 15 22:54:03 2017 +0200
@@ -68,7 +68,7 @@
fi
# Check if ffi is needed
- if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
+ if HOTSPOT_CHECK_JVM_VARIANT(zero); then
NEEDS_LIB_FFI=true
else
NEEDS_LIB_FFI=false
@@ -86,70 +86,12 @@
LIB_SETUP_FREETYPE
LIB_SETUP_ALSA
LIB_SETUP_LIBFFI
- LIB_SETUP_LLVM
LIB_SETUP_BUNDLED_LIBS
LIB_SETUP_MISC_LIBS
LIB_SETUP_SOLARIS_STLPORT
])
################################################################################
-# Setup llvm (Low-Level VM)
-################################################################################
-AC_DEFUN_ONCE([LIB_SETUP_LLVM],
-[
- if HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
- AC_CHECK_PROG([LLVM_CONFIG], [llvm-config], [llvm-config])
-
- if test "x$LLVM_CONFIG" != xllvm-config; then
- AC_MSG_ERROR([llvm-config not found in $PATH.])
- fi
-
- llvm_components="jit mcjit engine nativecodegen native"
- unset LLVM_CFLAGS
- for flag in $("$LLVM_CONFIG" --cxxflags); do
- if echo "${flag}" | grep -q '^-@<:@ID@:>@'; then
- if test "${flag}" != "-D_DEBUG" ; then
- if test "${LLVM_CFLAGS}" != "" ; then
- LLVM_CFLAGS="${LLVM_CFLAGS} "
- fi
- LLVM_CFLAGS="${LLVM_CFLAGS}${flag}"
- fi
- fi
- done
- llvm_version=$("${LLVM_CONFIG}" --version | $SED 's/\.//; s/svn.*//')
- LLVM_CFLAGS="${LLVM_CFLAGS} -DSHARK_LLVM_VERSION=${llvm_version}"
-
- unset LLVM_LDFLAGS
- for flag in $("${LLVM_CONFIG}" --ldflags); do
- if echo "${flag}" | grep -q '^-L'; then
- if test "${LLVM_LDFLAGS}" != ""; then
- LLVM_LDFLAGS="${LLVM_LDFLAGS} "
- fi
- LLVM_LDFLAGS="${LLVM_LDFLAGS}${flag}"
- fi
- done
-
- unset LLVM_LIBS
- for flag in $("${LLVM_CONFIG}" --libs ${llvm_components}); do
- if echo "${flag}" | grep -q '^-l'; then
- if test "${LLVM_LIBS}" != ""; then
- LLVM_LIBS="${LLVM_LIBS} "
- fi
- LLVM_LIBS="${LLVM_LIBS}${flag}"
- fi
- done
-
- # Due to https://llvm.org/bugs/show_bug.cgi?id=16902, llvm does not
- # always properly detect -ltinfo
- LLVM_LIBS="${LLVM_LIBS} -ltinfo"
-
- AC_SUBST(LLVM_CFLAGS)
- AC_SUBST(LLVM_LDFLAGS)
- AC_SUBST(LLVM_LIBS)
- fi
-])
-
-################################################################################
# Setup various libraries, typically small system libraries
################################################################################
AC_DEFUN_ONCE([LIB_SETUP_MISC_LIBS],
--- a/make/autoconf/spec.gmk.in Wed Oct 18 16:06:39 2017 +0200
+++ b/make/autoconf/spec.gmk.in Sun Oct 15 22:54:03 2017 +0200
@@ -222,7 +222,6 @@
JVM_FEATURES_core := @JVM_FEATURES_core@
JVM_FEATURES_minimal := @JVM_FEATURES_minimal@
JVM_FEATURES_zero := @JVM_FEATURES_zero@
-JVM_FEATURES_zeroshark := @JVM_FEATURES_zeroshark@
JVM_FEATURES_custom := @JVM_FEATURES_custom@
# Used for make-time verifications
@@ -396,11 +395,6 @@
JVM_LIBS := @JVM_LIBS@
JVM_RCFLAGS := @JVM_RCFLAGS@
-# Flags for zeroshark
-LLVM_CFLAGS := @LLVM_CFLAGS@
-LLVM_LIBS := @LLVM_LIBS@
-LLVM_LDFLAGS := @LLVM_LDFLAGS@
-
# These flags might contain variables set by a custom extension that is included later.
EXTRA_CFLAGS = @EXTRA_CFLAGS@
EXTRA_CXXFLAGS = @EXTRA_CXXFLAGS@
--- a/make/copy/Copy-java.base.gmk Wed Oct 18 16:06:39 2017 +0200
+++ b/make/copy/Copy-java.base.gmk Sun Oct 15 22:54:03 2017 +0200
@@ -87,7 +87,7 @@
#
# How to install jvm.cfg.
#
-ifeq ($(call check-jvm-variant, zero zeroshark), true)
+ifeq ($(call check-jvm-variant, zero), true)
JVMCFG_ARCH := zero
else
JVMCFG_ARCH := $(OPENJDK_TARGET_CPU_LEGACY)
@@ -102,8 +102,6 @@
endif
JVMCFG := $(LIB_DST_DIR)/jvm.cfg
-# To do: should this also support -zeroshark?
-
ifeq ($(OPENJDK_TARGET_CPU_BITS), 64)
COPY_JVM_CFG_FILE := true
else
@@ -120,7 +118,7 @@
COPY_JVM_CFG_FILE := true
else
# For zero, the default jvm.cfg file is sufficient
- ifeq ($(call check-jvm-variant, zero zeroshark), true)
+ ifeq ($(call check-jvm-variant, zero), true)
COPY_JVM_CFG_FILE := true
endif
endif
--- a/make/hotspot/ide/CreateVSProject.gmk Wed Oct 18 16:06:39 2017 +0200
+++ b/make/hotspot/ide/CreateVSProject.gmk Sun Oct 15 22:54:03 2017 +0200
@@ -75,7 +75,6 @@
-ignorePath linux \
-ignorePath posix \
-ignorePath ppc \
- -ignorePath shark \
-ignorePath solaris \
-ignorePath sparc \
-ignorePath x86_32 \
--- a/make/hotspot/lib/JvmFeatures.gmk Wed Oct 18 16:06:39 2017 +0200
+++ b/make/hotspot/lib/JvmFeatures.gmk Sun Oct 15 22:54:03 2017 +0200
@@ -52,14 +52,6 @@
endif
endif
-ifeq ($(call check-jvm-feature, shark), true)
- JVM_CFLAGS_FEATURES += -DSHARK $(LLVM_CFLAGS)
- JVM_LDFLAGS_FEATURES += $(LLVM_LDFLAGS)
- JVM_LIBS_FEATURES += $(LLVM_LIBS)
-else
- JVM_EXCLUDES += shark
-endif
-
ifeq ($(call check-jvm-feature, minimal), true)
JVM_CFLAGS_FEATURES += -DMINIMAL_JVM -DVMTYPE=\"Minimal\"
ifeq ($(OPENJDK_TARGET_OS), linux)
--- a/make/lib/CoreLibraries.gmk Wed Oct 18 16:06:39 2017 +0200
+++ b/make/lib/CoreLibraries.gmk Sun Oct 15 22:54:03 2017 +0200
@@ -300,7 +300,7 @@
LIBJLI_CFLAGS := $(CFLAGS_JDKLIB)
-ifeq ($(call check-jvm-variant, zero zeroshark), true)
+ifeq ($(call check-jvm-variant, zero), true)
ERGO_FAMILY := zero
else
ifeq ($(OPENJDK_TARGET_CPU_ARCH), x86)
--- a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -42,10 +42,6 @@
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
-#ifdef SHARK
-#include "compiler/compileBroker.hpp"
-#include "shark/sharkCompiler.hpp"
-#endif
#define __ masm->
--- a/src/hotspot/cpu/sparc/globalDefinitions_sparc.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/sparc/globalDefinitions_sparc.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -43,7 +43,7 @@
#elif defined(COMPILER1)
// pure C1, 32-bit, small machine
#define DEFAULT_CACHE_LINE_SIZE 16
-#elif defined(COMPILER2) || defined(SHARK)
+#elif defined(COMPILER2)
// pure C2, 64-bit, large machine
#define DEFAULT_CACHE_LINE_SIZE 128
#endif
--- a/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -41,10 +41,6 @@
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
-#ifdef SHARK
-#include "compiler/compileBroker.hpp"
-#include "shark/sharkCompiler.hpp"
-#endif
#if INCLUDE_JVMCI
#include "jvmci/jvmciJavaClasses.hpp"
#endif
--- a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -46,7 +46,7 @@
// pure C1, 32-bit, small machine
// i486 was the last Intel chip with 16-byte cache line size
#define DEFAULT_CACHE_LINE_SIZE 32
-#elif defined(COMPILER2) || defined(SHARK)
+#elif defined(COMPILER2)
#ifdef _LP64
// pure C2, 64-bit, large machine
#define DEFAULT_CACHE_LINE_SIZE 128
--- a/src/hotspot/cpu/zero/cppInterpreter_zero.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/zero/cppInterpreter_zero.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -50,9 +50,6 @@
#include "stack_zero.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/macros.hpp"
-#ifdef SHARK
-#include "shark/shark_globals.hpp"
-#endif
#ifdef CC_INTERP
--- a/src/hotspot/cpu/zero/frame_zero.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/zero/frame_zero.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -71,7 +71,6 @@
frame frame::sender_for_nonentry_frame(RegisterMap *map) const {
assert(zeroframe()->is_interpreter_frame() ||
- zeroframe()->is_shark_frame() ||
zeroframe()->is_fake_stub_frame(), "wrong type of frame");
return frame(zeroframe()->next(), sender_sp());
}
@@ -101,8 +100,6 @@
if (pc != NULL) {
_cb = CodeCache::find_blob(pc);
- SharkFrame* sharkframe = zeroframe()->as_shark_frame();
- sharkframe->set_pc(pc);
_pc = pc;
_deopt_state = is_deoptimized;
@@ -233,8 +230,6 @@
strncpy(valuebuf, "ENTRY_FRAME", buflen);
else if (is_interpreter_frame())
strncpy(valuebuf, "INTERPRETER_FRAME", buflen);
- else if (is_shark_frame())
- strncpy(valuebuf, "SHARK_FRAME", buflen);
else if (is_fake_stub_frame())
strncpy(valuebuf, "FAKE_STUB_FRAME", buflen);
break;
@@ -248,10 +243,6 @@
as_interpreter_frame()->identify_word(
frame_index, offset, fieldbuf, valuebuf, buflen);
}
- else if (is_shark_frame()) {
- as_shark_frame()->identify_word(
- frame_index, offset, fieldbuf, valuebuf, buflen);
- }
else if (is_fake_stub_frame()) {
as_fake_stub_frame()->identify_word(
frame_index, offset, fieldbuf, valuebuf, buflen);
@@ -350,50 +341,6 @@
fieldbuf, buflen);
}
-void SharkFrame::identify_word(int frame_index,
- int offset,
- char* fieldbuf,
- char* valuebuf,
- int buflen) const {
- // Fixed part
- switch (offset) {
- case pc_off:
- strncpy(fieldbuf, "pc", buflen);
- if (method()->is_method()) {
- CompiledMethod *code = method()->code();
- if (code && code->pc_desc_at(pc())) {
- SimpleScopeDesc ssd(code, pc());
- snprintf(valuebuf, buflen, PTR_FORMAT " (bci %d)",
- (intptr_t) pc(), ssd.bci());
- }
- }
- return;
-
- case unextended_sp_off:
- strncpy(fieldbuf, "unextended_sp", buflen);
- return;
-
- case method_off:
- strncpy(fieldbuf, "method", buflen);
- if (method()->is_method()) {
- method()->name_and_sig_as_C_string(valuebuf, buflen);
- }
- return;
-
- case oop_tmp_off:
- strncpy(fieldbuf, "oop_tmp", buflen);
- return;
- }
-
- // Variable part
- if (method()->is_method()) {
- identify_vp_word(frame_index, addr_of_word(offset),
- addr_of_word(header_words + 1),
- unextended_sp() + method()->max_stack(),
- fieldbuf, buflen);
- }
-}
-
void ZeroFrame::identify_vp_word(int frame_index,
intptr_t* addr,
intptr_t* monitor_base,
--- a/src/hotspot/cpu/zero/frame_zero.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/zero/frame_zero.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -62,9 +62,6 @@
const InterpreterFrame *zero_interpreterframe() const {
return zeroframe()->as_interpreter_frame();
}
- const SharkFrame *zero_sharkframe() const {
- return zeroframe()->as_shark_frame();
- }
public:
bool is_fake_stub_frame() const;
--- a/src/hotspot/cpu/zero/frame_zero.inline.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/zero/frame_zero.inline.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -56,18 +56,6 @@
_deopt_state = not_deoptimized;
break;
- case ZeroFrame::SHARK_FRAME: {
- _pc = zero_sharkframe()->pc();
- _cb = CodeCache::find_blob_unsafe(pc());
- address original_pc = CompiledMethod::get_deopt_original_pc(this);
- if (original_pc != NULL) {
- _pc = original_pc;
- _deopt_state = is_deoptimized;
- } else {
- _deopt_state = not_deoptimized;
- }
- break;
- }
case ZeroFrame::FAKE_STUB_FRAME:
_pc = NULL;
_cb = NULL;
@@ -177,10 +165,7 @@
}
inline intptr_t* frame::unextended_sp() const {
- if (zeroframe()->is_shark_frame())
- return zero_sharkframe()->unextended_sp();
- else
- return (intptr_t *) -1;
+ return (intptr_t *) -1;
}
#endif // CPU_ZERO_VM_FRAME_ZERO_INLINE_HPP
--- a/src/hotspot/cpu/zero/icache_zero.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/zero/icache_zero.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -29,7 +29,7 @@
// Interface for updating the instruction cache. Whenever the VM
// modifies code, part of the processor instruction cache potentially
// has to be flushed. This implementation is empty: Zero never deals
-// with code, and LLVM handles cache flushing for Shark.
+// with code.
class ICache : public AbstractICache {
public:
--- a/src/hotspot/cpu/zero/nativeInst_zero.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/zero/nativeInst_zero.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -42,11 +42,6 @@
// insert a jump to SharedRuntime::get_handle_wrong_method_stub()
// (dest) at the start of a compiled method (verified_entry) to avoid
// a race where a method is invoked while being made non-entrant.
-//
-// In Shark, verified_entry is a pointer to a SharkEntry. We can
-// handle this simply by changing it's entry point to point at the
-// interpreter. This only works because the interpreter and Shark
-// calling conventions are the same.
void NativeJump::patch_verified_entry(address entry,
address verified_entry,
--- a/src/hotspot/cpu/zero/relocInfo_zero.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/zero/relocInfo_zero.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -50,7 +50,7 @@
}
address* Relocation::pd_address_in_code() {
- // Relocations in Shark are just stored directly
+ ShouldNotCallThis();
return (address *) addr();
}
--- a/src/hotspot/cpu/zero/sharedRuntime_zero.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/zero/sharedRuntime_zero.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -41,11 +41,6 @@
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
-#ifdef SHARK
-#include "compiler/compileBroker.hpp"
-#include "shark/sharkCompiler.hpp"
-#endif
-
static address zero_null_code_stub() {
@@ -80,16 +75,8 @@
BasicType *sig_bt,
VMRegPair *regs,
BasicType ret_type) {
-#ifdef SHARK
- return SharkCompiler::compiler()->generate_native_wrapper(masm,
- method,
- compile_id,
- sig_bt,
- ret_type);
-#else
ShouldNotCallThis();
return NULL;
-#endif // SHARK
}
int Deoptimization::last_frame_adjust(int callee_parameters,
--- a/src/hotspot/cpu/zero/sharkFrame_zero.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * 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 CPU_ZERO_VM_SHARKFRAME_ZERO_HPP
-#define CPU_ZERO_VM_SHARKFRAME_ZERO_HPP
-
-#include "oops/method.hpp"
-#include "stack_zero.hpp"
-
-// | ... |
-// +--------------------+ ------------------
-// | stack slot n-1 | low addresses
-// | ... |
-// | stack slot 0 |
-// | monitor m-1 |
-// | ... |
-// | monitor 0 |
-// | oop_tmp |
-// | method |
-// | unextended_sp |
-// | pc |
-// | frame_type |
-// | next_frame | high addresses
-// +--------------------+ ------------------
-// | ... |
-
-class SharkFrame : public ZeroFrame {
- friend class SharkStack;
-
- private:
- SharkFrame() : ZeroFrame() {
- ShouldNotCallThis();
- }
-
- protected:
- enum Layout {
- pc_off = jf_header_words,
- unextended_sp_off,
- method_off,
- oop_tmp_off,
- header_words
- };
-
- public:
- address pc() const {
- return (address) value_of_word(pc_off);
- }
-
- void set_pc(address pc) const {
- *((address*) addr_of_word(pc_off)) = pc;
- }
-
- intptr_t* unextended_sp() const {
- return (intptr_t *) value_of_word(unextended_sp_off);
- }
-
- Method* method() const {
- return (Method*) value_of_word(method_off);
- }
-
- public:
- void identify_word(int frame_index,
- int offset,
- char* fieldbuf,
- char* valuebuf,
- int buflen) const;
-};
-
-#endif // CPU_ZERO_VM_SHARKFRAME_ZERO_HPP
--- a/src/hotspot/cpu/zero/shark_globals_zero.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * 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 CPU_ZERO_VM_SHARK_GLOBALS_ZERO_HPP
-#define CPU_ZERO_VM_SHARK_GLOBALS_ZERO_HPP
-
-// Set the default values for platform dependent flags used by the
-// Shark compiler. See globals.hpp for details of what they do.
-
-define_pd_global(bool, BackgroundCompilation, true );
-define_pd_global(bool, UseTLAB, true );
-define_pd_global(bool, ResizeTLAB, true );
-define_pd_global(bool, InlineIntrinsics, false);
-define_pd_global(bool, PreferInterpreterNativeStubs, false);
-define_pd_global(bool, ProfileTraps, false);
-define_pd_global(bool, UseOnStackReplacement, true );
-define_pd_global(bool, TieredCompilation, false);
-
-define_pd_global(intx, CompileThreshold, 1500);
-define_pd_global(intx, Tier2CompileThreshold, 1500);
-define_pd_global(intx, Tier3CompileThreshold, 2500);
-define_pd_global(intx, Tier4CompileThreshold, 4500);
-
-define_pd_global(intx, Tier2BackEdgeThreshold, 100000);
-define_pd_global(intx, Tier3BackEdgeThreshold, 100000);
-define_pd_global(intx, Tier4BackEdgeThreshold, 100000);
-
-define_pd_global(intx, OnStackReplacePercentage, 933 );
-define_pd_global(intx, FreqInlineSize, 325 );
-define_pd_global(uintx, NewRatio, 12 );
-define_pd_global(size_t, NewSizeThreadIncrease, 4*K );
-define_pd_global(intx, InitialCodeCacheSize, 160*K);
-define_pd_global(intx, ReservedCodeCacheSize, 32*M );
-define_pd_global(intx, NonProfiledCodeHeapSize, 13*M );
-define_pd_global(intx, ProfiledCodeHeapSize, 14*M );
-define_pd_global(intx, NonNMethodCodeHeapSize, 5*M );
-define_pd_global(bool, ProfileInterpreter, false);
-define_pd_global(intx, CodeCacheExpansionSize, 32*K );
-define_pd_global(uintx, CodeCacheMinBlockLength, 1 );
-define_pd_global(uintx, CodeCacheMinimumUseSpace, 200*K);
-
-define_pd_global(size_t, MetaspaceSize, 12*M );
-define_pd_global(bool, NeverActAsServerClassMachine, true );
-define_pd_global(uint64_t, MaxRAM, 1ULL*G);
-define_pd_global(bool, CICompileOSR, true );
-
-#endif // CPU_ZERO_VM_SHARK_GLOBALS_ZERO_HPP
--- a/src/hotspot/cpu/zero/stack_zero.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/zero/stack_zero.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -52,9 +52,6 @@
intptr_t *sp = thread->zero_stack()->sp();
ZeroFrame *frame = thread->top_zero_frame();
while (frame) {
- if (frame->is_shark_frame())
- break;
-
if (frame->is_interpreter_frame()) {
interpreterState istate =
frame->as_interpreter_frame()->interpreter_state();
--- a/src/hotspot/cpu/zero/stack_zero.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/zero/stack_zero.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -121,7 +121,6 @@
class EntryFrame;
class InterpreterFrame;
-class SharkFrame;
class FakeStubFrame;
//
@@ -151,7 +150,6 @@
enum FrameType {
ENTRY_FRAME = 1,
INTERPRETER_FRAME,
- SHARK_FRAME,
FAKE_STUB_FRAME
};
@@ -180,9 +178,6 @@
bool is_interpreter_frame() const {
return type() == INTERPRETER_FRAME;
}
- bool is_shark_frame() const {
- return type() == SHARK_FRAME;
- }
bool is_fake_stub_frame() const {
return type() == FAKE_STUB_FRAME;
}
@@ -196,10 +191,6 @@
assert(is_interpreter_frame(), "should be");
return (InterpreterFrame *) this;
}
- SharkFrame *as_shark_frame() const {
- assert(is_shark_frame(), "should be");
- return (SharkFrame *) this;
- }
FakeStubFrame *as_fake_stub_frame() const {
assert(is_fake_stub_frame(), "should be");
return (FakeStubFrame *) this;
--- a/src/hotspot/cpu/zero/stack_zero.inline.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/cpu/zero/stack_zero.inline.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -29,7 +29,6 @@
#include "runtime/thread.hpp"
#include "stack_zero.hpp"
-// This function should match SharkStack::CreateStackOverflowCheck
inline void ZeroStack::overflow_check(int required_words, TRAPS) {
// Check the Zero stack
if (available_words() < required_words) {
--- a/src/hotspot/share/ci/ciEnv.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/ci/ciEnv.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -1218,12 +1218,12 @@
method->signature()->as_quoted_ascii(),
entry_bci, comp_level);
if (compiler_data() != NULL) {
- if (is_c2_compile(comp_level)) { // C2 or Shark
+ if (is_c2_compile(comp_level)) {
#ifdef COMPILER2
// Dump C2 inlining data.
((Compile*)compiler_data())->dump_inline_data(out);
#endif
- } else if (is_c1_compile(comp_level)) { // C1
+ } else if (is_c1_compile(comp_level)) {
#ifdef COMPILER1
// Dump C1 inlining data.
((Compilation*)compiler_data())->dump_inline_data(out);
--- a/src/hotspot/share/ci/ciMethod.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/ci/ciMethod.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -53,10 +53,6 @@
#include "ci/ciTypeFlow.hpp"
#include "oops/method.hpp"
#endif
-#ifdef SHARK
-#include "ci/ciTypeFlow.hpp"
-#include "oops/method.hpp"
-#endif
// ciMethod
//
@@ -97,10 +93,10 @@
_exception_handlers = NULL;
_liveness = NULL;
_method_blocks = NULL;
-#if defined(COMPILER2) || defined(SHARK)
+#if defined(COMPILER2)
_flow = NULL;
_bcea = NULL;
-#endif // COMPILER2 || SHARK
+#endif // COMPILER2
ciEnv *env = CURRENT_ENV;
if (env->jvmti_can_hotswap_or_post_breakpoint() && can_be_compiled()) {
@@ -173,12 +169,12 @@
_can_be_statically_bound(false),
_method_blocks( NULL),
_method_data( NULL)
-#if defined(COMPILER2) || defined(SHARK)
+#if defined(COMPILER2)
,
_flow( NULL),
_bcea( NULL),
_instructions_size(-1)
-#endif // COMPILER2 || SHARK
+#endif // COMPILER2
{
// Usually holder and accessor are the same type but in some cases
// the holder has the wrong class loader (e.g. invokedynamic call
@@ -287,23 +283,6 @@
}
-#ifdef SHARK
-// ------------------------------------------------------------------
-// ciMethod::itable_index
-//
-// Get the position of this method's entry in the itable, if any.
-int ciMethod::itable_index() {
- check_is_loaded();
- assert(holder()->is_linked(), "must be linked");
- VM_ENTRY_MARK;
- Method* m = get_Method();
- if (!m->has_itable_index())
- return Method::nonvirtual_vtable_index;
- return m->itable_index();
-}
-#endif // SHARK
-
-
// ------------------------------------------------------------------
// ciMethod::native_entry
//
@@ -369,34 +348,34 @@
// ------------------------------------------------------------------
// ciMethod::get_flow_analysis
ciTypeFlow* ciMethod::get_flow_analysis() {
-#if defined(COMPILER2) || defined(SHARK)
+#if defined(COMPILER2)
if (_flow == NULL) {
ciEnv* env = CURRENT_ENV;
_flow = new (env->arena()) ciTypeFlow(env, this);
_flow->do_flow();
}
return _flow;
-#else // COMPILER2 || SHARK
+#else // COMPILER2
ShouldNotReachHere();
return NULL;
-#endif // COMPILER2 || SHARK
+#endif // COMPILER2
}
// ------------------------------------------------------------------
// ciMethod::get_osr_flow_analysis
ciTypeFlow* ciMethod::get_osr_flow_analysis(int osr_bci) {
-#if defined(COMPILER2) || defined(SHARK)
+#if defined(COMPILER2)
// OSR entry points are always place after a call bytecode of some sort
assert(osr_bci >= 0, "must supply valid OSR entry point");
ciEnv* env = CURRENT_ENV;
ciTypeFlow* flow = new (env->arena()) ciTypeFlow(env, this, osr_bci);
flow->do_flow();
return flow;
-#else // COMPILER2 || SHARK
+#else // COMPILER2
ShouldNotReachHere();
return NULL;
-#endif // COMPILER2 || SHARK
+#endif // COMPILER2
}
// ------------------------------------------------------------------
--- a/src/hotspot/share/ci/ciMethod.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/ci/ciMethod.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -96,7 +96,7 @@
// Optional liveness analyzer.
MethodLiveness* _liveness;
-#if defined(COMPILER2) || defined(SHARK)
+#if defined(COMPILER2)
ciTypeFlow* _flow;
BCEscapeAnalyzer* _bcea;
#endif
@@ -216,9 +216,6 @@
// Runtime information.
int vtable_index();
-#ifdef SHARK
- int itable_index();
-#endif // SHARK
address native_entry();
address interpreter_entry();
--- a/src/hotspot/share/ci/ciTypeFlow.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/ci/ciTypeFlow.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -30,12 +30,6 @@
#include "ci/ciKlass.hpp"
#include "ci/ciMethodBlocks.hpp"
#endif
-#ifdef SHARK
-#include "ci/ciEnv.hpp"
-#include "ci/ciKlass.hpp"
-#include "ci/ciMethodBlocks.hpp"
-#include "shark/shark_globals.hpp"
-#endif
class ciTypeFlow : public ResourceObj {
--- a/src/hotspot/share/code/codeBlob.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/code/codeBlob.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -125,7 +125,6 @@
inline bool is_compiled_by_c1() const { return _type == compiler_c1; };
inline bool is_compiled_by_c2() const { return _type == compiler_c2; };
inline bool is_compiled_by_jvmci() const { return _type == compiler_jvmci; };
- inline bool is_compiled_by_shark() const { return _type == compiler_shark; };
const char* compiler_name() const;
// Casting
--- a/src/hotspot/share/code/compiledMethod.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/code/compiledMethod.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -294,7 +294,6 @@
// Method that knows how to preserve outgoing arguments at call. This method must be
// called with a frame corresponding to a Java invoke
void CompiledMethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) {
-#ifndef SHARK
if (method() != NULL && !method()->is_native()) {
address pc = fr.pc();
SimpleScopeDesc ssd(this, pc);
@@ -314,7 +313,6 @@
fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f);
}
-#endif // !SHARK
}
Method* CompiledMethod::attached_method(address call_instr) {
--- a/src/hotspot/share/code/nmethod.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/code/nmethod.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -53,9 +53,6 @@
#include "utilities/events.hpp"
#include "utilities/resourceHash.hpp"
#include "utilities/xmlstream.hpp"
-#ifdef SHARK
-#include "shark/sharkCompiler.hpp"
-#endif
#if INCLUDE_JVMCI
#include "jvmci/jvmciJavaClasses.hpp"
#endif
@@ -200,9 +197,6 @@
#if INCLUDE_JVMCI
static java_nmethod_stats_struct jvmci_java_nmethod_stats;
#endif
-#ifdef SHARK
-static java_nmethod_stats_struct shark_java_nmethod_stats;
-#endif
static java_nmethod_stats_struct unknown_java_nmethod_stats;
static native_nmethod_stats_struct native_nmethod_stats;
@@ -224,11 +218,6 @@
jvmci_java_nmethod_stats.note_nmethod(nm);
} else
#endif
-#ifdef SHARK
- if (nm->is_compiled_by_shark()) {
- shark_java_nmethod_stats.note_nmethod(nm);
- } else
-#endif
{
unknown_java_nmethod_stats.note_nmethod(nm);
}
@@ -1325,10 +1314,6 @@
CodeCache::drop_scavenge_root_nmethod(this);
}
-#ifdef SHARK
- ((SharkCompiler *) compiler())->free_compiled_method(insts_begin());
-#endif // SHARK
-
CodeBlob::flush();
CodeCache::free(this);
}
@@ -2241,8 +2226,6 @@
tty->print("(c1) ");
} else if (is_compiled_by_c2()) {
tty->print("(c2) ");
- } else if (is_compiled_by_shark()) {
- tty->print("(shark) ");
} else if (is_compiled_by_jvmci()) {
tty->print("(JVMCI) ");
} else {
@@ -2864,9 +2847,6 @@
#if INCLUDE_JVMCI
jvmci_java_nmethod_stats.print_nmethod_stats("JVMCI");
#endif
-#ifdef SHARK
- shark_java_nmethod_stats.print_nmethod_stats("Shark");
-#endif
unknown_java_nmethod_stats.print_nmethod_stats("Unknown");
DebugInformationRecorder::print_statistics();
#ifndef PRODUCT
--- a/src/hotspot/share/compiler/abstractCompiler.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/compiler/abstractCompiler.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -152,7 +152,6 @@
const bool is_c1() { return _type == compiler_c1; }
const bool is_c2() { return _type == compiler_c2; }
const bool is_jvmci() { return _type == compiler_jvmci; }
- const bool is_shark() { return _type == compiler_shark; }
const CompilerType type() { return _type; }
// Extra tests to identify trivial methods for the tiered compilation policy.
--- a/src/hotspot/share/compiler/compileBroker.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/compiler/compileBroker.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -70,9 +70,6 @@
#ifdef COMPILER2
#include "opto/c2compiler.hpp"
#endif
-#ifdef SHARK
-#include "shark/sharkCompiler.hpp"
-#endif
#ifdef DTRACE_ENABLED
@@ -531,7 +528,6 @@
if (!UseCompiler) {
return;
}
-#ifndef SHARK
// Set the interface to the current compiler(s).
int c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple);
int c2_count = CompilationPolicy::policy()->compiler_count(CompLevel_full_optimization);
@@ -573,13 +569,6 @@
}
#endif // COMPILER2
-#else // SHARK
- int c1_count = 0;
- int c2_count = 1;
-
- _compilers[1] = new SharkCompiler();
-#endif // SHARK
-
// Start the compiler thread(s) and the sweeper thread
init_compiler_sweeper_threads(c1_count, c2_count);
// totalTime performance counter is always created as it is required
@@ -774,9 +763,9 @@
void CompileBroker::init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count) {
EXCEPTION_MARK;
-#if !defined(ZERO) && !defined(SHARK)
+#if !defined(ZERO)
assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?");
-#endif // !ZERO && !SHARK
+#endif // !ZERO
// Initialize the compilation queue
if (c2_compiler_count > 0) {
const char* name = JVMCI_ONLY(UseJVMCICompiler ? "JVMCI compile queue" :) "C2 compile queue";
@@ -796,7 +785,6 @@
// Create a name for our thread.
sprintf(name_buffer, "%s CompilerThread%d", _compilers[1]->name(), i);
CompilerCounters* counters = new CompilerCounters();
- // Shark and C2
make_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], compiler_thread, CHECK);
}
@@ -1100,7 +1088,7 @@
assert(!HAS_PENDING_EXCEPTION, "No exception should be present");
// some prerequisites that are compiler specific
- if (comp->is_c2() || comp->is_shark()) {
+ if (comp->is_c2()) {
method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NULL);
// Resolve all classes seen in the signature of the method
// we are compiling.
@@ -1490,10 +1478,8 @@
ThreadInVMfromNative tv(thread);
ResetNoHandleMark rnhm;
- if (!comp->is_shark()) {
- // Perform per-thread and global initializations
- comp->initialize();
- }
+ // Perform per-thread and global initializations
+ comp->initialize();
}
if (comp->is_failed()) {
--- a/src/hotspot/share/compiler/compilerDefinitions.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/compiler/compilerDefinitions.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -31,11 +31,10 @@
"",
"c1",
"c2",
- "jvmci",
- "shark"
+ "jvmci"
};
-#if defined(COMPILER2) || defined(SHARK)
+#if defined(COMPILER2)
CompLevel CompLevel_highest_tier = CompLevel_full_optimization; // pure C2 and tiered or JVMCI and tiered
#elif defined(COMPILER1)
CompLevel CompLevel_highest_tier = CompLevel_simple; // pure C1 or JVMCI
@@ -47,7 +46,7 @@
CompLevel CompLevel_initial_compile = CompLevel_full_profile; // tiered
#elif defined(COMPILER1) || INCLUDE_JVMCI
CompLevel CompLevel_initial_compile = CompLevel_simple; // pure C1 or JVMCI
-#elif defined(COMPILER2) || defined(SHARK)
+#elif defined(COMPILER2)
CompLevel CompLevel_initial_compile = CompLevel_full_optimization; // pure C2
#else
CompLevel CompLevel_initial_compile = CompLevel_none;
--- a/src/hotspot/share/compiler/compilerDefinitions.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/compiler/compilerDefinitions.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -33,7 +33,6 @@
compiler_c1,
compiler_c2,
compiler_jvmci,
- compiler_shark,
compiler_number_of_types
};
@@ -54,7 +53,7 @@
CompLevel_simple = 1, // C1
CompLevel_limited_profile = 2, // C1, invocation & backedge counters
CompLevel_full_profile = 3, // C1, invocation & backedge counters + mdo
- CompLevel_full_optimization = 4 // C2, Shark or JVMCI
+ CompLevel_full_optimization = 4 // C2 or JVMCI
};
extern CompLevel CompLevel_highest_tier;
--- a/src/hotspot/share/compiler/compilerDirectives.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/compiler/compilerDirectives.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -171,7 +171,7 @@
return _c2_store;
} else {
// use c1_store as default
- assert(comp->is_c1() || comp->is_jvmci() || comp->is_shark(), "");
+ assert(comp->is_c1() || comp->is_jvmci(), "");
return _c1_store;
}
}
--- a/src/hotspot/share/compiler/disassembler.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/compiler/disassembler.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -35,9 +35,6 @@
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/stubRoutines.hpp"
#include CPU_HEADER(depChecker)
-#ifdef SHARK
-#include "shark/sharkEntry.hpp"
-#endif
void* Disassembler::_library = NULL;
bool Disassembler::_tried_to_load_library = false;
@@ -521,14 +518,8 @@
decode_env env(nm, st);
env.output()->print_cr("----------------------------------------------------------------------");
-#ifdef SHARK
- SharkEntry* entry = (SharkEntry *) nm->code_begin();
- unsigned char* p = entry->code_start();
- unsigned char* end = entry->code_limit();
-#else
unsigned char* p = nm->code_begin();
unsigned char* end = nm->code_end();
-#endif // SHARK
nm->method()->method_holder()->name()->print_symbol_on(env.output());
env.output()->print(".");
--- a/src/hotspot/share/interpreter/bytecodeInterpreter.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/interpreter/bytecodeInterpreter.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -478,9 +478,7 @@
#ifdef ASSERT
if (istate->_msg != initialize) {
assert(labs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + 1), "bad stack limit");
-#ifndef SHARK
IA32_ONLY(assert(istate->_stack_limit == istate->_thread->last_Java_sp() + 1, "wrong"));
-#endif // !SHARK
}
// Verify linkages.
interpreterState l = istate;
--- a/src/hotspot/share/oops/method.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/oops/method.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -1165,15 +1165,11 @@
}
OrderAccess::storestore();
-#ifdef SHARK
- mh->_from_interpreted_entry = code->insts_begin();
-#else //!SHARK
mh->_from_compiled_entry = code->verified_entry_point();
OrderAccess::storestore();
// Instantly compiled code can execute.
if (!mh->is_method_handle_intrinsic())
mh->_from_interpreted_entry = mh->get_i2c_entry();
-#endif //!SHARK
}
--- a/src/hotspot/share/runtime/commandLineFlagConstraintsCompiler.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/runtime/commandLineFlagConstraintsCompiler.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -64,7 +64,7 @@
*/
Flag::Error CICompilerCountConstraintFunc(intx value, bool verbose) {
int min_number_of_compiler_threads = 0;
-#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK) && !INCLUDE_JVMCI
+#if !defined(COMPILER1) && !defined(COMPILER2) && !INCLUDE_JVMCI
// case 1
#else
if (!TieredCompilation || (TieredStopAtLevel < CompLevel_full_optimization)) {
--- a/src/hotspot/share/runtime/deoptimization.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/runtime/deoptimization.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -339,7 +339,6 @@
}
-#ifndef SHARK
// Compute the caller frame based on the sender sp of stub_frame and stored frame sizes info.
CodeBlob* cb = stub_frame.cb();
// Verify we have the right vframeArray
@@ -359,9 +358,6 @@
strcmp("Stub<UncommonTrapStub.uncommonTrapHandler>", cb->name()) == 0,
"unexpected code blob: %s", cb->name());
#endif
-#else
- intptr_t* unpack_sp = stub_frame.sender(&dummy_map).unextended_sp();
-#endif // !SHARK
// This is a guarantee instead of an assert because if vframe doesn't match
// we will unpack the wrong deoptimized frame and wind up in strange places
@@ -488,9 +484,7 @@
frame_pcs[0] = deopt_sender.raw_pc();
-#ifndef SHARK
assert(CodeCache::find_blob_unsafe(frame_pcs[0]) != NULL, "bad pc");
-#endif // SHARK
#ifdef INCLUDE_JVMCI
if (exceptionObject() != NULL) {
@@ -1449,7 +1443,7 @@
return mdo;
}
-#if defined(COMPILER2) || defined(SHARK) || INCLUDE_JVMCI
+#if defined(COMPILER2) || INCLUDE_JVMCI
void Deoptimization::load_class_by_index(const constantPoolHandle& constant_pool, int index, TRAPS) {
// in case of an unresolved klass entry, load the class.
if (constant_pool->tag_at(index).is_unresolved_klass()) {
@@ -2366,7 +2360,7 @@
if (xtty != NULL) xtty->tail("statistics");
}
}
-#else // COMPILER2 || SHARK || INCLUDE_JVMCI
+#else // COMPILER2 || INCLUDE_JVMCI
// Stubs for C1 only system.
@@ -2402,4 +2396,4 @@
return buf;
}
-#endif // COMPILER2 || SHARK || INCLUDE_JVMCI
+#endif // COMPILER2 || INCLUDE_JVMCI
--- a/src/hotspot/share/runtime/frame.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/runtime/frame.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -1115,10 +1115,6 @@
oops_entry_do(f, map);
} else if (CodeCache::contains(pc())) {
oops_code_blob_do(f, cf, map);
-#ifdef SHARK
- } else if (is_fake_stub_frame()) {
- // nothing to do
-#endif // SHARK
} else {
ShouldNotReachHere();
}
--- a/src/hotspot/share/runtime/frame.inline.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/runtime/frame.inline.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -37,7 +37,6 @@
# include "entryFrame_zero.hpp"
# include "fakeStubFrame_zero.hpp"
# include "interpreterFrame_zero.hpp"
-# include "sharkFrame_zero.hpp"
#endif
#include CPU_HEADER_INLINE(frame)
--- a/src/hotspot/share/runtime/globals.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/runtime/globals.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -50,9 +50,6 @@
#ifdef COMPILER2
#include "opto/c2_globals.hpp"
#endif
-#ifdef SHARK
-#include "shark/shark_globals.hpp"
-#endif
RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, \
MATERIALIZE_PD_DEVELOPER_FLAG, \
@@ -578,7 +575,6 @@
{ KIND_C1, "C1" },
{ KIND_C2, "C2" },
{ KIND_ARCH, "ARCH" },
- { KIND_SHARK, "SHARK" },
{ KIND_PLATFORM_DEPENDENT, "pd" },
{ KIND_PRODUCT, "product" },
{ KIND_MANAGEABLE, "manageable" },
@@ -754,14 +750,6 @@
#define ARCH_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_DEVELOP) },
#define ARCH_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_ARCH | Flag::KIND_NOT_PRODUCT) },
-#define SHARK_PRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_PRODUCT) },
-#define SHARK_PD_PRODUCT_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_PRODUCT | Flag::KIND_PLATFORM_DEPENDENT) },
-#define SHARK_DIAGNOSTIC_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DIAGNOSTIC) },
-#define SHARK_PD_DIAGNOSTIC_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DIAGNOSTIC | Flag::KIND_PLATFORM_DEPENDENT) },
-#define SHARK_DEVELOP_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DEVELOP) },
-#define SHARK_PD_DEVELOP_FLAG_STRUCT( type, name, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_DEVELOP | Flag::KIND_PLATFORM_DEPENDENT) },
-#define SHARK_NOTPRODUCT_FLAG_STRUCT( type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) Flag::Flags(Flag::DEFAULT | Flag::KIND_SHARK | Flag::KIND_NOT_PRODUCT) },
-
static Flag flagTable[] = {
RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
@@ -840,18 +828,6 @@
IGNORE_CONSTRAINT, \
IGNORE_WRITEABLE)
#endif // COMPILER2
-#ifdef SHARK
- SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, \
- SHARK_PD_DEVELOP_FLAG_STRUCT, \
- SHARK_PRODUCT_FLAG_STRUCT, \
- SHARK_PD_PRODUCT_FLAG_STRUCT, \
- SHARK_DIAGNOSTIC_FLAG_STRUCT, \
- SHARK_PD_DIAGNOSTIC_FLAG_STRUCT, \
- SHARK_NOTPRODUCT_FLAG_STRUCT, \
- IGNORE_RANGE, \
- IGNORE_CONSTRAINT, \
- IGNORE_WRITEABLE)
-#endif // SHARK
ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, \
ARCH_PRODUCT_FLAG_STRUCT, \
ARCH_DIAGNOSTIC_FLAG_STRUCT, \
--- a/src/hotspot/share/runtime/globals.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/runtime/globals.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -63,13 +63,8 @@
#include CPU_HEADER(c2_globals)
#include OS_HEADER(c2_globals)
#endif
-#ifdef SHARK
-#ifdef ZERO
-# include "shark_globals_zero.hpp"
-#endif
-#endif
-#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK) && !INCLUDE_JVMCI
+#if !defined(COMPILER1) && !defined(COMPILER2) && !INCLUDE_JVMCI
define_pd_global(bool, BackgroundCompilation, false);
define_pd_global(bool, UseTLAB, false);
define_pd_global(bool, CICompileOSR, false);
@@ -147,13 +142,12 @@
KIND_C1 = 1 << 12,
KIND_C2 = 1 << 13,
KIND_ARCH = 1 << 14,
- KIND_SHARK = 1 << 15,
- KIND_LP64_PRODUCT = 1 << 16,
- KIND_COMMERCIAL = 1 << 17,
- KIND_JVMCI = 1 << 18,
+ KIND_LP64_PRODUCT = 1 << 15,
+ KIND_COMMERCIAL = 1 << 16,
+ KIND_JVMCI = 1 << 17,
// set this bit if the flag was set on the command line
- ORIG_COMMAND_LINE = 1 << 19,
+ ORIG_COMMAND_LINE = 1 << 18,
KIND_MASK = ~(VALUE_ORIGIN_MASK | ORIG_COMMAND_LINE)
};
--- a/src/hotspot/share/runtime/thread.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/runtime/thread.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -3724,7 +3724,7 @@
}
// initialize compiler(s)
-#if defined(COMPILER1) || defined(COMPILER2) || defined(SHARK) || INCLUDE_JVMCI
+#if defined(COMPILER1) || defined(COMPILER2) || INCLUDE_JVMCI
CompileBroker::compilation_init(CHECK_JNI_ERR);
#endif
--- a/src/hotspot/share/runtime/vm_version.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/runtime/vm_version.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -95,11 +95,7 @@
#define VMTYPE "Server"
#else // TIERED
#ifdef ZERO
- #ifdef SHARK
- #define VMTYPE "Shark"
- #else // SHARK
#define VMTYPE "Zero"
- #endif // SHARK
#else // ZERO
#define VMTYPE COMPILER1_PRESENT("Client") \
COMPILER2_PRESENT("Server")
--- a/src/hotspot/share/shark/llvmHeaders.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_LLVMHEADERS_HPP
-#define SHARE_VM_SHARK_LLVMHEADERS_HPP
-
-#ifdef assert
- #undef assert
-#endif
-
-#ifdef DEBUG
- #define SHARK_DEBUG
- #undef DEBUG
-#endif
-
-#include <llvm/Analysis/Verifier.h>
-#include <llvm/ExecutionEngine/ExecutionEngine.h>
-
-// includes specific to each version
-#if SHARK_LLVM_VERSION <= 31
-#include <llvm/Support/IRBuilder.h>
-#include <llvm/Type.h>
-#include <llvm/Argument.h>
-#include <llvm/Constants.h>
-#include <llvm/DerivedTypes.h>
-#include <llvm/Instructions.h>
-#include <llvm/LLVMContext.h>
-#include <llvm/Module.h>
-#elif SHARK_LLVM_VERSION <= 32
-#include <llvm/IRBuilder.h>
-#include <llvm/Type.h>
-#include <llvm/Argument.h>
-#include <llvm/Constants.h>
-#include <llvm/DerivedTypes.h>
-#include <llvm/Instructions.h>
-#include <llvm/LLVMContext.h>
-#include <llvm/Module.h>
-#else // SHARK_LLVM_VERSION <= 34
-#include <llvm/IR/IRBuilder.h>
-#include <llvm/IR/Argument.h>
-#include <llvm/IR/Constants.h>
-#include <llvm/IR/DerivedTypes.h>
-#include <llvm/ExecutionEngine/ExecutionEngine.h>
-#include <llvm/IR/Instructions.h>
-#include <llvm/IR/LLVMContext.h>
-#include <llvm/IR/Module.h>
-#include <llvm/ADT/StringRef.h>
-#include <llvm/IR/Type.h>
-#endif
-
-// common includes
-#include <llvm/Support/Threading.h>
-#include <llvm/Support/TargetSelect.h>
-#include <llvm/ExecutionEngine/JITMemoryManager.h>
-#include <llvm/Support/CommandLine.h>
-#include <llvm/ExecutionEngine/MCJIT.h>
-#include <llvm/ExecutionEngine/JIT.h>
-#include <llvm/ADT/StringMap.h>
-#include <llvm/Support/Debug.h>
-#include <llvm/Support/Host.h>
-
-#include <map>
-
-#ifdef assert
- #undef assert
-#endif
-
-#define assert(p, msg) vmassert(p, msg)
-
-#ifdef DEBUG
- #undef DEBUG
-#endif
-#ifdef SHARK_DEBUG
- #define DEBUG
- #undef SHARK_DEBUG
-#endif
-
-#endif // SHARE_VM_SHARK_LLVMHEADERS_HPP
--- a/src/hotspot/share/shark/llvmValue.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_LLVMVALUE_HPP
-#define SHARE_VM_SHARK_LLVMVALUE_HPP
-
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkContext.hpp"
-#include "shark/sharkType.hpp"
-
-class LLVMValue : public AllStatic {
- public:
- static llvm::ConstantInt* jbyte_constant(jbyte value)
- {
- return llvm::ConstantInt::get(SharkType::jbyte_type(), value, true);
- }
- static llvm::ConstantInt* jint_constant(jint value)
- {
- return llvm::ConstantInt::get(SharkType::jint_type(), value, true);
- }
- static llvm::ConstantInt* jlong_constant(jlong value)
- {
- return llvm::ConstantInt::get(SharkType::jlong_type(), value, true);
- }
- static llvm::ConstantFP* jfloat_constant(jfloat value)
- {
- return llvm::ConstantFP::get(SharkContext::current(), llvm::APFloat(value));
- }
- static llvm::ConstantFP* jdouble_constant(jdouble value)
- {
- return llvm::ConstantFP::get(SharkContext::current(), llvm::APFloat(value));
- }
- static llvm::ConstantPointerNull* null()
- {
- return llvm::ConstantPointerNull::get(SharkType::oop_type());
- }
- static llvm::ConstantPointerNull* nullKlass()
- {
- return llvm::ConstantPointerNull::get(SharkType::klass_type());
- }
-
- public:
- static llvm::ConstantInt* bit_constant(int value)
- {
- return llvm::ConstantInt::get(SharkType::bit_type(), value, false);
- }
- static llvm::ConstantInt* intptr_constant(intptr_t value)
- {
- return llvm::ConstantInt::get(SharkType::intptr_type(), value, false);
- }
-};
-
-#endif // SHARE_VM_SHARK_LLVMVALUE_HPP
--- a/src/hotspot/share/shark/sharkBlock.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1286 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * 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 "interpreter/bytecodes.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/llvmValue.hpp"
-#include "shark/sharkBlock.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkConstant.hpp"
-#include "shark/sharkState.hpp"
-#include "shark/sharkValue.hpp"
-#include "shark/shark_globals.hpp"
-#include "utilities/debug.hpp"
-
-using namespace llvm;
-
-void SharkBlock::parse_bytecode(int start, int limit) {
- SharkValue *a, *b, *c, *d;
- int i;
-
- // Ensure the current state is initialized before we emit any code,
- // so that any setup code for the state is at the start of the block
- current_state();
-
- // Parse the bytecodes
- iter()->reset_to_bci(start);
- while (iter()->next_bci() < limit) {
- NOT_PRODUCT(a = b = c = d = NULL);
- iter()->next();
-
- if (SharkTraceBytecodes)
- tty->print_cr("%4d: %s", bci(), Bytecodes::name(bc()));
-
- if (has_trap() && trap_bci() == bci()) {
- do_trap(trap_request());
- return;
- }
-
- if (UseLoopSafepoints) {
- // XXX if a lcmp is followed by an if_?? then C2 maybe-inserts
- // the safepoint before the lcmp rather than before the if.
- // Maybe we should do this too. See parse2.cpp for details.
- switch (bc()) {
- case Bytecodes::_goto:
- case Bytecodes::_ifnull:
- case Bytecodes::_ifnonnull:
- case Bytecodes::_if_acmpeq:
- case Bytecodes::_if_acmpne:
- case Bytecodes::_ifeq:
- case Bytecodes::_ifne:
- case Bytecodes::_iflt:
- case Bytecodes::_ifle:
- case Bytecodes::_ifgt:
- case Bytecodes::_ifge:
- case Bytecodes::_if_icmpeq:
- case Bytecodes::_if_icmpne:
- case Bytecodes::_if_icmplt:
- case Bytecodes::_if_icmple:
- case Bytecodes::_if_icmpgt:
- case Bytecodes::_if_icmpge:
- if (iter()->get_dest() <= bci())
- maybe_add_backedge_safepoint();
- break;
-
- case Bytecodes::_goto_w:
- if (iter()->get_far_dest() <= bci())
- maybe_add_backedge_safepoint();
- break;
-
- case Bytecodes::_tableswitch:
- case Bytecodes::_lookupswitch:
- if (switch_default_dest() <= bci()) {
- maybe_add_backedge_safepoint();
- break;
- }
- int len = switch_table_length();
- for (int i = 0; i < len; i++) {
- if (switch_dest(i) <= bci()) {
- maybe_add_backedge_safepoint();
- break;
- }
- }
- break;
- }
- }
-
- switch (bc()) {
- case Bytecodes::_nop:
- break;
-
- case Bytecodes::_aconst_null:
- push(SharkValue::null());
- break;
-
- case Bytecodes::_iconst_m1:
- push(SharkValue::jint_constant(-1));
- break;
- case Bytecodes::_iconst_0:
- push(SharkValue::jint_constant(0));
- break;
- case Bytecodes::_iconst_1:
- push(SharkValue::jint_constant(1));
- break;
- case Bytecodes::_iconst_2:
- push(SharkValue::jint_constant(2));
- break;
- case Bytecodes::_iconst_3:
- push(SharkValue::jint_constant(3));
- break;
- case Bytecodes::_iconst_4:
- push(SharkValue::jint_constant(4));
- break;
- case Bytecodes::_iconst_5:
- push(SharkValue::jint_constant(5));
- break;
-
- case Bytecodes::_lconst_0:
- push(SharkValue::jlong_constant(0));
- break;
- case Bytecodes::_lconst_1:
- push(SharkValue::jlong_constant(1));
- break;
-
- case Bytecodes::_fconst_0:
- push(SharkValue::jfloat_constant(0));
- break;
- case Bytecodes::_fconst_1:
- push(SharkValue::jfloat_constant(1));
- break;
- case Bytecodes::_fconst_2:
- push(SharkValue::jfloat_constant(2));
- break;
-
- case Bytecodes::_dconst_0:
- push(SharkValue::jdouble_constant(0));
- break;
- case Bytecodes::_dconst_1:
- push(SharkValue::jdouble_constant(1));
- break;
-
- case Bytecodes::_bipush:
- push(SharkValue::jint_constant(iter()->get_constant_u1()));
- break;
- case Bytecodes::_sipush:
- push(SharkValue::jint_constant(iter()->get_constant_u2()));
- break;
-
- case Bytecodes::_ldc:
- case Bytecodes::_ldc_w:
- case Bytecodes::_ldc2_w: {
- SharkConstant* constant = SharkConstant::for_ldc(iter());
- assert(constant->is_loaded(), "trap should handle unloaded classes");
- push(constant->value(builder()));
- break;
- }
- case Bytecodes::_iload_0:
- case Bytecodes::_lload_0:
- case Bytecodes::_fload_0:
- case Bytecodes::_dload_0:
- case Bytecodes::_aload_0:
- push(local(0));
- break;
- case Bytecodes::_iload_1:
- case Bytecodes::_lload_1:
- case Bytecodes::_fload_1:
- case Bytecodes::_dload_1:
- case Bytecodes::_aload_1:
- push(local(1));
- break;
- case Bytecodes::_iload_2:
- case Bytecodes::_lload_2:
- case Bytecodes::_fload_2:
- case Bytecodes::_dload_2:
- case Bytecodes::_aload_2:
- push(local(2));
- break;
- case Bytecodes::_iload_3:
- case Bytecodes::_lload_3:
- case Bytecodes::_fload_3:
- case Bytecodes::_dload_3:
- case Bytecodes::_aload_3:
- push(local(3));
- break;
- case Bytecodes::_iload:
- case Bytecodes::_lload:
- case Bytecodes::_fload:
- case Bytecodes::_dload:
- case Bytecodes::_aload:
- push(local(iter()->get_index()));
- break;
-
- case Bytecodes::_baload:
- do_aload(T_BYTE);
- break;
- case Bytecodes::_caload:
- do_aload(T_CHAR);
- break;
- case Bytecodes::_saload:
- do_aload(T_SHORT);
- break;
- case Bytecodes::_iaload:
- do_aload(T_INT);
- break;
- case Bytecodes::_laload:
- do_aload(T_LONG);
- break;
- case Bytecodes::_faload:
- do_aload(T_FLOAT);
- break;
- case Bytecodes::_daload:
- do_aload(T_DOUBLE);
- break;
- case Bytecodes::_aaload:
- do_aload(T_OBJECT);
- break;
-
- case Bytecodes::_istore_0:
- case Bytecodes::_lstore_0:
- case Bytecodes::_fstore_0:
- case Bytecodes::_dstore_0:
- case Bytecodes::_astore_0:
- set_local(0, pop());
- break;
- case Bytecodes::_istore_1:
- case Bytecodes::_lstore_1:
- case Bytecodes::_fstore_1:
- case Bytecodes::_dstore_1:
- case Bytecodes::_astore_1:
- set_local(1, pop());
- break;
- case Bytecodes::_istore_2:
- case Bytecodes::_lstore_2:
- case Bytecodes::_fstore_2:
- case Bytecodes::_dstore_2:
- case Bytecodes::_astore_2:
- set_local(2, pop());
- break;
- case Bytecodes::_istore_3:
- case Bytecodes::_lstore_3:
- case Bytecodes::_fstore_3:
- case Bytecodes::_dstore_3:
- case Bytecodes::_astore_3:
- set_local(3, pop());
- break;
- case Bytecodes::_istore:
- case Bytecodes::_lstore:
- case Bytecodes::_fstore:
- case Bytecodes::_dstore:
- case Bytecodes::_astore:
- set_local(iter()->get_index(), pop());
- break;
-
- case Bytecodes::_bastore:
- do_astore(T_BYTE);
- break;
- case Bytecodes::_castore:
- do_astore(T_CHAR);
- break;
- case Bytecodes::_sastore:
- do_astore(T_SHORT);
- break;
- case Bytecodes::_iastore:
- do_astore(T_INT);
- break;
- case Bytecodes::_lastore:
- do_astore(T_LONG);
- break;
- case Bytecodes::_fastore:
- do_astore(T_FLOAT);
- break;
- case Bytecodes::_dastore:
- do_astore(T_DOUBLE);
- break;
- case Bytecodes::_aastore:
- do_astore(T_OBJECT);
- break;
-
- case Bytecodes::_pop:
- xpop();
- break;
- case Bytecodes::_pop2:
- xpop();
- xpop();
- break;
- case Bytecodes::_swap:
- a = xpop();
- b = xpop();
- xpush(a);
- xpush(b);
- break;
- case Bytecodes::_dup:
- a = xpop();
- xpush(a);
- xpush(a);
- break;
- case Bytecodes::_dup_x1:
- a = xpop();
- b = xpop();
- xpush(a);
- xpush(b);
- xpush(a);
- break;
- case Bytecodes::_dup_x2:
- a = xpop();
- b = xpop();
- c = xpop();
- xpush(a);
- xpush(c);
- xpush(b);
- xpush(a);
- break;
- case Bytecodes::_dup2:
- a = xpop();
- b = xpop();
- xpush(b);
- xpush(a);
- xpush(b);
- xpush(a);
- break;
- case Bytecodes::_dup2_x1:
- a = xpop();
- b = xpop();
- c = xpop();
- xpush(b);
- xpush(a);
- xpush(c);
- xpush(b);
- xpush(a);
- break;
- case Bytecodes::_dup2_x2:
- a = xpop();
- b = xpop();
- c = xpop();
- d = xpop();
- xpush(b);
- xpush(a);
- xpush(d);
- xpush(c);
- xpush(b);
- xpush(a);
- break;
-
- case Bytecodes::_arraylength:
- do_arraylength();
- break;
-
- case Bytecodes::_getfield:
- do_getfield();
- break;
- case Bytecodes::_getstatic:
- do_getstatic();
- break;
- case Bytecodes::_putfield:
- do_putfield();
- break;
- case Bytecodes::_putstatic:
- do_putstatic();
- break;
-
- case Bytecodes::_iadd:
- b = pop();
- a = pop();
- push(SharkValue::create_jint(
- builder()->CreateAdd(a->jint_value(), b->jint_value()), false));
- break;
- case Bytecodes::_isub:
- b = pop();
- a = pop();
- push(SharkValue::create_jint(
- builder()->CreateSub(a->jint_value(), b->jint_value()), false));
- break;
- case Bytecodes::_imul:
- b = pop();
- a = pop();
- push(SharkValue::create_jint(
- builder()->CreateMul(a->jint_value(), b->jint_value()), false));
- break;
- case Bytecodes::_idiv:
- do_idiv();
- break;
- case Bytecodes::_irem:
- do_irem();
- break;
- case Bytecodes::_ineg:
- a = pop();
- push(SharkValue::create_jint(
- builder()->CreateNeg(a->jint_value()), a->zero_checked()));
- break;
- case Bytecodes::_ishl:
- b = pop();
- a = pop();
- push(SharkValue::create_jint(
- builder()->CreateShl(
- a->jint_value(),
- builder()->CreateAnd(
- b->jint_value(), LLVMValue::jint_constant(0x1f))), false));
- break;
- case Bytecodes::_ishr:
- b = pop();
- a = pop();
- push(SharkValue::create_jint(
- builder()->CreateAShr(
- a->jint_value(),
- builder()->CreateAnd(
- b->jint_value(), LLVMValue::jint_constant(0x1f))), false));
- break;
- case Bytecodes::_iushr:
- b = pop();
- a = pop();
- push(SharkValue::create_jint(
- builder()->CreateLShr(
- a->jint_value(),
- builder()->CreateAnd(
- b->jint_value(), LLVMValue::jint_constant(0x1f))), false));
- break;
- case Bytecodes::_iand:
- b = pop();
- a = pop();
- push(SharkValue::create_jint(
- builder()->CreateAnd(a->jint_value(), b->jint_value()), false));
- break;
- case Bytecodes::_ior:
- b = pop();
- a = pop();
- push(SharkValue::create_jint(
- builder()->CreateOr(a->jint_value(), b->jint_value()),
- a->zero_checked() && b->zero_checked()));
- break;
- case Bytecodes::_ixor:
- b = pop();
- a = pop();
- push(SharkValue::create_jint(
- builder()->CreateXor(a->jint_value(), b->jint_value()), false));
- break;
-
- case Bytecodes::_ladd:
- b = pop();
- a = pop();
- push(SharkValue::create_jlong(
- builder()->CreateAdd(a->jlong_value(), b->jlong_value()), false));
- break;
- case Bytecodes::_lsub:
- b = pop();
- a = pop();
- push(SharkValue::create_jlong(
- builder()->CreateSub(a->jlong_value(), b->jlong_value()), false));
- break;
- case Bytecodes::_lmul:
- b = pop();
- a = pop();
- push(SharkValue::create_jlong(
- builder()->CreateMul(a->jlong_value(), b->jlong_value()), false));
- break;
- case Bytecodes::_ldiv:
- do_ldiv();
- break;
- case Bytecodes::_lrem:
- do_lrem();
- break;
- case Bytecodes::_lneg:
- a = pop();
- push(SharkValue::create_jlong(
- builder()->CreateNeg(a->jlong_value()), a->zero_checked()));
- break;
- case Bytecodes::_lshl:
- b = pop();
- a = pop();
- push(SharkValue::create_jlong(
- builder()->CreateShl(
- a->jlong_value(),
- builder()->CreateIntCast(
- builder()->CreateAnd(
- b->jint_value(), LLVMValue::jint_constant(0x3f)),
- SharkType::jlong_type(), true)), false));
- break;
- case Bytecodes::_lshr:
- b = pop();
- a = pop();
- push(SharkValue::create_jlong(
- builder()->CreateAShr(
- a->jlong_value(),
- builder()->CreateIntCast(
- builder()->CreateAnd(
- b->jint_value(), LLVMValue::jint_constant(0x3f)),
- SharkType::jlong_type(), true)), false));
- break;
- case Bytecodes::_lushr:
- b = pop();
- a = pop();
- push(SharkValue::create_jlong(
- builder()->CreateLShr(
- a->jlong_value(),
- builder()->CreateIntCast(
- builder()->CreateAnd(
- b->jint_value(), LLVMValue::jint_constant(0x3f)),
- SharkType::jlong_type(), true)), false));
- break;
- case Bytecodes::_land:
- b = pop();
- a = pop();
- push(SharkValue::create_jlong(
- builder()->CreateAnd(a->jlong_value(), b->jlong_value()), false));
- break;
- case Bytecodes::_lor:
- b = pop();
- a = pop();
- push(SharkValue::create_jlong(
- builder()->CreateOr(a->jlong_value(), b->jlong_value()),
- a->zero_checked() && b->zero_checked()));
- break;
- case Bytecodes::_lxor:
- b = pop();
- a = pop();
- push(SharkValue::create_jlong(
- builder()->CreateXor(a->jlong_value(), b->jlong_value()), false));
- break;
-
- case Bytecodes::_fadd:
- b = pop();
- a = pop();
- push(SharkValue::create_jfloat(
- builder()->CreateFAdd(a->jfloat_value(), b->jfloat_value())));
- break;
- case Bytecodes::_fsub:
- b = pop();
- a = pop();
- push(SharkValue::create_jfloat(
- builder()->CreateFSub(a->jfloat_value(), b->jfloat_value())));
- break;
- case Bytecodes::_fmul:
- b = pop();
- a = pop();
- push(SharkValue::create_jfloat(
- builder()->CreateFMul(a->jfloat_value(), b->jfloat_value())));
- break;
- case Bytecodes::_fdiv:
- b = pop();
- a = pop();
- push(SharkValue::create_jfloat(
- builder()->CreateFDiv(a->jfloat_value(), b->jfloat_value())));
- break;
- case Bytecodes::_frem:
- b = pop();
- a = pop();
- push(SharkValue::create_jfloat(
- builder()->CreateFRem(a->jfloat_value(), b->jfloat_value())));
- break;
- case Bytecodes::_fneg:
- a = pop();
- push(SharkValue::create_jfloat(
- builder()->CreateFNeg(a->jfloat_value())));
- break;
-
- case Bytecodes::_dadd:
- b = pop();
- a = pop();
- push(SharkValue::create_jdouble(
- builder()->CreateFAdd(a->jdouble_value(), b->jdouble_value())));
- break;
- case Bytecodes::_dsub:
- b = pop();
- a = pop();
- push(SharkValue::create_jdouble(
- builder()->CreateFSub(a->jdouble_value(), b->jdouble_value())));
- break;
- case Bytecodes::_dmul:
- b = pop();
- a = pop();
- push(SharkValue::create_jdouble(
- builder()->CreateFMul(a->jdouble_value(), b->jdouble_value())));
- break;
- case Bytecodes::_ddiv:
- b = pop();
- a = pop();
- push(SharkValue::create_jdouble(
- builder()->CreateFDiv(a->jdouble_value(), b->jdouble_value())));
- break;
- case Bytecodes::_drem:
- b = pop();
- a = pop();
- push(SharkValue::create_jdouble(
- builder()->CreateFRem(a->jdouble_value(), b->jdouble_value())));
- break;
- case Bytecodes::_dneg:
- a = pop();
- push(SharkValue::create_jdouble(
- builder()->CreateFNeg(a->jdouble_value())));
- break;
-
- case Bytecodes::_iinc:
- i = iter()->get_index();
- set_local(
- i,
- SharkValue::create_jint(
- builder()->CreateAdd(
- LLVMValue::jint_constant(iter()->get_iinc_con()),
- local(i)->jint_value()), false));
- break;
-
- case Bytecodes::_lcmp:
- do_lcmp();
- break;
-
- case Bytecodes::_fcmpl:
- do_fcmp(false, false);
- break;
- case Bytecodes::_fcmpg:
- do_fcmp(false, true);
- break;
- case Bytecodes::_dcmpl:
- do_fcmp(true, false);
- break;
- case Bytecodes::_dcmpg:
- do_fcmp(true, true);
- break;
-
- case Bytecodes::_i2l:
- a = pop();
- push(SharkValue::create_jlong(
- builder()->CreateIntCast(
- a->jint_value(), SharkType::jlong_type(), true), a->zero_checked()));
- break;
- case Bytecodes::_i2f:
- push(SharkValue::create_jfloat(
- builder()->CreateSIToFP(
- pop()->jint_value(), SharkType::jfloat_type())));
- break;
- case Bytecodes::_i2d:
- push(SharkValue::create_jdouble(
- builder()->CreateSIToFP(
- pop()->jint_value(), SharkType::jdouble_type())));
- break;
-
- case Bytecodes::_l2i:
- push(SharkValue::create_jint(
- builder()->CreateIntCast(
- pop()->jlong_value(), SharkType::jint_type(), true), false));
- break;
- case Bytecodes::_l2f:
- push(SharkValue::create_jfloat(
- builder()->CreateSIToFP(
- pop()->jlong_value(), SharkType::jfloat_type())));
- break;
- case Bytecodes::_l2d:
- push(SharkValue::create_jdouble(
- builder()->CreateSIToFP(
- pop()->jlong_value(), SharkType::jdouble_type())));
- break;
-
- case Bytecodes::_f2i:
- push(SharkValue::create_jint(
- builder()->CreateCall(
- builder()->f2i(), pop()->jfloat_value()), false));
- break;
- case Bytecodes::_f2l:
- push(SharkValue::create_jlong(
- builder()->CreateCall(
- builder()->f2l(), pop()->jfloat_value()), false));
- break;
- case Bytecodes::_f2d:
- push(SharkValue::create_jdouble(
- builder()->CreateFPExt(
- pop()->jfloat_value(), SharkType::jdouble_type())));
- break;
-
- case Bytecodes::_d2i:
- push(SharkValue::create_jint(
- builder()->CreateCall(
- builder()->d2i(), pop()->jdouble_value()), false));
- break;
- case Bytecodes::_d2l:
- push(SharkValue::create_jlong(
- builder()->CreateCall(
- builder()->d2l(), pop()->jdouble_value()), false));
- break;
- case Bytecodes::_d2f:
- push(SharkValue::create_jfloat(
- builder()->CreateFPTrunc(
- pop()->jdouble_value(), SharkType::jfloat_type())));
- break;
-
- case Bytecodes::_i2b:
- push(SharkValue::create_jint(
- builder()->CreateAShr(
- builder()->CreateShl(
- pop()->jint_value(),
- LLVMValue::jint_constant(24)),
- LLVMValue::jint_constant(24)), false));
- break;
- case Bytecodes::_i2c:
- push(SharkValue::create_jint(
- builder()->CreateAnd(
- pop()->jint_value(),
- LLVMValue::jint_constant(0xffff)), false));
- break;
- case Bytecodes::_i2s:
- push(SharkValue::create_jint(
- builder()->CreateAShr(
- builder()->CreateShl(
- pop()->jint_value(),
- LLVMValue::jint_constant(16)),
- LLVMValue::jint_constant(16)), false));
- break;
-
- case Bytecodes::_return:
- do_return(T_VOID);
- break;
- case Bytecodes::_ireturn:
- do_return(T_INT);
- break;
- case Bytecodes::_lreturn:
- do_return(T_LONG);
- break;
- case Bytecodes::_freturn:
- do_return(T_FLOAT);
- break;
- case Bytecodes::_dreturn:
- do_return(T_DOUBLE);
- break;
- case Bytecodes::_areturn:
- do_return(T_OBJECT);
- break;
-
- case Bytecodes::_athrow:
- do_athrow();
- break;
-
- case Bytecodes::_goto:
- case Bytecodes::_goto_w:
- do_goto();
- break;
-
- case Bytecodes::_jsr:
- case Bytecodes::_jsr_w:
- do_jsr();
- break;
-
- case Bytecodes::_ret:
- do_ret();
- break;
-
- case Bytecodes::_ifnull:
- do_if(ICmpInst::ICMP_EQ, SharkValue::null(), pop());
- break;
- case Bytecodes::_ifnonnull:
- do_if(ICmpInst::ICMP_NE, SharkValue::null(), pop());
- break;
- case Bytecodes::_if_acmpeq:
- b = pop();
- a = pop();
- do_if(ICmpInst::ICMP_EQ, b, a);
- break;
- case Bytecodes::_if_acmpne:
- b = pop();
- a = pop();
- do_if(ICmpInst::ICMP_NE, b, a);
- break;
- case Bytecodes::_ifeq:
- do_if(ICmpInst::ICMP_EQ, SharkValue::jint_constant(0), pop());
- break;
- case Bytecodes::_ifne:
- do_if(ICmpInst::ICMP_NE, SharkValue::jint_constant(0), pop());
- break;
- case Bytecodes::_iflt:
- do_if(ICmpInst::ICMP_SLT, SharkValue::jint_constant(0), pop());
- break;
- case Bytecodes::_ifle:
- do_if(ICmpInst::ICMP_SLE, SharkValue::jint_constant(0), pop());
- break;
- case Bytecodes::_ifgt:
- do_if(ICmpInst::ICMP_SGT, SharkValue::jint_constant(0), pop());
- break;
- case Bytecodes::_ifge:
- do_if(ICmpInst::ICMP_SGE, SharkValue::jint_constant(0), pop());
- break;
- case Bytecodes::_if_icmpeq:
- b = pop();
- a = pop();
- do_if(ICmpInst::ICMP_EQ, b, a);
- break;
- case Bytecodes::_if_icmpne:
- b = pop();
- a = pop();
- do_if(ICmpInst::ICMP_NE, b, a);
- break;
- case Bytecodes::_if_icmplt:
- b = pop();
- a = pop();
- do_if(ICmpInst::ICMP_SLT, b, a);
- break;
- case Bytecodes::_if_icmple:
- b = pop();
- a = pop();
- do_if(ICmpInst::ICMP_SLE, b, a);
- break;
- case Bytecodes::_if_icmpgt:
- b = pop();
- a = pop();
- do_if(ICmpInst::ICMP_SGT, b, a);
- break;
- case Bytecodes::_if_icmpge:
- b = pop();
- a = pop();
- do_if(ICmpInst::ICMP_SGE, b, a);
- break;
-
- case Bytecodes::_tableswitch:
- case Bytecodes::_lookupswitch:
- do_switch();
- break;
-
- case Bytecodes::_invokestatic:
- case Bytecodes::_invokespecial:
- case Bytecodes::_invokevirtual:
- case Bytecodes::_invokeinterface:
- do_call();
- break;
-
- case Bytecodes::_instanceof:
- // This is a very common construct:
- //
- // if (object instanceof Klass) {
- // something = (Klass) object;
- // ...
- // }
- //
- // which gets compiled to something like this:
- //
- // 28: aload 9
- // 30: instanceof <Class Klass>
- // 33: ifeq 52
- // 36: aload 9
- // 38: checkcast <Class Klass>
- //
- // Handling both bytecodes at once allows us
- // to eliminate the checkcast.
- if (iter()->next_bci() < limit &&
- (iter()->next_bc() == Bytecodes::_ifeq ||
- iter()->next_bc() == Bytecodes::_ifne) &&
- (!UseLoopSafepoints ||
- iter()->next_get_dest() > iter()->next_bci())) {
- if (maybe_do_instanceof_if()) {
- iter()->next();
- if (SharkTraceBytecodes)
- tty->print_cr("%4d: %s", bci(), Bytecodes::name(bc()));
- break;
- }
- }
- // fall through
- case Bytecodes::_checkcast:
- do_instance_check();
- break;
-
- case Bytecodes::_new:
- do_new();
- break;
- case Bytecodes::_newarray:
- do_newarray();
- break;
- case Bytecodes::_anewarray:
- do_anewarray();
- break;
- case Bytecodes::_multianewarray:
- do_multianewarray();
- break;
-
- case Bytecodes::_monitorenter:
- do_monitorenter();
- break;
- case Bytecodes::_monitorexit:
- do_monitorexit();
- break;
-
- default:
- ShouldNotReachHere();
- }
- }
-}
-
-SharkState* SharkBlock::initial_current_state() {
- return entry_state()->copy();
-}
-
-int SharkBlock::switch_default_dest() {
- return iter()->get_dest_table(0);
-}
-
-int SharkBlock::switch_table_length() {
- switch(bc()) {
- case Bytecodes::_tableswitch:
- return iter()->get_int_table(2) - iter()->get_int_table(1) + 1;
-
- case Bytecodes::_lookupswitch:
- return iter()->get_int_table(1);
-
- default:
- ShouldNotReachHere();
- }
-}
-
-int SharkBlock::switch_key(int i) {
- switch(bc()) {
- case Bytecodes::_tableswitch:
- return iter()->get_int_table(1) + i;
-
- case Bytecodes::_lookupswitch:
- return iter()->get_int_table(2 + 2 * i);
-
- default:
- ShouldNotReachHere();
- }
-}
-
-int SharkBlock::switch_dest(int i) {
- switch(bc()) {
- case Bytecodes::_tableswitch:
- return iter()->get_dest_table(i + 3);
-
- case Bytecodes::_lookupswitch:
- return iter()->get_dest_table(2 + 2 * i + 1);
-
- default:
- ShouldNotReachHere();
- }
-}
-
-void SharkBlock::do_div_or_rem(bool is_long, bool is_rem) {
- SharkValue *sb = pop();
- SharkValue *sa = pop();
-
- check_divide_by_zero(sb);
-
- Value *a, *b, *p, *q;
- if (is_long) {
- a = sa->jlong_value();
- b = sb->jlong_value();
- p = LLVMValue::jlong_constant(0x8000000000000000LL);
- q = LLVMValue::jlong_constant(-1);
- }
- else {
- a = sa->jint_value();
- b = sb->jint_value();
- p = LLVMValue::jint_constant(0x80000000);
- q = LLVMValue::jint_constant(-1);
- }
-
- BasicBlock *ip = builder()->GetBlockInsertionPoint();
- BasicBlock *special_case = builder()->CreateBlock(ip, "special_case");
- BasicBlock *general_case = builder()->CreateBlock(ip, "general_case");
- BasicBlock *done = builder()->CreateBlock(ip, "done");
-
- builder()->CreateCondBr(
- builder()->CreateAnd(
- builder()->CreateICmpEQ(a, p),
- builder()->CreateICmpEQ(b, q)),
- special_case, general_case);
-
- builder()->SetInsertPoint(special_case);
- Value *special_result;
- if (is_rem) {
- if (is_long)
- special_result = LLVMValue::jlong_constant(0);
- else
- special_result = LLVMValue::jint_constant(0);
- }
- else {
- special_result = a;
- }
- builder()->CreateBr(done);
-
- builder()->SetInsertPoint(general_case);
- Value *general_result;
- if (is_rem)
- general_result = builder()->CreateSRem(a, b);
- else
- general_result = builder()->CreateSDiv(a, b);
- builder()->CreateBr(done);
-
- builder()->SetInsertPoint(done);
- PHINode *result;
- if (is_long)
- result = builder()->CreatePHI(SharkType::jlong_type(), 0, "result");
- else
- result = builder()->CreatePHI(SharkType::jint_type(), 0, "result");
- result->addIncoming(special_result, special_case);
- result->addIncoming(general_result, general_case);
-
- if (is_long)
- push(SharkValue::create_jlong(result, false));
- else
- push(SharkValue::create_jint(result, false));
-}
-
-void SharkBlock::do_field_access(bool is_get, bool is_field) {
- bool will_link;
- ciField *field = iter()->get_field(will_link);
- assert(will_link, "typeflow responsibility");
- assert(is_field != field->is_static(), "mismatch");
-
- // Pop the value off the stack where necessary
- SharkValue *value = NULL;
- if (!is_get)
- value = pop();
-
- // Find the object we're accessing, if necessary
- Value *object = NULL;
- if (is_field) {
- SharkValue *value = pop();
- check_null(value);
- object = value->generic_value();
- }
- if (is_get && field->is_constant() && field->is_static()) {
- SharkConstant *constant = SharkConstant::for_field(iter());
- if (constant->is_loaded())
- value = constant->value(builder());
- }
- if (!is_get || value == NULL) {
- if (!is_field) {
- object = builder()->CreateInlineOop(field->holder()->java_mirror());
- }
- BasicType basic_type = field->type()->basic_type();
- Type *stack_type = SharkType::to_stackType(basic_type);
- Type *field_type = SharkType::to_arrayType(basic_type);
- Type *type = field_type;
- if (field->is_volatile()) {
- if (field_type == SharkType::jfloat_type()) {
- type = SharkType::jint_type();
- } else if (field_type == SharkType::jdouble_type()) {
- type = SharkType::jlong_type();
- }
- }
- Value *addr = builder()->CreateAddressOfStructEntry(
- object, in_ByteSize(field->offset_in_bytes()),
- PointerType::getUnqual(type),
- "addr");
-
- // Do the access
- if (is_get) {
- Value* field_value;
- if (field->is_volatile()) {
- field_value = builder()->CreateAtomicLoad(addr);
- field_value = builder()->CreateBitCast(field_value, field_type);
- } else {
- field_value = builder()->CreateLoad(addr);
- }
- if (field_type != stack_type) {
- field_value = builder()->CreateIntCast(
- field_value, stack_type, basic_type != T_CHAR);
- }
-
- value = SharkValue::create_generic(field->type(), field_value, false);
- }
- else {
- Value *field_value = value->generic_value();
-
- if (field_type != stack_type) {
- field_value = builder()->CreateIntCast(
- field_value, field_type, basic_type != T_CHAR);
- }
-
- if (field->is_volatile()) {
- field_value = builder()->CreateBitCast(field_value, type);
- builder()->CreateAtomicStore(field_value, addr);
- } else {
- builder()->CreateStore(field_value, addr);
- }
-
- if (!field->type()->is_primitive_type()) {
- builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr);
- }
- }
- }
-
- // Push the value onto the stack where necessary
- if (is_get)
- push(value);
-}
-
-void SharkBlock::do_lcmp() {
- Value *b = pop()->jlong_value();
- Value *a = pop()->jlong_value();
-
- BasicBlock *ip = builder()->GetBlockInsertionPoint();
- BasicBlock *ne = builder()->CreateBlock(ip, "lcmp_ne");
- BasicBlock *lt = builder()->CreateBlock(ip, "lcmp_lt");
- BasicBlock *gt = builder()->CreateBlock(ip, "lcmp_gt");
- BasicBlock *done = builder()->CreateBlock(ip, "done");
-
- BasicBlock *eq = builder()->GetInsertBlock();
- builder()->CreateCondBr(builder()->CreateICmpEQ(a, b), done, ne);
-
- builder()->SetInsertPoint(ne);
- builder()->CreateCondBr(builder()->CreateICmpSLT(a, b), lt, gt);
-
- builder()->SetInsertPoint(lt);
- builder()->CreateBr(done);
-
- builder()->SetInsertPoint(gt);
- builder()->CreateBr(done);
-
- builder()->SetInsertPoint(done);
- PHINode *result = builder()->CreatePHI(SharkType::jint_type(), 0, "result");
- result->addIncoming(LLVMValue::jint_constant(-1), lt);
- result->addIncoming(LLVMValue::jint_constant(0), eq);
- result->addIncoming(LLVMValue::jint_constant(1), gt);
-
- push(SharkValue::create_jint(result, false));
-}
-
-void SharkBlock::do_fcmp(bool is_double, bool unordered_is_greater) {
- Value *a, *b;
- if (is_double) {
- b = pop()->jdouble_value();
- a = pop()->jdouble_value();
- }
- else {
- b = pop()->jfloat_value();
- a = pop()->jfloat_value();
- }
-
- BasicBlock *ip = builder()->GetBlockInsertionPoint();
- BasicBlock *ordered = builder()->CreateBlock(ip, "ordered");
- BasicBlock *ge = builder()->CreateBlock(ip, "fcmp_ge");
- BasicBlock *lt = builder()->CreateBlock(ip, "fcmp_lt");
- BasicBlock *eq = builder()->CreateBlock(ip, "fcmp_eq");
- BasicBlock *gt = builder()->CreateBlock(ip, "fcmp_gt");
- BasicBlock *done = builder()->CreateBlock(ip, "done");
-
- builder()->CreateCondBr(
- builder()->CreateFCmpUNO(a, b),
- unordered_is_greater ? gt : lt, ordered);
-
- builder()->SetInsertPoint(ordered);
- builder()->CreateCondBr(builder()->CreateFCmpULT(a, b), lt, ge);
-
- builder()->SetInsertPoint(ge);
- builder()->CreateCondBr(builder()->CreateFCmpUGT(a, b), gt, eq);
-
- builder()->SetInsertPoint(lt);
- builder()->CreateBr(done);
-
- builder()->SetInsertPoint(gt);
- builder()->CreateBr(done);
-
- builder()->SetInsertPoint(eq);
- builder()->CreateBr(done);
-
- builder()->SetInsertPoint(done);
- PHINode *result = builder()->CreatePHI(SharkType::jint_type(), 0, "result");
- result->addIncoming(LLVMValue::jint_constant(-1), lt);
- result->addIncoming(LLVMValue::jint_constant(0), eq);
- result->addIncoming(LLVMValue::jint_constant(1), gt);
-
- push(SharkValue::create_jint(result, false));
-}
-
-void SharkBlock::emit_IR() {
- ShouldNotCallThis();
-}
-
-SharkState* SharkBlock::entry_state() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_zero_check(SharkValue* value) {
- ShouldNotCallThis();
-}
-
-void SharkBlock::maybe_add_backedge_safepoint() {
- ShouldNotCallThis();
-}
-
-bool SharkBlock::has_trap() {
- return false;
-}
-
-int SharkBlock::trap_request() {
- ShouldNotCallThis();
-}
-
-int SharkBlock::trap_bci() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_trap(int trap_request) {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_arraylength() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_aload(BasicType basic_type) {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_astore(BasicType basic_type) {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_return(BasicType type) {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_athrow() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_goto() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_jsr() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_ret() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_if(ICmpInst::Predicate p, SharkValue* b, SharkValue* a) {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_switch() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_call() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_instance_check() {
- ShouldNotCallThis();
-}
-
-bool SharkBlock::maybe_do_instanceof_if() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_new() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_newarray() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_anewarray() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_multianewarray() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_monitorenter() {
- ShouldNotCallThis();
-}
-
-void SharkBlock::do_monitorexit() {
- ShouldNotCallThis();
-}
--- a/src/hotspot/share/shark/sharkBlock.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,297 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKBLOCK_HPP
-#define SHARE_VM_SHARK_SHARKBLOCK_HPP
-
-#include "ci/ciMethod.hpp"
-#include "ci/ciStreams.hpp"
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkConstant.hpp"
-#include "shark/sharkInvariants.hpp"
-#include "shark/sharkState.hpp"
-#include "shark/sharkValue.hpp"
-#include "utilities/debug.hpp"
-
-class SharkState;
-
-class SharkBlock : public SharkTargetInvariants {
- protected:
- SharkBlock(const SharkTargetInvariants* parent)
- : SharkTargetInvariants(parent),
- _iter(target()),
- _current_state(NULL) {}
-
- SharkBlock(const SharkCompileInvariants* parent, ciMethod* target)
- : SharkTargetInvariants(parent, target),
- _iter(target),
- _current_state(NULL) {}
-
- private:
- ciBytecodeStream _iter;
- SharkState* _current_state;
-
- public:
- ciBytecodeStream* iter() {
- return &_iter;
- }
- Bytecodes::Code bc() {
- return iter()->cur_bc();
- }
- int bci() {
- return iter()->cur_bci();
- }
-
- // Entry state
- protected:
- virtual SharkState* entry_state();
-
- // Current state
- private:
- SharkState* initial_current_state();
-
- public:
- SharkState* current_state() {
- if (_current_state == NULL)
- set_current_state(initial_current_state());
- return _current_state;
- }
-
- protected:
- void set_current_state(SharkState* current_state) {
- _current_state = current_state;
- }
-
- // Local variables
- protected:
- SharkValue* local(int index) {
- SharkValue *value = current_state()->local(index);
- assert(value != NULL, "shouldn't be");
- assert(value->is_one_word() ||
- (index + 1 < max_locals() &&
- current_state()->local(index + 1) == NULL), "should be");
- return value;
- }
- void set_local(int index, SharkValue* value) {
- assert(value != NULL, "shouldn't be");
- current_state()->set_local(index, value);
- if (value->is_two_word())
- current_state()->set_local(index + 1, NULL);
- }
-
- // Expression stack (raw)
- protected:
- void xpush(SharkValue* value) {
- current_state()->push(value);
- }
- SharkValue* xpop() {
- return current_state()->pop();
- }
- SharkValue* xstack(int slot) {
- SharkValue *value = current_state()->stack(slot);
- assert(value != NULL, "shouldn't be");
- assert(value->is_one_word() ||
- (slot > 0 &&
- current_state()->stack(slot - 1) == NULL), "should be");
- return value;
- }
- int xstack_depth() {
- return current_state()->stack_depth();
- }
-
- // Expression stack (cooked)
- protected:
- void push(SharkValue* value) {
- assert(value != NULL, "shouldn't be");
- xpush(value);
- if (value->is_two_word())
- xpush(NULL);
- }
- SharkValue* pop() {
- int size = current_state()->stack(0) == NULL ? 2 : 1;
- if (size == 2)
- xpop();
- SharkValue *value = xpop();
- assert(value && value->size() == size, "should be");
- return value;
- }
- SharkValue* pop_result(BasicType type) {
- SharkValue *result = pop();
-
-#ifdef ASSERT
- switch (result->basic_type()) {
- case T_BOOLEAN:
- case T_BYTE:
- case T_CHAR:
- case T_SHORT:
- assert(type == T_INT, "type mismatch");
- break;
-
- case T_ARRAY:
- assert(type == T_OBJECT, "type mismatch");
- break;
-
- default:
- assert(result->basic_type() == type, "type mismatch");
- }
-#endif // ASSERT
-
- return result;
- }
-
- // Code generation
- public:
- virtual void emit_IR();
-
- protected:
- void parse_bytecode(int start, int limit);
-
- // Helpers
- protected:
- virtual void do_zero_check(SharkValue* value);
-
- // Zero checking
- protected:
- void check_null(SharkValue* object) {
- zero_check(object);
- }
- void check_divide_by_zero(SharkValue* value) {
- zero_check(value);
- }
- private:
- void zero_check(SharkValue* value) {
- if (!value->zero_checked())
- do_zero_check(value);
- }
-
- // Safepoints
- protected:
- virtual void maybe_add_backedge_safepoint();
-
- // Traps
- protected:
- virtual bool has_trap();
- virtual int trap_request();
- virtual int trap_bci();
- virtual void do_trap(int trap_request);
-
- // arraylength
- protected:
- virtual void do_arraylength();
-
- // *aload and *astore
- protected:
- virtual void do_aload(BasicType basic_type);
- virtual void do_astore(BasicType basic_type);
-
- // *div and *rem
- private:
- void do_idiv() {
- do_div_or_rem(false, false);
- }
- void do_irem() {
- do_div_or_rem(false, true);
- }
- void do_ldiv() {
- do_div_or_rem(true, false);
- }
- void do_lrem() {
- do_div_or_rem(true, true);
- }
- void do_div_or_rem(bool is_long, bool is_rem);
-
- // get* and put*
- private:
- void do_getstatic() {
- do_field_access(true, false);
- }
- void do_getfield() {
- do_field_access(true, true);
- }
- void do_putstatic() {
- do_field_access(false, false);
- }
- void do_putfield() {
- do_field_access(false, true);
- }
- void do_field_access(bool is_get, bool is_field);
-
- // lcmp and [fd]cmp[lg]
- private:
- void do_lcmp();
- void do_fcmp(bool is_double, bool unordered_is_greater);
-
- // *return and athrow
- protected:
- virtual void do_return(BasicType type);
- virtual void do_athrow();
-
- // goto*
- protected:
- virtual void do_goto();
-
- // jsr* and ret
- protected:
- virtual void do_jsr();
- virtual void do_ret();
-
- // if*
- protected:
- virtual void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a);
-
- // *switch
- protected:
- int switch_default_dest();
- int switch_table_length();
- int switch_key(int i);
- int switch_dest(int i);
-
- virtual void do_switch();
-
- // invoke*
- protected:
- virtual void do_call();
-
- // checkcast and instanceof
- protected:
- virtual void do_instance_check();
- virtual bool maybe_do_instanceof_if();
-
- // new and *newarray
- protected:
- virtual void do_new();
- virtual void do_newarray();
- virtual void do_anewarray();
- virtual void do_multianewarray();
-
- // monitorenter and monitorexit
- protected:
- virtual void do_monitorenter();
- virtual void do_monitorexit();
-};
-
-#endif // SHARE_VM_SHARK_SHARKBLOCK_HPP
--- a/src/hotspot/share/shark/sharkBuilder.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,530 +0,0 @@
-/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * 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 "ci/ciMethod.hpp"
-#include "gc/shared/barrierSet.hpp"
-#include "gc/shared/cardTableModRefBS.hpp"
-#include "memory/resourceArea.hpp"
-#include "oops/method.hpp"
-#include "prims/unsafe.hpp"
-#include "runtime/os.hpp"
-#include "runtime/synchronizer.hpp"
-#include "runtime/thread.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/llvmValue.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkContext.hpp"
-#include "shark/sharkRuntime.hpp"
-#include "utilities/debug.hpp"
-
-using namespace llvm;
-
-SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer)
- : IRBuilder<>(SharkContext::current()),
- _code_buffer(code_buffer) {
-}
-
-// Helpers for accessing structures
-Value* SharkBuilder::CreateAddressOfStructEntry(Value* base,
- ByteSize offset,
- Type* type,
- const char* name) {
- return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name);
-}
-
-LoadInst* SharkBuilder::CreateValueOfStructEntry(Value* base,
- ByteSize offset,
- Type* type,
- const char* name) {
- return CreateLoad(
- CreateAddressOfStructEntry(
- base, offset, PointerType::getUnqual(type)),
- name);
-}
-
-// Helpers for accessing arrays
-
-LoadInst* SharkBuilder::CreateArrayLength(Value* arrayoop) {
- return CreateValueOfStructEntry(
- arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()),
- SharkType::jint_type(), "length");
-}
-
-Value* SharkBuilder::CreateArrayAddress(Value* arrayoop,
- Type* element_type,
- int element_bytes,
- ByteSize base_offset,
- Value* index,
- const char* name) {
- Value* offset = CreateIntCast(index, SharkType::intptr_type(), false);
- if (element_bytes != 1)
- offset = CreateShl(
- offset,
- LLVMValue::intptr_constant(exact_log2(element_bytes)));
- offset = CreateAdd(
- LLVMValue::intptr_constant(in_bytes(base_offset)), offset);
-
- return CreateIntToPtr(
- CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset),
- PointerType::getUnqual(element_type),
- name);
-}
-
-Value* SharkBuilder::CreateArrayAddress(Value* arrayoop,
- BasicType basic_type,
- ByteSize base_offset,
- Value* index,
- const char* name) {
- return CreateArrayAddress(
- arrayoop,
- SharkType::to_arrayType(basic_type),
- type2aelembytes(basic_type),
- base_offset, index, name);
-}
-
-Value* SharkBuilder::CreateArrayAddress(Value* arrayoop,
- BasicType basic_type,
- Value* index,
- const char* name) {
- return CreateArrayAddress(
- arrayoop, basic_type,
- in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)),
- index, name);
-}
-
-// Helpers for creating intrinsics and external functions.
-
-Type* SharkBuilder::make_type(char type, bool void_ok) {
- switch (type) {
- // Primitive types
- case 'c':
- return SharkType::jbyte_type();
- case 'i':
- return SharkType::jint_type();
- case 'l':
- return SharkType::jlong_type();
- case 'x':
- return SharkType::intptr_type();
- case 'f':
- return SharkType::jfloat_type();
- case 'd':
- return SharkType::jdouble_type();
-
- // Pointers to primitive types
- case 'C':
- case 'I':
- case 'L':
- case 'X':
- case 'F':
- case 'D':
- return PointerType::getUnqual(make_type(tolower(type), false));
-
- // VM objects
- case 'T':
- return SharkType::thread_type();
- case 'M':
- return PointerType::getUnqual(SharkType::monitor_type());
- case 'O':
- return SharkType::oop_type();
- case 'K':
- return SharkType::klass_type();
-
- // Miscellaneous
- case 'v':
- assert(void_ok, "should be");
- return SharkType::void_type();
- case '1':
- return SharkType::bit_type();
-
- default:
- ShouldNotReachHere();
- }
-}
-
-FunctionType* SharkBuilder::make_ftype(const char* params,
- const char* ret) {
- std::vector<Type*> param_types;
- for (const char* c = params; *c; c++)
- param_types.push_back(make_type(*c, false));
-
- assert(strlen(ret) == 1, "should be");
- Type *return_type = make_type(*ret, true);
-
- return FunctionType::get(return_type, param_types, false);
-}
-
-// Create an object representing an intrinsic or external function by
-// referencing the symbol by name. This is the LLVM-style approach,
-// but it cannot be used on functions within libjvm.so its symbols
-// are not exported. Note that you cannot make this work simply by
-// exporting the symbols, as some symbols have the same names as
-// symbols in the standard libraries (eg, atan2, fabs) and would
-// obscure them were they visible.
-Value* SharkBuilder::make_function(const char* name,
- const char* params,
- const char* ret) {
- return SharkContext::current().get_external(name, make_ftype(params, ret));
-}
-
-// Create an object representing an external function by inlining a
-// function pointer in the code. This is not the LLVM way, but it's
-// the only way to access functions in libjvm.so and functions like
-// __kernel_dmb on ARM which is accessed via an absolute address.
-Value* SharkBuilder::make_function(address func,
- const char* params,
- const char* ret) {
- return CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) func),
- PointerType::getUnqual(make_ftype(params, ret)));
-}
-
-// VM calls
-
-Value* SharkBuilder::find_exception_handler() {
- return make_function(
- (address) SharkRuntime::find_exception_handler, "TIi", "i");
-}
-
-Value* SharkBuilder::monitorenter() {
- return make_function((address) SharkRuntime::monitorenter, "TM", "v");
-}
-
-Value* SharkBuilder::monitorexit() {
- return make_function((address) SharkRuntime::monitorexit, "TM", "v");
-}
-
-Value* SharkBuilder::new_instance() {
- return make_function((address) SharkRuntime::new_instance, "Ti", "v");
-}
-
-Value* SharkBuilder::newarray() {
- return make_function((address) SharkRuntime::newarray, "Tii", "v");
-}
-
-Value* SharkBuilder::anewarray() {
- return make_function((address) SharkRuntime::anewarray, "Tii", "v");
-}
-
-Value* SharkBuilder::multianewarray() {
- return make_function((address) SharkRuntime::multianewarray, "TiiI", "v");
-}
-
-Value* SharkBuilder::register_finalizer() {
- return make_function((address) SharkRuntime::register_finalizer, "TO", "v");
-}
-
-Value* SharkBuilder::safepoint() {
- return make_function((address) SafepointSynchronize::block, "T", "v");
-}
-
-Value* SharkBuilder::throw_ArithmeticException() {
- return make_function(
- (address) SharkRuntime::throw_ArithmeticException, "TCi", "v");
-}
-
-Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() {
- return make_function(
- (address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v");
-}
-
-Value* SharkBuilder::throw_ClassCastException() {
- return make_function(
- (address) SharkRuntime::throw_ClassCastException, "TCi", "v");
-}
-
-Value* SharkBuilder::throw_NullPointerException() {
- return make_function(
- (address) SharkRuntime::throw_NullPointerException, "TCi", "v");
-}
-
-// High-level non-VM calls
-
-Value* SharkBuilder::f2i() {
- return make_function((address) SharedRuntime::f2i, "f", "i");
-}
-
-Value* SharkBuilder::f2l() {
- return make_function((address) SharedRuntime::f2l, "f", "l");
-}
-
-Value* SharkBuilder::d2i() {
- return make_function((address) SharedRuntime::d2i, "d", "i");
-}
-
-Value* SharkBuilder::d2l() {
- return make_function((address) SharedRuntime::d2l, "d", "l");
-}
-
-Value* SharkBuilder::is_subtype_of() {
- return make_function((address) SharkRuntime::is_subtype_of, "KK", "c");
-}
-
-Value* SharkBuilder::current_time_millis() {
- return make_function((address) os::javaTimeMillis, "", "l");
-}
-
-Value* SharkBuilder::sin() {
- return make_function("llvm.sin.f64", "d", "d");
-}
-
-Value* SharkBuilder::cos() {
- return make_function("llvm.cos.f64", "d", "d");
-}
-
-Value* SharkBuilder::tan() {
- return make_function((address) ::tan, "d", "d");
-}
-
-Value* SharkBuilder::atan2() {
- return make_function((address) ::atan2, "dd", "d");
-}
-
-Value* SharkBuilder::sqrt() {
- return make_function("llvm.sqrt.f64", "d", "d");
-}
-
-Value* SharkBuilder::log() {
- return make_function("llvm.log.f64", "d", "d");
-}
-
-Value* SharkBuilder::log10() {
- return make_function("llvm.log10.f64", "d", "d");
-}
-
-Value* SharkBuilder::pow() {
- return make_function("llvm.pow.f64", "dd", "d");
-}
-
-Value* SharkBuilder::exp() {
- return make_function("llvm.exp.f64", "d", "d");
-}
-
-Value* SharkBuilder::fabs() {
- return make_function((address) ::fabs, "d", "d");
-}
-
-Value* SharkBuilder::unsafe_field_offset_to_byte_offset() {
- return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l");
-}
-
-Value* SharkBuilder::osr_migration_end() {
- return make_function((address) SharedRuntime::OSR_migration_end, "C", "v");
-}
-
-// Semi-VM calls
-
-Value* SharkBuilder::throw_StackOverflowError() {
- return make_function((address) ZeroStack::handle_overflow, "T", "v");
-}
-
-Value* SharkBuilder::uncommon_trap() {
- return make_function((address) SharkRuntime::uncommon_trap, "Ti", "i");
-}
-
-Value* SharkBuilder::deoptimized_entry_point() {
- return make_function((address) CppInterpreter::main_loop, "iT", "v");
-}
-
-// Native-Java transition
-
-Value* SharkBuilder::check_special_condition_for_native_trans() {
- return make_function(
- (address) JavaThread::check_special_condition_for_native_trans,
- "T", "v");
-}
-
-Value* SharkBuilder::frame_address() {
- return make_function("llvm.frameaddress", "i", "C");
-}
-
-Value* SharkBuilder::memset() {
- // LLVM 2.8 added a fifth isVolatile field for memset
- // introduced with LLVM r100304
- return make_function("llvm.memset.p0i8.i32", "Cciii", "v");
-}
-
-Value* SharkBuilder::unimplemented() {
- return make_function((address) report_unimplemented, "Ci", "v");
-}
-
-Value* SharkBuilder::should_not_reach_here() {
- return make_function((address) report_should_not_reach_here, "Ci", "v");
-}
-
-Value* SharkBuilder::dump() {
- return make_function((address) SharkRuntime::dump, "Cx", "v");
-}
-
-// Public interface to low-level non-VM calls
-
-CallInst* SharkBuilder::CreateGetFrameAddress() {
- return CreateCall(frame_address(), LLVMValue::jint_constant(0));
-}
-
-CallInst* SharkBuilder::CreateMemset(Value* dst,
- Value* value,
- Value* len,
- Value* align) {
- return CreateCall5(memset(), dst, value, len, align,
- LLVMValue::jint_constant(0));
-}
-
-CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) {
- return CreateCall2(
- unimplemented(),
- CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) file),
- PointerType::getUnqual(SharkType::jbyte_type())),
- LLVMValue::jint_constant(line));
-}
-
-CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line) {
- return CreateCall2(
- should_not_reach_here(),
- CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) file),
- PointerType::getUnqual(SharkType::jbyte_type())),
- LLVMValue::jint_constant(line));
-}
-
-#ifndef PRODUCT
-CallInst* SharkBuilder::CreateDump(Value* value) {
- const char *name;
- if (value->hasName())
- // XXX this leaks, but it's only debug code
- name = os::strdup(value->getName().str().c_str());
- else
- name = "unnamed_value";
-
- if (isa<PointerType>(value->getType()))
- value = CreatePtrToInt(value, SharkType::intptr_type());
- else if (value->getType()->
- isIntegerTy()
- )
- value = CreateIntCast(value, SharkType::intptr_type(), false);
- else
- Unimplemented();
-
- return CreateCall2(
- dump(),
- CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) name),
- PointerType::getUnqual(SharkType::jbyte_type())),
- value);
-}
-#endif // PRODUCT
-
-// HotSpot memory barriers
-
-void SharkBuilder::CreateUpdateBarrierSet(BarrierSet* bs, Value* field) {
- if (bs->kind() != BarrierSet::CardTableForRS &&
- bs->kind() != BarrierSet::CardTableExtension) {
- Unimplemented();
- }
-
- CreateStore(
- LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card_val()),
- CreateIntToPtr(
- CreateAdd(
- LLVMValue::intptr_constant(
- (intptr_t) (barrier_set_cast<CardTableModRefBS>(bs)->byte_map_base)),
- CreateLShr(
- CreatePtrToInt(field, SharkType::intptr_type()),
- LLVMValue::intptr_constant(CardTableModRefBS::card_shift))),
- PointerType::getUnqual(SharkType::jbyte_type())));
-}
-
-// Helpers for accessing the code buffer
-
-Value* SharkBuilder::code_buffer_address(int offset) {
- return CreateAdd(
- code_buffer()->base_pc(),
- LLVMValue::intptr_constant(offset));
-}
-
-Value* SharkBuilder::CreateInlineOop(jobject object, const char* name) {
- return CreateLoad(
- CreateIntToPtr(
- code_buffer_address(code_buffer()->inline_oop(object)),
- PointerType::getUnqual(SharkType::oop_type())),
- name);
-}
-
-Value* SharkBuilder::CreateInlineMetadata(Metadata* metadata, llvm::PointerType* type, const char* name) {
- assert(metadata != NULL, "inlined metadata must not be NULL");
- assert(metadata->is_metaspace_object(), "sanity check");
- return CreateLoad(
- CreateIntToPtr(
- code_buffer_address(code_buffer()->inline_Metadata(metadata)),
- PointerType::getUnqual(type)),
- name);
-}
-
-Value* SharkBuilder::CreateInlineData(void* data,
- size_t size,
- Type* type,
- const char* name) {
- return CreateIntToPtr(
- code_buffer_address(code_buffer()->inline_data(data, size)),
- type,
- name);
-}
-
-// Helpers for creating basic blocks.
-
-BasicBlock* SharkBuilder::GetBlockInsertionPoint() const {
- BasicBlock *cur = GetInsertBlock();
-
- // BasicBlock::Create takes an insertBefore argument, so
- // we need to find the block _after_ the current block
- Function::iterator iter = cur->getParent()->begin();
- Function::iterator end = cur->getParent()->end();
- while (iter != end) {
- iter++;
- if (&*iter == cur) {
- iter++;
- break;
- }
- }
-
- if (iter == end)
- return NULL;
- else
- return iter;
-}
-
-BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const {
- return BasicBlock::Create(
- SharkContext::current(), name, GetInsertBlock()->getParent(), ip);
-}
-
-LoadInst* SharkBuilder::CreateAtomicLoad(Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) {
- return Insert(new LoadInst(ptr, name, isVolatile, align, ordering, synchScope), name);
-}
-
-StoreInst* SharkBuilder::CreateAtomicStore(Value* val, Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) {
- return Insert(new StoreInst(val, ptr, isVolatile, align, ordering, synchScope), name);
-}
--- a/src/hotspot/share/shark/sharkBuilder.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,228 +0,0 @@
-/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKBUILDER_HPP
-#define SHARE_VM_SHARK_SHARKBUILDER_HPP
-
-#include "ci/ciType.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/llvmValue.hpp"
-#include "shark/sharkCodeBuffer.hpp"
-#include "shark/sharkEntry.hpp"
-#include "shark/sharkType.hpp"
-#include "shark/sharkValue.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/sizes.hpp"
-
-class BarrierSet;
-
-class SharkBuilder : public llvm::IRBuilder<> {
- friend class SharkCompileInvariants;
-
- public:
- SharkBuilder(SharkCodeBuffer* code_buffer);
-
- // The code buffer we are building into.
- private:
- SharkCodeBuffer* _code_buffer;
-
- protected:
- SharkCodeBuffer* code_buffer() const {
- return _code_buffer;
- }
-
- public:
- llvm::LoadInst* CreateAtomicLoad(llvm::Value* ptr,
- unsigned align = HeapWordSize,
- llvm::AtomicOrdering ordering = llvm::SequentiallyConsistent,
- llvm::SynchronizationScope synchScope = llvm::CrossThread,
- bool isVolatile = true,
- const char *name = "");
- llvm::StoreInst* CreateAtomicStore(llvm::Value *val,
- llvm::Value *ptr,
- unsigned align = HeapWordSize,
- llvm::AtomicOrdering ordering = llvm::SequentiallyConsistent,
- llvm::SynchronizationScope SynchScope = llvm::CrossThread,
- bool isVolatile = true,
- const char *name = "");
-
- // Helpers for accessing structures.
- public:
- llvm::Value* CreateAddressOfStructEntry(llvm::Value* base,
- ByteSize offset,
- llvm::Type* type,
- const char *name = "");
- llvm::LoadInst* CreateValueOfStructEntry(llvm::Value* base,
- ByteSize offset,
- llvm::Type* type,
- const char *name = "");
-
- // Helpers for accessing arrays.
- public:
- llvm::LoadInst* CreateArrayLength(llvm::Value* arrayoop);
- llvm::Value* CreateArrayAddress(llvm::Value* arrayoop,
- llvm::Type* element_type,
- int element_bytes,
- ByteSize base_offset,
- llvm::Value* index,
- const char* name = "");
- llvm::Value* CreateArrayAddress(llvm::Value* arrayoop,
- BasicType basic_type,
- ByteSize base_offset,
- llvm::Value* index,
- const char* name = "");
- llvm::Value* CreateArrayAddress(llvm::Value* arrayoop,
- BasicType basic_type,
- llvm::Value* index,
- const char* name = "");
-
- // Helpers for creating intrinsics and external functions.
- private:
- static llvm::Type* make_type(char type, bool void_ok);
- static llvm::FunctionType* make_ftype(const char* params,
- const char* ret);
- llvm::Value* make_function(const char* name,
- const char* params,
- const char* ret);
- llvm::Value* make_function(address func,
- const char* params,
- const char* ret);
-
- // Intrinsics and external functions, part 1: VM calls.
- // These are functions declared with JRT_ENTRY and JRT_EXIT,
- // macros which flip the thread from _thread_in_Java to
- // _thread_in_vm and back. VM calls always safepoint, and can
- // therefore throw exceptions. VM calls require of setup and
- // teardown, and must be called with SharkTopLevelBlock::call_vm.
- public:
- llvm::Value* find_exception_handler();
- llvm::Value* monitorenter();
- llvm::Value* monitorexit();
- llvm::Value* new_instance();
- llvm::Value* newarray();
- llvm::Value* anewarray();
- llvm::Value* multianewarray();
- llvm::Value* register_finalizer();
- llvm::Value* safepoint();
- llvm::Value* throw_ArithmeticException();
- llvm::Value* throw_ArrayIndexOutOfBoundsException();
- llvm::Value* throw_ClassCastException();
- llvm::Value* throw_NullPointerException();
-
- // Intrinsics and external functions, part 2: High-level non-VM calls.
- // These are called like normal functions. The stack is not set
- // up for walking so they must not safepoint or throw exceptions,
- // or call anything that might.
- public:
- llvm::Value* f2i();
- llvm::Value* f2l();
- llvm::Value* d2i();
- llvm::Value* d2l();
- llvm::Value* is_subtype_of();
- llvm::Value* current_time_millis();
- llvm::Value* sin();
- llvm::Value* cos();
- llvm::Value* tan();
- llvm::Value* atan2();
- llvm::Value* sqrt();
- llvm::Value* log();
- llvm::Value* log10();
- llvm::Value* pow();
- llvm::Value* exp();
- llvm::Value* fabs();
- llvm::Value* unsafe_field_offset_to_byte_offset();
- llvm::Value* osr_migration_end();
-
- // Intrinsics and external functions, part 3: semi-VM calls.
- // These are special cases that do VM call stuff but are invoked
- // as though they were normal calls. This is acceptable so long
- // as the method that calls them returns to its immediately that
- // the semi VM call returns.
- public:
- llvm::Value* throw_StackOverflowError();
- llvm::Value* uncommon_trap();
- llvm::Value* deoptimized_entry_point();
-
- // Intrinsics and external functions, part 4: Native-Java transition.
- // This is a special case in that it is invoked during a thread
- // state transition. The stack must be set up for walking, and it
- // may throw exceptions, but the state is _thread_in_native_trans.
- public:
- llvm::Value* check_special_condition_for_native_trans();
-
- // Intrinsics and external functions, part 5: Low-level non-VM calls.
- // These have the same caveats as the high-level non-VM calls
- // above. They are not accessed directly; rather, you should
- // access them via the various Create* methods below.
- private:
- llvm::Value* cmpxchg_int();
- llvm::Value* cmpxchg_ptr();
- llvm::Value* frame_address();
- llvm::Value* memset();
- llvm::Value* unimplemented();
- llvm::Value* should_not_reach_here();
- llvm::Value* dump();
-
- // Public interface to low-level non-VM calls.
- public:
- llvm::CallInst* CreateGetFrameAddress();
- llvm::CallInst* CreateMemset(llvm::Value* dst,
- llvm::Value* value,
- llvm::Value* len,
- llvm::Value* align);
- llvm::CallInst* CreateUnimplemented(const char* file, int line);
- llvm::CallInst* CreateShouldNotReachHere(const char* file, int line);
- NOT_PRODUCT(llvm::CallInst* CreateDump(llvm::Value* value));
-
- // HotSpot memory barriers
- public:
- void CreateUpdateBarrierSet(BarrierSet* bs, llvm::Value* field);
-
- // Helpers for accessing the code buffer.
- public:
- llvm::Value* code_buffer_address(int offset);
- llvm::Value* CreateInlineOop(jobject object, const char* name = "");
- llvm::Value* CreateInlineOop(ciObject* object, const char* name = "") {
- return CreateInlineOop(object->constant_encoding(), name);
- }
-
- llvm::Value* CreateInlineMetadata(Metadata* metadata, llvm::PointerType* type, const char* name = "");
- llvm::Value* CreateInlineMetadata(ciMetadata* metadata, llvm::PointerType* type, const char* name = "") {
- return CreateInlineMetadata(metadata->constant_encoding(), type, name);
- }
- llvm::Value* CreateInlineData(void* data,
- size_t size,
- llvm::Type* type,
- const char* name = "");
-
- // Helpers for creating basic blocks.
- // NB don't use unless SharkFunction::CreateBlock is unavailable.
- // XXX these are hacky and should be removed.
- public:
- llvm::BasicBlock* GetBlockInsertionPoint() const;
- llvm::BasicBlock* CreateBlock(llvm::BasicBlock* ip,
- const char* name="") const;
-};
- #endif // SHARE_VM_SHARK_SHARKBUILDER_HPP
--- a/src/hotspot/share/shark/sharkCacheDecache.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,266 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * 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 "ci/ciMethod.hpp"
-#include "code/debugInfoRec.hpp"
-#include "shark/llvmValue.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkCacheDecache.hpp"
-#include "shark/sharkFunction.hpp"
-#include "shark/sharkState.hpp"
-
-using namespace llvm;
-
-void SharkDecacher::start_frame() {
- // Start recording the debug information
- _pc_offset = code_buffer()->create_unique_offset();
- _oopmap = new OopMap(
- oopmap_slot_munge(stack()->oopmap_frame_size()),
- oopmap_slot_munge(arg_size()));
- debug_info()->add_safepoint(pc_offset(), oopmap());
-}
-
-void SharkDecacher::start_stack(int stack_depth) {
- // Create the array we'll record our stack slots in
- _exparray = new GrowableArray<ScopeValue*>(stack_depth);
-
- // Set the stack pointer
- stack()->CreateStoreStackPointer(
- builder()->CreatePtrToInt(
- stack()->slot_addr(
- stack()->stack_slots_offset() + max_stack() - stack_depth),
- SharkType::intptr_type()));
-}
-
-void SharkDecacher::process_stack_slot(int index,
- SharkValue** addr,
- int offset) {
- SharkValue *value = *addr;
-
- // Write the value to the frame if necessary
- if (stack_slot_needs_write(index, value)) {
- write_value_to_frame(
- SharkType::to_stackType(value->basic_type()),
- value->generic_value(),
- adjusted_offset(value, offset));
- }
-
- // Record the value in the oopmap if necessary
- if (stack_slot_needs_oopmap(index, value)) {
- oopmap()->set_oop(slot2reg(offset));
- }
-
- // Record the value in the debuginfo if necessary
- if (stack_slot_needs_debuginfo(index, value)) {
- exparray()->append(slot2lv(offset, stack_location_type(index, addr)));
- }
-}
-
-void SharkDecacher::start_monitors(int num_monitors) {
- // Create the array we'll record our monitors in
- _monarray = new GrowableArray<MonitorValue*>(num_monitors);
-}
-
-void SharkDecacher::process_monitor(int index, int box_offset, int obj_offset) {
- oopmap()->set_oop(slot2reg(obj_offset));
-
- monarray()->append(new MonitorValue(
- slot2lv (obj_offset, Location::oop),
- slot2loc(box_offset, Location::normal)));
-}
-
-void SharkDecacher::process_oop_tmp_slot(Value** value, int offset) {
- // Decache the temporary oop slot
- if (*value) {
- write_value_to_frame(
- SharkType::oop_type(),
- *value,
- offset);
-
- oopmap()->set_oop(slot2reg(offset));
- }
-}
-
-void SharkDecacher::process_method_slot(Value** value, int offset) {
- // Decache the method pointer
- write_value_to_frame(
- SharkType::Method_type(),
- *value,
- offset);
-
-}
-
-void SharkDecacher::process_pc_slot(int offset) {
- // Record the PC
- builder()->CreateStore(
- builder()->code_buffer_address(pc_offset()),
- stack()->slot_addr(offset));
-}
-
-void SharkDecacher::start_locals() {
- // Create the array we'll record our local variables in
- _locarray = new GrowableArray<ScopeValue*>(max_locals());}
-
-void SharkDecacher::process_local_slot(int index,
- SharkValue** addr,
- int offset) {
- SharkValue *value = *addr;
-
- // Write the value to the frame if necessary
- if (local_slot_needs_write(index, value)) {
- write_value_to_frame(
- SharkType::to_stackType(value->basic_type()),
- value->generic_value(),
- adjusted_offset(value, offset));
- }
-
- // Record the value in the oopmap if necessary
- if (local_slot_needs_oopmap(index, value)) {
- oopmap()->set_oop(slot2reg(offset));
- }
-
- // Record the value in the debuginfo if necessary
- if (local_slot_needs_debuginfo(index, value)) {
- locarray()->append(slot2lv(offset, local_location_type(index, addr)));
- }
-}
-
-void SharkDecacher::end_frame() {
- // Record the scope
- methodHandle null_mh;
- debug_info()->describe_scope(
- pc_offset(),
- null_mh,
- target(),
- bci(),
- true,
- false,
- false,
- debug_info()->create_scope_values(locarray()),
- debug_info()->create_scope_values(exparray()),
- debug_info()->create_monitor_values(monarray()));
-
- // Finish recording the debug information
- debug_info()->end_safepoint(pc_offset());
-}
-
-void SharkCacher::process_stack_slot(int index,
- SharkValue** addr,
- int offset) {
- SharkValue *value = *addr;
-
- // Read the value from the frame if necessary
- if (stack_slot_needs_read(index, value)) {
- *addr = SharkValue::create_generic(
- value->type(),
- read_value_from_frame(
- SharkType::to_stackType(value->basic_type()),
- adjusted_offset(value, offset)),
- value->zero_checked());
- }
-}
-
-void SharkOSREntryCacher::process_monitor(int index,
- int box_offset,
- int obj_offset) {
- // Copy the monitor from the OSR buffer to the frame
- int src_offset = max_locals() + index * 2;
- builder()->CreateStore(
- builder()->CreateLoad(
- CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())),
- stack()->slot_addr(box_offset, SharkType::intptr_type()));
- builder()->CreateStore(
- builder()->CreateLoad(
- CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())),
- stack()->slot_addr(obj_offset, SharkType::oop_type()));
-}
-
-void SharkCacher::process_oop_tmp_slot(Value** value, int offset) {
- // Cache the temporary oop
- if (*value)
- *value = read_value_from_frame(SharkType::oop_type(), offset);
-}
-
-void SharkCacher::process_method_slot(Value** value, int offset) {
- // Cache the method pointer
- *value = read_value_from_frame(SharkType::Method_type(), offset);
-}
-
-void SharkFunctionEntryCacher::process_method_slot(Value** value, int offset) {
- // "Cache" the method pointer
- *value = method();
-}
-
-void SharkCacher::process_local_slot(int index,
- SharkValue** addr,
- int offset) {
- SharkValue *value = *addr;
-
- // Read the value from the frame if necessary
- if (local_slot_needs_read(index, value)) {
- *addr = SharkValue::create_generic(
- value->type(),
- read_value_from_frame(
- SharkType::to_stackType(value->basic_type()),
- adjusted_offset(value, offset)),
- value->zero_checked());
- }
-}
-
-Value* SharkOSREntryCacher::CreateAddressOfOSRBufEntry(int offset,
- Type* type) {
- Value *result = builder()->CreateStructGEP(osr_buf(), offset);
- if (type != SharkType::intptr_type())
- result = builder()->CreateBitCast(result, PointerType::getUnqual(type));
- return result;
-}
-
-void SharkOSREntryCacher::process_local_slot(int index,
- SharkValue** addr,
- int offset) {
- SharkValue *value = *addr;
-
- // Read the value from the OSR buffer if necessary
- if (local_slot_needs_read(index, value)) {
- *addr = SharkValue::create_generic(
- value->type(),
- builder()->CreateLoad(
- CreateAddressOfOSRBufEntry(
- adjusted_offset(value, max_locals() - 1 - index),
- SharkType::to_stackType(value->basic_type()))),
- value->zero_checked());
- }
-}
-
-void SharkDecacher::write_value_to_frame(Type* type,
- Value* value,
- int offset) {
- builder()->CreateStore(value, stack()->slot_addr(offset, type));
-}
-
-Value* SharkCacher::read_value_from_frame(Type* type, int offset) {
- return builder()->CreateLoad(stack()->slot_addr(offset, type));
-}
--- a/src/hotspot/share/shark/sharkCacheDecache.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,428 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP
-#define SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP
-
-#include "ci/ciMethod.hpp"
-#include "code/debugInfoRec.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkFunction.hpp"
-#include "shark/sharkStateScanner.hpp"
-
-// Class hierarchy:
-// - SharkStateScanner
-// - SharkCacherDecacher
-// - SharkDecacher
-// - SharkJavaCallDecacher
-// - SharkVMCallDecacher
-// - SharkTrapDecacher
-// - SharkCacher
-// - SharkJavaCallCacher
-// - SharkVMCallCacher
-// - SharkFunctionEntryCacher
-// - SharkNormalEntryCacher
-// - SharkOSREntryCacher
-
-class SharkCacherDecacher : public SharkStateScanner {
- protected:
- SharkCacherDecacher(SharkFunction* function)
- : SharkStateScanner(function) {}
-
- // Helper
- protected:
- static int adjusted_offset(SharkValue* value, int offset) {
- if (value->is_two_word())
- offset--;
- return offset;
- }
-};
-
-class SharkDecacher : public SharkCacherDecacher {
- protected:
- SharkDecacher(SharkFunction* function, int bci)
- : SharkCacherDecacher(function), _bci(bci) {}
-
- private:
- int _bci;
-
- protected:
- int bci() const {
- return _bci;
- }
-
- private:
- int _pc_offset;
- OopMap* _oopmap;
- GrowableArray<ScopeValue*>* _exparray;
- GrowableArray<MonitorValue*>* _monarray;
- GrowableArray<ScopeValue*>* _locarray;
-
- private:
- int pc_offset() const {
- return _pc_offset;
- }
- OopMap* oopmap() const {
- return _oopmap;
- }
- GrowableArray<ScopeValue*>* exparray() const {
- return _exparray;
- }
- GrowableArray<MonitorValue*>* monarray() const {
- return _monarray;
- }
- GrowableArray<ScopeValue*>* locarray() const {
- return _locarray;
- }
-
- // Callbacks
- protected:
- void start_frame();
-
- void start_stack(int stack_depth);
- void process_stack_slot(int index, SharkValue** value, int offset);
-
- void start_monitors(int num_monitors);
- void process_monitor(int index, int box_offset, int obj_offset);
-
- void process_oop_tmp_slot(llvm::Value** value, int offset);
- void process_method_slot(llvm::Value** value, int offset);
- void process_pc_slot(int offset);
-
- void start_locals();
- void process_local_slot(int index, SharkValue** value, int offset);
-
- void end_frame();
-
- // oopmap and debuginfo helpers
- private:
- static int oopmap_slot_munge(int offset) {
- return SharkStack::oopmap_slot_munge(offset);
- }
- static VMReg slot2reg(int offset) {
- return SharkStack::slot2reg(offset);
- }
- static Location slot2loc(int offset, Location::Type type) {
- return Location::new_stk_loc(type, offset * wordSize);
- }
- static LocationValue* slot2lv(int offset, Location::Type type) {
- return new LocationValue(slot2loc(offset, type));
- }
- static Location::Type location_type(SharkValue** addr, bool maybe_two_word) {
- // low addresses this end
- // Type 32-bit 64-bit
- // ----------------------------------------------------
- // stack[0] local[3] jobject oop oop
- // stack[1] local[2] NULL normal lng
- // stack[2] local[1] jlong normal invalid
- // stack[3] local[0] jint normal normal
- //
- // high addresses this end
-
- SharkValue *value = *addr;
- if (value) {
- if (value->is_jobject())
- return Location::oop;
-#ifdef _LP64
- if (value->is_two_word())
- return Location::invalid;
-#endif // _LP64
- return Location::normal;
- }
- else {
- if (maybe_two_word) {
- value = *(addr - 1);
- if (value && value->is_two_word()) {
-#ifdef _LP64
- if (value->is_jlong())
- return Location::lng;
- if (value->is_jdouble())
- return Location::dbl;
- ShouldNotReachHere();
-#else
- return Location::normal;
-#endif // _LP64
- }
- }
- return Location::invalid;
- }
- }
-
- // Stack slot helpers
- protected:
- virtual bool stack_slot_needs_write(int index, SharkValue* value) = 0;
- virtual bool stack_slot_needs_oopmap(int index, SharkValue* value) = 0;
- virtual bool stack_slot_needs_debuginfo(int index, SharkValue* value) = 0;
-
- static Location::Type stack_location_type(int index, SharkValue** addr) {
- return location_type(addr, *addr == NULL);
- }
-
- // Local slot helpers
- protected:
- virtual bool local_slot_needs_write(int index, SharkValue* value) = 0;
- virtual bool local_slot_needs_oopmap(int index, SharkValue* value) = 0;
- virtual bool local_slot_needs_debuginfo(int index, SharkValue* value) = 0;
-
- static Location::Type local_location_type(int index, SharkValue** addr) {
- return location_type(addr, index > 0);
- }
-
- // Writer helper
- protected:
- void write_value_to_frame(llvm::Type* type,
- llvm::Value* value,
- int offset);
-};
-
-class SharkJavaCallDecacher : public SharkDecacher {
- public:
- SharkJavaCallDecacher(SharkFunction* function, int bci, ciMethod* callee)
- : SharkDecacher(function, bci), _callee(callee) {}
-
- private:
- ciMethod* _callee;
-
- protected:
- ciMethod* callee() const {
- return _callee;
- }
-
- // Stack slot helpers
- protected:
- bool stack_slot_needs_write(int index, SharkValue* value) {
- return value && (index < callee()->arg_size() || value->is_jobject());
- }
- bool stack_slot_needs_oopmap(int index, SharkValue* value) {
- return value && value->is_jobject() && index >= callee()->arg_size();
- }
- bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
- return index >= callee()->arg_size();
- }
-
- // Local slot helpers
- protected:
- bool local_slot_needs_write(int index, SharkValue* value) {
- return value && value->is_jobject();
- }
- bool local_slot_needs_oopmap(int index, SharkValue* value) {
- return value && value->is_jobject();
- }
- bool local_slot_needs_debuginfo(int index, SharkValue* value) {
- return true;
- }
-};
-
-class SharkVMCallDecacher : public SharkDecacher {
- public:
- SharkVMCallDecacher(SharkFunction* function, int bci)
- : SharkDecacher(function, bci) {}
-
- // Stack slot helpers
- protected:
- bool stack_slot_needs_write(int index, SharkValue* value) {
- return value && value->is_jobject();
- }
- bool stack_slot_needs_oopmap(int index, SharkValue* value) {
- return value && value->is_jobject();
- }
- bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
- return true;
- }
-
- // Local slot helpers
- protected:
- bool local_slot_needs_write(int index, SharkValue* value) {
- return value && value->is_jobject();
- }
- bool local_slot_needs_oopmap(int index, SharkValue* value) {
- return value && value->is_jobject();
- }
- bool local_slot_needs_debuginfo(int index, SharkValue* value) {
- return true;
- }
-};
-
-class SharkTrapDecacher : public SharkDecacher {
- public:
- SharkTrapDecacher(SharkFunction* function, int bci)
- : SharkDecacher(function, bci) {}
-
- // Stack slot helpers
- protected:
- bool stack_slot_needs_write(int index, SharkValue* value) {
- return value != NULL;
- }
- bool stack_slot_needs_oopmap(int index, SharkValue* value) {
- return value && value->is_jobject();
- }
- bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
- return true;
- }
-
- // Local slot helpers
- protected:
- bool local_slot_needs_write(int index, SharkValue* value) {
- return value != NULL;
- }
- bool local_slot_needs_oopmap(int index, SharkValue* value) {
- return value && value->is_jobject();
- }
- bool local_slot_needs_debuginfo(int index, SharkValue* value) {
- return true;
- }
-};
-
-class SharkCacher : public SharkCacherDecacher {
- protected:
- SharkCacher(SharkFunction* function)
- : SharkCacherDecacher(function) {}
-
- // Callbacks
- protected:
- void process_stack_slot(int index, SharkValue** value, int offset);
-
- void process_oop_tmp_slot(llvm::Value** value, int offset);
- virtual void process_method_slot(llvm::Value** value, int offset);
-
- virtual void process_local_slot(int index, SharkValue** value, int offset);
-
- // Stack slot helper
- protected:
- virtual bool stack_slot_needs_read(int index, SharkValue* value) = 0;
-
- // Local slot helper
- protected:
- virtual bool local_slot_needs_read(int index, SharkValue* value) {
- return value && value->is_jobject();
- }
-
- // Writer helper
- protected:
- llvm::Value* read_value_from_frame(llvm::Type* type, int offset);
-};
-
-class SharkJavaCallCacher : public SharkCacher {
- public:
- SharkJavaCallCacher(SharkFunction* function, ciMethod* callee)
- : SharkCacher(function), _callee(callee) {}
-
- private:
- ciMethod* _callee;
-
- protected:
- ciMethod* callee() const {
- return _callee;
- }
-
- // Stack slot helper
- protected:
- bool stack_slot_needs_read(int index, SharkValue* value) {
- return value && (index < callee()->return_type()->size() ||
- value->is_jobject());
- }
-};
-
-class SharkVMCallCacher : public SharkCacher {
- public:
- SharkVMCallCacher(SharkFunction* function)
- : SharkCacher(function) {}
-
- // Stack slot helper
- protected:
- bool stack_slot_needs_read(int index, SharkValue* value) {
- return value && value->is_jobject();
- }
-};
-
-class SharkFunctionEntryCacher : public SharkCacher {
- public:
- SharkFunctionEntryCacher(SharkFunction* function, llvm::Value* method)
- : SharkCacher(function), _method(method) {}
-
- private:
- llvm::Value* _method;
-
- private:
- llvm::Value* method() const {
- return _method;
- }
-
- // Method slot callback
- protected:
- void process_method_slot(llvm::Value** value, int offset);
-
- // Stack slot helper
- protected:
- bool stack_slot_needs_read(int index, SharkValue* value) {
- ShouldNotReachHere(); // entry block shouldn't have stack
- }
-
- // Local slot helper
- protected:
- bool local_slot_needs_read(int index, SharkValue* value) {
- return value != NULL;
- }
-};
-
-class SharkNormalEntryCacher : public SharkFunctionEntryCacher {
- public:
- SharkNormalEntryCacher(SharkFunction* function, llvm::Value* method)
- : SharkFunctionEntryCacher(function, method) {}
-};
-
-class SharkOSREntryCacher : public SharkFunctionEntryCacher {
- public:
- SharkOSREntryCacher(SharkFunction* function,
- llvm::Value* method,
- llvm::Value* osr_buf)
- : SharkFunctionEntryCacher(function, method),
- _osr_buf(
- builder()->CreateBitCast(
- osr_buf,
- llvm::PointerType::getUnqual(
- llvm::ArrayType::get(
- SharkType::intptr_type(),
- max_locals() + max_monitors() * 2)))) {}
-
- private:
- llvm::Value* _osr_buf;
-
- private:
- llvm::Value* osr_buf() const {
- return _osr_buf;
- }
-
- // Callbacks
- protected:
- void process_monitor(int index, int box_offset, int obj_offset);
- void process_local_slot(int index, SharkValue** value, int offset);
-
- // Helper
- private:
- llvm::Value* CreateAddressOfOSRBufEntry(int offset, llvm::Type* type);
-};
-
-#endif // SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP
--- a/src/hotspot/share/shark/sharkCodeBuffer.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKCODEBUFFER_HPP
-#define SHARE_VM_SHARK_SHARKCODEBUFFER_HPP
-
-#include "asm/codeBuffer.hpp"
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-
-class SharkCodeBuffer : public StackObj {
- public:
- SharkCodeBuffer(MacroAssembler* masm)
- : _masm(masm), _base_pc(NULL) {}
-
- private:
- MacroAssembler* _masm;
- llvm::Value* _base_pc;
-
- private:
- MacroAssembler* masm() const {
- return _masm;
- }
-
- public:
- llvm::Value* base_pc() const {
- return _base_pc;
- }
- void set_base_pc(llvm::Value* base_pc) {
- assert(_base_pc == NULL, "only do this once");
- _base_pc = base_pc;
- }
-
- // Allocate some space in the buffer and return its address.
- // This buffer will have been relocated by the time the method
- // is installed, so you can't inline the result in code.
- public:
- void* malloc(size_t size) const {
- masm()->align(BytesPerWord);
- void *result = masm()->pc();
- masm()->advance(size);
- return result;
- }
-
- // Create a unique offset in the buffer.
- public:
- int create_unique_offset() const {
- int offset = masm()->offset();
- masm()->advance(1);
- return offset;
- }
-
- // Inline an oop into the buffer and return its offset.
- public:
- int inline_oop(jobject object) const {
- masm()->align(BytesPerWord);
- int offset = masm()->offset();
- masm()->store_oop(object);
- return offset;
- }
-
- int inline_Metadata(Metadata* metadata) const {
- masm()->align(BytesPerWord);
- int offset = masm()->offset();
- masm()->store_Metadata(metadata);
- return offset;
- }
-
- // Inline a block of non-oop data into the buffer and return its offset.
- public:
- int inline_data(void *src, size_t size) const {
- masm()->align(BytesPerWord);
- int offset = masm()->offset();
- void *dst = masm()->pc();
- masm()->advance(size);
- memcpy(dst, src, size);
- return offset;
- }
-};
-
-#endif // SHARE_VM_SHARK_SHARKCODEBUFFER_HPP
--- a/src/hotspot/share/shark/sharkCompiler.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,372 +0,0 @@
-/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010, 2011 Red Hat, Inc.
- * 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 "ci/ciEnv.hpp"
-#include "ci/ciMethod.hpp"
-#include "code/debugInfoRec.hpp"
-#include "code/dependencies.hpp"
-#include "code/exceptionHandlerTable.hpp"
-#include "code/oopRecorder.hpp"
-#include "compiler/abstractCompiler.hpp"
-#include "compiler/oopMap.hpp"
-#include "memory/resourceArea.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkCodeBuffer.hpp"
-#include "shark/sharkCompiler.hpp"
-#include "shark/sharkContext.hpp"
-#include "shark/sharkEntry.hpp"
-#include "shark/sharkFunction.hpp"
-#include "shark/sharkMemoryManager.hpp"
-#include "shark/sharkNativeWrapper.hpp"
-#include "shark/shark_globals.hpp"
-#include "utilities/debug.hpp"
-
-#include <fnmatch.h>
-
-using namespace llvm;
-
-namespace {
- cl::opt<std::string>
- MCPU("mcpu");
-
- cl::list<std::string>
- MAttrs("mattr",
- cl::CommaSeparated);
-}
-
-SharkCompiler::SharkCompiler()
- : AbstractCompiler(shark) {
- // Create the lock to protect the memory manager and execution engine
- _execution_engine_lock = new Monitor(Mutex::leaf, "SharkExecutionEngineLock");
- MutexLocker locker(execution_engine_lock());
-
- // Make LLVM safe for multithreading
- if (!llvm_start_multithreaded())
- fatal("llvm_start_multithreaded() failed");
-
- // Initialize the native target
- InitializeNativeTarget();
-
- // MCJIT require a native AsmPrinter
- InitializeNativeTargetAsmPrinter();
-
- // Create the two contexts which we'll use
- _normal_context = new SharkContext("normal");
- _native_context = new SharkContext("native");
-
- // Create the memory manager
- _memory_manager = new SharkMemoryManager();
-
- // Finetune LLVM for the current host CPU.
- StringMap<bool> Features;
- bool gotCpuFeatures = llvm::sys::getHostCPUFeatures(Features);
- std::string cpu("-mcpu=" + llvm::sys::getHostCPUName());
-
- std::vector<const char*> args;
- args.push_back(""); // program name
- args.push_back(cpu.c_str());
-
- std::string mattr("-mattr=");
- if(gotCpuFeatures){
- for(StringMap<bool>::iterator I = Features.begin(),
- E = Features.end(); I != E; ++I){
- if(I->second){
- std::string attr(I->first());
- mattr+="+"+attr+",";
- }
- }
- args.push_back(mattr.c_str());
- }
-
- args.push_back(0); // terminator
- cl::ParseCommandLineOptions(args.size() - 1, (char **) &args[0]);
-
- // Create the JIT
- std::string ErrorMsg;
-
- EngineBuilder builder(_normal_context->module());
- builder.setMCPU(MCPU);
- builder.setMAttrs(MAttrs);
- builder.setJITMemoryManager(memory_manager());
- builder.setEngineKind(EngineKind::JIT);
- builder.setErrorStr(&ErrorMsg);
- if (! fnmatch(SharkOptimizationLevel, "None", 0)) {
- tty->print_cr("Shark optimization level set to: None");
- builder.setOptLevel(llvm::CodeGenOpt::None);
- } else if (! fnmatch(SharkOptimizationLevel, "Less", 0)) {
- tty->print_cr("Shark optimization level set to: Less");
- builder.setOptLevel(llvm::CodeGenOpt::Less);
- } else if (! fnmatch(SharkOptimizationLevel, "Aggressive", 0)) {
- tty->print_cr("Shark optimization level set to: Aggressive");
- builder.setOptLevel(llvm::CodeGenOpt::Aggressive);
- } // else Default is selected by, well, default :-)
- _execution_engine = builder.create();
-
- if (!execution_engine()) {
- if (!ErrorMsg.empty())
- printf("Error while creating Shark JIT: %s\n",ErrorMsg.c_str());
- else
- printf("Unknown error while creating Shark JIT\n");
- exit(1);
- }
-
- execution_engine()->addModule(_native_context->module());
-
- // All done
- set_state(initialized);
-}
-
-void SharkCompiler::initialize() {
- ShouldNotCallThis();
-}
-
-void SharkCompiler::compile_method(ciEnv* env,
- ciMethod* target,
- int entry_bci,
- DirectiveSet* directive) {
- assert(is_initialized(), "should be");
- ResourceMark rm;
- const char *name = methodname(
- target->holder()->name()->as_utf8(), target->name()->as_utf8());
-
- // Do the typeflow analysis
- ciTypeFlow *flow;
- if (entry_bci == InvocationEntryBci)
- flow = target->get_flow_analysis();
- else
- flow = target->get_osr_flow_analysis(entry_bci);
- if (flow->failing())
- return;
- if (SharkPrintTypeflowOf != NULL) {
- if (!fnmatch(SharkPrintTypeflowOf, name, 0))
- flow->print_on(tty);
- }
-
- // Create the recorders
- Arena arena;
- env->set_oop_recorder(new OopRecorder(&arena));
- OopMapSet oopmaps;
- env->set_debug_info(new DebugInformationRecorder(env->oop_recorder()));
- env->debug_info()->set_oopmaps(&oopmaps);
- env->set_dependencies(new Dependencies(env));
-
- // Create the code buffer and builder
- CodeBuffer hscb("Shark", 256 * K, 64 * K);
- hscb.initialize_oop_recorder(env->oop_recorder());
- MacroAssembler *masm = new MacroAssembler(&hscb);
- SharkCodeBuffer cb(masm);
- SharkBuilder builder(&cb);
-
- // Emit the entry point
- SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry));
-
- // Build the LLVM IR for the method
- Function *function = SharkFunction::build(env, &builder, flow, name);
- if (env->failing()) {
- return;
- }
-
- // Generate native code. It's unpleasant that we have to drop into
- // the VM to do this -- it blocks safepoints -- but I can't see any
- // other way to handle the locking.
- {
- ThreadInVMfromNative tiv(JavaThread::current());
- generate_native_code(entry, function, name);
- }
-
- // Install the method into the VM
- CodeOffsets offsets;
- offsets.set_value(CodeOffsets::Deopt, 0);
- offsets.set_value(CodeOffsets::Exceptions, 0);
- offsets.set_value(CodeOffsets::Verified_Entry,
- target->is_static() ? 0 : wordSize);
-
- ExceptionHandlerTable handler_table;
- ImplicitExceptionTable inc_table;
-
- env->register_method(target,
- entry_bci,
- &offsets,
- 0,
- &hscb,
- 0,
- &oopmaps,
- &handler_table,
- &inc_table,
- this,
- false,
- directive(),
- false);
-}
-
-nmethod* SharkCompiler::generate_native_wrapper(MacroAssembler* masm,
- const methodHandle& target,
- int compile_id,
- BasicType* arg_types,
- BasicType return_type) {
- assert(is_initialized(), "should be");
- ResourceMark rm;
- const char *name = methodname(
- target->klass_name()->as_utf8(), target->name()->as_utf8());
-
- // Create the code buffer and builder
- SharkCodeBuffer cb(masm);
- SharkBuilder builder(&cb);
-
- // Emit the entry point
- SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry));
-
- // Build the LLVM IR for the method
- SharkNativeWrapper *wrapper = SharkNativeWrapper::build(
- &builder, target, name, arg_types, return_type);
-
- // Generate native code
- generate_native_code(entry, wrapper->function(), name);
-
- // Return the nmethod for installation in the VM
- return nmethod::new_native_nmethod(target,
- compile_id,
- masm->code(),
- 0,
- 0,
- wrapper->frame_size(),
- wrapper->receiver_offset(),
- wrapper->lock_offset(),
- wrapper->oop_maps());
-}
-
-void SharkCompiler::generate_native_code(SharkEntry* entry,
- Function* function,
- const char* name) {
- // Print the LLVM bitcode, if requested
- if (SharkPrintBitcodeOf != NULL) {
- if (!fnmatch(SharkPrintBitcodeOf, name, 0))
- function->dump();
- }
-
- if (SharkVerifyFunction != NULL) {
- if (!fnmatch(SharkVerifyFunction, name, 0)) {
- verifyFunction(*function);
- }
- }
-
- // Compile to native code
- address code = NULL;
- context()->add_function(function);
- {
- MutexLocker locker(execution_engine_lock());
- free_queued_methods();
-
-#ifndef NDEBUG
-#if SHARK_LLVM_VERSION <= 31
-#define setCurrentDebugType SetCurrentDebugType
-#endif
- if (SharkPrintAsmOf != NULL) {
- if (!fnmatch(SharkPrintAsmOf, name, 0)) {
- llvm::setCurrentDebugType(X86_ONLY("x86-emitter") NOT_X86("jit"));
- llvm::DebugFlag = true;
- }
- else {
- llvm::setCurrentDebugType("");
- llvm::DebugFlag = false;
- }
- }
-#ifdef setCurrentDebugType
-#undef setCurrentDebugType
-#endif
-#endif // !NDEBUG
- memory_manager()->set_entry_for_function(function, entry);
- code = (address) execution_engine()->getPointerToFunction(function);
- }
- assert(code != NULL, "code must be != NULL");
- entry->set_entry_point(code);
- entry->set_function(function);
- entry->set_context(context());
- address code_start = entry->code_start();
- address code_limit = entry->code_limit();
-
- // Register generated code for profiling, etc
- if (JvmtiExport::should_post_dynamic_code_generated())
- JvmtiExport::post_dynamic_code_generated(name, code_start, code_limit);
-
- // Print debug information, if requested
- if (SharkTraceInstalls) {
- tty->print_cr(
- " [%p-%p): %s (%d bytes code)",
- code_start, code_limit, name, code_limit - code_start);
- }
-}
-
-void SharkCompiler::free_compiled_method(address code) {
- // This method may only be called when the VM is at a safepoint.
- // All _thread_in_vm threads will be waiting for the safepoint to
- // finish with the exception of the VM thread, so we can consider
- // ourself the owner of the execution engine lock even though we
- // can't actually acquire it at this time.
- assert(Thread::current()->is_Compiler_thread(), "must be called by compiler thread");
- assert_locked_or_safepoint(CodeCache_lock);
-
- SharkEntry *entry = (SharkEntry *) code;
- entry->context()->push_to_free_queue(entry->function());
-}
-
-void SharkCompiler::free_queued_methods() {
- // The free queue is protected by the execution engine lock
- assert(execution_engine_lock()->owned_by_self(), "should be");
-
- while (true) {
- Function *function = context()->pop_from_free_queue();
- if (function == NULL)
- break;
-
- execution_engine()->freeMachineCodeForFunction(function);
- function->eraseFromParent();
- }
-}
-
-const char* SharkCompiler::methodname(const char* klass, const char* method) {
- char *buf = NEW_RESOURCE_ARRAY(char, strlen(klass) + 2 + strlen(method) + 1);
-
- char *dst = buf;
- for (const char *c = klass; *c; c++) {
- if (*c == '/')
- *(dst++) = '.';
- else
- *(dst++) = *c;
- }
- *(dst++) = ':';
- *(dst++) = ':';
- for (const char *c = method; *c; c++) {
- *(dst++) = *c;
- }
- *(dst++) = '\0';
- return buf;
-}
-
-void SharkCompiler::print_timers() {
- // do nothing
-}
--- a/src/hotspot/share/shark/sharkCompiler.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010, 2011 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKCOMPILER_HPP
-#define SHARE_VM_SHARK_SHARKCOMPILER_HPP
-
-#include "ci/ciEnv.hpp"
-#include "ci/ciMethod.hpp"
-#include "compiler/abstractCompiler.hpp"
-#include "compiler/compileBroker.hpp"
-#include "compiler/compilerDirectives.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkMemoryManager.hpp"
-
-class SharkContext;
-
-class SharkCompiler : public AbstractCompiler {
- public:
- // Creation
- SharkCompiler();
-
- // Name of this compiler
- const char *name() { return "shark"; }
-
- // Missing feature tests
- bool supports_native() { return true; }
- bool supports_osr() { return true; }
- bool can_compile_method(const methodHandle& method) {
- return ! (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form());
- }
-
- // Initialization
- void initialize();
-
- // Compile a normal (bytecode) method and install it in the VM
- void compile_method(ciEnv* env, ciMethod* target, int entry_bci, DirectiveSet* dirset);
-
- // Print compilation timers and statistics
- void print_timers();
-
- // Generate a wrapper for a native (JNI) method
- nmethod* generate_native_wrapper(MacroAssembler* masm,
- const methodHandle& target,
- int compile_id,
- BasicType* arg_types,
- BasicType return_type);
-
- // Free compiled methods (and native wrappers)
- void free_compiled_method(address code);
-
- // Each thread generating IR needs its own context. The normal
- // context is used for bytecode methods, and is protected from
- // multiple simultaneous accesses by being restricted to the
- // compiler thread. The native context is used for JNI methods,
- // and is protected from multiple simultaneous accesses by the
- // adapter handler library lock.
- private:
- SharkContext* _normal_context;
- SharkContext* _native_context;
-
- public:
- SharkContext* context() const {
- if (JavaThread::current()->is_Compiler_thread()) {
- return _normal_context;
- }
- else {
- assert(AdapterHandlerLibrary_lock->owned_by_self(), "should be");
- return _native_context;
- }
- }
-
- // The LLVM execution engine is the JIT we use to generate native
- // code. It is thread safe, but we need to protect it with a lock
- // of our own because otherwise LLVM's lock and HotSpot's locks
- // interleave and deadlock. The SharkMemoryManager is not thread
- // safe, and is protected by the same lock as the execution engine.
- private:
- Monitor* _execution_engine_lock;
- SharkMemoryManager* _memory_manager;
- llvm::ExecutionEngine* _execution_engine;
-
- private:
- Monitor* execution_engine_lock() const {
- return _execution_engine_lock;
- }
- SharkMemoryManager* memory_manager() const {
- assert(execution_engine_lock()->owned_by_self(), "should be");
- return _memory_manager;
- }
- llvm::ExecutionEngine* execution_engine() const {
- assert(execution_engine_lock()->owned_by_self(), "should be");
- return _execution_engine;
- }
-
- // Global access
- public:
- static SharkCompiler* compiler() {
- AbstractCompiler *compiler =
- CompileBroker::compiler(CompLevel_full_optimization);
- assert(compiler->is_shark() && compiler->is_initialized(), "should be");
- return (SharkCompiler *) compiler;
- }
-
- // Helpers
- private:
- static const char* methodname(const char* klass, const char* method);
- void generate_native_code(SharkEntry* entry,
- llvm::Function* function,
- const char* name);
- void free_queued_methods();
-};
-
-#endif // SHARE_VM_SHARK_SHARKCOMPILER_HPP
--- a/src/hotspot/share/shark/sharkConstant.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,134 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
- * 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 "ci/ciInstance.hpp"
-#include "ci/ciStreams.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkConstant.hpp"
-#include "shark/sharkValue.hpp"
-
-using namespace llvm;
-
-SharkConstant* SharkConstant::for_ldc(ciBytecodeStream *iter) {
- ciConstant constant = iter->get_constant();
- ciType *type = NULL;
- if (constant.basic_type() == T_OBJECT) {
- ciEnv *env = ciEnv::current();
-
- assert(constant.as_object()->klass() == env->String_klass()
- || constant.as_object()->klass() == env->Class_klass()
- || constant.as_object()->klass()->is_subtype_of(env->MethodType_klass())
- || constant.as_object()->klass()->is_subtype_of(env->MethodHandle_klass()), "should be");
-
- type = constant.as_object()->klass();
- }
- return new SharkConstant(constant, type);
-}
-
-SharkConstant* SharkConstant::for_field(ciBytecodeStream *iter) {
- bool will_link;
- ciField *field = iter->get_field(will_link);
- assert(will_link, "typeflow responsibility");
-
- return new SharkConstant(field->constant_value(), field->type());
-}
-
-SharkConstant::SharkConstant(ciConstant constant, ciType *type) {
- SharkValue *value = NULL;
-
- switch (constant.basic_type()) {
- case T_BOOLEAN:
- case T_BYTE:
- case T_CHAR:
- case T_SHORT:
- case T_INT:
- value = SharkValue::jint_constant(constant.as_int());
- break;
-
- case T_LONG:
- value = SharkValue::jlong_constant(constant.as_long());
- break;
-
- case T_FLOAT:
- value = SharkValue::jfloat_constant(constant.as_float());
- break;
-
- case T_DOUBLE:
- value = SharkValue::jdouble_constant(constant.as_double());
- break;
-
- case T_OBJECT:
- case T_ARRAY:
- break;
-
- case T_ILLEGAL:
- // out of memory
- _is_loaded = false;
- return;
-
- default:
- tty->print_cr("Unhandled type %s", type2name(constant.basic_type()));
- ShouldNotReachHere();
- }
-
- // Handle primitive types. We create SharkValues for these
- // now; doing so doesn't emit any code, and it allows us to
- // delegate a bunch of stuff to the SharkValue code.
- if (value) {
- _value = value;
- _is_loaded = true;
- _is_nonzero = value->zero_checked();
- _is_two_word = value->is_two_word();
- return;
- }
-
- // Handle reference types. This is tricky because some
- // ciObjects are psuedo-objects that refer to oops which
- // have yet to be created. We need to spot the unloaded
- // objects (which differ between ldc* and get*, thanks!)
- ciObject *object = constant.as_object();
- assert(type != NULL, "shouldn't be");
-
- if ((! object->is_null_object()) && object->klass() == ciEnv::current()->Class_klass()) {
- ciKlass *klass = object->klass();
- if (! klass->is_loaded()) {
- _is_loaded = false;
- return;
- }
- }
-
- if (object->is_null_object() || ! object->can_be_constant() || ! object->is_loaded()) {
- _is_loaded = false;
- return;
- }
-
- _value = NULL;
- _object = object;
- _type = type;
- _is_loaded = true;
- _is_nonzero = true;
- _is_two_word = false;
-}
--- a/src/hotspot/share/shark/sharkConstant.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKCONSTANT_HPP
-#define SHARE_VM_SHARK_SHARKCONSTANT_HPP
-
-#include "ci/ciStreams.hpp"
-#include "memory/allocation.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkValue.hpp"
-
-class SharkConstant : public ResourceObj {
- public:
- static SharkConstant* for_ldc(ciBytecodeStream* iter);
- static SharkConstant* for_field(ciBytecodeStream* iter);
-
- private:
- SharkConstant(ciConstant constant, ciType* type);
-
- private:
- SharkValue* _value;
- ciObject* _object;
- ciType* _type;
- bool _is_loaded;
- bool _is_nonzero;
- bool _is_two_word;
-
- public:
- bool is_loaded() const {
- return _is_loaded;
- }
- bool is_nonzero() const {
- assert(is_loaded(), "should be");
- return _is_nonzero;
- }
- bool is_two_word() const {
- assert(is_loaded(), "should be");
- return _is_two_word;
- }
-
- public:
- SharkValue* value(SharkBuilder* builder) {
- assert(is_loaded(), "should be");
- if (_value == NULL) {
- _value = SharkValue::create_generic(
- _type, builder->CreateInlineOop(_object), _is_nonzero);
- }
- return _value;
- }
-};
-
-#endif // SHARE_VM_SHARK_SHARKCONSTANT_HPP
--- a/src/hotspot/share/shark/sharkContext.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,188 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009, 2010 Red Hat, Inc.
- * 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 "oops/arrayOop.hpp"
-#include "oops/oop.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkContext.hpp"
-#include "utilities/globalDefinitions.hpp"
-#include "memory/allocation.hpp"
-
-using namespace llvm;
-
-SharkContext::SharkContext(const char* name)
- : LLVMContext(),
- _free_queue(NULL) {
- // Create a module to build our functions into
- _module = new Module(name, *this);
-
- // Create basic types
- _void_type = Type::getVoidTy(*this);
- _bit_type = Type::getInt1Ty(*this);
- _jbyte_type = Type::getInt8Ty(*this);
- _jshort_type = Type::getInt16Ty(*this);
- _jint_type = Type::getInt32Ty(*this);
- _jlong_type = Type::getInt64Ty(*this);
- _jfloat_type = Type::getFloatTy(*this);
- _jdouble_type = Type::getDoubleTy(*this);
-
- // Create compound types
- _itableOffsetEntry_type = PointerType::getUnqual(
- ArrayType::get(jbyte_type(), itableOffsetEntry::size() * wordSize));
-
- _Metadata_type = PointerType::getUnqual(
- ArrayType::get(jbyte_type(), sizeof(Metadata)));
-
- _klass_type = PointerType::getUnqual(
- ArrayType::get(jbyte_type(), sizeof(Klass)));
-
- _jniEnv_type = PointerType::getUnqual(
- ArrayType::get(jbyte_type(), sizeof(JNIEnv)));
-
- _jniHandleBlock_type = PointerType::getUnqual(
- ArrayType::get(jbyte_type(), sizeof(JNIHandleBlock)));
-
- _Method_type = PointerType::getUnqual(
- ArrayType::get(jbyte_type(), sizeof(Method)));
-
- _monitor_type = ArrayType::get(
- jbyte_type(), frame::interpreter_frame_monitor_size() * wordSize);
-
- _oop_type = PointerType::getUnqual(
- ArrayType::get(jbyte_type(), sizeof(oopDesc)));
-
- _thread_type = PointerType::getUnqual(
- ArrayType::get(jbyte_type(), sizeof(JavaThread)));
-
- _zeroStack_type = PointerType::getUnqual(
- ArrayType::get(jbyte_type(), sizeof(ZeroStack)));
-
- std::vector<Type*> params;
- params.push_back(Method_type());
- params.push_back(intptr_type());
- params.push_back(thread_type());
- _entry_point_type = FunctionType::get(jint_type(), params, false);
-
- params.clear();
- params.push_back(Method_type());
- params.push_back(PointerType::getUnqual(jbyte_type()));
- params.push_back(intptr_type());
- params.push_back(thread_type());
- _osr_entry_point_type = FunctionType::get(jint_type(), params, false);
-
- // Create mappings
- for (int i = 0; i < T_CONFLICT; i++) {
- switch (i) {
- case T_BOOLEAN:
- _to_stackType[i] = jint_type();
- _to_arrayType[i] = jbyte_type();
- break;
-
- case T_BYTE:
- _to_stackType[i] = jint_type();
- _to_arrayType[i] = jbyte_type();
- break;
-
- case T_CHAR:
- _to_stackType[i] = jint_type();
- _to_arrayType[i] = jshort_type();
- break;
-
- case T_SHORT:
- _to_stackType[i] = jint_type();
- _to_arrayType[i] = jshort_type();
- break;
-
- case T_INT:
- _to_stackType[i] = jint_type();
- _to_arrayType[i] = jint_type();
- break;
-
- case T_LONG:
- _to_stackType[i] = jlong_type();
- _to_arrayType[i] = jlong_type();
- break;
-
- case T_FLOAT:
- _to_stackType[i] = jfloat_type();
- _to_arrayType[i] = jfloat_type();
- break;
-
- case T_DOUBLE:
- _to_stackType[i] = jdouble_type();
- _to_arrayType[i] = jdouble_type();
- break;
-
- case T_OBJECT:
- case T_ARRAY:
- _to_stackType[i] = oop_type();
- _to_arrayType[i] = oop_type();
- break;
-
- case T_ADDRESS:
- _to_stackType[i] = intptr_type();
- _to_arrayType[i] = NULL;
- break;
-
- default:
- _to_stackType[i] = NULL;
- _to_arrayType[i] = NULL;
- }
- }
-}
-
-class SharkFreeQueueItem : public CHeapObj<mtNone> {
- public:
- SharkFreeQueueItem(llvm::Function* function, SharkFreeQueueItem *next)
- : _function(function), _next(next) {}
-
- private:
- llvm::Function* _function;
- SharkFreeQueueItem* _next;
-
- public:
- llvm::Function* function() const {
- return _function;
- }
- SharkFreeQueueItem* next() const {
- return _next;
- }
-};
-
-void SharkContext::push_to_free_queue(Function* function) {
- _free_queue = new SharkFreeQueueItem(function, _free_queue);
-}
-
-Function* SharkContext::pop_from_free_queue() {
- if (_free_queue == NULL)
- return NULL;
-
- SharkFreeQueueItem *item = _free_queue;
- Function *function = item->function();
- _free_queue = item->next();
- delete item;
- return function;
-}
--- a/src/hotspot/share/shark/sharkContext.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009, 2010 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKCONTEXT_HPP
-#define SHARE_VM_SHARK_SHARKCONTEXT_HPP
-
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkCompiler.hpp"
-
-// The LLVMContext class allows multiple instances of LLVM to operate
-// independently of each other in a multithreaded context. We extend
-// this here to store things in Shark that are LLVMContext-specific.
-
-class SharkFreeQueueItem;
-
-class SharkContext : public llvm::LLVMContext {
- public:
- SharkContext(const char* name);
-
- private:
- llvm::Module* _module;
-
- public:
- llvm::Module* module() const {
- return _module;
- }
-
- // Get this thread's SharkContext
- public:
- static SharkContext& current() {
- return *SharkCompiler::compiler()->context();
- }
-
- // Module accessors
- public:
- void add_function(llvm::Function* function) const {
- module()->getFunctionList().push_back(function);
- }
- llvm::Constant* get_external(const char* name,
- llvm::FunctionType* sig) {
- return module()->getOrInsertFunction(name, sig);
- }
-
- // Basic types
- private:
- llvm::Type* _void_type;
- llvm::IntegerType* _bit_type;
- llvm::IntegerType* _jbyte_type;
- llvm::IntegerType* _jshort_type;
- llvm::IntegerType* _jint_type;
- llvm::IntegerType* _jlong_type;
- llvm::Type* _jfloat_type;
- llvm::Type* _jdouble_type;
-
- public:
- llvm::Type* void_type() const {
- return _void_type;
- }
- llvm::IntegerType* bit_type() const {
- return _bit_type;
- }
- llvm::IntegerType* jbyte_type() const {
- return _jbyte_type;
- }
- llvm::IntegerType* jshort_type() const {
- return _jshort_type;
- }
- llvm::IntegerType* jint_type() const {
- return _jint_type;
- }
- llvm::IntegerType* jlong_type() const {
- return _jlong_type;
- }
- llvm::Type* jfloat_type() const {
- return _jfloat_type;
- }
- llvm::Type* jdouble_type() const {
- return _jdouble_type;
- }
- llvm::IntegerType* intptr_type() const {
- return LP64_ONLY(jlong_type()) NOT_LP64(jint_type());
- }
-
- // Compound types
- private:
- llvm::PointerType* _itableOffsetEntry_type;
- llvm::PointerType* _jniEnv_type;
- llvm::PointerType* _jniHandleBlock_type;
- llvm::PointerType* _Metadata_type;
- llvm::PointerType* _klass_type;
- llvm::PointerType* _Method_type;
- llvm::ArrayType* _monitor_type;
- llvm::PointerType* _oop_type;
- llvm::PointerType* _thread_type;
- llvm::PointerType* _zeroStack_type;
- llvm::FunctionType* _entry_point_type;
- llvm::FunctionType* _osr_entry_point_type;
-
- public:
- llvm::PointerType* itableOffsetEntry_type() const {
- return _itableOffsetEntry_type;
- }
- llvm::PointerType* jniEnv_type() const {
- return _jniEnv_type;
- }
- llvm::PointerType* jniHandleBlock_type() const {
- return _jniHandleBlock_type;
- }
- llvm::PointerType* Metadata_type() const {
- return _Metadata_type;
- }
- llvm::PointerType* klass_type() const {
- return _klass_type;
- }
- llvm::PointerType* Method_type() const {
- return _Method_type;
- }
- llvm::ArrayType* monitor_type() const {
- return _monitor_type;
- }
- llvm::PointerType* oop_type() const {
- return _oop_type;
- }
- llvm::PointerType* thread_type() const {
- return _thread_type;
- }
- llvm::PointerType* zeroStack_type() const {
- return _zeroStack_type;
- }
- llvm::FunctionType* entry_point_type() const {
- return _entry_point_type;
- }
- llvm::FunctionType* osr_entry_point_type() const {
- return _osr_entry_point_type;
- }
-
- // Mappings
- private:
- llvm::Type* _to_stackType[T_CONFLICT];
- llvm::Type* _to_arrayType[T_CONFLICT];
-
- private:
- llvm::Type* map_type(llvm::Type* const* table,
- BasicType type) const {
- assert(type >= 0 && type < T_CONFLICT, "unhandled type");
- llvm::Type* result = table[type];
- assert(result != NULL, "unhandled type");
- return result;
- }
-
- public:
- llvm::Type* to_stackType(BasicType type) const {
- return map_type(_to_stackType, type);
- }
- llvm::Type* to_arrayType(BasicType type) const {
- return map_type(_to_arrayType, type);
- }
-
- // Functions queued for freeing
- private:
- SharkFreeQueueItem* _free_queue;
-
- public:
- void push_to_free_queue(llvm::Function* function);
- llvm::Function* pop_from_free_queue();
-};
-
-#endif // SHARE_VM_SHARK_SHARKCONTEXT_HPP
--- a/src/hotspot/share/shark/sharkEntry.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKENTRY_HPP
-#define SHARE_VM_SHARK_SHARKENTRY_HPP
-
-#include "shark/llvmHeaders.hpp"
-
-class SharkContext;
-
-class SharkEntry : public ZeroEntry {
- private:
- address _code_limit;
- SharkContext* _context;
- llvm::Function* _function;
-
- public:
- address code_start() const {
- return entry_point();
- }
- address code_limit() const {
- return _code_limit;
- }
- SharkContext* context() const {
- return _context;
- }
- llvm::Function* function() const {
- return _function;
- }
-
- public:
- void set_code_limit(address code_limit) {
- _code_limit = code_limit;
- }
- void set_context(SharkContext* context) {
- _context = context;
- }
- void set_function(llvm::Function* function) {
- _function = function;
- }
-};
-
-#endif // SHARE_VM_SHARK_SHARKENTRY_HPP
--- a/src/hotspot/share/shark/sharkFunction.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * 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 "ci/ciTypeFlow.hpp"
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/llvmValue.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkEntry.hpp"
-#include "shark/sharkFunction.hpp"
-#include "shark/sharkState.hpp"
-#include "shark/sharkTopLevelBlock.hpp"
-#include "shark/shark_globals.hpp"
-#include "utilities/debug.hpp"
-
-using namespace llvm;
-
-void SharkFunction::initialize(const char *name) {
- // Create the function
- _function = Function::Create(
- entry_point_type(),
- GlobalVariable::InternalLinkage,
- name);
-
- // Get our arguments
- Function::arg_iterator ai = function()->arg_begin();
- Argument *method = ai++;
- method->setName("method");
- Argument *osr_buf = NULL;
- if (is_osr()) {
- osr_buf = ai++;
- osr_buf->setName("osr_buf");
- }
- Argument *base_pc = ai++;
- base_pc->setName("base_pc");
- code_buffer()->set_base_pc(base_pc);
- Argument *thread = ai++;
- thread->setName("thread");
- set_thread(thread);
-
- // Create the list of blocks
- set_block_insertion_point(NULL);
- _blocks = NEW_RESOURCE_ARRAY(SharkTopLevelBlock*, block_count());
- for (int i = 0; i < block_count(); i++) {
- ciTypeFlow::Block *b = flow()->pre_order_at(i);
-
- // Work around a bug in pre_order_at() that does not return
- // the correct pre-ordering. If pre_order_at() were correct
- // this line could simply be:
- // _blocks[i] = new SharkTopLevelBlock(this, b);
- _blocks[b->pre_order()] = new SharkTopLevelBlock(this, b);
- }
-
- // Walk the tree from the start block to determine which
- // blocks are entered and which blocks require phis
- SharkTopLevelBlock *start_block = block(flow()->start_block_num());
- if (is_osr() && start_block->stack_depth_at_entry() != 0) {
- env()->record_method_not_compilable("can't compile OSR block with incoming stack-depth > 0");
- return;
- }
- assert(start_block->start() == flow()->start_bci(), "blocks out of order");
- start_block->enter();
-
- // Initialize all entered blocks
- for (int i = 0; i < block_count(); i++) {
- if (block(i)->entered())
- block(i)->initialize();
- }
-
- // Create and push our stack frame
- set_block_insertion_point(&function()->front());
- builder()->SetInsertPoint(CreateBlock());
- _stack = SharkStack::CreateBuildAndPushFrame(this, method);
-
- // Create the entry state
- SharkState *entry_state;
- if (is_osr()) {
- entry_state = new SharkOSREntryState(start_block, method, osr_buf);
-
- // Free the OSR buffer
- builder()->CreateCall(builder()->osr_migration_end(), osr_buf);
- }
- else {
- entry_state = new SharkNormalEntryState(start_block, method);
-
- // Lock if necessary
- if (is_synchronized()) {
- SharkTopLevelBlock *locker =
- new SharkTopLevelBlock(this, start_block->ciblock());
- locker->add_incoming(entry_state);
-
- set_block_insertion_point(start_block->entry_block());
- locker->acquire_method_lock();
-
- entry_state = locker->current_state();
- }
- }
-
- // Transition into the method proper
- start_block->add_incoming(entry_state);
- builder()->CreateBr(start_block->entry_block());
-
- // Parse the blocks
- for (int i = 0; i < block_count(); i++) {
- if (!block(i)->entered())
- continue;
-
- if (i + 1 < block_count())
- set_block_insertion_point(block(i + 1)->entry_block());
- else
- set_block_insertion_point(NULL);
-
- block(i)->emit_IR();
- }
- do_deferred_zero_checks();
-}
-
-class DeferredZeroCheck : public SharkTargetInvariants {
- public:
- DeferredZeroCheck(SharkTopLevelBlock* block, SharkValue* value)
- : SharkTargetInvariants(block),
- _block(block),
- _value(value),
- _bci(block->bci()),
- _state(block->current_state()->copy()),
- _check_block(builder()->GetInsertBlock()),
- _continue_block(function()->CreateBlock("not_zero")) {
- builder()->SetInsertPoint(continue_block());
- }
-
- private:
- SharkTopLevelBlock* _block;
- SharkValue* _value;
- int _bci;
- SharkState* _state;
- BasicBlock* _check_block;
- BasicBlock* _continue_block;
-
- public:
- SharkTopLevelBlock* block() const {
- return _block;
- }
- SharkValue* value() const {
- return _value;
- }
- int bci() const {
- return _bci;
- }
- SharkState* state() const {
- return _state;
- }
- BasicBlock* check_block() const {
- return _check_block;
- }
- BasicBlock* continue_block() const {
- return _continue_block;
- }
-
- public:
- SharkFunction* function() const {
- return block()->function();
- }
-
- public:
- void process() const {
- builder()->SetInsertPoint(check_block());
- block()->do_deferred_zero_check(value(), bci(), state(), continue_block());
- }
-};
-
-void SharkFunction::add_deferred_zero_check(SharkTopLevelBlock* block,
- SharkValue* value) {
- deferred_zero_checks()->append(new DeferredZeroCheck(block, value));
-}
-
-void SharkFunction::do_deferred_zero_checks() {
- for (int i = 0; i < deferred_zero_checks()->length(); i++)
- deferred_zero_checks()->at(i)->process();
-}
--- a/src/hotspot/share/shark/sharkFunction.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKFUNCTION_HPP
-#define SHARE_VM_SHARK_SHARKFUNCTION_HPP
-
-#include "ci/ciEnv.hpp"
-#include "ci/ciStreams.hpp"
-#include "ci/ciTypeFlow.hpp"
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/llvmValue.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkContext.hpp"
-#include "shark/sharkInvariants.hpp"
-#include "shark/sharkStack.hpp"
-
-class SharkTopLevelBlock;
-class DeferredZeroCheck;
-
-class SharkFunction : public SharkTargetInvariants {
- friend class SharkStackWithNormalFrame;
-
- public:
- static llvm::Function* build(ciEnv* env,
- SharkBuilder* builder,
- ciTypeFlow* flow,
- const char* name) {
- SharkFunction function(env, builder, flow, name);
- return function.function();
- }
-
- private:
- SharkFunction(ciEnv* env,
- SharkBuilder* builder,
- ciTypeFlow* flow,
- const char* name)
- : SharkTargetInvariants(env, builder, flow) { initialize(name); }
-
- private:
- void initialize(const char* name);
-
- private:
- llvm::Function* _function;
- SharkTopLevelBlock** _blocks;
- GrowableArray<DeferredZeroCheck*> _deferred_zero_checks;
- SharkStack* _stack;
-
- public:
- llvm::Function* function() const {
- return _function;
- }
- int block_count() const {
- return flow()->block_count();
- }
- SharkTopLevelBlock* block(int i) const {
- assert(i < block_count(), "should be");
- return _blocks[i];
- }
- GrowableArray<DeferredZeroCheck*>* deferred_zero_checks() {
- return &_deferred_zero_checks;
- }
- SharkStack* stack() const {
- return _stack;
- }
-
- // On-stack replacement
- private:
- bool is_osr() const {
- return flow()->is_osr_flow();
- }
- llvm::FunctionType* entry_point_type() const {
- if (is_osr())
- return SharkType::osr_entry_point_type();
- else
- return SharkType::entry_point_type();
- }
-
- // Block management
- private:
- llvm::BasicBlock* _block_insertion_point;
-
- void set_block_insertion_point(llvm::BasicBlock* block_insertion_point) {
- _block_insertion_point = block_insertion_point;
- }
- llvm::BasicBlock* block_insertion_point() const {
- return _block_insertion_point;
- }
-
- public:
- llvm::BasicBlock* CreateBlock(const char* name = "") const {
- return llvm::BasicBlock::Create(
- SharkContext::current(), name, function(), block_insertion_point());
- }
-
- // Deferred zero checks
- public:
- void add_deferred_zero_check(SharkTopLevelBlock* block,
- SharkValue* value);
-
- private:
- void do_deferred_zero_checks();
-};
-
-#endif // SHARE_VM_SHARK_SHARKFUNCTION_HPP
--- a/src/hotspot/share/shark/sharkInliner.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,765 +0,0 @@
-/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
- * 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 "ci/ciField.hpp"
-#include "ci/ciMethod.hpp"
-#include "ci/ciStreams.hpp"
-#include "interpreter/bytecodes.hpp"
-#include "memory/allocation.hpp"
-#include "memory/resourceArea.hpp"
-#include "shark/sharkBlock.hpp"
-#include "shark/sharkConstant.hpp"
-#include "shark/sharkInliner.hpp"
-#include "shark/sharkIntrinsics.hpp"
-#include "shark/sharkState.hpp"
-#include "shark/sharkValue.hpp"
-#include "shark/shark_globals.hpp"
-
-using namespace llvm;
-
-class SharkInlineBlock : public SharkBlock {
- public:
- SharkInlineBlock(ciMethod* target, SharkState* state)
- : SharkBlock(state, target),
- _outer_state(state),
- _entry_state(new SharkState(this)) {
- for (int i = target->max_locals() - 1; i >= 0; i--) {
- SharkValue *value = NULL;
- if (i < target->arg_size())
- value = outer_state()->pop();
- entry_state()->set_local(i, value);
- }
- }
-
- private:
- SharkState* _outer_state;
- SharkState* _entry_state;
-
- private:
- SharkState* outer_state() {
- return _outer_state;
- }
- SharkState* entry_state() {
- return _entry_state;
- }
-
- public:
- void emit_IR() {
- parse_bytecode(0, target()->code_size());
- }
-
- private:
- void do_return(BasicType type) {
- if (type != T_VOID) {
- SharkValue *result = pop_result(type);
- outer_state()->push(result);
- if (result->is_two_word())
- outer_state()->push(NULL);
- }
- }
-};
-
-class SharkInlinerHelper : public StackObj {
- public:
- SharkInlinerHelper(ciMethod* target, SharkState* entry_state)
- : _target(target),
- _entry_state(entry_state),
- _iter(target) {}
-
- private:
- ciBytecodeStream _iter;
- SharkState* _entry_state;
- ciMethod* _target;
-
- public:
- ciBytecodeStream* iter() {
- return &_iter;
- }
- SharkState* entry_state() const {
- return _entry_state;
- }
- ciMethod* target() const {
- return _target;
- }
-
- public:
- Bytecodes::Code bc() {
- return iter()->cur_bc();
- }
- int max_locals() const {
- return target()->max_locals();
- }
- int max_stack() const {
- return target()->max_stack();
- }
-
- // Inlinability check
- public:
- bool is_inlinable();
-
- private:
- void initialize_for_check();
-
- bool do_getstatic() {
- return do_field_access(true, false);
- }
- bool do_getfield() {
- return do_field_access(true, true);
- }
- bool do_putfield() {
- return do_field_access(false, true);
- }
- bool do_field_access(bool is_get, bool is_field);
-
- // Local variables for inlinability check
- private:
- bool* _locals;
-
- public:
- bool* local_addr(int index) const {
- assert(index >= 0 && index < max_locals(), "bad local variable index");
- return &_locals[index];
- }
- bool local(int index) const {
- return *local_addr(index);
- }
- void set_local(int index, bool value) {
- *local_addr(index) = value;
- }
-
- // Expression stack for inlinability check
- private:
- bool* _stack;
- bool* _sp;
-
- public:
- int stack_depth() const {
- return _sp - _stack;
- }
- bool* stack_addr(int slot) const {
- assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
- return &_sp[-(slot + 1)];
- }
- void push(bool value) {
- assert(stack_depth() < max_stack(), "stack overrun");
- *(_sp++) = value;
- }
- bool pop() {
- assert(stack_depth() > 0, "stack underrun");
- return *(--_sp);
- }
-
- // Methods for two-word locals
- public:
- void push_pair_local(int index) {
- push(local(index));
- push(local(index + 1));
- }
- void pop_pair_local(int index) {
- set_local(index + 1, pop());
- set_local(index, pop());
- }
-
- // Code generation
- public:
- void do_inline() {
- (new SharkInlineBlock(target(), entry_state()))->emit_IR();
- }
-};
-
-// Quick checks so we can bail out before doing too much
-bool SharkInliner::may_be_inlinable(ciMethod *target) {
- // We can't inline native methods
- if (target->is_native())
- return false;
-
- // Not much point inlining abstract ones, and in any
- // case we'd need a stack frame to throw the exception
- if (target->is_abstract())
- return false;
-
- // Don't inline anything huge
- if (target->code_size() > SharkMaxInlineSize)
- return false;
-
- // Monitors aren't allowed without a frame to put them in
- if (target->is_synchronized() || target->has_monitor_bytecodes())
- return false;
-
- // We don't do control flow
- if (target->has_exception_handlers() || target->has_jsrs())
- return false;
-
- // Don't try to inline constructors, as they must
- // eventually call Object.<init> which we can't inline.
- // Note that this catches <clinit> too, but why would
- // we be compiling that?
- if (target->is_initializer())
- return false;
-
- // Mustn't inline Object.<init>
- // Should be caught by the above, but just in case...
- if (target->intrinsic_id() == vmIntrinsics::_Object_init)
- return false;
-
- return true;
-}
-
-// Full-on detailed check, for methods that pass the quick checks
-// Inlined methods have no stack frame, so we can't do anything
-// that would require one. This means no safepoints (and hence
-// no loops) and no VM calls. No VM calls means, amongst other
-// things, that no exceptions can be created, which means no null
-// checks or divide-by-zero checks are allowed. The lack of null
-// checks in particular would eliminate practically everything,
-// but we can get around that restriction by relying on the zero-
-// check eliminator to strip the checks. To do that, we need to
-// walk through the method, tracking which values are and are not
-// zero-checked.
-bool SharkInlinerHelper::is_inlinable() {
- ResourceMark rm;
- initialize_for_check();
-
- SharkConstant *sc;
- bool a, b, c, d;
-
- iter()->reset_to_bci(0);
- while (iter()->next() != ciBytecodeStream::EOBC()) {
- switch (bc()) {
- case Bytecodes::_nop:
- break;
-
- case Bytecodes::_aconst_null:
- push(false);
- break;
-
- case Bytecodes::_iconst_0:
- push(false);
- break;
- case Bytecodes::_iconst_m1:
- case Bytecodes::_iconst_1:
- case Bytecodes::_iconst_2:
- case Bytecodes::_iconst_3:
- case Bytecodes::_iconst_4:
- case Bytecodes::_iconst_5:
- push(true);
- break;
-
- case Bytecodes::_lconst_0:
- push(false);
- push(false);
- break;
- case Bytecodes::_lconst_1:
- push(true);
- push(false);
- break;
-
- case Bytecodes::_fconst_0:
- case Bytecodes::_fconst_1:
- case Bytecodes::_fconst_2:
- push(false);
- break;
-
- case Bytecodes::_dconst_0:
- case Bytecodes::_dconst_1:
- push(false);
- push(false);
- break;
-
- case Bytecodes::_bipush:
- push(iter()->get_constant_u1() != 0);
- break;
- case Bytecodes::_sipush:
- push(iter()->get_constant_u2() != 0);
- break;
-
- case Bytecodes::_ldc:
- case Bytecodes::_ldc_w:
- case Bytecodes::_ldc2_w:
- sc = SharkConstant::for_ldc(iter());
- if (!sc->is_loaded())
- return false;
- push(sc->is_nonzero());
- if (sc->is_two_word())
- push(false);
- break;
-
- case Bytecodes::_iload_0:
- case Bytecodes::_fload_0:
- case Bytecodes::_aload_0:
- push(local(0));
- break;
- case Bytecodes::_lload_0:
- case Bytecodes::_dload_0:
- push_pair_local(0);
- break;
-
- case Bytecodes::_iload_1:
- case Bytecodes::_fload_1:
- case Bytecodes::_aload_1:
- push(local(1));
- break;
- case Bytecodes::_lload_1:
- case Bytecodes::_dload_1:
- push_pair_local(1);
- break;
-
- case Bytecodes::_iload_2:
- case Bytecodes::_fload_2:
- case Bytecodes::_aload_2:
- push(local(2));
- break;
- case Bytecodes::_lload_2:
- case Bytecodes::_dload_2:
- push_pair_local(2);
- break;
-
- case Bytecodes::_iload_3:
- case Bytecodes::_fload_3:
- case Bytecodes::_aload_3:
- push(local(3));
- break;
- case Bytecodes::_lload_3:
- case Bytecodes::_dload_3:
- push_pair_local(3);
- break;
-
- case Bytecodes::_iload:
- case Bytecodes::_fload:
- case Bytecodes::_aload:
- push(local(iter()->get_index()));
- break;
- case Bytecodes::_lload:
- case Bytecodes::_dload:
- push_pair_local(iter()->get_index());
- break;
-
- case Bytecodes::_istore_0:
- case Bytecodes::_fstore_0:
- case Bytecodes::_astore_0:
- set_local(0, pop());
- break;
- case Bytecodes::_lstore_0:
- case Bytecodes::_dstore_0:
- pop_pair_local(0);
- break;
-
- case Bytecodes::_istore_1:
- case Bytecodes::_fstore_1:
- case Bytecodes::_astore_1:
- set_local(1, pop());
- break;
- case Bytecodes::_lstore_1:
- case Bytecodes::_dstore_1:
- pop_pair_local(1);
- break;
-
- case Bytecodes::_istore_2:
- case Bytecodes::_fstore_2:
- case Bytecodes::_astore_2:
- set_local(2, pop());
- break;
- case Bytecodes::_lstore_2:
- case Bytecodes::_dstore_2:
- pop_pair_local(2);
- break;
-
- case Bytecodes::_istore_3:
- case Bytecodes::_fstore_3:
- case Bytecodes::_astore_3:
- set_local(3, pop());
- break;
- case Bytecodes::_lstore_3:
- case Bytecodes::_dstore_3:
- pop_pair_local(3);
- break;
-
- case Bytecodes::_istore:
- case Bytecodes::_fstore:
- case Bytecodes::_astore:
- set_local(iter()->get_index(), pop());
- break;
- case Bytecodes::_lstore:
- case Bytecodes::_dstore:
- pop_pair_local(iter()->get_index());
- break;
-
- case Bytecodes::_pop:
- pop();
- break;
- case Bytecodes::_pop2:
- pop();
- pop();
- break;
- case Bytecodes::_swap:
- a = pop();
- b = pop();
- push(a);
- push(b);
- break;
- case Bytecodes::_dup:
- a = pop();
- push(a);
- push(a);
- break;
- case Bytecodes::_dup_x1:
- a = pop();
- b = pop();
- push(a);
- push(b);
- push(a);
- break;
- case Bytecodes::_dup_x2:
- a = pop();
- b = pop();
- c = pop();
- push(a);
- push(c);
- push(b);
- push(a);
- break;
- case Bytecodes::_dup2:
- a = pop();
- b = pop();
- push(b);
- push(a);
- push(b);
- push(a);
- break;
- case Bytecodes::_dup2_x1:
- a = pop();
- b = pop();
- c = pop();
- push(b);
- push(a);
- push(c);
- push(b);
- push(a);
- break;
- case Bytecodes::_dup2_x2:
- a = pop();
- b = pop();
- c = pop();
- d = pop();
- push(b);
- push(a);
- push(d);
- push(c);
- push(b);
- push(a);
- break;
-
- case Bytecodes::_getfield:
- if (!do_getfield())
- return false;
- break;
- case Bytecodes::_getstatic:
- if (!do_getstatic())
- return false;
- break;
- case Bytecodes::_putfield:
- if (!do_putfield())
- return false;
- break;
-
- case Bytecodes::_iadd:
- case Bytecodes::_isub:
- case Bytecodes::_imul:
- case Bytecodes::_iand:
- case Bytecodes::_ixor:
- case Bytecodes::_ishl:
- case Bytecodes::_ishr:
- case Bytecodes::_iushr:
- pop();
- pop();
- push(false);
- break;
- case Bytecodes::_ior:
- a = pop();
- b = pop();
- push(a && b);
- break;
- case Bytecodes::_idiv:
- case Bytecodes::_irem:
- if (!pop())
- return false;
- pop();
- push(false);
- break;
- case Bytecodes::_ineg:
- break;
-
- case Bytecodes::_ladd:
- case Bytecodes::_lsub:
- case Bytecodes::_lmul:
- case Bytecodes::_land:
- case Bytecodes::_lxor:
- pop();
- pop();
- pop();
- pop();
- push(false);
- push(false);
- break;
- case Bytecodes::_lor:
- a = pop();
- b = pop();
- push(a && b);
- break;
- case Bytecodes::_ldiv:
- case Bytecodes::_lrem:
- pop();
- if (!pop())
- return false;
- pop();
- pop();
- push(false);
- push(false);
- break;
- case Bytecodes::_lneg:
- break;
- case Bytecodes::_lshl:
- case Bytecodes::_lshr:
- case Bytecodes::_lushr:
- pop();
- pop();
- pop();
- push(false);
- push(false);
- break;
-
- case Bytecodes::_fadd:
- case Bytecodes::_fsub:
- case Bytecodes::_fmul:
- case Bytecodes::_fdiv:
- case Bytecodes::_frem:
- pop();
- pop();
- push(false);
- break;
- case Bytecodes::_fneg:
- break;
-
- case Bytecodes::_dadd:
- case Bytecodes::_dsub:
- case Bytecodes::_dmul:
- case Bytecodes::_ddiv:
- case Bytecodes::_drem:
- pop();
- pop();
- pop();
- pop();
- push(false);
- push(false);
- break;
- case Bytecodes::_dneg:
- break;
-
- case Bytecodes::_iinc:
- set_local(iter()->get_index(), false);
- break;
-
- case Bytecodes::_lcmp:
- pop();
- pop();
- pop();
- pop();
- push(false);
- break;
-
- case Bytecodes::_fcmpl:
- case Bytecodes::_fcmpg:
- pop();
- pop();
- push(false);
- break;
-
- case Bytecodes::_dcmpl:
- case Bytecodes::_dcmpg:
- pop();
- pop();
- pop();
- pop();
- push(false);
- break;
-
- case Bytecodes::_i2l:
- push(false);
- break;
- case Bytecodes::_i2f:
- pop();
- push(false);
- break;
- case Bytecodes::_i2d:
- pop();
- push(false);
- push(false);
- break;
-
- case Bytecodes::_l2i:
- case Bytecodes::_l2f:
- pop();
- pop();
- push(false);
- break;
- case Bytecodes::_l2d:
- pop();
- pop();
- push(false);
- push(false);
- break;
-
- case Bytecodes::_f2i:
- pop();
- push(false);
- break;
- case Bytecodes::_f2l:
- case Bytecodes::_f2d:
- pop();
- push(false);
- push(false);
- break;
-
- case Bytecodes::_d2i:
- case Bytecodes::_d2f:
- pop();
- pop();
- push(false);
- break;
- case Bytecodes::_d2l:
- pop();
- pop();
- push(false);
- push(false);
- break;
-
- case Bytecodes::_i2b:
- case Bytecodes::_i2c:
- case Bytecodes::_i2s:
- pop();
- push(false);
- break;
-
- case Bytecodes::_return:
- case Bytecodes::_ireturn:
- case Bytecodes::_lreturn:
- case Bytecodes::_freturn:
- case Bytecodes::_dreturn:
- case Bytecodes::_areturn:
- break;
-
- default:
- return false;
- }
- }
-
- return true;
-}
-
-void SharkInlinerHelper::initialize_for_check() {
- _locals = NEW_RESOURCE_ARRAY(bool, max_locals());
- _stack = NEW_RESOURCE_ARRAY(bool, max_stack());
-
- memset(_locals, 0, max_locals() * sizeof(bool));
- for (int i = 0; i < target()->arg_size(); i++) {
- SharkValue *arg = entry_state()->stack(target()->arg_size() - 1 - i);
- if (arg && arg->zero_checked())
- set_local(i, true);
- }
-
- _sp = _stack;
-}
-
-bool SharkInlinerHelper::do_field_access(bool is_get, bool is_field) {
- assert(is_get || is_field, "can't inline putstatic");
-
- // If the holder isn't linked then there isn't a lot we can do
- if (!target()->holder()->is_linked())
- return false;
-
- // Get the field
- bool will_link;
- ciField *field = iter()->get_field(will_link);
- if (!will_link)
- return false;
-
- // If the field is mismatched then an exception needs throwing
- if (is_field == field->is_static())
- return false;
-
- // Pop the value off the stack if necessary
- if (!is_get) {
- pop();
- if (field->type()->is_two_word())
- pop();
- }
-
- // Pop and null-check the receiver if necessary
- if (is_field) {
- if (!pop())
- return false;
- }
-
- // Push the result if necessary
- if (is_get) {
- bool result_pushed = false;
- if (field->is_constant() && field->is_static()) {
- SharkConstant *sc = SharkConstant::for_field(iter());
- if (sc->is_loaded()) {
- push(sc->is_nonzero());
- result_pushed = true;
- }
- }
-
- if (!result_pushed)
- push(false);
-
- if (field->type()->is_two_word())
- push(false);
- }
-
- return true;
-}
-
-bool SharkInliner::attempt_inline(ciMethod *target, SharkState *state) {
- if (!Inline) {
- return false;
- }
-
- if (SharkIntrinsics::is_intrinsic(target)) {
- SharkIntrinsics::inline_intrinsic(target, state);
- return true;
- }
-
- if (may_be_inlinable(target)) {
- SharkInlinerHelper inliner(target, state);
- if (inliner.is_inlinable()) {
- inliner.do_inline();
- return true;
- }
- }
- return false;
-}
--- a/src/hotspot/share/shark/sharkInliner.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKINLINER_HPP
-#define SHARE_VM_SHARK_SHARKINLINER_HPP
-
-#include "ci/ciMethod.hpp"
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkState.hpp"
-
-class SharkInliner : public AllStatic {
- public:
- static bool attempt_inline(ciMethod* target, SharkState* state);
-
- private:
- static bool may_be_inlinable(ciMethod* target);
-};
-
-#endif // SHARE_VM_SHARK_SHARKINLINER_HPP
--- a/src/hotspot/share/shark/sharkIntrinsics.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,275 +0,0 @@
-/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
- * 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 "ci/ciMethod.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkIntrinsics.hpp"
-#include "shark/sharkState.hpp"
-#include "shark/sharkValue.hpp"
-#include "shark/shark_globals.hpp"
-
-using namespace llvm;
-
-bool SharkIntrinsics::is_intrinsic(ciMethod *target) {
- switch (target->intrinsic_id()) {
- case vmIntrinsics::_none:
- return false;
-
- // java.lang.Math
- case vmIntrinsics::_min:
- case vmIntrinsics::_max:
- case vmIntrinsics::_dabs:
- case vmIntrinsics::_dsin:
- case vmIntrinsics::_dcos:
- case vmIntrinsics::_dtan:
- case vmIntrinsics::_datan2:
- case vmIntrinsics::_dsqrt:
- case vmIntrinsics::_dlog:
- case vmIntrinsics::_dlog10:
- case vmIntrinsics::_dpow:
- case vmIntrinsics::_dexp:
- return true;
-
- // java.lang.Object
- case vmIntrinsics::_getClass:
- return true;
-
- // java.lang.System
- case vmIntrinsics::_currentTimeMillis:
- return true;
-
- // java.lang.Thread
- case vmIntrinsics::_currentThread:
- return true;
-
- // Unsafe
- case vmIntrinsics::_compareAndSetInt:
- return true;
-
- default:
- if (SharkPerformanceWarnings) {
- warning(
- "unhandled intrinsic vmIntrinsic::%s",
- vmIntrinsics::name_at(target->intrinsic_id()));
- }
- }
- return false;
-}
-
-void SharkIntrinsics::inline_intrinsic(ciMethod *target, SharkState *state) {
- SharkIntrinsics intrinsic(state, target);
- intrinsic.do_intrinsic();
-}
-
-void SharkIntrinsics::do_intrinsic() {
- switch (target()->intrinsic_id()) {
- // java.lang.Math
- case vmIntrinsics::_min:
- do_Math_minmax(llvm::ICmpInst::ICMP_SLE);
- break;
- case vmIntrinsics::_max:
- do_Math_minmax(llvm::ICmpInst::ICMP_SGE);
- break;
- case vmIntrinsics::_dabs:
- do_Math_1to1(builder()->fabs());
- break;
- case vmIntrinsics::_dsin:
- do_Math_1to1(builder()->sin());
- break;
- case vmIntrinsics::_dcos:
- do_Math_1to1(builder()->cos());
- break;
- case vmIntrinsics::_dtan:
- do_Math_1to1(builder()->tan());
- break;
- case vmIntrinsics::_datan2:
- do_Math_2to1(builder()->atan2());
- break;
- case vmIntrinsics::_dsqrt:
- do_Math_1to1(builder()->sqrt());
- break;
- case vmIntrinsics::_dlog:
- do_Math_1to1(builder()->log());
- break;
- case vmIntrinsics::_dlog10:
- do_Math_1to1(builder()->log10());
- break;
- case vmIntrinsics::_dpow:
- do_Math_2to1(builder()->pow());
- break;
- case vmIntrinsics::_dexp:
- do_Math_1to1(builder()->exp());
- break;
-
- // java.lang.Object
- case vmIntrinsics::_getClass:
- do_Object_getClass();
- break;
-
- // java.lang.System
- case vmIntrinsics::_currentTimeMillis:
- do_System_currentTimeMillis();
- break;
-
- // java.lang.Thread
- case vmIntrinsics::_currentThread:
- do_Thread_currentThread();
- break;
-
- // Unsafe
- case vmIntrinsics::_compareAndSetInt:
- do_Unsafe_compareAndSetInt();
- break;
-
- default:
- ShouldNotReachHere();
- }
-}
-
-void SharkIntrinsics::do_Math_minmax(ICmpInst::Predicate p) {
- // Pop the arguments
- SharkValue *sb = state()->pop();
- SharkValue *sa = state()->pop();
- Value *a = sa->jint_value();
- Value *b = sb->jint_value();
-
- // Perform the test
- BasicBlock *ip = builder()->GetBlockInsertionPoint();
- BasicBlock *return_a = builder()->CreateBlock(ip, "return_a");
- BasicBlock *return_b = builder()->CreateBlock(ip, "return_b");
- BasicBlock *done = builder()->CreateBlock(ip, "done");
-
- builder()->CreateCondBr(builder()->CreateICmp(p, a, b), return_a, return_b);
-
- builder()->SetInsertPoint(return_a);
- builder()->CreateBr(done);
-
- builder()->SetInsertPoint(return_b);
- builder()->CreateBr(done);
-
- builder()->SetInsertPoint(done);
- PHINode *phi = builder()->CreatePHI(a->getType(), 0, "result");
- phi->addIncoming(a, return_a);
- phi->addIncoming(b, return_b);
-
- // Push the result
- state()->push(
- SharkValue::create_jint(
- phi,
- sa->zero_checked() && sb->zero_checked()));
-}
-
-void SharkIntrinsics::do_Math_1to1(Value *function) {
- SharkValue *empty = state()->pop();
- assert(empty == NULL, "should be");
- state()->push(
- SharkValue::create_jdouble(
- builder()->CreateCall(
- function, state()->pop()->jdouble_value())));
- state()->push(NULL);
-}
-
-void SharkIntrinsics::do_Math_2to1(Value *function) {
- SharkValue *empty = state()->pop();
- assert(empty == NULL, "should be");
- Value *y = state()->pop()->jdouble_value();
- empty = state()->pop();
- assert(empty == NULL, "should be");
- Value *x = state()->pop()->jdouble_value();
-
- state()->push(
- SharkValue::create_jdouble(
- builder()->CreateCall2(function, x, y)));
- state()->push(NULL);
-}
-
-void SharkIntrinsics::do_Object_getClass() {
- Value *klass = builder()->CreateValueOfStructEntry(
- state()->pop()->jobject_value(),
- in_ByteSize(oopDesc::klass_offset_in_bytes()),
- SharkType::klass_type(),
- "klass");
-
- state()->push(
- SharkValue::create_jobject(
- builder()->CreateValueOfStructEntry(
- klass,
- Klass::java_mirror_offset(),
- SharkType::oop_type(),
- "java_mirror"),
- true));
-}
-
-void SharkIntrinsics::do_System_currentTimeMillis() {
- state()->push(
- SharkValue::create_jlong(
- builder()->CreateCall(builder()->current_time_millis()),
- false));
- state()->push(NULL);
-}
-
-void SharkIntrinsics::do_Thread_currentThread() {
- state()->push(
- SharkValue::create_jobject(
- builder()->CreateValueOfStructEntry(
- thread(), JavaThread::threadObj_offset(),
- SharkType::oop_type(),
- "threadObj"),
- true));
-}
-
-void SharkIntrinsics::do_Unsafe_compareAndSetInt() {
- // Pop the arguments
- Value *x = state()->pop()->jint_value();
- Value *e = state()->pop()->jint_value();
- SharkValue *empty = state()->pop();
- assert(empty == NULL, "should be");
- Value *offset = state()->pop()->jlong_value();
- Value *object = state()->pop()->jobject_value();
- Value *unsafe = state()->pop()->jobject_value();
-
- // Convert the offset
- offset = builder()->CreateCall(
- builder()->unsafe_field_offset_to_byte_offset(),
- offset);
-
- // Locate the field
- Value *addr = builder()->CreateIntToPtr(
- builder()->CreateAdd(
- builder()->CreatePtrToInt(object, SharkType::intptr_type()),
- builder()->CreateIntCast(offset, SharkType::intptr_type(), true)),
- PointerType::getUnqual(SharkType::jint_type()),
- "addr");
-
- // Perform the operation
- Value *result = builder()->CreateAtomicCmpXchg(addr, e, x, llvm::SequentiallyConsistent);
- // Push the result
- state()->push(
- SharkValue::create_jint(
- builder()->CreateIntCast(
- builder()->CreateICmpEQ(result, e), SharkType::jint_type(), true),
- false));
-}
--- a/src/hotspot/share/shark/sharkIntrinsics.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKINTRINSICS_HPP
-#define SHARE_VM_SHARK_SHARKINTRINSICS_HPP
-
-#include "ci/ciMethod.hpp"
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkState.hpp"
-
-class SharkIntrinsics : public SharkTargetInvariants {
- public:
- static bool is_intrinsic(ciMethod* target);
- static void inline_intrinsic(ciMethod* target, SharkState* state);
-
- private:
- SharkIntrinsics(SharkState* state, ciMethod* target)
- : SharkTargetInvariants(state, target), _state(state) {}
-
- private:
- SharkState* _state;
-
- private:
- SharkState* state() const {
- return _state;
- }
-
- private:
- void do_intrinsic();
-
- private:
- void do_Math_minmax(llvm::ICmpInst::Predicate p);
- void do_Math_1to1(llvm::Value* function);
- void do_Math_2to1(llvm::Value* function);
- void do_Object_getClass();
- void do_System_currentTimeMillis();
- void do_Thread_currentThread();
- void do_Unsafe_compareAndSetInt();
-};
-
-#endif // SHARE_VM_SHARK_SHARKINTRINSICS_HPP
--- a/src/hotspot/share/shark/sharkInvariants.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * 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 "shark/sharkInvariants.hpp"
-
-int SharkTargetInvariants::count_monitors() {
- int result = 0;
- if (is_synchronized() || target()->has_monitor_bytecodes()) {
- for (int i = 0; i < flow()->block_count(); i++) {
- result = MAX2(result, flow()->pre_order_at(i)->monitor_count());
- }
- }
- return result;
-}
--- a/src/hotspot/share/shark/sharkInvariants.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,184 +0,0 @@
-/*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKINVARIANTS_HPP
-#define SHARE_VM_SHARK_SHARKINVARIANTS_HPP
-
-#include "ci/ciEnv.hpp"
-#include "ci/ciInstanceKlass.hpp"
-#include "ci/ciMethod.hpp"
-#include "ci/ciTypeFlow.hpp"
-#include "code/debugInfoRec.hpp"
-#include "code/dependencies.hpp"
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkBuilder.hpp"
-
-// Base classes used to track various values through the compilation.
-// SharkCompileInvariants is used to track values which remain the
-// same for the top-level method and any inlined methods it may have
-// (ie for the whole compilation). SharkTargetInvariants is used to
-// track values which differ between methods.
-
-class SharkCompileInvariants : public ResourceObj {
- protected:
- SharkCompileInvariants(ciEnv* env, SharkBuilder* builder)
- : _env(env),
- _builder(builder),
- _thread(NULL) {}
-
- SharkCompileInvariants(const SharkCompileInvariants* parent)
- : _env(parent->_env),
- _builder(parent->_builder),
- _thread(parent->_thread) {}
-
- private:
- ciEnv* _env;
- SharkBuilder* _builder;
- llvm::Value* _thread;
-
- // Top-level broker for HotSpot's Compiler Interface.
- //
- // Its main purpose is to allow the various CI classes to access
- // oops in the VM without having to worry about safepointing. In
- // addition to this it acts as a holder for various recorders and
- // memory allocators.
- //
- // Accessing this directly is kind of ugly, so it's private. Add
- // new accessors below if you need something from it.
- protected:
- ciEnv* env() const {
- assert(_env != NULL, "env not available");
- return _env;
- }
-
- // The SharkBuilder that is used to build LLVM IR.
- protected:
- SharkBuilder* builder() const {
- return _builder;
- }
-
- // Pointer to this thread's JavaThread object. This is not
- // available until a short way into SharkFunction creation
- // so a setter is required. Assertions are used to enforce
- // invariance.
- protected:
- llvm::Value* thread() const {
- assert(_thread != NULL, "thread not available");
- return _thread;
- }
- void set_thread(llvm::Value* thread) {
- assert(_thread == NULL, "thread already set");
- _thread = thread;
- }
-
- // Objects that handle various aspects of the compilation.
- protected:
- DebugInformationRecorder* debug_info() const {
- return env()->debug_info();
- }
- SharkCodeBuffer* code_buffer() const {
- return builder()->code_buffer();
- }
-
- public:
- Dependencies* dependencies() const {
- return env()->dependencies();
- }
-
- // Commonly used classes
- protected:
- ciInstanceKlass* java_lang_Object_klass() const {
- return env()->Object_klass();
- }
- ciInstanceKlass* java_lang_Throwable_klass() const {
- return env()->Throwable_klass();
- }
-};
-
-class SharkTargetInvariants : public SharkCompileInvariants {
- protected:
- SharkTargetInvariants(ciEnv* env, SharkBuilder* builder, ciTypeFlow* flow)
- : SharkCompileInvariants(env, builder),
- _target(flow->method()),
- _flow(flow),
- _max_monitors(count_monitors()) {}
-
- SharkTargetInvariants(const SharkCompileInvariants* parent, ciMethod* target)
- : SharkCompileInvariants(parent),
- _target(target),
- _flow(NULL),
- _max_monitors(count_monitors()) {}
-
- SharkTargetInvariants(const SharkTargetInvariants* parent)
- : SharkCompileInvariants(parent),
- _target(parent->_target),
- _flow(parent->_flow),
- _max_monitors(parent->_max_monitors) {}
-
- private:
- int count_monitors();
-
- private:
- ciMethod* _target;
- ciTypeFlow* _flow;
- int _max_monitors;
-
- // The method being compiled.
- protected:
- ciMethod* target() const {
- return _target;
- }
-
- // Typeflow analysis of the method being compiled.
- protected:
- ciTypeFlow* flow() const {
- assert(_flow != NULL, "typeflow not available");
- return _flow;
- }
-
- // Properties of the method.
- protected:
- int max_locals() const {
- return target()->max_locals();
- }
- int max_stack() const {
- return target()->max_stack();
- }
- int max_monitors() const {
- return _max_monitors;
- }
- int arg_size() const {
- return target()->arg_size();
- }
- bool is_static() const {
- return target()->is_static();
- }
- bool is_synchronized() const {
- return target()->is_synchronized();
- }
-};
-
-#endif // SHARE_VM_SHARK_SHARKINVARIANTS_HPP
--- a/src/hotspot/share/shark/sharkMemoryManager.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
- * 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 "shark/llvmHeaders.hpp"
-#include "shark/sharkEntry.hpp"
-#include "shark/sharkMemoryManager.hpp"
-
-using namespace llvm;
-
-void SharkMemoryManager::AllocateGOT() {
- mm()->AllocateGOT();
-}
-
-unsigned char* SharkMemoryManager::getGOTBase() const {
- return mm()->getGOTBase();
-}
-
-unsigned char* SharkMemoryManager::allocateStub(const GlobalValue* F,
- unsigned StubSize,
- unsigned Alignment) {
- return mm()->allocateStub(F, StubSize, Alignment);
-}
-
-unsigned char* SharkMemoryManager::startFunctionBody(const Function* F,
- uintptr_t& ActualSize) {
- return mm()->startFunctionBody(F, ActualSize);
-}
-
-void SharkMemoryManager::endFunctionBody(const Function* F,
- unsigned char* FunctionStart,
- unsigned char* FunctionEnd) {
- mm()->endFunctionBody(F, FunctionStart, FunctionEnd);
-
- SharkEntry *entry = get_entry_for_function(F);
- if (entry != NULL)
- entry->set_code_limit(FunctionEnd);
-}
-
-void SharkMemoryManager::setMemoryWritable() {
- mm()->setMemoryWritable();
-}
-
-void SharkMemoryManager::setMemoryExecutable() {
- mm()->setMemoryExecutable();
-}
-
-void SharkMemoryManager::deallocateFunctionBody(void *ptr) {
- mm()->deallocateFunctionBody(ptr);
-}
-
-uint8_t* SharkMemoryManager::allocateGlobal(uintptr_t Size,
- unsigned int Alignment) {
- return mm()->allocateGlobal(Size, Alignment);
-}
-
-void* SharkMemoryManager::getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) {
- return mm()->getPointerToNamedFunction(Name, AbortOnFailure);
-}
-
-void SharkMemoryManager::setPoisonMemory(bool poison) {
- mm()->setPoisonMemory(poison);
-}
-
-unsigned char *SharkMemoryManager::allocateSpace(intptr_t Size,
- unsigned int Alignment) {
- return mm()->allocateSpace(Size, Alignment);
-}
-
-#if SHARK_LLVM_VERSION <= 32
-
-uint8_t* SharkMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) {
- return mm()->allocateCodeSection(Size, Alignment, SectionID);
-}
-
-uint8_t* SharkMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) {
- return mm()->allocateDataSection(Size, Alignment, SectionID);
-}
-
-void SharkMemoryManager::deallocateExceptionTable(void *ptr) {
- mm()->deallocateExceptionTable(ptr);
-}
-
-unsigned char* SharkMemoryManager::startExceptionTable(const Function* F,
- uintptr_t& ActualSize) {
- return mm()->startExceptionTable(F, ActualSize);
-}
-
-void SharkMemoryManager::endExceptionTable(const Function* F,
- unsigned char* TableStart,
- unsigned char* TableEnd,
- unsigned char* FrameRegister) {
- mm()->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
-}
-
-#else
-
-uint8_t *SharkMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName) {
- return mm()->allocateCodeSection(Size, Alignment, SectionID, SectionName);
-}
-
-uint8_t* SharkMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, StringRef SectionName, bool IsReadOnly) {
- return mm()->allocateDataSection(Size, Alignment, SectionID, SectionName, IsReadOnly);
-}
-
-bool SharkMemoryManager::finalizeMemory(std::string *ErrMsg) {
- return mm()->finalizeMemory(ErrMsg);
-}
-
-#endif
--- a/src/hotspot/share/shark/sharkMemoryManager.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKMEMORYMANAGER_HPP
-#define SHARE_VM_SHARK_SHARKMEMORYMANAGER_HPP
-
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkEntry.hpp"
-
-// SharkMemoryManager wraps the LLVM JIT Memory Manager. We could use
-// this to run our own memory allocation policies, but for now all we
-// use it for is figuring out where the resulting native code ended up.
-
-class SharkMemoryManager : public llvm::JITMemoryManager {
- public:
- SharkMemoryManager()
- : _mm(llvm::JITMemoryManager::CreateDefaultMemManager()) {}
-
- private:
- llvm::JITMemoryManager* _mm;
-
- private:
- llvm::JITMemoryManager* mm() const {
- return _mm;
- }
-
- private:
- std::map<const llvm::Function*, SharkEntry*> _entry_map;
-
- public:
- void set_entry_for_function(const llvm::Function* function,
- SharkEntry* entry) {
- _entry_map[function] = entry;
- }
- SharkEntry* get_entry_for_function(const llvm::Function* function) {
- return _entry_map[function];
- }
-
- public:
- void AllocateGOT();
- unsigned char* getGOTBase() const;
- unsigned char* allocateStub(const llvm::GlobalValue* F,
- unsigned StubSize,
- unsigned Alignment);
- unsigned char* startFunctionBody(const llvm::Function* F,
- uintptr_t& ActualSize);
- void endFunctionBody(const llvm::Function* F,
- unsigned char* FunctionStart,
- unsigned char* FunctionEnd);
-
- void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true);
- void setPoisonMemory(bool);
- uint8_t* allocateGlobal(uintptr_t, unsigned int);
- void setMemoryWritable();
- void setMemoryExecutable();
- void deallocateFunctionBody(void *ptr);
- unsigned char *allocateSpace(intptr_t Size,
- unsigned int Alignment);
-
-#if SHARK_LLVM_VERSION <= 32
-uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID);
-uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID);
-unsigned char* startExceptionTable(const llvm::Function* F,
- uintptr_t& ActualSize);
-void deallocateExceptionTable(void *ptr);
-void endExceptionTable(const llvm::Function* F,
- unsigned char* TableStart,
- unsigned char* TableEnd,
- unsigned char* FrameRegister);
-#else
-uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName);
-uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName, bool IsReadOnly);
-bool finalizeMemory(std::string *ErrMsg = 0);
-#endif
-
-};
-
-#endif // SHARE_VM_SHARK_SHARKMEMORYMANAGER_HPP
--- a/src/hotspot/share/shark/sharkNativeWrapper.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,354 +0,0 @@
-/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009, 2010 Red Hat, Inc.
- * 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 "shark/llvmHeaders.hpp"
-#include "shark/sharkNativeWrapper.hpp"
-#include "shark/sharkType.hpp"
-
-using namespace llvm;
-
-void SharkNativeWrapper::initialize(const char *name) {
- // Create the function
- _function = Function::Create(
- SharkType::entry_point_type(),
- GlobalVariable::InternalLinkage,
- name);
-
- // Get our arguments
- Function::arg_iterator ai = function()->arg_begin();
- Argument *method = ai++;
- method->setName("method");
- Argument *base_pc = ai++;
- base_pc->setName("base_pc");
- code_buffer()->set_base_pc(base_pc);
- Argument *thread = ai++;
- thread->setName("thread");
- set_thread(thread);
-
- // Create and push our stack frame
- builder()->SetInsertPoint(CreateBlock());
- _stack = SharkStack::CreateBuildAndPushFrame(this, method);
- NOT_PRODUCT(method = NULL);
-
- // Create the oopmap. We use the one oopmap for every call site in
- // the wrapper, which results in the odd mild inefficiency but is a
- // damn sight easier to code.
- OopMap *oopmap = new OopMap(
- SharkStack::oopmap_slot_munge(stack()->oopmap_frame_size()),
- SharkStack::oopmap_slot_munge(arg_size()));
-
- // Set up the oop_tmp slot if required:
- // - For static methods we use it to handlize the class argument
- // for the call, and to protect the same during slow path locks
- // (if synchronized).
- // - For methods returning oops, we use it to protect the return
- // value across safepoints or slow path unlocking.
- if (is_static() || is_returning_oop()) {
- _oop_tmp_slot = stack()->slot_addr(
- stack()->oop_tmp_slot_offset(),
- SharkType::oop_type(),
- "oop_tmp_slot");
-
- oopmap->set_oop(SharkStack::slot2reg(stack()->oop_tmp_slot_offset()));
- }
-
- // Set up the monitor slot, for synchronized methods
- if (is_synchronized()) {
- Unimplemented();
- _lock_slot_offset = 23;
- }
-
- // Start building the argument list
- std::vector<Type*> param_types;
- std::vector<Value*> param_values;
- PointerType *box_type = PointerType::getUnqual(SharkType::oop_type());
-
- // First argument is the JNIEnv
- param_types.push_back(SharkType::jniEnv_type());
- param_values.push_back(
- builder()->CreateAddressOfStructEntry(
- thread,
- JavaThread::jni_environment_offset(),
- SharkType::jniEnv_type(),
- "jni_environment"));
-
- // For static methods, the second argument is the class
- if (is_static()) {
- builder()->CreateStore(
- builder()->CreateInlineOop(
- JNIHandles::make_local(
- target()->method_holder()->java_mirror())),
- oop_tmp_slot());
-
- param_types.push_back(box_type);
- param_values.push_back(oop_tmp_slot());
-
- _receiver_slot_offset = stack()->oop_tmp_slot_offset();
- }
- else if (is_returning_oop()) {
- // The oop_tmp slot is registered in the oopmap,
- // so we need to clear it. This is one of the
- // mild inefficiencies I mentioned earlier.
- builder()->CreateStore(LLVMValue::null(), oop_tmp_slot());
- }
-
- // Parse the arguments
- for (int i = 0; i < arg_size(); i++) {
- int slot_offset = stack()->locals_slots_offset() + arg_size() - 1 - i;
- int adjusted_offset = slot_offset;
- BasicBlock *null, *not_null, *merge;
- Value *box;
- PHINode *phi;
-
- switch (arg_type(i)) {
- case T_VOID:
- break;
-
- case T_OBJECT:
- case T_ARRAY:
- null = CreateBlock("null");
- not_null = CreateBlock("not_null");
- merge = CreateBlock("merge");
-
- box = stack()->slot_addr(slot_offset, SharkType::oop_type());
- builder()->CreateCondBr(
- builder()->CreateICmp(
- ICmpInst::ICMP_EQ,
- builder()->CreateLoad(box),
- LLVMValue::null()),
- null, not_null);
-
- builder()->SetInsertPoint(null);
- builder()->CreateBr(merge);
-
- builder()->SetInsertPoint(not_null);
- builder()->CreateBr(merge);
-
- builder()->SetInsertPoint(merge);
- phi = builder()->CreatePHI(box_type, 0, "boxed_object");
- phi->addIncoming(ConstantPointerNull::get(box_type), null);
- phi->addIncoming(box, not_null);
- box = phi;
-
- param_types.push_back(box_type);
- param_values.push_back(box);
-
- oopmap->set_oop(SharkStack::slot2reg(slot_offset));
-
- if (i == 0 && !is_static())
- _receiver_slot_offset = slot_offset;
-
- break;
-
- case T_LONG:
- case T_DOUBLE:
- adjusted_offset--;
- // fall through
-
- default:
- Type *param_type = SharkType::to_stackType(arg_type(i));
-
- param_types.push_back(param_type);
- param_values.push_back(
- builder()->CreateLoad(stack()->slot_addr(adjusted_offset, param_type)));
- }
- }
-
- // The oopmap is now complete, and everything is written
- // into the frame except the PC.
- int pc_offset = code_buffer()->create_unique_offset();
-
- _oop_maps = new OopMapSet();
- oop_maps()->add_gc_map(pc_offset, oopmap);
-
- builder()->CreateStore(
- builder()->code_buffer_address(pc_offset),
- stack()->slot_addr(stack()->pc_slot_offset()));
-
- // Set up the Java frame anchor
- stack()->CreateSetLastJavaFrame();
-
- // Lock if necessary
- if (is_synchronized())
- Unimplemented();
-
- // Change the thread state to _thread_in_native
- CreateSetThreadState(_thread_in_native);
-
- // Make the call
- BasicType result_type = target()->result_type();
- Type* return_type;
- if (result_type == T_VOID)
- return_type = SharkType::void_type();
- else if (is_returning_oop())
- return_type = box_type;
- else
- return_type = SharkType::to_arrayType(result_type);
- Value* native_function = builder()->CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) target()->native_function()),
- PointerType::getUnqual(
- FunctionType::get(return_type, param_types, false)));
- Value *result = builder()->CreateCall(
- native_function, llvm::makeArrayRef(param_values));
-
- // Start the transition back to _thread_in_Java
- CreateSetThreadState(_thread_in_native_trans);
-
- // Make sure new state is visible in the GC thread
- if (os::is_MP()) {
- if (UseMembar)
- builder()->CreateFence(llvm::SequentiallyConsistent, llvm::CrossThread);
- else
- CreateWriteMemorySerializePage();
- }
-
- // Handle safepoint operations, pending suspend requests,
- // and pending asynchronous exceptions.
- BasicBlock *check_thread = CreateBlock("check_thread");
- BasicBlock *do_safepoint = CreateBlock("do_safepoint");
- BasicBlock *safepointed = CreateBlock("safepointed");
-
- Value *global_state = builder()->CreateLoad(
- builder()->CreateIntToPtr(
- LLVMValue::intptr_constant(
- (intptr_t) SafepointSynchronize::address_of_state()),
- PointerType::getUnqual(SharkType::jint_type())),
- "global_state");
-
- builder()->CreateCondBr(
- builder()->CreateICmpNE(
- global_state,
- LLVMValue::jint_constant(SafepointSynchronize::_not_synchronized)),
- do_safepoint, check_thread);
-
- builder()->SetInsertPoint(check_thread);
- Value *thread_state = builder()->CreateValueOfStructEntry(
- thread,
- JavaThread::suspend_flags_offset(),
- SharkType::jint_type(),
- "thread_state");
-
- builder()->CreateCondBr(
- builder()->CreateICmpNE(
- thread_state,
- LLVMValue::jint_constant(0)),
- do_safepoint, safepointed);
-
- builder()->SetInsertPoint(do_safepoint);
- builder()->CreateCall(
- builder()->check_special_condition_for_native_trans(), thread);
- builder()->CreateBr(safepointed);
-
- // Finally we can change the thread state to _thread_in_Java
- builder()->SetInsertPoint(safepointed);
- CreateSetThreadState(_thread_in_Java);
-
- // Clear the frame anchor
- stack()->CreateResetLastJavaFrame();
-
- // If there is a pending exception then we can just unwind and
- // return. It seems totally wrong that unlocking is skipped here
- // but apparently the template interpreter does this so we do too.
- BasicBlock *exception = CreateBlock("exception");
- BasicBlock *no_exception = CreateBlock("no_exception");
-
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(
- CreateLoadPendingException(),
- LLVMValue::null()),
- no_exception, exception);
-
- builder()->SetInsertPoint(exception);
- CreateResetHandleBlock();
- stack()->CreatePopFrame(0);
- builder()->CreateRet(LLVMValue::jint_constant(0));
-
- builder()->SetInsertPoint(no_exception);
-
- // If the result was an oop then unbox it before
- // releasing the handle it might be protected by
- if (is_returning_oop()) {
- BasicBlock *null = builder()->GetInsertBlock();
- BasicBlock *not_null = CreateBlock("not_null");
- BasicBlock *merge = CreateBlock("merge");
-
- builder()->CreateCondBr(
- builder()->CreateICmpNE(result, ConstantPointerNull::get(box_type)),
- not_null, merge);
-
- builder()->SetInsertPoint(not_null);
-#error Needs to be updated for tagged jweak; see JNIHandles.
- Value *unboxed_result = builder()->CreateLoad(result);
- builder()->CreateBr(merge);
-
- builder()->SetInsertPoint(merge);
- PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), 0, "result");
- phi->addIncoming(LLVMValue::null(), null);
- phi->addIncoming(unboxed_result, not_null);
- result = phi;
- }
-
- // Reset handle block
- CreateResetHandleBlock();
-
- // Unlock if necessary.
- if (is_synchronized())
- Unimplemented();
-
- // Unwind and return
- Value *result_addr = stack()->CreatePopFrame(type2size[result_type]);
- if (result_type != T_VOID) {
- bool needs_cast = false;
- bool is_signed = false;
- switch (result_type) {
- case T_BOOLEAN:
- result = builder()->CreateICmpNE(result, LLVMValue::jbyte_constant(0));
- needs_cast = true;
- break;
-
- case T_CHAR:
- needs_cast = true;
- break;
-
- case T_BYTE:
- case T_SHORT:
- needs_cast = true;
- is_signed = true;
- break;
- }
- if (needs_cast) {
- result = builder()->CreateIntCast(
- result, SharkType::to_stackType(result_type), is_signed);
- }
-
- builder()->CreateStore(
- result,
- builder()->CreateIntToPtr(
- result_addr,
- PointerType::getUnqual(SharkType::to_stackType(result_type))));
- }
- builder()->CreateRet(LLVMValue::jint_constant(0));
-}
--- a/src/hotspot/share/shark/sharkNativeWrapper.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKNATIVEWRAPPER_HPP
-#define SHARE_VM_SHARK_SHARKNATIVEWRAPPER_HPP
-
-#include "runtime/handles.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkContext.hpp"
-#include "shark/sharkInvariants.hpp"
-#include "shark/sharkStack.hpp"
-
-class SharkNativeWrapper : public SharkCompileInvariants {
- friend class SharkStackWithNativeFrame;
-
- public:
- static SharkNativeWrapper* build(SharkBuilder* builder,
- methodHandle target,
- const char* name,
- BasicType* arg_types,
- BasicType return_type) {
- return new SharkNativeWrapper(builder,
- target,
- name,
- arg_types,
- return_type);
- }
-
- private:
- SharkNativeWrapper(SharkBuilder* builder,
- methodHandle target,
- const char* name,
- BasicType* arg_types,
- BasicType return_type)
- : SharkCompileInvariants(NULL, builder),
- _target(target),
- _arg_types(arg_types),
- _return_type(return_type),
- _lock_slot_offset(0) { initialize(name); }
-
- private:
- void initialize(const char* name);
-
- private:
- methodHandle _target;
- BasicType* _arg_types;
- BasicType _return_type;
- llvm::Function* _function;
- SharkStack* _stack;
- llvm::Value* _oop_tmp_slot;
- OopMapSet* _oop_maps;
- int _receiver_slot_offset;
- int _lock_slot_offset;
-
- // The method being compiled.
- protected:
- methodHandle target() const {
- return _target;
- }
-
- // Properties of the method.
- protected:
- int arg_size() const {
- return target()->size_of_parameters();
- }
- BasicType arg_type(int i) const {
- return _arg_types[i];
- }
- BasicType return_type() const {
- return _return_type;
- }
- bool is_static() const {
- return target()->is_static();
- }
- bool is_synchronized() const {
- return target()->is_synchronized();
- }
- bool is_returning_oop() const {
- return target()->is_returning_oop();
- }
-
- // The LLVM function we are building.
- public:
- llvm::Function* function() const {
- return _function;
- }
-
- // The Zero stack and our frame on it.
- protected:
- SharkStack* stack() const {
- return _stack;
- }
-
- // Temporary oop storage.
- protected:
- llvm::Value* oop_tmp_slot() const {
- assert(is_static() || is_returning_oop(), "should be");
- return _oop_tmp_slot;
- }
-
- // Information required by nmethod::new_native_nmethod().
- public:
- int frame_size() const {
- return stack()->oopmap_frame_size();
- }
- ByteSize receiver_offset() const {
- return in_ByteSize(_receiver_slot_offset * wordSize);
- }
- ByteSize lock_offset() const {
- return in_ByteSize(_lock_slot_offset * wordSize);
- }
- OopMapSet* oop_maps() const {
- return _oop_maps;
- }
-
- // Helpers.
- private:
- llvm::BasicBlock* CreateBlock(const char* name = "") const {
- return llvm::BasicBlock::Create(SharkContext::current(), name, function());
- }
- llvm::Value* thread_state_address() const {
- return builder()->CreateAddressOfStructEntry(
- thread(), JavaThread::thread_state_offset(),
- llvm::PointerType::getUnqual(SharkType::jint_type()),
- "thread_state_address");
- }
- llvm::Value* pending_exception_address() const {
- return builder()->CreateAddressOfStructEntry(
- thread(), Thread::pending_exception_offset(),
- llvm::PointerType::getUnqual(SharkType::oop_type()),
- "pending_exception_address");
- }
- void CreateSetThreadState(JavaThreadState state) const {
- builder()->CreateStore(
- LLVMValue::jint_constant(state), thread_state_address());
- }
- void CreateWriteMemorySerializePage() const {
- builder()->CreateStore(
- LLVMValue::jint_constant(1),
- builder()->CreateIntToPtr(
- builder()->CreateAdd(
- LLVMValue::intptr_constant(
- (intptr_t) os::get_memory_serialize_page()),
- builder()->CreateAnd(
- builder()->CreateLShr(
- builder()->CreatePtrToInt(thread(), SharkType::intptr_type()),
- LLVMValue::intptr_constant(os::get_serialize_page_shift_count())),
- LLVMValue::intptr_constant(os::get_serialize_page_mask()))),
- llvm::PointerType::getUnqual(SharkType::jint_type())));
- }
- void CreateResetHandleBlock() const {
- llvm::Value *active_handles = builder()->CreateValueOfStructEntry(
- thread(),
- JavaThread::active_handles_offset(),
- SharkType::jniHandleBlock_type(),
- "active_handles");
- builder()->CreateStore(
- LLVMValue::intptr_constant(0),
- builder()->CreateAddressOfStructEntry(
- active_handles,
- in_ByteSize(JNIHandleBlock::top_offset_in_bytes()),
- llvm::PointerType::getUnqual(SharkType::intptr_type()),
- "top"));
- }
- llvm::LoadInst* CreateLoadPendingException() const {
- return builder()->CreateLoad(
- pending_exception_address(), "pending_exception");
- }
-};
-
-#endif // SHARE_VM_SHARK_SHARKNATIVEWRAPPER_HPP
--- a/src/hotspot/share/shark/sharkRuntime.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,260 +0,0 @@
-/*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * 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/atomic.hpp"
-#include "runtime/biasedLocking.hpp"
-#include "runtime/deoptimization.hpp"
-#include "runtime/thread.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkRuntime.hpp"
-#include "utilities/macros.hpp"
-#ifdef ZERO
-# include "stack_zero.inline.hpp"
-#endif
-
-using namespace llvm;
-
-JRT_ENTRY(int, SharkRuntime::find_exception_handler(JavaThread* thread,
- int* indexes,
- int num_indexes))
- constantPoolHandle pool(thread, method(thread)->constants());
- Klass* exc_klass = ((oop) tos_at(thread, 0))->klass();
-
- for (int i = 0; i < num_indexes; i++) {
- Klass* tmp = pool->klass_at(indexes[i], CHECK_0);
-
- if (exc_klass() == tmp)
- return i;
-
- if (exc_klass()->is_subtype_of(tmp))
- return i;
- }
-
- return -1;
-JRT_END
-
-JRT_ENTRY(void, SharkRuntime::monitorenter(JavaThread* thread,
- BasicObjectLock* lock))
- if (PrintBiasedLockingStatistics)
- Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
-
- Handle object(thread, lock->obj());
- assert(Universe::heap()->is_in_reserved_or_null(object()), "should be");
- if (UseBiasedLocking) {
- // Retry fast entry if bias is revoked to avoid unnecessary inflation
- ObjectSynchronizer::fast_enter(object, lock->lock(), true, CHECK);
- } else {
- ObjectSynchronizer::slow_enter(object, lock->lock(), CHECK);
- }
- assert(Universe::heap()->is_in_reserved_or_null(lock->obj()), "should be");
-JRT_END
-
-JRT_ENTRY(void, SharkRuntime::monitorexit(JavaThread* thread,
- BasicObjectLock* lock))
- Handle object(thread, lock->obj());
- assert(Universe::heap()->is_in_reserved_or_null(object()), "should be");
- if (lock == NULL || object()->is_unlocked()) {
- THROW(vmSymbols::java_lang_IllegalMonitorStateException());
- }
- ObjectSynchronizer::slow_exit(object(), lock->lock(), thread);
-JRT_END
-
-JRT_ENTRY(void, SharkRuntime::new_instance(JavaThread* thread, int index))
- Klass* k_oop = method(thread)->constants()->klass_at(index, CHECK);
- InstanceKlass* klass = InstanceKlass::cast(k);
-
- // Make sure we are not instantiating an abstract klass
- klass->check_valid_for_instantiation(true, CHECK);
-
- // Make sure klass is initialized
- klass->initialize(CHECK);
-
- // At this point the class may not be fully initialized
- // because of recursive initialization. If it is fully
- // initialized & has_finalized is not set, we rewrite
- // it into its fast version (Note: no locking is needed
- // here since this is an atomic byte write and can be
- // done more than once).
- //
- // Note: In case of classes with has_finalized we don't
- // rewrite since that saves us an extra check in
- // the fast version which then would call the
- // slow version anyway (and do a call back into
- // Java).
- // If we have a breakpoint, then we don't rewrite
- // because the _breakpoint bytecode would be lost.
- oop obj = klass->allocate_instance(CHECK);
- thread->set_vm_result(obj);
-JRT_END
-
-JRT_ENTRY(void, SharkRuntime::newarray(JavaThread* thread,
- BasicType type,
- int size))
- oop obj = oopFactory::new_typeArray(type, size, CHECK);
- thread->set_vm_result(obj);
-JRT_END
-
-JRT_ENTRY(void, SharkRuntime::anewarray(JavaThread* thread,
- int index,
- int size))
- Klass* klass = method(thread)->constants()->klass_at(index, CHECK);
- objArrayOop obj = oopFactory::new_objArray(klass, size, CHECK);
- thread->set_vm_result(obj);
-JRT_END
-
-JRT_ENTRY(void, SharkRuntime::multianewarray(JavaThread* thread,
- int index,
- int ndims,
- int* dims))
- Klass* klass = method(thread)->constants()->klass_at(index, CHECK);
- oop obj = ArrayKlass::cast(klass)->multi_allocate(ndims, dims, CHECK);
- thread->set_vm_result(obj);
-JRT_END
-
-JRT_ENTRY(void, SharkRuntime::register_finalizer(JavaThread* thread,
- oop object))
- assert(oopDesc::is_oop(object), "should be");
- assert(object->klass()->has_finalizer(), "should have");
- InstanceKlass::register_finalizer(instanceOop(object), CHECK);
-JRT_END
-
-JRT_ENTRY(void, SharkRuntime::throw_ArithmeticException(JavaThread* thread,
- const char* file,
- int line))
- Exceptions::_throw_msg(
- thread, file, line,
- vmSymbols::java_lang_ArithmeticException(),
- "");
-JRT_END
-
-JRT_ENTRY(void, SharkRuntime::throw_ArrayIndexOutOfBoundsException(
- JavaThread* thread,
- const char* file,
- int line,
- int index))
- char msg[jintAsStringSize];
- snprintf(msg, sizeof(msg), "%d", index);
- Exceptions::_throw_msg(
- thread, file, line,
- vmSymbols::java_lang_ArrayIndexOutOfBoundsException(),
- msg);
-JRT_END
-
-JRT_ENTRY(void, SharkRuntime::throw_ClassCastException(JavaThread* thread,
- const char* file,
- int line))
- Exceptions::_throw_msg(
- thread, file, line,
- vmSymbols::java_lang_ClassCastException(),
- "");
-JRT_END
-
-JRT_ENTRY(void, SharkRuntime::throw_NullPointerException(JavaThread* thread,
- const char* file,
- int line))
- Exceptions::_throw_msg(
- thread, file, line,
- vmSymbols::java_lang_NullPointerException(),
- "");
-JRT_END
-
-// Non-VM calls
-// Nothing in these must ever GC!
-
-void SharkRuntime::dump(const char *name, intptr_t value) {
- oop valueOop = (oop) value;
- tty->print("%s = ", name);
- if (valueOop->is_oop(true))
- valueOop->print_on(tty);
- else if (value >= ' ' && value <= '~')
- tty->print("'%c' (%d)", value, value);
- else
- tty->print("%p", value);
- tty->print_cr("");
-}
-
-bool SharkRuntime::is_subtype_of(Klass* check_klass, Klass* object_klass) {
- return object_klass->is_subtype_of(check_klass);
-}
-
-int SharkRuntime::uncommon_trap(JavaThread* thread, int trap_request) {
- Thread *THREAD = thread;
-
- // In C2, uncommon_trap_blob creates a frame, so all the various
- // deoptimization functions expect to find the frame of the method
- // being deopted one frame down on the stack. We create a dummy
- // frame to mirror this.
- FakeStubFrame *stubframe = FakeStubFrame::build(CHECK_0);
- thread->push_zero_frame(stubframe);
-
- // Initiate the trap
- thread->set_last_Java_frame();
- Deoptimization::UnrollBlock *urb =
- Deoptimization::uncommon_trap(thread, trap_request, Deoptimization::Unpack_uncommon_trap);
- thread->reset_last_Java_frame();
- assert(urb->unpack_kind() == Deoptimization::Unpack_uncommon_trap, "expected Unpack_uncommon_trap");
-
- // Pop our dummy frame and the frame being deoptimized
- thread->pop_zero_frame();
- thread->pop_zero_frame();
-
- // Push skeleton frames
- int number_of_frames = urb->number_of_frames();
- for (int i = 0; i < number_of_frames; i++) {
- intptr_t size = urb->frame_sizes()[i];
- InterpreterFrame *frame = InterpreterFrame::build(size, CHECK_0);
- thread->push_zero_frame(frame);
- }
-
- // Push another dummy frame
- stubframe = FakeStubFrame::build(CHECK_0);
- thread->push_zero_frame(stubframe);
-
- // Fill in the skeleton frames
- thread->set_last_Java_frame();
- Deoptimization::unpack_frames(thread, Deoptimization::Unpack_uncommon_trap);
- thread->reset_last_Java_frame();
-
- // Pop our dummy frame
- thread->pop_zero_frame();
-
- // Fall back into the interpreter
- return number_of_frames;
-}
-
-FakeStubFrame* FakeStubFrame::build(TRAPS) {
- ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack();
- stack->overflow_check(header_words, CHECK_NULL);
-
- stack->push(0); // next_frame, filled in later
- intptr_t *fp = stack->sp();
- assert(fp - stack->sp() == next_frame_off, "should be");
-
- stack->push(FAKE_STUB_FRAME);
- assert(fp - stack->sp() == frame_type_off, "should be");
-
- return (FakeStubFrame *) fp;
-}
--- a/src/hotspot/share/shark/sharkRuntime.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKRUNTIME_HPP
-#define SHARE_VM_SHARK_SHARKRUNTIME_HPP
-
-#include "memory/allocation.hpp"
-#include "runtime/thread.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/llvmValue.hpp"
-
-class SharkRuntime : public AllStatic {
- // VM calls
- public:
- static int find_exception_handler(JavaThread* thread,
- int* indexes,
- int num_indexes);
-
- static void monitorenter(JavaThread* thread, BasicObjectLock* lock);
- static void monitorexit(JavaThread* thread, BasicObjectLock* lock);
-
- static void new_instance(JavaThread* thread, int index);
- static void newarray(JavaThread* thread, BasicType type, int size);
- static void anewarray(JavaThread* thread, int index, int size);
- static void multianewarray(JavaThread* thread,
- int index,
- int ndims,
- int* dims);
-
- static void register_finalizer(JavaThread* thread, oop object);
-
- static void throw_ArithmeticException(JavaThread* thread,
- const char* file,
- int line);
- static void throw_ArrayIndexOutOfBoundsException(JavaThread* thread,
- const char* file,
- int line,
- int index);
- static void throw_ClassCastException(JavaThread* thread,
- const char* file,
- int line);
- static void throw_NullPointerException(JavaThread* thread,
- const char* file,
- int line);
-
- // Helpers for VM calls
- private:
- static const SharkFrame* last_frame(JavaThread *thread) {
- return thread->last_frame().zero_sharkframe();
- }
- static Method* method(JavaThread *thread) {
- return last_frame(thread)->method();
- }
- static address bcp(JavaThread *thread, int bci) {
- return method(thread)->code_base() + bci;
- }
- static int two_byte_index(JavaThread *thread, int bci) {
- return Bytes::get_Java_u2(bcp(thread, bci) + 1);
- }
- static intptr_t tos_at(JavaThread *thread, int offset) {
- return *(thread->zero_stack()->sp() + offset);
- }
-
- // Non-VM calls
- public:
- static void dump(const char *name, intptr_t value);
- static bool is_subtype_of(Klass* check_klass, Klass* object_klass);
- static int uncommon_trap(JavaThread* thread, int trap_request);
-};
-
-#endif // SHARE_VM_SHARK_SHARKRUNTIME_HPP
--- a/src/hotspot/share/shark/sharkStack.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * 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 "shark/llvmHeaders.hpp"
-#include "shark/sharkFunction.hpp"
-#include "shark/sharkNativeWrapper.hpp"
-#include "shark/sharkStack.hpp"
-#include "shark/sharkType.hpp"
-
-using namespace llvm;
-
-void SharkStack::initialize(Value* method) {
- bool setup_sp_and_method = (method != NULL);
-
- int locals_words = max_locals();
- int extra_locals = locals_words - arg_size();
- int header_words = SharkFrame::header_words;
- int monitor_words = max_monitors()*frame::interpreter_frame_monitor_size();
- int stack_words = max_stack();
- int frame_words = header_words + monitor_words + stack_words;
-
- _extended_frame_size = frame_words + locals_words;
-
- // Update the stack pointer
- Value *stack_pointer = builder()->CreateSub(
- CreateLoadStackPointer(),
- LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize));
- CreateStackOverflowCheck(stack_pointer);
- if (setup_sp_and_method)
- CreateStoreStackPointer(stack_pointer);
-
- // Create the frame
- _frame = builder()->CreateIntToPtr(
- stack_pointer,
- PointerType::getUnqual(
- ArrayType::get(SharkType::intptr_type(), extended_frame_size())),
- "frame");
- int offset = 0;
-
- // Expression stack
- _stack_slots_offset = offset;
- offset += stack_words;
-
- // Monitors
- _monitors_slots_offset = offset;
- offset += monitor_words;
-
- // Temporary oop slot
- _oop_tmp_slot_offset = offset++;
-
- // Method pointer
- _method_slot_offset = offset++;
- if (setup_sp_and_method) {
- builder()->CreateStore(
- method, slot_addr(method_slot_offset(), SharkType::Method_type()));
- }
-
- // Unextended SP
- builder()->CreateStore(stack_pointer, slot_addr(offset++));
-
- // PC
- _pc_slot_offset = offset++;
-
- // Frame header
- builder()->CreateStore(
- LLVMValue::intptr_constant(ZeroFrame::SHARK_FRAME), slot_addr(offset++));
- Value *fp = slot_addr(offset++);
-
- // Local variables
- _locals_slots_offset = offset;
- offset += locals_words;
-
- // Push the frame
- assert(offset == extended_frame_size(), "should do");
- builder()->CreateStore(CreateLoadFramePointer(), fp);
- CreateStoreFramePointer(
- builder()->CreatePtrToInt(fp, SharkType::intptr_type()));
-}
-
-// This function should match ZeroStack::overflow_check
-void SharkStack::CreateStackOverflowCheck(Value* sp) {
- BasicBlock *zero_ok = CreateBlock("zero_stack_ok");
- BasicBlock *overflow = CreateBlock("stack_overflow");
- BasicBlock *abi_ok = CreateBlock("abi_stack_ok");
-
- // Check the Zero stack
- builder()->CreateCondBr(
- builder()->CreateICmpULT(sp, stack_base()),
- overflow, zero_ok);
-
- // Check the ABI stack
- builder()->SetInsertPoint(zero_ok);
- Value *stack_top = builder()->CreateSub(
- builder()->CreateValueOfStructEntry(
- thread(),
- Thread::stack_base_offset(),
- SharkType::intptr_type(),
- "abi_base"),
- builder()->CreateValueOfStructEntry(
- thread(),
- Thread::stack_size_offset(),
- SharkType::intptr_type(),
- "abi_size"));
- Value *free_stack = builder()->CreateSub(
- builder()->CreatePtrToInt(
- builder()->CreateGetFrameAddress(),
- SharkType::intptr_type(),
- "abi_sp"),
- stack_top);
- builder()->CreateCondBr(
- builder()->CreateICmpULT(
- free_stack,
- LLVMValue::intptr_constant(JavaThread::stack_shadow_zone_size())),
- overflow, abi_ok);
-
- // Handle overflows
- builder()->SetInsertPoint(overflow);
- builder()->CreateCall(builder()->throw_StackOverflowError(), thread());
- builder()->CreateRet(LLVMValue::jint_constant(0));
-
- builder()->SetInsertPoint(abi_ok);
-}
-
-Value* SharkStack::CreatePopFrame(int result_slots) {
- assert(result_slots >= 0 && result_slots <= 2, "should be");
- int locals_to_pop = max_locals() - result_slots;
-
- Value *fp = CreateLoadFramePointer();
- Value *sp = builder()->CreateAdd(
- fp,
- LLVMValue::intptr_constant((1 + locals_to_pop) * wordSize));
-
- CreateStoreStackPointer(sp);
- CreateStoreFramePointer(
- builder()->CreateLoad(
- builder()->CreateIntToPtr(
- fp, PointerType::getUnqual(SharkType::intptr_type()))));
-
- return sp;
-}
-
-Value* SharkStack::slot_addr(int offset,
- Type* type,
- const char* name) const {
- bool needs_cast = type && type != SharkType::intptr_type();
-
- Value* result = builder()->CreateStructGEP(
- _frame, offset, needs_cast ? "" : name);
-
- if (needs_cast) {
- result = builder()->CreateBitCast(
- result, PointerType::getUnqual(type), name);
- }
- return result;
-}
-
-// The bits that differentiate stacks with normal and native frames on top
-
-SharkStack* SharkStack::CreateBuildAndPushFrame(SharkFunction* function,
- Value* method) {
- return new SharkStackWithNormalFrame(function, method);
-}
-SharkStack* SharkStack::CreateBuildAndPushFrame(SharkNativeWrapper* wrapper,
- Value* method) {
- return new SharkStackWithNativeFrame(wrapper, method);
-}
-
-SharkStackWithNormalFrame::SharkStackWithNormalFrame(SharkFunction* function,
- Value* method)
- : SharkStack(function), _function(function) {
- // For normal frames, the stack pointer and the method slot will
- // be set during each decache, so it is not necessary to do them
- // at the time the frame is created. However, we set them for
- // non-PRODUCT builds to make crash dumps easier to understand.
- initialize(PRODUCT_ONLY(NULL) NOT_PRODUCT(method));
-}
-SharkStackWithNativeFrame::SharkStackWithNativeFrame(SharkNativeWrapper* wrp,
- Value* method)
- : SharkStack(wrp), _wrapper(wrp) {
- initialize(method);
-}
-
-int SharkStackWithNormalFrame::arg_size() const {
- return function()->arg_size();
-}
-int SharkStackWithNativeFrame::arg_size() const {
- return wrapper()->arg_size();
-}
-
-int SharkStackWithNormalFrame::max_locals() const {
- return function()->max_locals();
-}
-int SharkStackWithNativeFrame::max_locals() const {
- return wrapper()->arg_size();
-}
-
-int SharkStackWithNormalFrame::max_stack() const {
- return function()->max_stack();
-}
-int SharkStackWithNativeFrame::max_stack() const {
- return 0;
-}
-
-int SharkStackWithNormalFrame::max_monitors() const {
- return function()->max_monitors();
-}
-int SharkStackWithNativeFrame::max_monitors() const {
- return wrapper()->is_synchronized() ? 1 : 0;
-}
-
-BasicBlock* SharkStackWithNormalFrame::CreateBlock(const char* name) const {
- return function()->CreateBlock(name);
-}
-BasicBlock* SharkStackWithNativeFrame::CreateBlock(const char* name) const {
- return wrapper()->CreateBlock(name);
-}
-
-address SharkStackWithNormalFrame::interpreter_entry_point() const {
- return (address) CppInterpreter::normal_entry;
-}
-address SharkStackWithNativeFrame::interpreter_entry_point() const {
- return (address) CppInterpreter::native_entry;
-}
-
-#ifndef PRODUCT
-void SharkStack::CreateAssertLastJavaSPIsNull() const {
-#ifdef ASSERT
- BasicBlock *fail = CreateBlock("assert_failed");
- BasicBlock *pass = CreateBlock("assert_ok");
-
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(
- builder()->CreateLoad(last_Java_sp_addr()),
- LLVMValue::intptr_constant(0)),
- pass, fail);
-
- builder()->SetInsertPoint(fail);
- builder()->CreateShouldNotReachHere(__FILE__, __LINE__);
- builder()->CreateUnreachable();
-
- builder()->SetInsertPoint(pass);
-#endif // ASSERT
-}
-#endif // !PRODUCT
--- a/src/hotspot/share/shark/sharkStack.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,299 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKSTACK_HPP
-#define SHARE_VM_SHARK_SHARKSTACK_HPP
-
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkInvariants.hpp"
-#include "shark/sharkType.hpp"
-
-class SharkFunction;
-class SharkNativeWrapper;
-class SharkStackWithNormalFrame;
-class SharkStackWithNativeFrame;
-
-class SharkStack : public SharkCompileInvariants {
- public:
- static SharkStack* CreateBuildAndPushFrame(
- SharkFunction* function, llvm::Value* method);
- static SharkStack* CreateBuildAndPushFrame(
- SharkNativeWrapper* wrapper, llvm::Value* method);
-
- protected:
- SharkStack(const SharkCompileInvariants* parent)
- : SharkCompileInvariants(parent) {}
-
- protected:
- void initialize(llvm::Value* method);
-
- protected:
- void CreateStackOverflowCheck(llvm::Value* sp);
-
- // Properties of the method being compiled
- protected:
- virtual int arg_size() const = 0;
- virtual int max_locals() const = 0;
- virtual int max_stack() const = 0;
- virtual int max_monitors() const = 0;
-
- // BasicBlock creation
- protected:
- virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0;
-
- // Interpreter entry point for bailouts
- protected:
- virtual address interpreter_entry_point() const = 0;
-
- // Interface with the Zero stack
- private:
- llvm::Value* zero_stack() const {
- return builder()->CreateAddressOfStructEntry(
- thread(),
- JavaThread::zero_stack_offset(),
- SharkType::zeroStack_type(),
- "zero_stack");
- }
- llvm::Value* stack_base() const {
- return builder()->CreateValueOfStructEntry(
- zero_stack(),
- ZeroStack::base_offset(),
- SharkType::intptr_type(),
- "stack_base");
- }
- llvm::Value* stack_pointer_addr() const {
- return builder()->CreateAddressOfStructEntry(
- zero_stack(),
- ZeroStack::sp_offset(),
- llvm::PointerType::getUnqual(SharkType::intptr_type()),
- "stack_pointer_addr");
- }
- llvm::Value* frame_pointer_addr() const {
- return builder()->CreateAddressOfStructEntry(
- thread(),
- JavaThread::top_zero_frame_offset(),
- llvm::PointerType::getUnqual(SharkType::intptr_type()),
- "frame_pointer_addr");
- }
-
- public:
- llvm::LoadInst* CreateLoadStackPointer(const char *name = "") {
- return builder()->CreateLoad(stack_pointer_addr(), name);
- }
- llvm::StoreInst* CreateStoreStackPointer(llvm::Value* value) {
- return builder()->CreateStore(value, stack_pointer_addr());
- }
- llvm::LoadInst* CreateLoadFramePointer(const char *name = "") {
- return builder()->CreateLoad(frame_pointer_addr(), name);
- }
- llvm::StoreInst* CreateStoreFramePointer(llvm::Value* value) {
- return builder()->CreateStore(value, frame_pointer_addr());
- }
- llvm::Value* CreatePopFrame(int result_slots);
-
- // Interface with the frame anchor
- private:
- llvm::Value* last_Java_sp_addr() const {
- return builder()->CreateAddressOfStructEntry(
- thread(),
- JavaThread::last_Java_sp_offset(),
- llvm::PointerType::getUnqual(SharkType::intptr_type()),
- "last_Java_sp_addr");
- }
- llvm::Value* last_Java_fp_addr() const {
- return builder()->CreateAddressOfStructEntry(
- thread(),
- JavaThread::last_Java_fp_offset(),
- llvm::PointerType::getUnqual(SharkType::intptr_type()),
- "last_Java_fp_addr");
- }
-
- public:
- void CreateSetLastJavaFrame() {
- // Note that whenever _last_Java_sp != NULL other anchor fields
- // must be valid. The profiler apparently depends on this.
- NOT_PRODUCT(CreateAssertLastJavaSPIsNull());
- builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr());
- // XXX There's last_Java_pc as well, but I don't think anything uses it
- // Also XXX: should we fence here? Zero doesn't...
- builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr());
- // Also also XXX: we could probably cache the sp (and the fp we know??)
- }
- void CreateResetLastJavaFrame() {
- builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr());
- }
-
- private:
- void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN;
-
- // Our method's frame
- private:
- llvm::Value* _frame;
- int _extended_frame_size;
- int _stack_slots_offset;
-
- public:
- int extended_frame_size() const {
- return _extended_frame_size;
- }
- int oopmap_frame_size() const {
- return extended_frame_size() - arg_size();
- }
-
- // Offsets of things in the frame
- private:
- int _monitors_slots_offset;
- int _oop_tmp_slot_offset;
- int _method_slot_offset;
- int _pc_slot_offset;
- int _locals_slots_offset;
-
- public:
- int stack_slots_offset() const {
- return _stack_slots_offset;
- }
- int oop_tmp_slot_offset() const {
- return _oop_tmp_slot_offset;
- }
- int method_slot_offset() const {
- return _method_slot_offset;
- }
- int pc_slot_offset() const {
- return _pc_slot_offset;
- }
- int locals_slots_offset() const {
- return _locals_slots_offset;
- }
- int monitor_offset(int index) const {
- assert(index >= 0 && index < max_monitors(), "invalid monitor index");
- return _monitors_slots_offset +
- (max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size();
- }
- int monitor_object_offset(int index) const {
- return monitor_offset(index) +
- (BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord);
- }
- int monitor_header_offset(int index) const {
- return monitor_offset(index) +
- ((BasicObjectLock::lock_offset_in_bytes() +
- BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord);
- }
-
- // Addresses of things in the frame
- public:
- llvm::Value* slot_addr(int offset,
- llvm::Type* type = NULL,
- const char* name = "") const;
-
- llvm::Value* monitor_addr(int index) const {
- return slot_addr(
- monitor_offset(index),
- SharkType::monitor_type(),
- "monitor");
- }
- llvm::Value* monitor_object_addr(int index) const {
- return slot_addr(
- monitor_object_offset(index),
- SharkType::oop_type(),
- "object_addr");
- }
- llvm::Value* monitor_header_addr(int index) const {
- return slot_addr(
- monitor_header_offset(index),
- SharkType::intptr_type(),
- "displaced_header_addr");
- }
-
- // oopmap helpers
- public:
- static int oopmap_slot_munge(int offset) {
- return offset << (LogBytesPerWord - LogBytesPerInt);
- }
- static VMReg slot2reg(int offset) {
- return VMRegImpl::stack2reg(oopmap_slot_munge(offset));
- }
-};
-
-class SharkStackWithNormalFrame : public SharkStack {
- friend class SharkStack;
-
- protected:
- SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method);
-
- private:
- SharkFunction* _function;
-
- private:
- SharkFunction* function() const {
- return _function;
- }
-
- // Properties of the method being compiled
- private:
- int arg_size() const;
- int max_locals() const;
- int max_stack() const;
- int max_monitors() const;
-
- // BasicBlock creation
- private:
- llvm::BasicBlock* CreateBlock(const char* name = "") const;
-
- // Interpreter entry point for bailouts
- private:
- address interpreter_entry_point() const;
-};
-
-class SharkStackWithNativeFrame : public SharkStack {
- friend class SharkStack;
-
- protected:
- SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method);
-
- private:
- SharkNativeWrapper* _wrapper;
-
- private:
- SharkNativeWrapper* wrapper() const {
- return _wrapper;
- }
-
- // Properties of the method being compiled
- private:
- int arg_size() const;
- int max_locals() const;
- int max_stack() const;
- int max_monitors() const;
-
- // BasicBlock creation
- private:
- llvm::BasicBlock* CreateBlock(const char* name = "") const;
-
- // Interpreter entry point for bailouts
- private:
- address interpreter_entry_point() const;
-};
-
-#endif // SHARE_VM_SHARK_SHARKSTACK_HPP
--- a/src/hotspot/share/shark/sharkState.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,397 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * 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 "ci/ciType.hpp"
-#include "ci/ciTypeFlow.hpp"
-#include "memory/allocation.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkCacheDecache.hpp"
-#include "shark/sharkState.hpp"
-#include "shark/sharkTopLevelBlock.hpp"
-#include "shark/sharkType.hpp"
-#include "shark/sharkValue.hpp"
-
-using namespace llvm;
-
-void SharkState::initialize(const SharkState *state) {
- _locals = NEW_RESOURCE_ARRAY(SharkValue*, max_locals());
- _stack = NEW_RESOURCE_ARRAY(SharkValue*, max_stack());
-
- NOT_PRODUCT(memset(_locals, 23, max_locals() * sizeof(SharkValue *)));
- NOT_PRODUCT(memset(_stack, 23, max_stack() * sizeof(SharkValue *)));
- _sp = _stack;
-
- if (state) {
- for (int i = 0; i < max_locals(); i++) {
- SharkValue *value = state->local(i);
- if (value)
- value = value->clone();
- set_local(i, value);
- }
-
- for (int i = state->stack_depth() - 1; i >= 0; i--) {
- SharkValue *value = state->stack(i);
- if (value)
- value = value->clone();
- push(value);
- }
- }
-
- set_num_monitors(state ? state->num_monitors() : 0);
-}
-
-bool SharkState::equal_to(SharkState *other) {
- if (target() != other->target())
- return false;
-
- if (method() != other->method())
- return false;
-
- if (oop_tmp() != other->oop_tmp())
- return false;
-
- if (max_locals() != other->max_locals())
- return false;
-
- if (stack_depth() != other->stack_depth())
- return false;
-
- if (num_monitors() != other->num_monitors())
- return false;
-
- if (has_safepointed() != other->has_safepointed())
- return false;
-
- // Local variables
- for (int i = 0; i < max_locals(); i++) {
- SharkValue *value = local(i);
- SharkValue *other_value = other->local(i);
-
- if (value == NULL) {
- if (other_value != NULL)
- return false;
- }
- else {
- if (other_value == NULL)
- return false;
-
- if (!value->equal_to(other_value))
- return false;
- }
- }
-
- // Expression stack
- for (int i = 0; i < stack_depth(); i++) {
- SharkValue *value = stack(i);
- SharkValue *other_value = other->stack(i);
-
- if (value == NULL) {
- if (other_value != NULL)
- return false;
- }
- else {
- if (other_value == NULL)
- return false;
-
- if (!value->equal_to(other_value))
- return false;
- }
- }
-
- return true;
-}
-
-void SharkState::merge(SharkState* other,
- BasicBlock* other_block,
- BasicBlock* this_block) {
- // Method
- Value *this_method = this->method();
- Value *other_method = other->method();
- if (this_method != other_method) {
- PHINode *phi = builder()->CreatePHI(SharkType::Method_type(), 0, "method");
- phi->addIncoming(this_method, this_block);
- phi->addIncoming(other_method, other_block);
- set_method(phi);
- }
-
- // Temporary oop slot
- Value *this_oop_tmp = this->oop_tmp();
- Value *other_oop_tmp = other->oop_tmp();
- if (this_oop_tmp != other_oop_tmp) {
- assert(this_oop_tmp && other_oop_tmp, "can't merge NULL with non-NULL");
- PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), 0, "oop_tmp");
- phi->addIncoming(this_oop_tmp, this_block);
- phi->addIncoming(other_oop_tmp, other_block);
- set_oop_tmp(phi);
- }
-
- // Monitors
- assert(this->num_monitors() == other->num_monitors(), "should be");
-
- // Local variables
- assert(this->max_locals() == other->max_locals(), "should be");
- for (int i = 0; i < max_locals(); i++) {
- SharkValue *this_value = this->local(i);
- SharkValue *other_value = other->local(i);
- assert((this_value == NULL) == (other_value == NULL), "should be");
- if (this_value != NULL) {
- char name[18];
- snprintf(name, sizeof(name), "local_%d_", i);
- set_local(i, this_value->merge(
- builder(), other_value, other_block, this_block, name));
- }
- }
-
- // Expression stack
- assert(this->stack_depth() == other->stack_depth(), "should be");
- for (int i = 0; i < stack_depth(); i++) {
- SharkValue *this_value = this->stack(i);
- SharkValue *other_value = other->stack(i);
- assert((this_value == NULL) == (other_value == NULL), "should be");
- if (this_value != NULL) {
- char name[18];
- snprintf(name, sizeof(name), "stack_%d_", i);
- set_stack(i, this_value->merge(
- builder(), other_value, other_block, this_block, name));
- }
- }
-
- // Safepointed status
- set_has_safepointed(this->has_safepointed() && other->has_safepointed());
-}
-
-void SharkState::replace_all(SharkValue* old_value, SharkValue* new_value) {
- // Local variables
- for (int i = 0; i < max_locals(); i++) {
- if (local(i) == old_value)
- set_local(i, new_value);
- }
-
- // Expression stack
- for (int i = 0; i < stack_depth(); i++) {
- if (stack(i) == old_value)
- set_stack(i, new_value);
- }
-}
-
-SharkNormalEntryState::SharkNormalEntryState(SharkTopLevelBlock* block,
- Value* method)
- : SharkState(block) {
- assert(!block->stack_depth_at_entry(), "entry block shouldn't have stack");
-
- // Local variables
- for (int i = 0; i < max_locals(); i++) {
- ciType *type = block->local_type_at_entry(i);
-
- SharkValue *value = NULL;
- switch (type->basic_type()) {
- case T_INT:
- case T_LONG:
- case T_FLOAT:
- case T_DOUBLE:
- case T_OBJECT:
- case T_ARRAY:
- if (i >= arg_size()) {
- ShouldNotReachHere();
- }
- value = SharkValue::create_generic(type, NULL, i == 0 && !is_static());
- break;
-
- case ciTypeFlow::StateVector::T_NULL:
- value = SharkValue::null();
- break;
-
- case ciTypeFlow::StateVector::T_BOTTOM:
- break;
-
- case ciTypeFlow::StateVector::T_LONG2:
- case ciTypeFlow::StateVector::T_DOUBLE2:
- break;
-
- default:
- ShouldNotReachHere();
- }
- set_local(i, value);
- }
- SharkNormalEntryCacher(block->function(), method).scan(this);
-}
-
-SharkOSREntryState::SharkOSREntryState(SharkTopLevelBlock* block,
- Value* method,
- Value* osr_buf)
- : SharkState(block) {
- assert(block->stack_depth_at_entry() == 0, "entry block shouldn't have stack");
- set_num_monitors(block->ciblock()->monitor_count());
-
- // Local variables
- for (int i = 0; i < max_locals(); i++) {
- ciType *type = block->local_type_at_entry(i);
-
- SharkValue *value = NULL;
- switch (type->basic_type()) {
- case T_INT:
- case T_LONG:
- case T_FLOAT:
- case T_DOUBLE:
- case T_OBJECT:
- case T_ARRAY:
- value = SharkValue::create_generic(type, NULL, false);
- break;
-
- case ciTypeFlow::StateVector::T_NULL:
- value = SharkValue::null();
- break;
-
- case ciTypeFlow::StateVector::T_BOTTOM:
- break;
-
- case ciTypeFlow::StateVector::T_LONG2:
- case ciTypeFlow::StateVector::T_DOUBLE2:
- break;
-
- default:
- ShouldNotReachHere();
- }
- set_local(i, value);
- }
- SharkOSREntryCacher(block->function(), method, osr_buf).scan(this);
-}
-
-SharkPHIState::SharkPHIState(SharkTopLevelBlock* block)
- : SharkState(block), _block(block) {
- BasicBlock *saved_insert_point = builder()->GetInsertBlock();
- builder()->SetInsertPoint(block->entry_block());
- char name[18];
-
- // Method
- set_method(builder()->CreatePHI(SharkType::Method_type(), 0, "method"));
-
- // Local variables
- for (int i = 0; i < max_locals(); i++) {
- ciType *type = block->local_type_at_entry(i);
- if (type->basic_type() == (BasicType) ciTypeFlow::StateVector::T_NULL) {
- // XXX we could do all kinds of clever stuff here
- type = ciType::make(T_OBJECT); // XXX what about T_ARRAY?
- }
-
- SharkValue *value = NULL;
- switch (type->basic_type()) {
- case T_INT:
- case T_LONG:
- case T_FLOAT:
- case T_DOUBLE:
- case T_OBJECT:
- case T_ARRAY:
- snprintf(name, sizeof(name), "local_%d_", i);
- value = SharkValue::create_phi(
- type, builder()->CreatePHI(SharkType::to_stackType(type), 0, name));
- break;
-
- case T_ADDRESS:
- value = SharkValue::address_constant(type->as_return_address()->bci());
- break;
-
- case ciTypeFlow::StateVector::T_BOTTOM:
- break;
-
- case ciTypeFlow::StateVector::T_LONG2:
- case ciTypeFlow::StateVector::T_DOUBLE2:
- break;
-
- default:
- ShouldNotReachHere();
- }
- set_local(i, value);
- }
-
- // Expression stack
- for (int i = 0; i < block->stack_depth_at_entry(); i++) {
- ciType *type = block->stack_type_at_entry(i);
- if (type->basic_type() == (BasicType) ciTypeFlow::StateVector::T_NULL) {
- // XXX we could do all kinds of clever stuff here
- type = ciType::make(T_OBJECT); // XXX what about T_ARRAY?
- }
-
- SharkValue *value = NULL;
- switch (type->basic_type()) {
- case T_INT:
- case T_LONG:
- case T_FLOAT:
- case T_DOUBLE:
- case T_OBJECT:
- case T_ARRAY:
- snprintf(name, sizeof(name), "stack_%d_", i);
- value = SharkValue::create_phi(
- type, builder()->CreatePHI(SharkType::to_stackType(type), 0, name));
- break;
-
- case T_ADDRESS:
- value = SharkValue::address_constant(type->as_return_address()->bci());
- break;
-
- case ciTypeFlow::StateVector::T_LONG2:
- case ciTypeFlow::StateVector::T_DOUBLE2:
- break;
-
- default:
- ShouldNotReachHere();
- }
- push(value);
- }
-
- // Monitors
- set_num_monitors(block->ciblock()->monitor_count());
-
- builder()->SetInsertPoint(saved_insert_point);
-}
-
-void SharkPHIState::add_incoming(SharkState* incoming_state) {
- BasicBlock *predecessor = builder()->GetInsertBlock();
-
- // Method
- ((PHINode *) method())->addIncoming(incoming_state->method(), predecessor);
-
- // Local variables
- for (int i = 0; i < max_locals(); i++) {
- if (local(i) != NULL)
- local(i)->addIncoming(incoming_state->local(i), predecessor);
- }
-
- // Expression stack
- int stack_depth = block()->stack_depth_at_entry();
- assert(stack_depth == incoming_state->stack_depth(), "should be");
- for (int i = 0; i < stack_depth; i++) {
- assert((stack(i) == NULL) == (incoming_state->stack(i) == NULL), "oops");
- if (stack(i))
- stack(i)->addIncoming(incoming_state->stack(i), predecessor);
- }
-
- // Monitors
- assert(num_monitors() == incoming_state->num_monitors(), "should be");
-
- // Temporary oop slot
- assert(oop_tmp() == incoming_state->oop_tmp(), "should be");
-}
--- a/src/hotspot/share/shark/sharkState.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKSTATE_HPP
-#define SHARE_VM_SHARK_SHARKSTATE_HPP
-
-#include "ci/ciMethod.hpp"
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkInvariants.hpp"
-#include "shark/sharkValue.hpp"
-
-class SharkState : public SharkTargetInvariants {
- public:
- SharkState(const SharkTargetInvariants* parent)
- : SharkTargetInvariants(parent),
- _method(NULL),
- _oop_tmp(NULL),
- _has_safepointed(false) { initialize(NULL); }
-
- SharkState(const SharkState* state)
- : SharkTargetInvariants(state),
- _method(state->_method),
- _oop_tmp(state->_oop_tmp),
- _has_safepointed(state->_has_safepointed) { initialize(state); }
-
- private:
- void initialize(const SharkState* state);
-
- private:
- llvm::Value* _method;
- SharkValue** _locals;
- SharkValue** _stack;
- SharkValue** _sp;
- int _num_monitors;
- llvm::Value* _oop_tmp;
- bool _has_safepointed;
-
- // Method
- public:
- llvm::Value** method_addr() {
- return &_method;
- }
- llvm::Value* method() const {
- return _method;
- }
- protected:
- void set_method(llvm::Value* method) {
- _method = method;
- }
-
- // Local variables
- public:
- SharkValue** local_addr(int index) const {
- assert(index >= 0 && index < max_locals(), "bad local variable index");
- return &_locals[index];
- }
- SharkValue* local(int index) const {
- return *local_addr(index);
- }
- void set_local(int index, SharkValue* value) {
- *local_addr(index) = value;
- }
-
- // Expression stack
- public:
- SharkValue** stack_addr(int slot) const {
- assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
- return &_sp[-(slot + 1)];
- }
- SharkValue* stack(int slot) const {
- return *stack_addr(slot);
- }
- protected:
- void set_stack(int slot, SharkValue* value) {
- *stack_addr(slot) = value;
- }
- public:
- int stack_depth() const {
- return _sp - _stack;
- }
- void push(SharkValue* value) {
- assert(stack_depth() < max_stack(), "stack overrun");
- *(_sp++) = value;
- }
- SharkValue* pop() {
- assert(stack_depth() > 0, "stack underrun");
- return *(--_sp);
- }
-
- // Monitors
- public:
- int num_monitors() const {
- return _num_monitors;
- }
- void set_num_monitors(int num_monitors) {
- _num_monitors = num_monitors;
- }
-
- // Temporary oop slot
- public:
- llvm::Value** oop_tmp_addr() {
- return &_oop_tmp;
- }
- llvm::Value* oop_tmp() const {
- return _oop_tmp;
- }
- void set_oop_tmp(llvm::Value* oop_tmp) {
- _oop_tmp = oop_tmp;
- }
-
- // Safepointed status
- public:
- bool has_safepointed() const {
- return _has_safepointed;
- }
- void set_has_safepointed(bool has_safepointed) {
- _has_safepointed = has_safepointed;
- }
-
- // Comparison
- public:
- bool equal_to(SharkState* other);
-
- // Copy and merge
- public:
- SharkState* copy() const {
- return new SharkState(this);
- }
- void merge(SharkState* other,
- llvm::BasicBlock* other_block,
- llvm::BasicBlock* this_block);
-
- // Value replacement
- public:
- void replace_all(SharkValue* old_value, SharkValue* new_value);
-};
-
-class SharkTopLevelBlock;
-
-// SharkNormalEntryState objects are used to create the state
-// that the method will be entered with for a normal invocation.
-class SharkNormalEntryState : public SharkState {
- public:
- SharkNormalEntryState(SharkTopLevelBlock* block,
- llvm::Value* method);
-};
-
-// SharkOSREntryState objects are used to create the state
-// that the method will be entered with for an OSR invocation.
-class SharkOSREntryState : public SharkState {
- public:
- SharkOSREntryState(SharkTopLevelBlock* block,
- llvm::Value* method,
- llvm::Value* osr_buf);
-};
-
-// SharkPHIState objects are used to manage the entry state
-// for blocks with more than one entry path or for blocks
-// entered from blocks that will be compiled later.
-class SharkPHIState : public SharkState {
- public:
- SharkPHIState(SharkTopLevelBlock* block);
-
- private:
- SharkTopLevelBlock* _block;
-
- private:
- SharkTopLevelBlock* block() const {
- return _block;
- }
-
- public:
- void add_incoming(SharkState* incoming_state);
-};
-
-#endif // SHARE_VM_SHARK_SHARKSTATE_HPP
--- a/src/hotspot/share/shark/sharkStateScanner.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * 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 "shark/sharkState.hpp"
-#include "shark/sharkStateScanner.hpp"
-
-using namespace llvm;
-
-void SharkStateScanner::scan(SharkState* state) {
- start_frame();
-
- // Expression stack
- stack_integrity_checks(state);
- start_stack(state->stack_depth());
- for (int i = state->stack_depth() - 1; i >= 0; i--) {
- process_stack_slot(
- i,
- state->stack_addr(i),
- stack()->stack_slots_offset() +
- i + max_stack() - state->stack_depth());
- }
- end_stack();
-
- // Monitors
- start_monitors(state->num_monitors());
- for (int i = 0; i < state->num_monitors(); i++) {
- process_monitor(
- i,
- stack()->monitor_offset(i),
- stack()->monitor_object_offset(i));
- }
- end_monitors();
-
- // Frame header
- start_frame_header();
- process_oop_tmp_slot(
- state->oop_tmp_addr(), stack()->oop_tmp_slot_offset());
- process_method_slot(state->method_addr(), stack()->method_slot_offset());
- process_pc_slot(stack()->pc_slot_offset());
- end_frame_header();
-
- // Local variables
- locals_integrity_checks(state);
- start_locals();
- for (int i = 0; i < max_locals(); i++) {
- process_local_slot(
- i,
- state->local_addr(i),
- stack()->locals_slots_offset() + max_locals() - 1 - i);
- }
- end_locals();
-
- end_frame();
-}
-
-#ifndef PRODUCT
-void SharkStateScanner::stack_integrity_checks(SharkState* state) {
- for (int i = 0; i < state->stack_depth(); i++) {
- if (state->stack(i)) {
- if (state->stack(i)->is_two_word())
- assert(state->stack(i - 1) == NULL, "should be");
- }
- else {
- assert(state->stack(i + 1)->is_two_word(), "should be");
- }
- }
-}
-
-void SharkStateScanner::locals_integrity_checks(SharkState* state) {
- for (int i = 0; i < max_locals(); i++) {
- if (state->local(i)) {
- if (state->local(i)->is_two_word())
- assert(state->local(i + 1) == NULL, "should be");
- }
- }
-}
-#endif // !PRODUCT
--- a/src/hotspot/share/shark/sharkStateScanner.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKSTATESCANNER_HPP
-#define SHARE_VM_SHARK_SHARKSTATESCANNER_HPP
-
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkFunction.hpp"
-#include "shark/sharkInvariants.hpp"
-
-class SharkState;
-
-class SharkStateScanner : public SharkTargetInvariants {
- protected:
- SharkStateScanner(SharkFunction* function)
- : SharkTargetInvariants(function), _stack(function->stack()) {}
-
- private:
- SharkStack* _stack;
-
- protected:
- SharkStack* stack() const {
- return _stack;
- }
-
- // Scan the frame
- public:
- void scan(SharkState* state);
-
- // Callbacks
- // Note that the offsets supplied to the various process_* callbacks
- // are specified in wordSize words from the frame's unextended_sp.
- protected:
- virtual void start_frame() {}
-
- virtual void start_stack(int stack_depth) {}
- virtual void process_stack_slot(int index, SharkValue** value, int offset) {}
- virtual void end_stack() {}
-
- virtual void start_monitors(int num_monitors) {}
- virtual void process_monitor(int index, int box_offset, int obj_offset) {}
- virtual void end_monitors() {}
-
- virtual void start_frame_header() {}
- virtual void process_oop_tmp_slot(llvm::Value** value, int offset) {}
- virtual void process_method_slot(llvm::Value** value, int offset) {}
- virtual void process_pc_slot(int offset) {}
- virtual void end_frame_header() {}
-
- virtual void start_locals() {}
- virtual void process_local_slot(int index, SharkValue** value, int offset) {}
- virtual void end_locals() {}
-
- virtual void end_frame() {}
-
- // Integrity checks
- private:
- void stack_integrity_checks(SharkState* state) PRODUCT_RETURN;
- void locals_integrity_checks(SharkState* state) PRODUCT_RETURN;
-};
-
-#endif // SHARE_VM_SHARK_SHARKSTATESCANNER_HPP
--- a/src/hotspot/share/shark/sharkTopLevelBlock.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2043 +0,0 @@
-/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * 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 "ci/ciField.hpp"
-#include "ci/ciInstance.hpp"
-#include "ci/ciObjArrayKlass.hpp"
-#include "ci/ciStreams.hpp"
-#include "ci/ciType.hpp"
-#include "ci/ciTypeFlow.hpp"
-#include "interpreter/bytecodes.hpp"
-#include "memory/allocation.hpp"
-#include "runtime/deoptimization.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/llvmValue.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkCacheDecache.hpp"
-#include "shark/sharkConstant.hpp"
-#include "shark/sharkInliner.hpp"
-#include "shark/sharkState.hpp"
-#include "shark/sharkTopLevelBlock.hpp"
-#include "shark/sharkValue.hpp"
-#include "shark/shark_globals.hpp"
-#include "utilities/debug.hpp"
-
-using namespace llvm;
-
-void SharkTopLevelBlock::scan_for_traps() {
- // If typeflow found a trap then don't scan past it
- int limit_bci = ciblock()->has_trap() ? ciblock()->trap_bci() : limit();
-
- // Scan the bytecode for traps that are always hit
- iter()->reset_to_bci(start());
- while (iter()->next_bci() < limit_bci) {
- iter()->next();
-
- ciField *field;
- ciMethod *method;
- ciInstanceKlass *klass;
- bool will_link;
- bool is_field;
-
- switch (bc()) {
- case Bytecodes::_ldc:
- case Bytecodes::_ldc_w:
- case Bytecodes::_ldc2_w:
- if (!SharkConstant::for_ldc(iter())->is_loaded()) {
- set_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_uninitialized,
- Deoptimization::Action_reinterpret), bci());
- return;
- }
- break;
-
- case Bytecodes::_getfield:
- case Bytecodes::_getstatic:
- case Bytecodes::_putfield:
- case Bytecodes::_putstatic:
- field = iter()->get_field(will_link);
- assert(will_link, "typeflow responsibility");
- is_field = (bc() == Bytecodes::_getfield || bc() == Bytecodes::_putfield);
-
- // If the bytecode does not match the field then bail out to
- // the interpreter to throw an IncompatibleClassChangeError
- if (is_field == field->is_static()) {
- set_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_unhandled,
- Deoptimization::Action_none), bci());
- return;
- }
-
- // Bail out if we are trying to access a static variable
- // before the class initializer has completed.
- if (!is_field && !field->holder()->is_initialized()) {
- if (!static_field_ok_in_clinit(field)) {
- set_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_uninitialized,
- Deoptimization::Action_reinterpret), bci());
- return;
- }
- }
- break;
-
- case Bytecodes::_invokestatic:
- case Bytecodes::_invokespecial:
- case Bytecodes::_invokevirtual:
- case Bytecodes::_invokeinterface:
- ciSignature* sig;
- method = iter()->get_method(will_link, &sig);
- assert(will_link, "typeflow responsibility");
- // We can't compile calls to method handle intrinsics, because we use
- // the interpreter entry points and they expect the top frame to be an
- // interpreter frame. We need to implement the intrinsics for Shark.
- if (method->is_method_handle_intrinsic() || method->is_compiled_lambda_form()) {
- if (SharkPerformanceWarnings) {
- warning("JSR292 optimization not yet implemented in Shark");
- }
- set_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_unhandled,
- Deoptimization::Action_make_not_compilable), bci());
- return;
- }
- if (!method->holder()->is_linked()) {
- set_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_uninitialized,
- Deoptimization::Action_reinterpret), bci());
- return;
- }
-
- if (bc() == Bytecodes::_invokevirtual) {
- klass = ciEnv::get_instance_klass_for_declared_method_holder(
- iter()->get_declared_method_holder());
- if (!klass->is_linked()) {
- set_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_uninitialized,
- Deoptimization::Action_reinterpret), bci());
- return;
- }
- }
- break;
-
- case Bytecodes::_new:
- klass = iter()->get_klass(will_link)->as_instance_klass();
- assert(will_link, "typeflow responsibility");
-
- // Bail out if the class is unloaded
- if (iter()->is_unresolved_klass() || !klass->is_initialized()) {
- set_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_uninitialized,
- Deoptimization::Action_reinterpret), bci());
- return;
- }
-
- // Bail out if the class cannot be instantiated
- if (klass->is_abstract() || klass->is_interface() ||
- klass->name() == ciSymbol::java_lang_Class()) {
- set_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_unhandled,
- Deoptimization::Action_reinterpret), bci());
- return;
- }
- break;
- case Bytecodes::_invokedynamic:
- case Bytecodes::_invokehandle:
- if (SharkPerformanceWarnings) {
- warning("JSR292 optimization not yet implemented in Shark");
- }
- set_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_unhandled,
- Deoptimization::Action_make_not_compilable), bci());
- return;
- }
- }
-
- // Trap if typeflow trapped (and we didn't before)
- if (ciblock()->has_trap()) {
- set_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_unloaded,
- Deoptimization::Action_reinterpret,
- ciblock()->trap_index()), ciblock()->trap_bci());
- return;
- }
-}
-
-bool SharkTopLevelBlock::static_field_ok_in_clinit(ciField* field) {
- assert(field->is_static(), "should be");
-
- // This code is lifted pretty much verbatim from C2's
- // Parse::static_field_ok_in_clinit() in parse3.cpp.
- bool access_OK = false;
- if (target()->holder()->is_subclass_of(field->holder())) {
- if (target()->is_static()) {
- if (target()->name() == ciSymbol::class_initializer_name()) {
- // It's OK to access static fields from the class initializer
- access_OK = true;
- }
- }
- else {
- if (target()->name() == ciSymbol::object_initializer_name()) {
- // It's also OK to access static fields inside a constructor,
- // because any thread calling the constructor must first have
- // synchronized on the class by executing a "new" bytecode.
- access_OK = true;
- }
- }
- }
- return access_OK;
-}
-
-SharkState* SharkTopLevelBlock::entry_state() {
- if (_entry_state == NULL) {
- assert(needs_phis(), "should do");
- _entry_state = new SharkPHIState(this);
- }
- return _entry_state;
-}
-
-void SharkTopLevelBlock::add_incoming(SharkState* incoming_state) {
- if (needs_phis()) {
- ((SharkPHIState *) entry_state())->add_incoming(incoming_state);
- }
- else if (_entry_state == NULL) {
- _entry_state = incoming_state;
- }
- else {
- assert(entry_state()->equal_to(incoming_state), "should be");
- }
-}
-
-void SharkTopLevelBlock::enter(SharkTopLevelBlock* predecessor,
- bool is_exception) {
- // This block requires phis:
- // - if it is entered more than once
- // - if it is an exception handler, because in which
- // case we assume it's entered more than once.
- // - if the predecessor will be compiled after this
- // block, in which case we can't simple propagate
- // the state forward.
- if (!needs_phis() &&
- (entered() ||
- is_exception ||
- (predecessor && predecessor->index() >= index())))
- _needs_phis = true;
-
- // Recurse into the tree
- if (!entered()) {
- _entered = true;
-
- scan_for_traps();
- if (!has_trap()) {
- for (int i = 0; i < num_successors(); i++) {
- successor(i)->enter(this, false);
- }
- }
- compute_exceptions();
- for (int i = 0; i < num_exceptions(); i++) {
- SharkTopLevelBlock *handler = exception(i);
- if (handler)
- handler->enter(this, true);
- }
- }
-}
-
-void SharkTopLevelBlock::initialize() {
- char name[28];
- snprintf(name, sizeof(name),
- "bci_%d%s",
- start(), is_backedge_copy() ? "_backedge_copy" : "");
- _entry_block = function()->CreateBlock(name);
-}
-
-void SharkTopLevelBlock::decache_for_Java_call(ciMethod *callee) {
- SharkJavaCallDecacher(function(), bci(), callee).scan(current_state());
- for (int i = 0; i < callee->arg_size(); i++)
- xpop();
-}
-
-void SharkTopLevelBlock::cache_after_Java_call(ciMethod *callee) {
- if (callee->return_type()->size()) {
- ciType *type;
- switch (callee->return_type()->basic_type()) {
- case T_BOOLEAN:
- case T_BYTE:
- case T_CHAR:
- case T_SHORT:
- type = ciType::make(T_INT);
- break;
-
- default:
- type = callee->return_type();
- }
-
- push(SharkValue::create_generic(type, NULL, false));
- }
- SharkJavaCallCacher(function(), callee).scan(current_state());
-}
-
-void SharkTopLevelBlock::decache_for_VM_call() {
- SharkVMCallDecacher(function(), bci()).scan(current_state());
-}
-
-void SharkTopLevelBlock::cache_after_VM_call() {
- SharkVMCallCacher(function()).scan(current_state());
-}
-
-void SharkTopLevelBlock::decache_for_trap() {
- SharkTrapDecacher(function(), bci()).scan(current_state());
-}
-
-void SharkTopLevelBlock::emit_IR() {
- builder()->SetInsertPoint(entry_block());
-
- // Parse the bytecode
- parse_bytecode(start(), limit());
-
- // If this block falls through to the next then it won't have been
- // terminated by a bytecode and we have to add the branch ourselves
- if (falls_through() && !has_trap())
- do_branch(ciTypeFlow::FALL_THROUGH);
-}
-
-SharkTopLevelBlock* SharkTopLevelBlock::bci_successor(int bci) const {
- // XXX now with Linear Search Technology (tm)
- for (int i = 0; i < num_successors(); i++) {
- ciTypeFlow::Block *successor = ciblock()->successors()->at(i);
- if (successor->start() == bci)
- return function()->block(successor->pre_order());
- }
- ShouldNotReachHere();
-}
-
-void SharkTopLevelBlock::do_zero_check(SharkValue *value) {
- if (value->is_phi() && value->as_phi()->all_incomers_zero_checked()) {
- function()->add_deferred_zero_check(this, value);
- }
- else {
- BasicBlock *continue_block = function()->CreateBlock("not_zero");
- SharkState *saved_state = current_state();
- set_current_state(saved_state->copy());
- zero_check_value(value, continue_block);
- builder()->SetInsertPoint(continue_block);
- set_current_state(saved_state);
- }
-
- value->set_zero_checked(true);
-}
-
-void SharkTopLevelBlock::do_deferred_zero_check(SharkValue* value,
- int bci,
- SharkState* saved_state,
- BasicBlock* continue_block) {
- if (value->as_phi()->all_incomers_zero_checked()) {
- builder()->CreateBr(continue_block);
- }
- else {
- iter()->force_bci(start());
- set_current_state(saved_state);
- zero_check_value(value, continue_block);
- }
-}
-
-void SharkTopLevelBlock::zero_check_value(SharkValue* value,
- BasicBlock* continue_block) {
- BasicBlock *zero_block = builder()->CreateBlock(continue_block, "zero");
-
- Value *a, *b;
- switch (value->basic_type()) {
- case T_BYTE:
- case T_CHAR:
- case T_SHORT:
- case T_INT:
- a = value->jint_value();
- b = LLVMValue::jint_constant(0);
- break;
- case T_LONG:
- a = value->jlong_value();
- b = LLVMValue::jlong_constant(0);
- break;
- case T_OBJECT:
- case T_ARRAY:
- a = value->jobject_value();
- b = LLVMValue::LLVMValue::null();
- break;
- default:
- tty->print_cr("Unhandled type %s", type2name(value->basic_type()));
- ShouldNotReachHere();
- }
-
- builder()->CreateCondBr(
- builder()->CreateICmpNE(a, b), continue_block, zero_block);
-
- builder()->SetInsertPoint(zero_block);
- if (value->is_jobject()) {
- call_vm(
- builder()->throw_NullPointerException(),
- builder()->CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) __FILE__),
- PointerType::getUnqual(SharkType::jbyte_type())),
- LLVMValue::jint_constant(__LINE__),
- EX_CHECK_NONE);
- }
- else {
- call_vm(
- builder()->throw_ArithmeticException(),
- builder()->CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) __FILE__),
- PointerType::getUnqual(SharkType::jbyte_type())),
- LLVMValue::jint_constant(__LINE__),
- EX_CHECK_NONE);
- }
-
- Value *pending_exception = get_pending_exception();
- clear_pending_exception();
- handle_exception(pending_exception, EX_CHECK_FULL);
-}
-
-void SharkTopLevelBlock::check_bounds(SharkValue* array, SharkValue* index) {
- BasicBlock *out_of_bounds = function()->CreateBlock("out_of_bounds");
- BasicBlock *in_bounds = function()->CreateBlock("in_bounds");
-
- Value *length = builder()->CreateArrayLength(array->jarray_value());
- // we use an unsigned comparison to catch negative values
- builder()->CreateCondBr(
- builder()->CreateICmpULT(index->jint_value(), length),
- in_bounds, out_of_bounds);
-
- builder()->SetInsertPoint(out_of_bounds);
- SharkState *saved_state = current_state()->copy();
-
- call_vm(
- builder()->throw_ArrayIndexOutOfBoundsException(),
- builder()->CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) __FILE__),
- PointerType::getUnqual(SharkType::jbyte_type())),
- LLVMValue::jint_constant(__LINE__),
- index->jint_value(),
- EX_CHECK_NONE);
-
- Value *pending_exception = get_pending_exception();
- clear_pending_exception();
- handle_exception(pending_exception, EX_CHECK_FULL);
-
- set_current_state(saved_state);
-
- builder()->SetInsertPoint(in_bounds);
-}
-
-void SharkTopLevelBlock::check_pending_exception(int action) {
- assert(action & EAM_CHECK, "should be");
-
- BasicBlock *exception = function()->CreateBlock("exception");
- BasicBlock *no_exception = function()->CreateBlock("no_exception");
-
- Value *pending_exception = get_pending_exception();
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(pending_exception, LLVMValue::null()),
- no_exception, exception);
-
- builder()->SetInsertPoint(exception);
- SharkState *saved_state = current_state()->copy();
- if (action & EAM_MONITOR_FUDGE) {
- // The top monitor is marked live, but the exception was thrown
- // while setting it up so we need to mark it dead before we enter
- // any exception handlers as they will not expect it to be there.
- set_num_monitors(num_monitors() - 1);
- action ^= EAM_MONITOR_FUDGE;
- }
- clear_pending_exception();
- handle_exception(pending_exception, action);
- set_current_state(saved_state);
-
- builder()->SetInsertPoint(no_exception);
-}
-
-void SharkTopLevelBlock::compute_exceptions() {
- ciExceptionHandlerStream str(target(), start());
-
- int exc_count = str.count();
- _exc_handlers = new GrowableArray<ciExceptionHandler*>(exc_count);
- _exceptions = new GrowableArray<SharkTopLevelBlock*>(exc_count);
-
- int index = 0;
- for (; !str.is_done(); str.next()) {
- ciExceptionHandler *handler = str.handler();
- if (handler->handler_bci() == -1)
- break;
- _exc_handlers->append(handler);
-
- // Try and get this exception's handler from typeflow. We should
- // do it this way always, really, except that typeflow sometimes
- // doesn't record exceptions, even loaded ones, and sometimes it
- // returns them with a different handler bci. Why???
- SharkTopLevelBlock *block = NULL;
- ciInstanceKlass* klass;
- if (handler->is_catch_all()) {
- klass = java_lang_Throwable_klass();
- }
- else {
- klass = handler->catch_klass();
- }
- for (int i = 0; i < ciblock()->exceptions()->length(); i++) {
- if (klass == ciblock()->exc_klasses()->at(i)) {
- block = function()->block(ciblock()->exceptions()->at(i)->pre_order());
- if (block->start() == handler->handler_bci())
- break;
- else
- block = NULL;
- }
- }
-
- // If typeflow let us down then try and figure it out ourselves
- if (block == NULL) {
- for (int i = 0; i < function()->block_count(); i++) {
- SharkTopLevelBlock *candidate = function()->block(i);
- if (candidate->start() == handler->handler_bci()) {
- if (block != NULL) {
- NOT_PRODUCT(warning("there may be trouble ahead"));
- block = NULL;
- break;
- }
- block = candidate;
- }
- }
- }
- _exceptions->append(block);
- }
-}
-
-void SharkTopLevelBlock::handle_exception(Value* exception, int action) {
- if (action & EAM_HANDLE && num_exceptions() != 0) {
- // Clear the stack and push the exception onto it
- while (xstack_depth())
- pop();
- push(SharkValue::create_jobject(exception, true));
-
- // Work out how many options we have to check
- bool has_catch_all = exc_handler(num_exceptions() - 1)->is_catch_all();
- int num_options = num_exceptions();
- if (has_catch_all)
- num_options--;
-
- // Marshal any non-catch-all handlers
- if (num_options > 0) {
- bool all_loaded = true;
- for (int i = 0; i < num_options; i++) {
- if (!exc_handler(i)->catch_klass()->is_loaded()) {
- all_loaded = false;
- break;
- }
- }
-
- if (all_loaded)
- marshal_exception_fast(num_options);
- else
- marshal_exception_slow(num_options);
- }
-
- // Install the catch-all handler, if present
- if (has_catch_all) {
- SharkTopLevelBlock* handler = this->exception(num_options);
- assert(handler != NULL, "catch-all handler cannot be unloaded");
-
- builder()->CreateBr(handler->entry_block());
- handler->add_incoming(current_state());
- return;
- }
- }
-
- // No exception handler was found; unwind and return
- handle_return(T_VOID, exception);
-}
-
-void SharkTopLevelBlock::marshal_exception_fast(int num_options) {
- Value *exception_klass = builder()->CreateValueOfStructEntry(
- xstack(0)->jobject_value(),
- in_ByteSize(oopDesc::klass_offset_in_bytes()),
- SharkType::klass_type(),
- "exception_klass");
-
- for (int i = 0; i < num_options; i++) {
- Value *check_klass =
- builder()->CreateInlineMetadata(exc_handler(i)->catch_klass(), SharkType::klass_type());
-
- BasicBlock *not_exact = function()->CreateBlock("not_exact");
- BasicBlock *not_subtype = function()->CreateBlock("not_subtype");
-
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(check_klass, exception_klass),
- handler_for_exception(i), not_exact);
-
- builder()->SetInsertPoint(not_exact);
- builder()->CreateCondBr(
- builder()->CreateICmpNE(
- builder()->CreateCall2(
- builder()->is_subtype_of(), check_klass, exception_klass),
- LLVMValue::jbyte_constant(0)),
- handler_for_exception(i), not_subtype);
-
- builder()->SetInsertPoint(not_subtype);
- }
-}
-
-void SharkTopLevelBlock::marshal_exception_slow(int num_options) {
- int *indexes = NEW_RESOURCE_ARRAY(int, num_options);
- for (int i = 0; i < num_options; i++)
- indexes[i] = exc_handler(i)->catch_klass_index();
-
- Value *index = call_vm(
- builder()->find_exception_handler(),
- builder()->CreateInlineData(
- indexes,
- num_options * sizeof(int),
- PointerType::getUnqual(SharkType::jint_type())),
- LLVMValue::jint_constant(num_options),
- EX_CHECK_NO_CATCH);
-
- BasicBlock *no_handler = function()->CreateBlock("no_handler");
- SwitchInst *switchinst = builder()->CreateSwitch(
- index, no_handler, num_options);
-
- for (int i = 0; i < num_options; i++) {
- switchinst->addCase(
- LLVMValue::jint_constant(i),
- handler_for_exception(i));
- }
-
- builder()->SetInsertPoint(no_handler);
-}
-
-BasicBlock* SharkTopLevelBlock::handler_for_exception(int index) {
- SharkTopLevelBlock *successor = this->exception(index);
- if (successor) {
- successor->add_incoming(current_state());
- return successor->entry_block();
- }
- else {
- return make_trap(
- exc_handler(index)->handler_bci(),
- Deoptimization::make_trap_request(
- Deoptimization::Reason_unhandled,
- Deoptimization::Action_reinterpret));
- }
-}
-
-void SharkTopLevelBlock::maybe_add_safepoint() {
- if (current_state()->has_safepointed())
- return;
-
- BasicBlock *orig_block = builder()->GetInsertBlock();
- SharkState *orig_state = current_state()->copy();
-
- BasicBlock *do_safepoint = function()->CreateBlock("do_safepoint");
- BasicBlock *safepointed = function()->CreateBlock("safepointed");
-
- Value *state = builder()->CreateLoad(
- builder()->CreateIntToPtr(
- LLVMValue::intptr_constant(
- (intptr_t) SafepointSynchronize::address_of_state()),
- PointerType::getUnqual(SharkType::jint_type())),
- "state");
-
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(
- state,
- LLVMValue::jint_constant(SafepointSynchronize::_synchronizing)),
- do_safepoint, safepointed);
-
- builder()->SetInsertPoint(do_safepoint);
- call_vm(builder()->safepoint(), EX_CHECK_FULL);
- BasicBlock *safepointed_block = builder()->GetInsertBlock();
- builder()->CreateBr(safepointed);
-
- builder()->SetInsertPoint(safepointed);
- current_state()->merge(orig_state, orig_block, safepointed_block);
-
- current_state()->set_has_safepointed(true);
-}
-
-void SharkTopLevelBlock::maybe_add_backedge_safepoint() {
- if (current_state()->has_safepointed())
- return;
-
- for (int i = 0; i < num_successors(); i++) {
- if (successor(i)->can_reach(this)) {
- maybe_add_safepoint();
- break;
- }
- }
-}
-
-bool SharkTopLevelBlock::can_reach(SharkTopLevelBlock* other) {
- for (int i = 0; i < function()->block_count(); i++)
- function()->block(i)->_can_reach_visited = false;
-
- return can_reach_helper(other);
-}
-
-bool SharkTopLevelBlock::can_reach_helper(SharkTopLevelBlock* other) {
- if (this == other)
- return true;
-
- if (_can_reach_visited)
- return false;
- _can_reach_visited = true;
-
- if (!has_trap()) {
- for (int i = 0; i < num_successors(); i++) {
- if (successor(i)->can_reach_helper(other))
- return true;
- }
- }
-
- for (int i = 0; i < num_exceptions(); i++) {
- SharkTopLevelBlock *handler = exception(i);
- if (handler && handler->can_reach_helper(other))
- return true;
- }
-
- return false;
-}
-
-BasicBlock* SharkTopLevelBlock::make_trap(int trap_bci, int trap_request) {
- BasicBlock *trap_block = function()->CreateBlock("trap");
- BasicBlock *orig_block = builder()->GetInsertBlock();
- builder()->SetInsertPoint(trap_block);
-
- int orig_bci = bci();
- iter()->force_bci(trap_bci);
-
- do_trap(trap_request);
-
- builder()->SetInsertPoint(orig_block);
- iter()->force_bci(orig_bci);
-
- return trap_block;
-}
-
-void SharkTopLevelBlock::do_trap(int trap_request) {
- decache_for_trap();
- builder()->CreateRet(
- builder()->CreateCall2(
- builder()->uncommon_trap(),
- thread(),
- LLVMValue::jint_constant(trap_request)));
-}
-
-void SharkTopLevelBlock::call_register_finalizer(Value *receiver) {
- BasicBlock *orig_block = builder()->GetInsertBlock();
- SharkState *orig_state = current_state()->copy();
-
- BasicBlock *do_call = function()->CreateBlock("has_finalizer");
- BasicBlock *done = function()->CreateBlock("done");
-
- Value *klass = builder()->CreateValueOfStructEntry(
- receiver,
- in_ByteSize(oopDesc::klass_offset_in_bytes()),
- SharkType::oop_type(),
- "klass");
-
- Value *access_flags = builder()->CreateValueOfStructEntry(
- klass,
- Klass::access_flags_offset(),
- SharkType::jint_type(),
- "access_flags");
-
- builder()->CreateCondBr(
- builder()->CreateICmpNE(
- builder()->CreateAnd(
- access_flags,
- LLVMValue::jint_constant(JVM_ACC_HAS_FINALIZER)),
- LLVMValue::jint_constant(0)),
- do_call, done);
-
- builder()->SetInsertPoint(do_call);
- call_vm(builder()->register_finalizer(), receiver, EX_CHECK_FULL);
- BasicBlock *branch_block = builder()->GetInsertBlock();
- builder()->CreateBr(done);
-
- builder()->SetInsertPoint(done);
- current_state()->merge(orig_state, orig_block, branch_block);
-}
-
-void SharkTopLevelBlock::handle_return(BasicType type, Value* exception) {
- assert (exception == NULL || type == T_VOID, "exception OR result, please");
-
- if (num_monitors()) {
- // Protect our exception across possible monitor release decaches
- if (exception)
- set_oop_tmp(exception);
-
- // We don't need to check for exceptions thrown here. If
- // we're returning a value then we just carry on as normal:
- // the caller will see the pending exception and handle it.
- // If we're returning with an exception then that exception
- // takes priority and the release_lock one will be ignored.
- while (num_monitors())
- release_lock(EX_CHECK_NONE);
-
- // Reload the exception we're throwing
- if (exception)
- exception = get_oop_tmp();
- }
-
- if (exception) {
- builder()->CreateStore(exception, pending_exception_address());
- }
-
- Value *result_addr = stack()->CreatePopFrame(type2size[type]);
- if (type != T_VOID) {
- builder()->CreateStore(
- pop_result(type)->generic_value(),
- builder()->CreateIntToPtr(
- result_addr,
- PointerType::getUnqual(SharkType::to_stackType(type))));
- }
-
- builder()->CreateRet(LLVMValue::jint_constant(0));
-}
-
-void SharkTopLevelBlock::do_arraylength() {
- SharkValue *array = pop();
- check_null(array);
- Value *length = builder()->CreateArrayLength(array->jarray_value());
- push(SharkValue::create_jint(length, false));
-}
-
-void SharkTopLevelBlock::do_aload(BasicType basic_type) {
- SharkValue *index = pop();
- SharkValue *array = pop();
-
- check_null(array);
- check_bounds(array, index);
-
- Value *value = builder()->CreateLoad(
- builder()->CreateArrayAddress(
- array->jarray_value(), basic_type, index->jint_value()));
-
- Type *stack_type = SharkType::to_stackType(basic_type);
- if (value->getType() != stack_type)
- value = builder()->CreateIntCast(value, stack_type, basic_type != T_CHAR);
-
- switch (basic_type) {
- case T_BYTE:
- case T_CHAR:
- case T_SHORT:
- case T_INT:
- push(SharkValue::create_jint(value, false));
- break;
-
- case T_LONG:
- push(SharkValue::create_jlong(value, false));
- break;
-
- case T_FLOAT:
- push(SharkValue::create_jfloat(value));
- break;
-
- case T_DOUBLE:
- push(SharkValue::create_jdouble(value));
- break;
-
- case T_OBJECT:
- // You might expect that array->type()->is_array_klass() would
- // always be true, but it isn't. If ciTypeFlow detects that a
- // value is always null then that value becomes an untyped null
- // object. Shark doesn't presently support this, so a generic
- // T_OBJECT is created. In this case we guess the type using
- // the BasicType we were supplied. In reality the generated
- // code will never be used, as the null value will be caught
- // by the above null pointer check.
- // http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=324
- push(
- SharkValue::create_generic(
- array->type()->is_array_klass() ?
- ((ciArrayKlass *) array->type())->element_type() :
- ciType::make(basic_type),
- value, false));
- break;
-
- default:
- tty->print_cr("Unhandled type %s", type2name(basic_type));
- ShouldNotReachHere();
- }
-}
-
-void SharkTopLevelBlock::do_astore(BasicType basic_type) {
- SharkValue *svalue = pop();
- SharkValue *index = pop();
- SharkValue *array = pop();
-
- check_null(array);
- check_bounds(array, index);
-
- Value *value;
- switch (basic_type) {
- case T_BYTE:
- case T_CHAR:
- case T_SHORT:
- case T_INT:
- value = svalue->jint_value();
- break;
-
- case T_LONG:
- value = svalue->jlong_value();
- break;
-
- case T_FLOAT:
- value = svalue->jfloat_value();
- break;
-
- case T_DOUBLE:
- value = svalue->jdouble_value();
- break;
-
- case T_OBJECT:
- value = svalue->jobject_value();
- // XXX assignability check
- break;
-
- default:
- tty->print_cr("Unhandled type %s", type2name(basic_type));
- ShouldNotReachHere();
- }
-
- Type *array_type = SharkType::to_arrayType(basic_type);
- if (value->getType() != array_type)
- value = builder()->CreateIntCast(value, array_type, basic_type != T_CHAR);
-
- Value *addr = builder()->CreateArrayAddress(
- array->jarray_value(), basic_type, index->jint_value(), "addr");
-
- builder()->CreateStore(value, addr);
-
- if (basic_type == T_OBJECT) // XXX or T_ARRAY?
- builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr);
-}
-
-void SharkTopLevelBlock::do_return(BasicType type) {
- if (target()->intrinsic_id() == vmIntrinsics::_Object_init)
- call_register_finalizer(local(0)->jobject_value());
- maybe_add_safepoint();
- handle_return(type, NULL);
-}
-
-void SharkTopLevelBlock::do_athrow() {
- SharkValue *exception = pop();
- check_null(exception);
- handle_exception(exception->jobject_value(), EX_CHECK_FULL);
-}
-
-void SharkTopLevelBlock::do_goto() {
- do_branch(ciTypeFlow::GOTO_TARGET);
-}
-
-void SharkTopLevelBlock::do_jsr() {
- push(SharkValue::address_constant(iter()->next_bci()));
- do_branch(ciTypeFlow::GOTO_TARGET);
-}
-
-void SharkTopLevelBlock::do_ret() {
- assert(local(iter()->get_index())->address_value() ==
- successor(ciTypeFlow::GOTO_TARGET)->start(), "should be");
- do_branch(ciTypeFlow::GOTO_TARGET);
-}
-
-// All propagation of state from one block to the next (via
-// dest->add_incoming) is handled by these methods:
-// do_branch
-// do_if_helper
-// do_switch
-// handle_exception
-
-void SharkTopLevelBlock::do_branch(int successor_index) {
- SharkTopLevelBlock *dest = successor(successor_index);
- builder()->CreateBr(dest->entry_block());
- dest->add_incoming(current_state());
-}
-
-void SharkTopLevelBlock::do_if(ICmpInst::Predicate p,
- SharkValue* b,
- SharkValue* a) {
- Value *llvm_a, *llvm_b;
- if (a->is_jobject()) {
- llvm_a = a->intptr_value(builder());
- llvm_b = b->intptr_value(builder());
- }
- else {
- llvm_a = a->jint_value();
- llvm_b = b->jint_value();
- }
- do_if_helper(p, llvm_b, llvm_a, current_state(), current_state());
-}
-
-void SharkTopLevelBlock::do_if_helper(ICmpInst::Predicate p,
- Value* b,
- Value* a,
- SharkState* if_taken_state,
- SharkState* not_taken_state) {
- SharkTopLevelBlock *if_taken = successor(ciTypeFlow::IF_TAKEN);
- SharkTopLevelBlock *not_taken = successor(ciTypeFlow::IF_NOT_TAKEN);
-
- builder()->CreateCondBr(
- builder()->CreateICmp(p, a, b),
- if_taken->entry_block(), not_taken->entry_block());
-
- if_taken->add_incoming(if_taken_state);
- not_taken->add_incoming(not_taken_state);
-}
-
-void SharkTopLevelBlock::do_switch() {
- int len = switch_table_length();
-
- SharkTopLevelBlock *dest_block = successor(ciTypeFlow::SWITCH_DEFAULT);
- SwitchInst *switchinst = builder()->CreateSwitch(
- pop()->jint_value(), dest_block->entry_block(), len);
- dest_block->add_incoming(current_state());
-
- for (int i = 0; i < len; i++) {
- int dest_bci = switch_dest(i);
- if (dest_bci != switch_default_dest()) {
- dest_block = bci_successor(dest_bci);
- switchinst->addCase(
- LLVMValue::jint_constant(switch_key(i)),
- dest_block->entry_block());
- dest_block->add_incoming(current_state());
- }
- }
-}
-
-ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod* caller,
- ciInstanceKlass* klass,
- ciMethod* dest_method,
- ciType* receiver_type) {
- // If the method is obviously final then we are already done
- if (dest_method->can_be_statically_bound())
- return dest_method;
-
- // Array methods are all inherited from Object and are monomorphic
- if (receiver_type->is_array_klass() &&
- dest_method->holder() == java_lang_Object_klass())
- return dest_method;
-
- // This code can replace a virtual call with a direct call if this
- // class is the only one in the entire set of loaded classes that
- // implements this method. This makes the compiled code dependent
- // on other classes that implement the method not being loaded, a
- // condition which is enforced by the dependency tracker. If the
- // dependency tracker determines a method has become invalid it
- // will mark it for recompilation, causing running copies to be
- // deoptimized. Shark currently can't deoptimize arbitrarily like
- // that, so this optimization cannot be used.
- // http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=481
-
- // All other interesting cases are instance classes
- if (!receiver_type->is_instance_klass())
- return NULL;
-
- // Attempt to improve the receiver
- ciInstanceKlass* actual_receiver = klass;
- ciInstanceKlass *improved_receiver = receiver_type->as_instance_klass();
- if (improved_receiver->is_loaded() &&
- improved_receiver->is_initialized() &&
- !improved_receiver->is_interface() &&
- improved_receiver->is_subtype_of(actual_receiver)) {
- actual_receiver = improved_receiver;
- }
-
- // Attempt to find a monomorphic target for this call using
- // class heirachy analysis.
- ciInstanceKlass *calling_klass = caller->holder();
- ciMethod* monomorphic_target =
- dest_method->find_monomorphic_target(calling_klass, klass, actual_receiver);
- if (monomorphic_target != NULL) {
- assert(!monomorphic_target->is_abstract(), "shouldn't be");
-
- function()->dependencies()->assert_unique_concrete_method(actual_receiver, monomorphic_target);
-
- // Opto has a bunch of type checking here that I don't
- // understand. It's to inhibit casting in one direction,
- // possibly because objects in Opto can have inexact
- // types, but I can't even tell which direction it
- // doesn't like. For now I'm going to block *any* cast.
- if (monomorphic_target != dest_method) {
- if (SharkPerformanceWarnings) {
- warning("found monomorphic target, but inhibited cast:");
- tty->print(" dest_method = ");
- dest_method->print_short_name(tty);
- tty->cr();
- tty->print(" monomorphic_target = ");
- monomorphic_target->print_short_name(tty);
- tty->cr();
- }
- monomorphic_target = NULL;
- }
- }
-
- // Replace the virtual call with a direct one. This makes
- // us dependent on that target method not getting overridden
- // by dynamic class loading.
- if (monomorphic_target != NULL) {
- dependencies()->assert_unique_concrete_method(
- actual_receiver, monomorphic_target);
- return monomorphic_target;
- }
-
- // Because Opto distinguishes exact types from inexact ones
- // it can perform a further optimization to replace calls
- // with non-monomorphic targets if the receiver has an exact
- // type. We don't mark types this way, so we can't do this.
-
-
- return NULL;
-}
-
-Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method) {
- return builder()->CreateBitCast(
- builder()->CreateInlineMetadata(method, SharkType::Method_type()),
- SharkType::Method_type(),
- "callee");
-}
-
-Value *SharkTopLevelBlock::get_virtual_callee(SharkValue* receiver,
- int vtable_index) {
- Value *klass = builder()->CreateValueOfStructEntry(
- receiver->jobject_value(),
- in_ByteSize(oopDesc::klass_offset_in_bytes()),
- SharkType::oop_type(),
- "klass");
-
- return builder()->CreateLoad(
- builder()->CreateArrayAddress(
- klass,
- SharkType::Method_type(),
- vtableEntry::size_in_bytes(),
- Klass::vtable_start_offset(),
- LLVMValue::intptr_constant(vtable_index)),
- "callee");
-}
-
-Value* SharkTopLevelBlock::get_interface_callee(SharkValue *receiver,
- ciMethod* method) {
- BasicBlock *loop = function()->CreateBlock("loop");
- BasicBlock *got_null = function()->CreateBlock("got_null");
- BasicBlock *not_null = function()->CreateBlock("not_null");
- BasicBlock *next = function()->CreateBlock("next");
- BasicBlock *got_entry = function()->CreateBlock("got_entry");
-
- // Locate the receiver's itable
- Value *object_klass = builder()->CreateValueOfStructEntry(
- receiver->jobject_value(), in_ByteSize(oopDesc::klass_offset_in_bytes()),
- SharkType::klass_type(),
- "object_klass");
-
- Value *vtable_start = builder()->CreateAdd(
- builder()->CreatePtrToInt(object_klass, SharkType::intptr_type()),
- LLVMValue::intptr_constant(
- in_bytes(Klass::vtable_start_offset())),
- "vtable_start");
-
- Value *vtable_length = builder()->CreateValueOfStructEntry(
- object_klass,
- Klass::vtable_length_offset(),
- SharkType::jint_type(),
- "vtable_length");
- vtable_length =
- builder()->CreateIntCast(vtable_length, SharkType::intptr_type(), false);
-
- bool needs_aligning = HeapWordsPerLong > 1;
- Value *itable_start = builder()->CreateAdd(
- vtable_start,
- builder()->CreateShl(
- vtable_length,
- LLVMValue::intptr_constant(exact_log2(vtableEntry::size_in_bytes()))),
- needs_aligning ? "" : "itable_start");
- if (needs_aligning) {
- itable_start = builder()->CreateAnd(
- builder()->CreateAdd(
- itable_start, LLVMValue::intptr_constant(BytesPerLong - 1)),
- LLVMValue::intptr_constant(~(BytesPerLong - 1)),
- "itable_start");
- }
-
- // Locate this interface's entry in the table
- Value *iklass = builder()->CreateInlineMetadata(method->holder(), SharkType::klass_type());
- BasicBlock *loop_entry = builder()->GetInsertBlock();
- builder()->CreateBr(loop);
- builder()->SetInsertPoint(loop);
- PHINode *itable_entry_addr = builder()->CreatePHI(
- SharkType::intptr_type(), 0, "itable_entry_addr");
- itable_entry_addr->addIncoming(itable_start, loop_entry);
-
- Value *itable_entry = builder()->CreateIntToPtr(
- itable_entry_addr, SharkType::itableOffsetEntry_type(), "itable_entry");
-
- Value *itable_iklass = builder()->CreateValueOfStructEntry(
- itable_entry,
- in_ByteSize(itableOffsetEntry::interface_offset_in_bytes()),
- SharkType::klass_type(),
- "itable_iklass");
-
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(itable_iklass, LLVMValue::nullKlass()),
- got_null, not_null);
-
- // A null entry means that the class doesn't implement the
- // interface, and wasn't the same as the class checked when
- // the interface was resolved.
- builder()->SetInsertPoint(got_null);
- builder()->CreateUnimplemented(__FILE__, __LINE__);
- builder()->CreateUnreachable();
-
- builder()->SetInsertPoint(not_null);
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(itable_iklass, iklass),
- got_entry, next);
-
- builder()->SetInsertPoint(next);
- Value *next_entry = builder()->CreateAdd(
- itable_entry_addr,
- LLVMValue::intptr_constant(itableOffsetEntry::size() * wordSize));
- builder()->CreateBr(loop);
- itable_entry_addr->addIncoming(next_entry, next);
-
- // Locate the method pointer
- builder()->SetInsertPoint(got_entry);
- Value *offset = builder()->CreateValueOfStructEntry(
- itable_entry,
- in_ByteSize(itableOffsetEntry::offset_offset_in_bytes()),
- SharkType::jint_type(),
- "offset");
- offset =
- builder()->CreateIntCast(offset, SharkType::intptr_type(), false);
-
- return builder()->CreateLoad(
- builder()->CreateIntToPtr(
- builder()->CreateAdd(
- builder()->CreateAdd(
- builder()->CreateAdd(
- builder()->CreatePtrToInt(
- object_klass, SharkType::intptr_type()),
- offset),
- LLVMValue::intptr_constant(
- method->itable_index() * itableMethodEntry::size() * wordSize)),
- LLVMValue::intptr_constant(
- itableMethodEntry::method_offset_in_bytes())),
- PointerType::getUnqual(SharkType::Method_type())),
- "callee");
-}
-
-void SharkTopLevelBlock::do_call() {
- // Set frequently used booleans
- bool is_static = bc() == Bytecodes::_invokestatic;
- bool is_virtual = bc() == Bytecodes::_invokevirtual;
- bool is_interface = bc() == Bytecodes::_invokeinterface;
-
- // Find the method being called
- bool will_link;
- ciSignature* sig;
- ciMethod *dest_method = iter()->get_method(will_link, &sig);
-
- assert(will_link, "typeflow responsibility");
- assert(dest_method->is_static() == is_static, "must match bc");
-
- // Find the class of the method being called. Note
- // that the superclass check in the second assertion
- // is to cope with a hole in the spec that allows for
- // invokeinterface instructions where the resolved
- // method is a virtual method in java.lang.Object.
- // javac doesn't generate code like that, but there's
- // no reason a compliant Java compiler might not.
- ciInstanceKlass *holder_klass = dest_method->holder();
- assert(holder_klass->is_loaded(), "scan_for_traps responsibility");
- assert(holder_klass->is_interface() ||
- holder_klass->super() == NULL ||
- !is_interface, "must match bc");
-
- bool is_forced_virtual = is_interface && holder_klass == java_lang_Object_klass();
-
- ciKlass *holder = iter()->get_declared_method_holder();
- ciInstanceKlass *klass =
- ciEnv::get_instance_klass_for_declared_method_holder(holder);
-
- if (is_forced_virtual) {
- klass = java_lang_Object_klass();
- }
-
- // Find the receiver in the stack. We do this before
- // trying to inline because the inliner can only use
- // zero-checked values, not being able to perform the
- // check itself.
- SharkValue *receiver = NULL;
- if (!is_static) {
- receiver = xstack(dest_method->arg_size() - 1);
- check_null(receiver);
- }
-
- // Try to improve non-direct calls
- bool call_is_virtual = is_virtual || is_interface;
- ciMethod *call_method = dest_method;
- if (call_is_virtual) {
- ciMethod *optimized_method = improve_virtual_call(
- target(), klass, dest_method, receiver->type());
- if (optimized_method) {
- call_method = optimized_method;
- call_is_virtual = false;
- }
- }
-
- // Try to inline the call
- if (!call_is_virtual) {
- if (SharkInliner::attempt_inline(call_method, current_state())) {
- return;
- }
- }
-
- // Find the method we are calling
- Value *callee;
- if (call_is_virtual) {
- if (is_virtual || is_forced_virtual) {
- assert(klass->is_linked(), "scan_for_traps responsibility");
- int vtable_index = call_method->resolve_vtable_index(
- target()->holder(), klass);
- assert(vtable_index >= 0, "should be");
- callee = get_virtual_callee(receiver, vtable_index);
- }
- else {
- assert(is_interface, "should be");
- callee = get_interface_callee(receiver, call_method);
- }
- }
- else {
- callee = get_direct_callee(call_method);
- }
-
- // Load the SharkEntry from the callee
- Value *base_pc = builder()->CreateValueOfStructEntry(
- callee, Method::from_interpreted_offset(),
- SharkType::intptr_type(),
- "base_pc");
-
- // Load the entry point from the SharkEntry
- Value *entry_point = builder()->CreateLoad(
- builder()->CreateIntToPtr(
- builder()->CreateAdd(
- base_pc,
- LLVMValue::intptr_constant(in_bytes(ZeroEntry::entry_point_offset()))),
- PointerType::getUnqual(
- PointerType::getUnqual(SharkType::entry_point_type()))),
- "entry_point");
-
- // Make the call
- decache_for_Java_call(call_method);
- Value *deoptimized_frames = builder()->CreateCall3(
- entry_point, callee, base_pc, thread());
-
- // If the callee got deoptimized then reexecute in the interpreter
- BasicBlock *reexecute = function()->CreateBlock("reexecute");
- BasicBlock *call_completed = function()->CreateBlock("call_completed");
- builder()->CreateCondBr(
- builder()->CreateICmpNE(deoptimized_frames, LLVMValue::jint_constant(0)),
- reexecute, call_completed);
-
- builder()->SetInsertPoint(reexecute);
- builder()->CreateCall2(
- builder()->deoptimized_entry_point(),
- builder()->CreateSub(deoptimized_frames, LLVMValue::jint_constant(1)),
- thread());
- builder()->CreateBr(call_completed);
-
- // Cache after the call
- builder()->SetInsertPoint(call_completed);
- cache_after_Java_call(call_method);
-
- // Check for pending exceptions
- check_pending_exception(EX_CHECK_FULL);
-
- // Mark that a safepoint check has occurred
- current_state()->set_has_safepointed(true);
-}
-
-bool SharkTopLevelBlock::static_subtype_check(ciKlass* check_klass,
- ciKlass* object_klass) {
- // If the class we're checking against is java.lang.Object
- // then this is a no brainer. Apparently this can happen
- // in reflective code...
- if (check_klass == java_lang_Object_klass())
- return true;
-
- // Perform a subtype check. NB in opto's code for this
- // (GraphKit::static_subtype_check) it says that static
- // interface types cannot be trusted, and if opto can't
- // trust them then I assume we can't either.
- if (object_klass->is_loaded() && !object_klass->is_interface()) {
- if (object_klass == check_klass)
- return true;
-
- if (check_klass->is_loaded() && object_klass->is_subtype_of(check_klass))
- return true;
- }
-
- return false;
-}
-
-void SharkTopLevelBlock::do_instance_check() {
- // Get the class we're checking against
- bool will_link;
- ciKlass *check_klass = iter()->get_klass(will_link);
-
- // Get the class of the object we're checking
- ciKlass *object_klass = xstack(0)->type()->as_klass();
-
- // Can we optimize this check away?
- if (static_subtype_check(check_klass, object_klass)) {
- if (bc() == Bytecodes::_instanceof) {
- pop();
- push(SharkValue::jint_constant(1));
- }
- return;
- }
-
- // Need to check this one at runtime
- if (will_link)
- do_full_instance_check(check_klass);
- else
- do_trapping_instance_check(check_klass);
-}
-
-bool SharkTopLevelBlock::maybe_do_instanceof_if() {
- // Get the class we're checking against
- bool will_link;
- ciKlass *check_klass = iter()->get_klass(will_link);
-
- // If the class is unloaded then the instanceof
- // cannot possibly succeed.
- if (!will_link)
- return false;
-
- // Keep a copy of the object we're checking
- SharkValue *old_object = xstack(0);
-
- // Get the class of the object we're checking
- ciKlass *object_klass = old_object->type()->as_klass();
-
- // If the instanceof can be optimized away at compile time
- // then any subsequent checkcasts will be too so we handle
- // it normally.
- if (static_subtype_check(check_klass, object_klass))
- return false;
-
- // Perform the instance check
- do_full_instance_check(check_klass);
- Value *result = pop()->jint_value();
-
- // Create the casted object
- SharkValue *new_object = SharkValue::create_generic(
- check_klass, old_object->jobject_value(), old_object->zero_checked());
-
- // Create two copies of the current state, one with the
- // original object and one with all instances of the
- // original object replaced with the new, casted object.
- SharkState *new_state = current_state();
- SharkState *old_state = new_state->copy();
- new_state->replace_all(old_object, new_object);
-
- // Perform the check-and-branch
- switch (iter()->next_bc()) {
- case Bytecodes::_ifeq:
- // branch if not an instance
- do_if_helper(
- ICmpInst::ICMP_EQ,
- LLVMValue::jint_constant(0), result,
- old_state, new_state);
- break;
-
- case Bytecodes::_ifne:
- // branch if an instance
- do_if_helper(
- ICmpInst::ICMP_NE,
- LLVMValue::jint_constant(0), result,
- new_state, old_state);
- break;
-
- default:
- ShouldNotReachHere();
- }
-
- return true;
-}
-
-void SharkTopLevelBlock::do_full_instance_check(ciKlass* klass) {
- BasicBlock *not_null = function()->CreateBlock("not_null");
- BasicBlock *subtype_check = function()->CreateBlock("subtype_check");
- BasicBlock *is_instance = function()->CreateBlock("is_instance");
- BasicBlock *not_instance = function()->CreateBlock("not_instance");
- BasicBlock *merge1 = function()->CreateBlock("merge1");
- BasicBlock *merge2 = function()->CreateBlock("merge2");
-
- enum InstanceCheckStates {
- IC_IS_NULL,
- IC_IS_INSTANCE,
- IC_NOT_INSTANCE,
- };
-
- // Pop the object off the stack
- Value *object = pop()->jobject_value();
-
- // Null objects aren't instances of anything
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(object, LLVMValue::null()),
- merge2, not_null);
- BasicBlock *null_block = builder()->GetInsertBlock();
-
- // Get the class we're checking against
- builder()->SetInsertPoint(not_null);
- Value *check_klass = builder()->CreateInlineMetadata(klass, SharkType::klass_type());
-
- // Get the class of the object being tested
- Value *object_klass = builder()->CreateValueOfStructEntry(
- object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
- SharkType::klass_type(),
- "object_klass");
-
- // Perform the check
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(check_klass, object_klass),
- is_instance, subtype_check);
-
- builder()->SetInsertPoint(subtype_check);
- builder()->CreateCondBr(
- builder()->CreateICmpNE(
- builder()->CreateCall2(
- builder()->is_subtype_of(), check_klass, object_klass),
- LLVMValue::jbyte_constant(0)),
- is_instance, not_instance);
-
- builder()->SetInsertPoint(is_instance);
- builder()->CreateBr(merge1);
-
- builder()->SetInsertPoint(not_instance);
- builder()->CreateBr(merge1);
-
- // First merge
- builder()->SetInsertPoint(merge1);
- PHINode *nonnull_result = builder()->CreatePHI(
- SharkType::jint_type(), 0, "nonnull_result");
- nonnull_result->addIncoming(
- LLVMValue::jint_constant(IC_IS_INSTANCE), is_instance);
- nonnull_result->addIncoming(
- LLVMValue::jint_constant(IC_NOT_INSTANCE), not_instance);
- BasicBlock *nonnull_block = builder()->GetInsertBlock();
- builder()->CreateBr(merge2);
-
- // Second merge
- builder()->SetInsertPoint(merge2);
- PHINode *result = builder()->CreatePHI(
- SharkType::jint_type(), 0, "result");
- result->addIncoming(LLVMValue::jint_constant(IC_IS_NULL), null_block);
- result->addIncoming(nonnull_result, nonnull_block);
-
- // Handle the result
- if (bc() == Bytecodes::_checkcast) {
- BasicBlock *failure = function()->CreateBlock("failure");
- BasicBlock *success = function()->CreateBlock("success");
-
- builder()->CreateCondBr(
- builder()->CreateICmpNE(
- result, LLVMValue::jint_constant(IC_NOT_INSTANCE)),
- success, failure);
-
- builder()->SetInsertPoint(failure);
- SharkState *saved_state = current_state()->copy();
-
- call_vm(
- builder()->throw_ClassCastException(),
- builder()->CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) __FILE__),
- PointerType::getUnqual(SharkType::jbyte_type())),
- LLVMValue::jint_constant(__LINE__),
- EX_CHECK_NONE);
-
- Value *pending_exception = get_pending_exception();
- clear_pending_exception();
- handle_exception(pending_exception, EX_CHECK_FULL);
-
- set_current_state(saved_state);
- builder()->SetInsertPoint(success);
- push(SharkValue::create_generic(klass, object, false));
- }
- else {
- push(
- SharkValue::create_jint(
- builder()->CreateIntCast(
- builder()->CreateICmpEQ(
- result, LLVMValue::jint_constant(IC_IS_INSTANCE)),
- SharkType::jint_type(), false), false));
- }
-}
-
-void SharkTopLevelBlock::do_trapping_instance_check(ciKlass* klass) {
- BasicBlock *not_null = function()->CreateBlock("not_null");
- BasicBlock *is_null = function()->CreateBlock("null");
-
- // Leave the object on the stack so it's there if we trap
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(xstack(0)->jobject_value(), LLVMValue::null()),
- is_null, not_null);
- SharkState *saved_state = current_state()->copy();
-
- // If it's not null then we need to trap
- builder()->SetInsertPoint(not_null);
- set_current_state(saved_state->copy());
- do_trap(
- Deoptimization::make_trap_request(
- Deoptimization::Reason_uninitialized,
- Deoptimization::Action_reinterpret));
-
- // If it's null then we're ok
- builder()->SetInsertPoint(is_null);
- set_current_state(saved_state);
- if (bc() == Bytecodes::_checkcast) {
- push(SharkValue::create_generic(klass, pop()->jobject_value(), false));
- }
- else {
- pop();
- push(SharkValue::jint_constant(0));
- }
-}
-
-void SharkTopLevelBlock::do_new() {
- bool will_link;
- ciInstanceKlass* klass = iter()->get_klass(will_link)->as_instance_klass();
- assert(will_link, "typeflow responsibility");
-
- BasicBlock *got_tlab = NULL;
- BasicBlock *heap_alloc = NULL;
- BasicBlock *retry = NULL;
- BasicBlock *got_heap = NULL;
- BasicBlock *initialize = NULL;
- BasicBlock *got_fast = NULL;
- BasicBlock *slow_alloc_and_init = NULL;
- BasicBlock *got_slow = NULL;
- BasicBlock *push_object = NULL;
-
- SharkState *fast_state = NULL;
-
- Value *tlab_object = NULL;
- Value *heap_object = NULL;
- Value *fast_object = NULL;
- Value *slow_object = NULL;
- Value *object = NULL;
-
- // The fast path
- if (!Klass::layout_helper_needs_slow_path(klass->layout_helper())) {
- if (UseTLAB) {
- got_tlab = function()->CreateBlock("got_tlab");
- heap_alloc = function()->CreateBlock("heap_alloc");
- }
- retry = function()->CreateBlock("retry");
- got_heap = function()->CreateBlock("got_heap");
- initialize = function()->CreateBlock("initialize");
- slow_alloc_and_init = function()->CreateBlock("slow_alloc_and_init");
- push_object = function()->CreateBlock("push_object");
-
- size_t size_in_bytes = klass->size_helper() << LogHeapWordSize;
-
- // Thread local allocation
- if (UseTLAB) {
- Value *top_addr = builder()->CreateAddressOfStructEntry(
- thread(), Thread::tlab_top_offset(),
- PointerType::getUnqual(SharkType::intptr_type()),
- "top_addr");
-
- Value *end = builder()->CreateValueOfStructEntry(
- thread(), Thread::tlab_end_offset(),
- SharkType::intptr_type(),
- "end");
-
- Value *old_top = builder()->CreateLoad(top_addr, "old_top");
- Value *new_top = builder()->CreateAdd(
- old_top, LLVMValue::intptr_constant(size_in_bytes));
-
- builder()->CreateCondBr(
- builder()->CreateICmpULE(new_top, end),
- got_tlab, heap_alloc);
-
- builder()->SetInsertPoint(got_tlab);
- tlab_object = builder()->CreateIntToPtr(
- old_top, SharkType::oop_type(), "tlab_object");
-
- builder()->CreateStore(new_top, top_addr);
- builder()->CreateBr(initialize);
-
- builder()->SetInsertPoint(heap_alloc);
- }
-
- // Heap allocation
- Value *top_addr = builder()->CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) Universe::heap()->top_addr()),
- PointerType::getUnqual(SharkType::intptr_type()),
- "top_addr");
-
- Value *end = builder()->CreateLoad(
- builder()->CreateIntToPtr(
- LLVMValue::intptr_constant((intptr_t) Universe::heap()->end_addr()),
- PointerType::getUnqual(SharkType::intptr_type())),
- "end");
-
- builder()->CreateBr(retry);
- builder()->SetInsertPoint(retry);
-
- Value *old_top = builder()->CreateLoad(top_addr, "top");
- Value *new_top = builder()->CreateAdd(
- old_top, LLVMValue::intptr_constant(size_in_bytes));
-
- builder()->CreateCondBr(
- builder()->CreateICmpULE(new_top, end),
- got_heap, slow_alloc_and_init);
-
- builder()->SetInsertPoint(got_heap);
- heap_object = builder()->CreateIntToPtr(
- old_top, SharkType::oop_type(), "heap_object");
-
- Value *check = builder()->CreateAtomicCmpXchg(top_addr, old_top, new_top, llvm::SequentiallyConsistent);
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(old_top, check),
- initialize, retry);
-
- // Initialize the object
- builder()->SetInsertPoint(initialize);
- if (tlab_object) {
- PHINode *phi = builder()->CreatePHI(
- SharkType::oop_type(), 0, "fast_object");
- phi->addIncoming(tlab_object, got_tlab);
- phi->addIncoming(heap_object, got_heap);
- fast_object = phi;
- }
- else {
- fast_object = heap_object;
- }
-
- builder()->CreateMemset(
- builder()->CreateBitCast(
- fast_object, PointerType::getUnqual(SharkType::jbyte_type())),
- LLVMValue::jbyte_constant(0),
- LLVMValue::jint_constant(size_in_bytes),
- LLVMValue::jint_constant(HeapWordSize));
-
- Value *mark_addr = builder()->CreateAddressOfStructEntry(
- fast_object, in_ByteSize(oopDesc::mark_offset_in_bytes()),
- PointerType::getUnqual(SharkType::intptr_type()),
- "mark_addr");
-
- Value *klass_addr = builder()->CreateAddressOfStructEntry(
- fast_object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
- PointerType::getUnqual(SharkType::klass_type()),
- "klass_addr");
-
- // Set the mark
- intptr_t mark;
- if (UseBiasedLocking) {
- Unimplemented();
- }
- else {
- mark = (intptr_t) markOopDesc::prototype();
- }
- builder()->CreateStore(LLVMValue::intptr_constant(mark), mark_addr);
-
- // Set the class
- Value *rtklass = builder()->CreateInlineMetadata(klass, SharkType::klass_type());
- builder()->CreateStore(rtklass, klass_addr);
- got_fast = builder()->GetInsertBlock();
-
- builder()->CreateBr(push_object);
- builder()->SetInsertPoint(slow_alloc_and_init);
- fast_state = current_state()->copy();
- }
-
- // The slow path
- call_vm(
- builder()->new_instance(),
- LLVMValue::jint_constant(iter()->get_klass_index()),
- EX_CHECK_FULL);
- slow_object = get_vm_result();
- got_slow = builder()->GetInsertBlock();
-
- // Push the object
- if (push_object) {
- builder()->CreateBr(push_object);
- builder()->SetInsertPoint(push_object);
- }
- if (fast_object) {
- PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), 0, "object");
- phi->addIncoming(fast_object, got_fast);
- phi->addIncoming(slow_object, got_slow);
- object = phi;
- current_state()->merge(fast_state, got_fast, got_slow);
- }
- else {
- object = slow_object;
- }
-
- push(SharkValue::create_jobject(object, true));
-}
-
-void SharkTopLevelBlock::do_newarray() {
- BasicType type = (BasicType) iter()->get_index();
-
- call_vm(
- builder()->newarray(),
- LLVMValue::jint_constant(type),
- pop()->jint_value(),
- EX_CHECK_FULL);
-
- ciArrayKlass *array_klass = ciArrayKlass::make(ciType::make(type));
- push(SharkValue::create_generic(array_klass, get_vm_result(), true));
-}
-
-void SharkTopLevelBlock::do_anewarray() {
- bool will_link;
- ciKlass *klass = iter()->get_klass(will_link);
- assert(will_link, "typeflow responsibility");
-
- ciObjArrayKlass *array_klass = ciObjArrayKlass::make(klass);
- if (!array_klass->is_loaded()) {
- Unimplemented();
- }
-
- call_vm(
- builder()->anewarray(),
- LLVMValue::jint_constant(iter()->get_klass_index()),
- pop()->jint_value(),
- EX_CHECK_FULL);
-
- push(SharkValue::create_generic(array_klass, get_vm_result(), true));
-}
-
-void SharkTopLevelBlock::do_multianewarray() {
- bool will_link;
- ciArrayKlass *array_klass = iter()->get_klass(will_link)->as_array_klass();
- assert(will_link, "typeflow responsibility");
-
- // The dimensions are stack values, so we use their slots for the
- // dimensions array. Note that we are storing them in the reverse
- // of normal stack order.
- int ndims = iter()->get_dimensions();
-
- Value *dimensions = stack()->slot_addr(
- stack()->stack_slots_offset() + max_stack() - xstack_depth(),
- ArrayType::get(SharkType::jint_type(), ndims),
- "dimensions");
-
- for (int i = 0; i < ndims; i++) {
- builder()->CreateStore(
- xstack(ndims - 1 - i)->jint_value(),
- builder()->CreateStructGEP(dimensions, i));
- }
-
- call_vm(
- builder()->multianewarray(),
- LLVMValue::jint_constant(iter()->get_klass_index()),
- LLVMValue::jint_constant(ndims),
- builder()->CreateStructGEP(dimensions, 0),
- EX_CHECK_FULL);
-
- // Now we can pop the dimensions off the stack
- for (int i = 0; i < ndims; i++)
- pop();
-
- push(SharkValue::create_generic(array_klass, get_vm_result(), true));
-}
-
-void SharkTopLevelBlock::acquire_method_lock() {
- Value *lockee;
- if (target()->is_static()) {
- lockee = builder()->CreateInlineOop(target()->holder()->java_mirror());
- }
- else
- lockee = local(0)->jobject_value();
-
- iter()->force_bci(start()); // for the decache in acquire_lock
- acquire_lock(lockee, EX_CHECK_NO_CATCH);
-}
-
-void SharkTopLevelBlock::do_monitorenter() {
- SharkValue *lockee = pop();
- check_null(lockee);
- acquire_lock(lockee->jobject_value(), EX_CHECK_FULL);
-}
-
-void SharkTopLevelBlock::do_monitorexit() {
- pop(); // don't need this (monitors are block structured)
- release_lock(EX_CHECK_NO_CATCH);
-}
-
-void SharkTopLevelBlock::acquire_lock(Value *lockee, int exception_action) {
- BasicBlock *try_recursive = function()->CreateBlock("try_recursive");
- BasicBlock *got_recursive = function()->CreateBlock("got_recursive");
- BasicBlock *not_recursive = function()->CreateBlock("not_recursive");
- BasicBlock *acquired_fast = function()->CreateBlock("acquired_fast");
- BasicBlock *lock_acquired = function()->CreateBlock("lock_acquired");
-
- int monitor = num_monitors();
- Value *monitor_addr = stack()->monitor_addr(monitor);
- Value *monitor_object_addr = stack()->monitor_object_addr(monitor);
- Value *monitor_header_addr = stack()->monitor_header_addr(monitor);
-
- // Store the object and mark the slot as live
- builder()->CreateStore(lockee, monitor_object_addr);
- set_num_monitors(monitor + 1);
-
- // Try a simple lock
- Value *mark_addr = builder()->CreateAddressOfStructEntry(
- lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()),
- PointerType::getUnqual(SharkType::intptr_type()),
- "mark_addr");
-
- Value *mark = builder()->CreateLoad(mark_addr, "mark");
- Value *disp = builder()->CreateOr(
- mark, LLVMValue::intptr_constant(markOopDesc::unlocked_value), "disp");
- builder()->CreateStore(disp, monitor_header_addr);
-
- Value *lock = builder()->CreatePtrToInt(
- monitor_header_addr, SharkType::intptr_type());
- Value *check = builder()->CreateAtomicCmpXchg(mark_addr, disp, lock, llvm::Acquire);
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(disp, check),
- acquired_fast, try_recursive);
-
- // Locking failed, but maybe this thread already owns it
- builder()->SetInsertPoint(try_recursive);
- Value *addr = builder()->CreateAnd(
- disp,
- LLVMValue::intptr_constant(~markOopDesc::lock_mask_in_place));
-
- // NB we use the entire stack, but JavaThread::is_lock_owned()
- // uses a more limited range. I don't think it hurts though...
- Value *stack_limit = builder()->CreateValueOfStructEntry(
- thread(), Thread::stack_base_offset(),
- SharkType::intptr_type(),
- "stack_limit");
-
- assert(sizeof(size_t) == sizeof(intptr_t), "should be");
- Value *stack_size = builder()->CreateValueOfStructEntry(
- thread(), Thread::stack_size_offset(),
- SharkType::intptr_type(),
- "stack_size");
-
- Value *stack_start =
- builder()->CreateSub(stack_limit, stack_size, "stack_start");
-
- builder()->CreateCondBr(
- builder()->CreateAnd(
- builder()->CreateICmpUGE(addr, stack_start),
- builder()->CreateICmpULT(addr, stack_limit)),
- got_recursive, not_recursive);
-
- builder()->SetInsertPoint(got_recursive);
- builder()->CreateStore(LLVMValue::intptr_constant(0), monitor_header_addr);
- builder()->CreateBr(acquired_fast);
-
- // Create an edge for the state merge
- builder()->SetInsertPoint(acquired_fast);
- SharkState *fast_state = current_state()->copy();
- builder()->CreateBr(lock_acquired);
-
- // It's not a recursive case so we need to drop into the runtime
- builder()->SetInsertPoint(not_recursive);
- call_vm(
- builder()->monitorenter(), monitor_addr,
- exception_action | EAM_MONITOR_FUDGE);
- BasicBlock *acquired_slow = builder()->GetInsertBlock();
- builder()->CreateBr(lock_acquired);
-
- // All done
- builder()->SetInsertPoint(lock_acquired);
- current_state()->merge(fast_state, acquired_fast, acquired_slow);
-}
-
-void SharkTopLevelBlock::release_lock(int exception_action) {
- BasicBlock *not_recursive = function()->CreateBlock("not_recursive");
- BasicBlock *released_fast = function()->CreateBlock("released_fast");
- BasicBlock *slow_path = function()->CreateBlock("slow_path");
- BasicBlock *lock_released = function()->CreateBlock("lock_released");
-
- int monitor = num_monitors() - 1;
- Value *monitor_addr = stack()->monitor_addr(monitor);
- Value *monitor_object_addr = stack()->monitor_object_addr(monitor);
- Value *monitor_header_addr = stack()->monitor_header_addr(monitor);
-
- // If it is recursive then we're already done
- Value *disp = builder()->CreateLoad(monitor_header_addr);
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(disp, LLVMValue::intptr_constant(0)),
- released_fast, not_recursive);
-
- // Try a simple unlock
- builder()->SetInsertPoint(not_recursive);
-
- Value *lock = builder()->CreatePtrToInt(
- monitor_header_addr, SharkType::intptr_type());
-
- Value *lockee = builder()->CreateLoad(monitor_object_addr);
-
- Value *mark_addr = builder()->CreateAddressOfStructEntry(
- lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()),
- PointerType::getUnqual(SharkType::intptr_type()),
- "mark_addr");
-
- Value *check = builder()->CreateAtomicCmpXchg(mark_addr, lock, disp, llvm::Release);
- builder()->CreateCondBr(
- builder()->CreateICmpEQ(lock, check),
- released_fast, slow_path);
-
- // Create an edge for the state merge
- builder()->SetInsertPoint(released_fast);
- SharkState *fast_state = current_state()->copy();
- builder()->CreateBr(lock_released);
-
- // Need to drop into the runtime to release this one
- builder()->SetInsertPoint(slow_path);
- call_vm(builder()->monitorexit(), monitor_addr, exception_action);
- BasicBlock *released_slow = builder()->GetInsertBlock();
- builder()->CreateBr(lock_released);
-
- // All done
- builder()->SetInsertPoint(lock_released);
- current_state()->merge(fast_state, released_fast, released_slow);
-
- // The object slot is now dead
- set_num_monitors(monitor);
-}
--- a/src/hotspot/share/shark/sharkTopLevelBlock.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,447 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP
-#define SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP
-
-#include "ci/ciStreams.hpp"
-#include "ci/ciType.hpp"
-#include "ci/ciTypeFlow.hpp"
-#include "interpreter/bytecodes.hpp"
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkBlock.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkFunction.hpp"
-#include "shark/sharkState.hpp"
-#include "shark/sharkValue.hpp"
-
-class SharkTopLevelBlock : public SharkBlock {
- public:
- SharkTopLevelBlock(SharkFunction* function, ciTypeFlow::Block* ciblock)
- : SharkBlock(function),
- _function(function),
- _ciblock(ciblock),
- _entered(false),
- _has_trap(false),
- _needs_phis(false),
- _entry_state(NULL),
- _entry_block(NULL) {}
-
- private:
- SharkFunction* _function;
- ciTypeFlow::Block* _ciblock;
-
- public:
- SharkFunction* function() const {
- return _function;
- }
- ciTypeFlow::Block* ciblock() const {
- return _ciblock;
- }
-
- // Function properties
- public:
- SharkStack* stack() const {
- return function()->stack();
- }
-
- // Typeflow properties
- public:
- int index() const {
- return ciblock()->pre_order();
- }
- bool is_backedge_copy() const {
- return ciblock()->is_backedge_copy();
- }
- int stack_depth_at_entry() const {
- return ciblock()->stack_size();
- }
- ciType* local_type_at_entry(int index) const {
- return ciblock()->local_type_at(index);
- }
- ciType* stack_type_at_entry(int slot) const {
- return ciblock()->stack_type_at(slot);
- }
- int start() const {
- return ciblock()->start();
- }
- int limit() const {
- return ciblock()->limit();
- }
- bool falls_through() const {
- return ciblock()->control() == ciBlock::fall_through_bci;
- }
- int num_successors() const {
- return ciblock()->successors()->length();
- }
- SharkTopLevelBlock* successor(int index) const {
- return function()->block(ciblock()->successors()->at(index)->pre_order());
- }
- SharkTopLevelBlock* bci_successor(int bci) const;
-
- // Exceptions
- private:
- GrowableArray<ciExceptionHandler*>* _exc_handlers;
- GrowableArray<SharkTopLevelBlock*>* _exceptions;
-
- private:
- void compute_exceptions();
-
- private:
- int num_exceptions() const {
- return _exc_handlers->length();
- }
- ciExceptionHandler* exc_handler(int index) const {
- return _exc_handlers->at(index);
- }
- SharkTopLevelBlock* exception(int index) const {
- return _exceptions->at(index);
- }
-
- // Traps
- private:
- bool _has_trap;
- int _trap_request;
- int _trap_bci;
-
- void set_trap(int trap_request, int trap_bci) {
- assert(!has_trap(), "shouldn't have");
- _has_trap = true;
- _trap_request = trap_request;
- _trap_bci = trap_bci;
- }
-
- private:
- bool has_trap() {
- return _has_trap;
- }
- int trap_request() {
- assert(has_trap(), "should have");
- return _trap_request;
- }
- int trap_bci() {
- assert(has_trap(), "should have");
- return _trap_bci;
- }
-
- private:
- void scan_for_traps();
-
- private:
- bool static_field_ok_in_clinit(ciField* field);
-
- // Entry state
- private:
- bool _entered;
- bool _needs_phis;
-
- public:
- bool entered() const {
- return _entered;
- }
- bool needs_phis() const {
- return _needs_phis;
- }
-
- private:
- void enter(SharkTopLevelBlock* predecessor, bool is_exception);
-
- public:
- void enter() {
- enter(NULL, false);
- }
-
- private:
- SharkState* _entry_state;
-
- private:
- SharkState* entry_state();
-
- private:
- llvm::BasicBlock* _entry_block;
-
- public:
- llvm::BasicBlock* entry_block() const {
- return _entry_block;
- }
-
- public:
- void initialize();
-
- public:
- void add_incoming(SharkState* incoming_state);
-
- // Method
- public:
- llvm::Value* method() {
- return current_state()->method();
- }
-
- // Temporary oop storage
- public:
- void set_oop_tmp(llvm::Value* value) {
- assert(value, "value must be non-NULL (will be reset by get_oop_tmp)");
- assert(!current_state()->oop_tmp(), "oop_tmp gets and sets must match");
- current_state()->set_oop_tmp(value);
- }
- llvm::Value* get_oop_tmp() {
- llvm::Value* value = current_state()->oop_tmp();
- assert(value, "oop_tmp gets and sets must match");
- current_state()->set_oop_tmp(NULL);
- return value;
- }
-
- // Cache and decache
- private:
- void decache_for_Java_call(ciMethod* callee);
- void cache_after_Java_call(ciMethod* callee);
- void decache_for_VM_call();
- void cache_after_VM_call();
- void decache_for_trap();
-
- // Monitors
- private:
- int num_monitors() {
- return current_state()->num_monitors();
- }
- int set_num_monitors(int num_monitors) {
- current_state()->set_num_monitors(num_monitors);
- }
-
- // Code generation
- public:
- void emit_IR();
-
- // Branch helpers
- private:
- void do_branch(int successor_index);
-
- // Zero checks
- private:
- void do_zero_check(SharkValue* value);
- void zero_check_value(SharkValue* value, llvm::BasicBlock* continue_block);
-
- public:
- void do_deferred_zero_check(SharkValue* value,
- int bci,
- SharkState* saved_state,
- llvm::BasicBlock* continue_block);
- // Exceptions
- private:
- llvm::Value* pending_exception_address() const {
- return builder()->CreateAddressOfStructEntry(
- thread(), Thread::pending_exception_offset(),
- llvm::PointerType::getUnqual(SharkType::oop_type()),
- "pending_exception_addr");
- }
- llvm::LoadInst* get_pending_exception() const {
- return builder()->CreateLoad(
- pending_exception_address(), "pending_exception");
- }
- void clear_pending_exception() const {
- builder()->CreateStore(LLVMValue::null(), pending_exception_address());
- }
- public:
- enum ExceptionActionMask {
- // The actual bitmasks that things test against
- EAM_CHECK = 1, // whether to check for pending exceptions
- EAM_HANDLE = 2, // whether to attempt to handle pending exceptions
- EAM_MONITOR_FUDGE = 4, // whether the monitor count needs adjusting
-
- // More convenient values for passing
- EX_CHECK_NONE = 0,
- EX_CHECK_NO_CATCH = EAM_CHECK,
- EX_CHECK_FULL = EAM_CHECK | EAM_HANDLE
- };
- void check_pending_exception(int action);
- void handle_exception(llvm::Value* exception, int action);
- void marshal_exception_fast(int num_options);
- void marshal_exception_slow(int num_options);
- llvm::BasicBlock* handler_for_exception(int index);
-
- // VM calls
- private:
- llvm::CallInst* call_vm(llvm::Value* callee,
- llvm::Value** args_start,
- llvm::Value** args_end,
- int exception_action) {
- decache_for_VM_call();
- stack()->CreateSetLastJavaFrame();
- llvm::CallInst *res = builder()->CreateCall(callee, llvm::makeArrayRef(args_start, args_end));
- stack()->CreateResetLastJavaFrame();
- cache_after_VM_call();
- if (exception_action & EAM_CHECK) {
- check_pending_exception(exception_action);
- current_state()->set_has_safepointed(true);
- }
- return res;
- }
-
- public:
- llvm::CallInst* call_vm(llvm::Value* callee,
- int exception_action) {
- llvm::Value *args[] = {thread()};
- return call_vm(callee, args, args + 1, exception_action);
- }
- llvm::CallInst* call_vm(llvm::Value* callee,
- llvm::Value* arg1,
- int exception_action) {
- llvm::Value *args[] = {thread(), arg1};
- return call_vm(callee, args, args + 2, exception_action);
- }
- llvm::CallInst* call_vm(llvm::Value* callee,
- llvm::Value* arg1,
- llvm::Value* arg2,
- int exception_action) {
- llvm::Value *args[] = {thread(), arg1, arg2};
- return call_vm(callee, args, args + 3, exception_action);
- }
- llvm::CallInst* call_vm(llvm::Value* callee,
- llvm::Value* arg1,
- llvm::Value* arg2,
- llvm::Value* arg3,
- int exception_action) {
- llvm::Value *args[] = {thread(), arg1, arg2, arg3};
- return call_vm(callee, args, args + 4, exception_action);
- }
-
- // VM call oop return handling
- private:
- llvm::LoadInst* get_vm_result() const {
- llvm::Value *addr = builder()->CreateAddressOfStructEntry(
- thread(), JavaThread::vm_result_offset(),
- llvm::PointerType::getUnqual(SharkType::oop_type()),
- "vm_result_addr");
- llvm::LoadInst *result = builder()->CreateLoad(addr, "vm_result");
- builder()->CreateStore(LLVMValue::null(), addr);
- return result;
- }
-
- // Synchronization
- private:
- void acquire_lock(llvm::Value* lockee, int exception_action);
- void release_lock(int exception_action);
-
- public:
- void acquire_method_lock();
-
- // Bounds checks
- private:
- void check_bounds(SharkValue* array, SharkValue* index);
-
- // Safepoints
- private:
- void maybe_add_safepoint();
- void maybe_add_backedge_safepoint();
-
- // Loop safepoint removal
- private:
- bool _can_reach_visited;
-
- bool can_reach(SharkTopLevelBlock* other);
- bool can_reach_helper(SharkTopLevelBlock* other);
-
- // Traps
- private:
- llvm::BasicBlock* make_trap(int trap_bci, int trap_request);
- void do_trap(int trap_request);
-
- // Returns
- private:
- void call_register_finalizer(llvm::Value* receiver);
- void handle_return(BasicType type, llvm::Value* exception);
-
- // arraylength
- private:
- void do_arraylength();
-
- // *aload and *astore
- private:
- void do_aload(BasicType basic_type);
- void do_astore(BasicType basic_type);
-
- // *return and athrow
- private:
- void do_return(BasicType type);
- void do_athrow();
-
- // goto*
- private:
- void do_goto();
-
- // jsr* and ret
- private:
- void do_jsr();
- void do_ret();
-
- // if*
- private:
- void do_if_helper(llvm::ICmpInst::Predicate p,
- llvm::Value* b,
- llvm::Value* a,
- SharkState* if_taken_state,
- SharkState* not_taken_state);
- void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a);
-
- // tableswitch and lookupswitch
- private:
- void do_switch();
-
- // invoke*
- private:
- ciMethod* improve_virtual_call(ciMethod* caller,
- ciInstanceKlass* klass,
- ciMethod* dest_method,
- ciType* receiver_type);
- llvm::Value* get_direct_callee(ciMethod* method);
- llvm::Value* get_virtual_callee(SharkValue* receiver, int vtable_index);
- llvm::Value* get_interface_callee(SharkValue* receiver, ciMethod* method);
-
- void do_call();
-
- // checkcast and instanceof
- private:
- bool static_subtype_check(ciKlass* check_klass, ciKlass* object_klass);
- void do_full_instance_check(ciKlass* klass);
- void do_trapping_instance_check(ciKlass* klass);
-
- void do_instance_check();
- bool maybe_do_instanceof_if();
-
- // new and *newarray
- private:
- void do_new();
- void do_newarray();
- void do_anewarray();
- void do_multianewarray();
-
- // monitorenter and monitorexit
- private:
- void do_monitorenter();
- void do_monitorexit();
-};
-
-#endif // SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP
--- a/src/hotspot/share/shark/sharkType.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKTYPE_HPP
-#define SHARE_VM_SHARK_SHARKTYPE_HPP
-
-#include "ci/ciType.hpp"
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/sharkContext.hpp"
-#include "utilities/globalDefinitions.hpp"
-
-class SharkType : public AllStatic {
- private:
- static SharkContext& context() {
- return SharkContext::current();
- }
-
- // Basic types
- public:
- static llvm::Type* void_type() {
- return context().void_type();
- }
- static llvm::IntegerType* bit_type() {
- return context().bit_type();
- }
- static llvm::IntegerType* jbyte_type() {
- return context().jbyte_type();
- }
- static llvm::IntegerType* jshort_type() {
- return context().jshort_type();
- }
- static llvm::IntegerType* jint_type() {
- return context().jint_type();
- }
- static llvm::IntegerType* jlong_type() {
- return context().jlong_type();
- }
- static llvm::Type* jfloat_type() {
- return context().jfloat_type();
- }
- static llvm::Type* jdouble_type() {
- return context().jdouble_type();
- }
- static llvm::IntegerType* intptr_type() {
- return context().intptr_type();
- }
-
- // Compound types
- public:
- static llvm::PointerType* itableOffsetEntry_type() {
- return context().itableOffsetEntry_type();
- }
- static llvm::PointerType* jniEnv_type() {
- return context().jniEnv_type();
- }
- static llvm::PointerType* jniHandleBlock_type() {
- return context().jniHandleBlock_type();
- }
- static llvm::PointerType* Metadata_type() {
- return context().Metadata_type();
- }
- static llvm::PointerType* klass_type() {
- return context().klass_type();
- }
- static llvm::PointerType* Method_type() {
- return context().Method_type();
- }
- static llvm::ArrayType* monitor_type() {
- return context().monitor_type();
- }
- static llvm::PointerType* oop_type() {
- return context().oop_type();
- }
- static llvm::PointerType* thread_type() {
- return context().thread_type();
- }
- static llvm::PointerType* zeroStack_type() {
- return context().zeroStack_type();
- }
- static llvm::FunctionType* entry_point_type() {
- return context().entry_point_type();
- }
- static llvm::FunctionType* osr_entry_point_type() {
- return context().osr_entry_point_type();
- }
-
- // Mappings
- public:
- static llvm::Type* to_stackType(BasicType type) {
- return context().to_stackType(type);
- }
- static llvm::Type* to_stackType(ciType* type) {
- return to_stackType(type->basic_type());
- }
- static llvm::Type* to_arrayType(BasicType type) {
- return context().to_arrayType(type);
- }
- static llvm::Type* to_arrayType(ciType* type) {
- return to_arrayType(type->basic_type());
- }
-};
-
-#endif // SHARE_VM_SHARK_SHARKTYPE_HPP
--- a/src/hotspot/share/shark/sharkValue.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,264 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * 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 "ci/ciType.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/llvmValue.hpp"
-#include "shark/sharkBuilder.hpp"
-#include "shark/sharkValue.hpp"
-
-using namespace llvm;
-
-// Cloning
-
-SharkValue* SharkNormalValue::clone() const {
- return SharkValue::create_generic(type(), generic_value(), zero_checked());
-}
-SharkValue* SharkPHIValue::clone() const {
- return SharkValue::create_phi(type(), (PHINode *) generic_value(), this);
-}
-SharkValue* SharkAddressValue::clone() const {
- return SharkValue::address_constant(address_value());
-}
-
-// Casting
-
-bool SharkValue::is_phi() const {
- return false;
-}
-bool SharkPHIValue::is_phi() const {
- return true;
-}
-SharkPHIValue* SharkValue::as_phi() {
- ShouldNotCallThis();
-}
-SharkPHIValue* SharkPHIValue::as_phi() {
- return this;
-}
-
-// Comparison
-
-bool SharkNormalValue::equal_to(SharkValue *other) const {
- return (this->type() == other->type() &&
- this->generic_value() == other->generic_value() &&
- this->zero_checked() == other->zero_checked());
-}
-bool SharkAddressValue::equal_to(SharkValue *other) const {
- return (this->address_value() == other->address_value());
-}
-
-// Type access
-
-ciType* SharkValue::type() const {
- ShouldNotCallThis();
-}
-ciType* SharkNormalValue::type() const {
- return _type;
-}
-
-BasicType SharkNormalValue::basic_type() const {
- return type()->basic_type();
-}
-BasicType SharkAddressValue::basic_type() const {
- return T_ADDRESS;
-}
-
-int SharkNormalValue::size() const {
- return type()->size();
-}
-int SharkAddressValue::size() const {
- return 1;
-}
-
-bool SharkValue::is_jint() const {
- return false;
-}
-bool SharkValue::is_jlong() const {
- return false;
-}
-bool SharkValue::is_jfloat() const {
- return false;
-}
-bool SharkValue::is_jdouble() const {
- return false;
-}
-bool SharkValue::is_jobject() const {
- return false;
-}
-bool SharkValue::is_jarray() const {
- return false;
-}
-bool SharkValue::is_address() const {
- return false;
-}
-
-bool SharkNormalValue::is_jint() const {
- return llvm_value()->getType() == SharkType::jint_type();
-}
-bool SharkNormalValue::is_jlong() const {
- return llvm_value()->getType() == SharkType::jlong_type();
-}
-bool SharkNormalValue::is_jfloat() const {
- return llvm_value()->getType() == SharkType::jfloat_type();
-}
-bool SharkNormalValue::is_jdouble() const {
- return llvm_value()->getType() == SharkType::jdouble_type();
-}
-bool SharkNormalValue::is_jobject() const {
- return llvm_value()->getType() == SharkType::oop_type();
-}
-bool SharkNormalValue::is_jarray() const {
- return basic_type() == T_ARRAY;
-}
-bool SharkAddressValue::is_address() const {
- return true;
-}
-
-// Typed conversions from SharkValues
-
-Value* SharkValue::jint_value() const {
- ShouldNotCallThis();
-}
-Value* SharkValue::jlong_value() const {
- ShouldNotCallThis();
-}
-Value* SharkValue::jfloat_value() const {
- ShouldNotCallThis();
-}
-Value* SharkValue::jdouble_value() const {
- ShouldNotCallThis();
-}
-Value* SharkValue::jobject_value() const {
- ShouldNotCallThis();
-}
-Value* SharkValue::jarray_value() const {
- ShouldNotCallThis();
-}
-int SharkValue::address_value() const {
- ShouldNotCallThis();
-}
-
-Value* SharkNormalValue::jint_value() const {
- assert(is_jint(), "should be");
- return llvm_value();
-}
-Value* SharkNormalValue::jlong_value() const {
- assert(is_jlong(), "should be");
- return llvm_value();
-}
-Value* SharkNormalValue::jfloat_value() const {
- assert(is_jfloat(), "should be");
- return llvm_value();
-}
-Value* SharkNormalValue::jdouble_value() const {
- assert(is_jdouble(), "should be");
- return llvm_value();
-}
-Value* SharkNormalValue::jobject_value() const {
- assert(is_jobject(), "should be");
- return llvm_value();
-}
-Value* SharkNormalValue::jarray_value() const {
- // XXX assert(is_jarray(), "should be");
- // XXX http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=324
- assert(is_jobject(), "should be");
- return llvm_value();
-}
-int SharkAddressValue::address_value() const {
- return _bci;
-}
-
-// Type-losing conversions -- use with care!
-
-Value* SharkNormalValue::generic_value() const {
- return llvm_value();
-}
-Value* SharkAddressValue::generic_value() const {
- return LLVMValue::intptr_constant(address_value());
-}
-
-Value* SharkValue::intptr_value(SharkBuilder* builder) const {
- ShouldNotCallThis();
-}
-Value* SharkNormalValue::intptr_value(SharkBuilder* builder) const {
- return builder->CreatePtrToInt(jobject_value(), SharkType::intptr_type());
-}
-
-// Phi-style stuff for SharkPHIState::add_incoming
-
-void SharkValue::addIncoming(SharkValue *value, BasicBlock* block) {
- ShouldNotCallThis();
-}
-void SharkPHIValue::addIncoming(SharkValue *value, BasicBlock* block) {
- assert(!is_clone(), "shouldn't be");
- ((llvm::PHINode *) generic_value())->addIncoming(
- value->generic_value(), block);
- if (!value->zero_checked())
- _all_incomers_zero_checked = false;
-}
-void SharkAddressValue::addIncoming(SharkValue *value, BasicBlock* block) {
- assert(this->equal_to(value), "should be");
-}
-
-// Phi-style stuff for SharkState::merge
-
-SharkValue* SharkNormalValue::merge(SharkBuilder* builder,
- SharkValue* other,
- BasicBlock* other_block,
- BasicBlock* this_block,
- const char* name) {
- assert(type() == other->type(), "should be");
- assert(zero_checked() == other->zero_checked(), "should be");
-
- PHINode *phi = builder->CreatePHI(SharkType::to_stackType(type()), 0, name);
- phi->addIncoming(this->generic_value(), this_block);
- phi->addIncoming(other->generic_value(), other_block);
- return SharkValue::create_generic(type(), phi, zero_checked());
-}
-SharkValue* SharkAddressValue::merge(SharkBuilder* builder,
- SharkValue* other,
- BasicBlock* other_block,
- BasicBlock* this_block,
- const char* name) {
- assert(this->equal_to(other), "should be");
- return this;
-}
-
-// Repeated null and divide-by-zero check removal
-
-bool SharkValue::zero_checked() const {
- ShouldNotCallThis();
-}
-void SharkValue::set_zero_checked(bool zero_checked) {
- ShouldNotCallThis();
-}
-
-bool SharkNormalValue::zero_checked() const {
- return _zero_checked;
-}
-void SharkNormalValue::set_zero_checked(bool zero_checked) {
- _zero_checked = zero_checked;
-}
--- a/src/hotspot/share/shark/sharkValue.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARKVALUE_HPP
-#define SHARE_VM_SHARK_SHARKVALUE_HPP
-
-#include "ci/ciType.hpp"
-#include "memory/allocation.hpp"
-#include "shark/llvmHeaders.hpp"
-#include "shark/llvmValue.hpp"
-#include "shark/sharkType.hpp"
-
-// Items on the stack and in local variables are tracked using
-// SharkValue objects.
-//
-// All SharkValues are one of two core types, SharkNormalValue
-// and SharkAddressValue, but no code outside this file should
-// ever refer to those directly. The split is because of the
-// way JSRs are handled: the typeflow pass expands them into
-// multiple copies, so the return addresses pushed by jsr and
-// popped by ret only exist at compile time. Having separate
-// classes for these allows us to check that our jsr handling
-// is correct, via assertions.
-//
-// There is one more type, SharkPHIValue, which is a subclass
-// of SharkNormalValue with a couple of extra methods. Use of
-// SharkPHIValue outside of this file is acceptable, so long
-// as it is obtained via SharkValue::as_phi().
-
-class SharkBuilder;
-class SharkPHIValue;
-
-class SharkValue : public ResourceObj {
- protected:
- SharkValue() {}
-
- // Cloning
- public:
- virtual SharkValue* clone() const = 0;
-
- // Casting
- public:
- virtual bool is_phi() const;
- virtual SharkPHIValue* as_phi();
-
- // Comparison
- public:
- virtual bool equal_to(SharkValue* other) const = 0;
-
- // Type access
- public:
- virtual BasicType basic_type() const = 0;
- virtual ciType* type() const;
-
- virtual bool is_jint() const;
- virtual bool is_jlong() const;
- virtual bool is_jfloat() const;
- virtual bool is_jdouble() const;
- virtual bool is_jobject() const;
- virtual bool is_jarray() const;
- virtual bool is_address() const;
-
- virtual int size() const = 0;
-
- bool is_one_word() const {
- return size() == 1;
- }
- bool is_two_word() const {
- return size() == 2;
- }
-
- // Typed conversion from SharkValues
- public:
- virtual llvm::Value* jint_value() const;
- virtual llvm::Value* jlong_value() const;
- virtual llvm::Value* jfloat_value() const;
- virtual llvm::Value* jdouble_value() const;
- virtual llvm::Value* jobject_value() const;
- virtual llvm::Value* jarray_value() const;
- virtual int address_value() const;
-
- // Typed conversion to SharkValues
- public:
- static SharkValue* create_jint(llvm::Value* value, bool zero_checked) {
- assert(value->getType() == SharkType::jint_type(), "should be");
- return create_generic(ciType::make(T_INT), value, zero_checked);
- }
- static SharkValue* create_jlong(llvm::Value* value, bool zero_checked) {
- assert(value->getType() == SharkType::jlong_type(), "should be");
- return create_generic(ciType::make(T_LONG), value, zero_checked);
- }
- static SharkValue* create_jfloat(llvm::Value* value) {
- assert(value->getType() == SharkType::jfloat_type(), "should be");
- return create_generic(ciType::make(T_FLOAT), value, false);
- }
- static SharkValue* create_jdouble(llvm::Value* value) {
- assert(value->getType() == SharkType::jdouble_type(), "should be");
- return create_generic(ciType::make(T_DOUBLE), value, false);
- }
- static SharkValue* create_jobject(llvm::Value* value, bool zero_checked) {
- assert(value->getType() == SharkType::oop_type(), "should be");
- return create_generic(ciType::make(T_OBJECT), value, zero_checked);
- }
-
- // Typed conversion from constants of various types
- public:
- static SharkValue* jint_constant(jint value) {
- return create_jint(LLVMValue::jint_constant(value), value != 0);
- }
- static SharkValue* jlong_constant(jlong value) {
- return create_jlong(LLVMValue::jlong_constant(value), value != 0);
- }
- static SharkValue* jfloat_constant(jfloat value) {
- return create_jfloat(LLVMValue::jfloat_constant(value));
- }
- static SharkValue* jdouble_constant(jdouble value) {
- return create_jdouble(LLVMValue::jdouble_constant(value));
- }
- static SharkValue* null() {
- return create_jobject(LLVMValue::null(), false);
- }
- static inline SharkValue* address_constant(int bci);
-
- // Type-losing conversions -- use with care!
- public:
- virtual llvm::Value* generic_value() const = 0;
- virtual llvm::Value* intptr_value(SharkBuilder* builder) const;
-
- static inline SharkValue* create_generic(ciType* type,
- llvm::Value* value,
- bool zero_checked);
- static inline SharkValue* create_phi(ciType* type,
- llvm::PHINode* phi,
- const SharkPHIValue* parent = NULL);
-
- // Phi-style stuff
- public:
- virtual void addIncoming(SharkValue* value, llvm::BasicBlock* block);
- virtual SharkValue* merge(SharkBuilder* builder,
- SharkValue* other,
- llvm::BasicBlock* other_block,
- llvm::BasicBlock* this_block,
- const char* name) = 0;
-
- // Repeated null and divide-by-zero check removal
- public:
- virtual bool zero_checked() const;
- virtual void set_zero_checked(bool zero_checked);
-};
-
-class SharkNormalValue : public SharkValue {
- friend class SharkValue;
-
- protected:
- SharkNormalValue(ciType* type, llvm::Value* value, bool zero_checked)
- : _type(type), _llvm_value(value), _zero_checked(zero_checked) {}
-
- private:
- ciType* _type;
- llvm::Value* _llvm_value;
- bool _zero_checked;
-
- private:
- llvm::Value* llvm_value() const {
- return _llvm_value;
- }
-
- // Cloning
- public:
- SharkValue* clone() const;
-
- // Comparison
- public:
- bool equal_to(SharkValue* other) const;
-
- // Type access
- public:
- ciType* type() const;
- BasicType basic_type() const;
- int size() const;
-
- public:
- bool is_jint() const;
- bool is_jlong() const;
- bool is_jfloat() const;
- bool is_jdouble() const;
- bool is_jobject() const;
- bool is_jarray() const;
-
- // Typed conversions to LLVM values
- public:
- llvm::Value* jint_value() const;
- llvm::Value* jlong_value() const;
- llvm::Value* jfloat_value() const;
- llvm::Value* jdouble_value() const;
- llvm::Value* jobject_value() const;
- llvm::Value* jarray_value() const;
-
- // Type-losing conversions, use with care
- public:
- llvm::Value* generic_value() const;
- llvm::Value* intptr_value(SharkBuilder* builder) const;
-
- // Phi-style stuff
- public:
- SharkValue* merge(SharkBuilder* builder,
- SharkValue* other,
- llvm::BasicBlock* other_block,
- llvm::BasicBlock* this_block,
- const char* name);
-
- // Repeated null and divide-by-zero check removal
- public:
- bool zero_checked() const;
- void set_zero_checked(bool zero_checked);
-};
-
-class SharkPHIValue : public SharkNormalValue {
- friend class SharkValue;
-
- protected:
- SharkPHIValue(ciType* type, llvm::PHINode* phi, const SharkPHIValue *parent)
- : SharkNormalValue(type, phi, parent && parent->zero_checked()),
- _parent(parent),
- _all_incomers_zero_checked(true) {}
-
- private:
- const SharkPHIValue* _parent;
- bool _all_incomers_zero_checked;
-
- private:
- const SharkPHIValue* parent() const {
- return _parent;
- }
- bool is_clone() const {
- return parent() != NULL;
- }
-
- public:
- bool all_incomers_zero_checked() const {
- if (is_clone())
- return parent()->all_incomers_zero_checked();
-
- return _all_incomers_zero_checked;
- }
-
- // Cloning
- public:
- SharkValue* clone() const;
-
- // Casting
- public:
- bool is_phi() const;
- SharkPHIValue* as_phi();
-
- // Phi-style stuff
- public:
- void addIncoming(SharkValue *value, llvm::BasicBlock* block);
-};
-
-class SharkAddressValue : public SharkValue {
- friend class SharkValue;
-
- protected:
- SharkAddressValue(int bci)
- : _bci(bci) {}
-
- private:
- int _bci;
-
- // Cloning
- public:
- SharkValue* clone() const;
-
- // Comparison
- public:
- bool equal_to(SharkValue* other) const;
-
- // Type access
- public:
- BasicType basic_type() const;
- int size() const;
- bool is_address() const;
-
- // Typed conversion from SharkValues
- public:
- int address_value() const;
-
- // Type-losing conversion -- use with care!
- public:
- llvm::Value* generic_value() const;
-
- // Phi-style stuff
- public:
- void addIncoming(SharkValue *value, llvm::BasicBlock* block);
- SharkValue* merge(SharkBuilder* builder,
- SharkValue* other,
- llvm::BasicBlock* other_block,
- llvm::BasicBlock* this_block,
- const char* name);
-};
-
-// SharkValue methods that can't be declared above
-
-inline SharkValue* SharkValue::create_generic(ciType* type,
- llvm::Value* value,
- bool zero_checked) {
- return new SharkNormalValue(type, value, zero_checked);
-}
-
-inline SharkValue* SharkValue::create_phi(ciType* type,
- llvm::PHINode* phi,
- const SharkPHIValue* parent) {
- return new SharkPHIValue(type, phi, parent);
-}
-
-inline SharkValue* SharkValue::address_constant(int bci) {
- return new SharkAddressValue(bci);
-}
-
-#endif // SHARE_VM_SHARK_SHARKVALUE_HPP
--- a/src/hotspot/share/shark/shark_globals.cpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008 Red Hat, Inc.
- * 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 "shark/shark_globals.hpp"
-
-SHARK_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
--- a/src/hotspot/share/shark/shark_globals.hpp Wed Oct 18 16:06:39 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2008, 2009, 2010 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_VM_SHARK_SHARK_GLOBALS_HPP
-#define SHARE_VM_SHARK_SHARK_GLOBALS_HPP
-
-#include "runtime/globals.hpp"
-#include "utilities/macros.hpp"
-#ifdef ZERO
-# include "shark_globals_zero.hpp"
-#endif
-
-#define SHARK_FLAGS(develop, develop_pd, product, product_pd, diagnostic, diagnostic_pd, notproduct) \
- \
- product(intx, MaxNodeLimit, 65000, \
- "Maximum number of nodes") \
- \
- /* inlining */ \
- product(intx, SharkMaxInlineSize, 32, \
- "Maximum bytecode size of methods to inline when using Shark") \
- \
- product(bool, EliminateNestedLocks, true, \
- "Eliminate nested locks of the same object when possible") \
- \
- product(ccstr, SharkOptimizationLevel, "Default", \
- "The optimization level passed to LLVM, possible values: None, Less, Default and Agressive") \
- \
- /* compiler debugging */ \
- develop(ccstr, SharkPrintTypeflowOf, NULL, \
- "Print the typeflow of the specified method") \
- \
- diagnostic(ccstr, SharkPrintBitcodeOf, NULL, \
- "Print the LLVM bitcode of the specified method") \
- \
- diagnostic(ccstr, SharkPrintAsmOf, NULL, \
- "Print the asm of the specified method") \
- \
- develop(bool, SharkTraceBytecodes, false, \
- "Trace bytecode compilation") \
- \
- diagnostic(bool, SharkTraceInstalls, false, \
- "Trace method installation") \
- \
- diagnostic(bool, SharkPerformanceWarnings, false, \
- "Warn about things that could be made faster") \
- \
- develop(ccstr, SharkVerifyFunction, NULL, \
- "Runs LLVM verify over LLVM IR") \
-
-
-SHARK_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_PD_DIAGNOSTIC_FLAG,
- DECLARE_NOTPRODUCT_FLAG)
-
-#endif // SHARE_VM_SHARK_SHARK_GLOBALS_HPP
--- a/src/hotspot/share/utilities/macros.hpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/utilities/macros.hpp Sun Oct 15 22:54:03 2017 +0200
@@ -346,14 +346,6 @@
#define NOT_ZERO(code) code
#endif
-#if defined(SHARK)
-#define SHARK_ONLY(code) code
-#define NOT_SHARK(code)
-#else
-#define SHARK_ONLY(code)
-#define NOT_SHARK(code) code
-#endif
-
#if defined(IA32) || defined(AMD64)
#define X86
#define X86_ONLY(code) code
--- a/src/hotspot/share/utilities/vmError.cpp Wed Oct 18 16:06:39 2017 +0200
+++ b/src/hotspot/share/utilities/vmError.cpp Sun Oct 15 22:54:03 2017 +0200
@@ -189,20 +189,10 @@
if (!has_last_Java_frame)
jt->set_last_Java_frame();
st->print("Java frames:");
-
- // If the top frame is a Shark frame and the frame anchor isn't
- // set up then it's possible that the information in the frame
- // is garbage: it could be from a previous decache, or it could
- // simply have never been written. So we print a warning...
- StackFrameStream sfs(jt);
- if (!has_last_Java_frame && !sfs.is_done()) {
- if (sfs.current()->zeroframe()->is_shark_frame()) {
- st->print(" (TOP FRAME MAY BE JUNK)");
- }
- }
st->cr();
// Print the frames
+ StackFrameStream sfs(jt);
for(int i = 0; !sfs.is_done(); sfs.next(), i++) {
sfs.current()->zero_print_on_error(i, st, buf, buflen);
st->cr();
--- a/test/hotspot/jtreg/compiler/whitebox/CompilerWhiteBoxTest.java Wed Oct 18 16:06:39 2017 +0200
+++ b/test/hotspot/jtreg/compiler/whitebox/CompilerWhiteBoxTest.java Sun Oct 15 22:54:03 2017 +0200
@@ -51,7 +51,7 @@
public static final int COMP_LEVEL_LIMITED_PROFILE = 2;
/** {@code CompLevel::CompLevel_full_profile} -- C1, invocation & backedge counters + mdo */
public static final int COMP_LEVEL_FULL_PROFILE = 3;
- /** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */
+ /** {@code CompLevel::CompLevel_full_optimization} -- C2 */
public static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
/** Maximal value for CompLevel */
public static final int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION;