# HG changeset patch # User rkennke # Date 1508100843 -7200 # Sun Oct 15 22:54:03 2017 +0200 # Node ID 3fea28296eb52207cbdcf9401cdd35ce8904c761 # Parent 52cf482c4d28c0c7fc8daa912a93ce4f0532485c 8171853: Remove Shark compiler diff --git a/doc/building.html b/doc/building.html --- a/doc/building.html +++ b/doc/building.html @@ -463,7 +463,7 @@
  • --with-native-debug-symbols=<method> - Specify if and how native debug symbols should be built. Available methods are none, internal, external, zipped. Default behavior depends on platform. See Native Debug Symbols for more details.
  • --with-version-string=<string> - Specify the version string this build will be identified with.
  • --with-version-<part>=<value> - A group of options, where <part> can be any of pre, opt, build, major, minor, security or patch. Use these options to modify just the corresponding part of the version string 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 variants are possible to combine in a single build.
  • +
  • --with-jvm-variants=<variant>[,<variant>...] - Build the specified variant (or variants) of Hotspot. Valid variants are: server, client, 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 of the default list. For the custom JVM variant, this default list is empty. A complete list of available JVM features can be found using bash configure --help.
  • --with-target-bits=<bits> - Create a target binary suitable for running on a <bits> 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 reduced build.)
  • diff --git a/doc/building.md b/doc/building.md --- a/doc/building.md +++ b/doc/building.md @@ -668,7 +668,7 @@ from the default, or the value provided by `--with-version-string`. * `--with-jvm-variants=[,...]` - 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=[,...]` - Use the specified JVM features when building Hotspot. The list of features will be enabled on top diff --git a/make/autoconf/flags.m4 b/make/autoconf/flags.m4 --- a/make/autoconf/flags.m4 +++ b/make/autoconf/flags.m4 @@ -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 diff --git a/make/autoconf/hotspot.m4 b/make/autoconf/hotspot.m4 --- a/make/autoconf/hotspot.m4 +++ b/make/autoconf/hotspot.m4 @@ -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,18 +324,6 @@ fi fi - if ! HOTSPOT_CHECK_JVM_VARIANT(zero) && ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); 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]) - fi - fi - # Only enable jvmci on x86_64, sparcv9 and aarch64. if test "x$OPENJDK_TARGET_CPU" = "xx86_64" || \ test "x$OPENJDK_TARGET_CPU" = "xsparcv9" || \ @@ -408,7 +395,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 +402,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 +422,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 diff --git a/make/autoconf/jdk-options.m4 b/make/autoconf/jdk-options.m4 --- a/make/autoconf/jdk-options.m4 +++ b/make/autoconf/jdk-options.m4 @@ -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 diff --git a/make/autoconf/lib-std.m4 b/make/autoconf/lib-std.m4 --- a/make/autoconf/lib-std.m4 +++ b/make/autoconf/lib-std.m4 @@ -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" diff --git a/make/autoconf/libraries.m4 b/make/autoconf/libraries.m4 --- a/make/autoconf/libraries.m4 +++ b/make/autoconf/libraries.m4 @@ -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], diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in --- a/make/autoconf/spec.gmk.in +++ b/make/autoconf/spec.gmk.in @@ -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@ diff --git a/make/copy/Copy-java.base.gmk b/make/copy/Copy-java.base.gmk --- a/make/copy/Copy-java.base.gmk +++ b/make/copy/Copy-java.base.gmk @@ -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 diff --git a/make/hotspot/ide/CreateVSProject.gmk b/make/hotspot/ide/CreateVSProject.gmk --- a/make/hotspot/ide/CreateVSProject.gmk +++ b/make/hotspot/ide/CreateVSProject.gmk @@ -75,7 +75,6 @@ -ignorePath linux \ -ignorePath posix \ -ignorePath ppc \ - -ignorePath shark \ -ignorePath solaris \ -ignorePath sparc \ -ignorePath x86_32 \ diff --git a/make/hotspot/lib/JvmFeatures.gmk b/make/hotspot/lib/JvmFeatures.gmk --- a/make/hotspot/lib/JvmFeatures.gmk +++ b/make/hotspot/lib/JvmFeatures.gmk @@ -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) diff --git a/make/lib/CoreLibraries.gmk b/make/lib/CoreLibraries.gmk --- a/make/lib/CoreLibraries.gmk +++ b/make/lib/CoreLibraries.gmk @@ -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) diff --git a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp --- a/src/hotspot/cpu/arm/sharedRuntime_arm.cpp +++ b/src/hotspot/cpu/arm/sharedRuntime_arm.cpp @@ -42,10 +42,6 @@ #ifdef COMPILER2 #include "opto/runtime.hpp" #endif -#ifdef SHARK -#include "compiler/compileBroker.hpp" -#include "shark/sharkCompiler.hpp" -#endif #define __ masm-> diff --git a/src/hotspot/cpu/sparc/globalDefinitions_sparc.hpp b/src/hotspot/cpu/sparc/globalDefinitions_sparc.hpp --- a/src/hotspot/cpu/sparc/globalDefinitions_sparc.hpp +++ b/src/hotspot/cpu/sparc/globalDefinitions_sparc.hpp @@ -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 diff --git a/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp b/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp --- a/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp +++ b/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp @@ -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 diff --git a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp --- a/src/hotspot/cpu/x86/globalDefinitions_x86.hpp +++ b/src/hotspot/cpu/x86/globalDefinitions_x86.hpp @@ -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 diff --git a/src/hotspot/cpu/zero/cppInterpreter_zero.cpp b/src/hotspot/cpu/zero/cppInterpreter_zero.cpp --- a/src/hotspot/cpu/zero/cppInterpreter_zero.cpp +++ b/src/hotspot/cpu/zero/cppInterpreter_zero.cpp @@ -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 diff --git a/src/hotspot/cpu/zero/frame_zero.cpp b/src/hotspot/cpu/zero/frame_zero.cpp --- a/src/hotspot/cpu/zero/frame_zero.cpp +++ b/src/hotspot/cpu/zero/frame_zero.cpp @@ -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, diff --git a/src/hotspot/cpu/zero/frame_zero.hpp b/src/hotspot/cpu/zero/frame_zero.hpp --- a/src/hotspot/cpu/zero/frame_zero.hpp +++ b/src/hotspot/cpu/zero/frame_zero.hpp @@ -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; diff --git a/src/hotspot/cpu/zero/frame_zero.inline.hpp b/src/hotspot/cpu/zero/frame_zero.inline.hpp --- a/src/hotspot/cpu/zero/frame_zero.inline.hpp +++ b/src/hotspot/cpu/zero/frame_zero.inline.hpp @@ -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 diff --git a/src/hotspot/cpu/zero/icache_zero.hpp b/src/hotspot/cpu/zero/icache_zero.hpp --- a/src/hotspot/cpu/zero/icache_zero.hpp +++ b/src/hotspot/cpu/zero/icache_zero.hpp @@ -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: diff --git a/src/hotspot/cpu/zero/nativeInst_zero.cpp b/src/hotspot/cpu/zero/nativeInst_zero.cpp --- a/src/hotspot/cpu/zero/nativeInst_zero.cpp +++ b/src/hotspot/cpu/zero/nativeInst_zero.cpp @@ -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, diff --git a/src/hotspot/cpu/zero/relocInfo_zero.cpp b/src/hotspot/cpu/zero/relocInfo_zero.cpp --- a/src/hotspot/cpu/zero/relocInfo_zero.cpp +++ b/src/hotspot/cpu/zero/relocInfo_zero.cpp @@ -50,7 +50,7 @@ } address* Relocation::pd_address_in_code() { - // Relocations in Shark are just stored directly + ShouldNotCallThis(); return (address *) addr(); } diff --git a/src/hotspot/cpu/zero/sharedRuntime_zero.cpp b/src/hotspot/cpu/zero/sharedRuntime_zero.cpp --- a/src/hotspot/cpu/zero/sharedRuntime_zero.cpp +++ b/src/hotspot/cpu/zero/sharedRuntime_zero.cpp @@ -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, diff --git a/src/hotspot/cpu/zero/sharkFrame_zero.hpp b/src/hotspot/cpu/zero/sharkFrame_zero.hpp deleted file mode 100644 --- a/src/hotspot/cpu/zero/sharkFrame_zero.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/cpu/zero/shark_globals_zero.hpp b/src/hotspot/cpu/zero/shark_globals_zero.hpp deleted file mode 100644 --- a/src/hotspot/cpu/zero/shark_globals_zero.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/cpu/zero/stack_zero.cpp b/src/hotspot/cpu/zero/stack_zero.cpp --- a/src/hotspot/cpu/zero/stack_zero.cpp +++ b/src/hotspot/cpu/zero/stack_zero.cpp @@ -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(); diff --git a/src/hotspot/cpu/zero/stack_zero.hpp b/src/hotspot/cpu/zero/stack_zero.hpp --- a/src/hotspot/cpu/zero/stack_zero.hpp +++ b/src/hotspot/cpu/zero/stack_zero.hpp @@ -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; diff --git a/src/hotspot/cpu/zero/stack_zero.inline.hpp b/src/hotspot/cpu/zero/stack_zero.inline.hpp --- a/src/hotspot/cpu/zero/stack_zero.inline.hpp +++ b/src/hotspot/cpu/zero/stack_zero.inline.hpp @@ -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) { diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -1218,7 +1218,7 @@ 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)) { // C2 #ifdef COMPILER2 // Dump C2 inlining data. ((Compile*)compiler_data())->dump_inline_data(out); diff --git a/src/hotspot/share/ci/ciMethod.cpp b/src/hotspot/share/ci/ciMethod.cpp --- a/src/hotspot/share/ci/ciMethod.cpp +++ b/src/hotspot/share/ci/ciMethod.cpp @@ -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 } // ------------------------------------------------------------------ diff --git a/src/hotspot/share/ci/ciMethod.hpp b/src/hotspot/share/ci/ciMethod.hpp --- a/src/hotspot/share/ci/ciMethod.hpp +++ b/src/hotspot/share/ci/ciMethod.hpp @@ -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(); diff --git a/src/hotspot/share/ci/ciTypeFlow.hpp b/src/hotspot/share/ci/ciTypeFlow.hpp --- a/src/hotspot/share/ci/ciTypeFlow.hpp +++ b/src/hotspot/share/ci/ciTypeFlow.hpp @@ -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 { diff --git a/src/hotspot/share/code/codeBlob.hpp b/src/hotspot/share/code/codeBlob.hpp --- a/src/hotspot/share/code/codeBlob.hpp +++ b/src/hotspot/share/code/codeBlob.hpp @@ -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 diff --git a/src/hotspot/share/code/compiledMethod.cpp b/src/hotspot/share/code/compiledMethod.cpp --- a/src/hotspot/share/code/compiledMethod.cpp +++ b/src/hotspot/share/code/compiledMethod.cpp @@ -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) { diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -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); } @@ -2245,8 +2230,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 { @@ -2868,9 +2851,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 diff --git a/src/hotspot/share/compiler/abstractCompiler.hpp b/src/hotspot/share/compiler/abstractCompiler.hpp --- a/src/hotspot/share/compiler/abstractCompiler.hpp +++ b/src/hotspot/share/compiler/abstractCompiler.hpp @@ -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. diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp --- a/src/hotspot/share/compiler/compileBroker.cpp +++ b/src/hotspot/share/compiler/compileBroker.cpp @@ -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,7 @@ // Create a name for our thread. sprintf(name_buffer, "%s CompilerThread%d", _compilers[1]->name(), i); CompilerCounters* counters = new CompilerCounters(); - // Shark and C2 + // C2 make_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], compiler_thread, CHECK); } @@ -1100,7 +1089,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 +1479,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()) { diff --git a/src/hotspot/share/compiler/compilerDefinitions.cpp b/src/hotspot/share/compiler/compilerDefinitions.cpp --- a/src/hotspot/share/compiler/compilerDefinitions.cpp +++ b/src/hotspot/share/compiler/compilerDefinitions.cpp @@ -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; diff --git a/src/hotspot/share/compiler/compilerDefinitions.hpp b/src/hotspot/share/compiler/compilerDefinitions.hpp --- a/src/hotspot/share/compiler/compilerDefinitions.hpp +++ b/src/hotspot/share/compiler/compilerDefinitions.hpp @@ -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; diff --git a/src/hotspot/share/compiler/compilerDirectives.cpp b/src/hotspot/share/compiler/compilerDirectives.cpp --- a/src/hotspot/share/compiler/compilerDirectives.cpp +++ b/src/hotspot/share/compiler/compilerDirectives.cpp @@ -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; } } diff --git a/src/hotspot/share/compiler/disassembler.cpp b/src/hotspot/share/compiler/disassembler.cpp --- a/src/hotspot/share/compiler/disassembler.cpp +++ b/src/hotspot/share/compiler/disassembler.cpp @@ -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("."); diff --git a/src/hotspot/share/interpreter/bytecodeInterpreter.cpp b/src/hotspot/share/interpreter/bytecodeInterpreter.cpp --- a/src/hotspot/share/interpreter/bytecodeInterpreter.cpp +++ b/src/hotspot/share/interpreter/bytecodeInterpreter.cpp @@ -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; diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -1160,15 +1160,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 } diff --git a/src/hotspot/share/runtime/commandLineFlagConstraintsCompiler.cpp b/src/hotspot/share/runtime/commandLineFlagConstraintsCompiler.cpp --- a/src/hotspot/share/runtime/commandLineFlagConstraintsCompiler.cpp +++ b/src/hotspot/share/runtime/commandLineFlagConstraintsCompiler.cpp @@ -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)) { diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -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", 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 diff --git a/src/hotspot/share/runtime/frame.cpp b/src/hotspot/share/runtime/frame.cpp --- a/src/hotspot/share/runtime/frame.cpp +++ b/src/hotspot/share/runtime/frame.cpp @@ -1122,10 +1122,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(); } diff --git a/src/hotspot/share/runtime/frame.inline.hpp b/src/hotspot/share/runtime/frame.inline.hpp --- a/src/hotspot/share/runtime/frame.inline.hpp +++ b/src/hotspot/share/runtime/frame.inline.hpp @@ -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) diff --git a/src/hotspot/share/runtime/globals.cpp b/src/hotspot/share/runtime/globals.cpp --- a/src/hotspot/share/runtime/globals.cpp +++ b/src/hotspot/share/runtime/globals.cpp @@ -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, \ diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -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) }; diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp --- a/src/hotspot/share/runtime/thread.cpp +++ b/src/hotspot/share/runtime/thread.cpp @@ -3727,7 +3727,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 diff --git a/src/hotspot/share/runtime/vm_version.cpp b/src/hotspot/share/runtime/vm_version.cpp --- a/src/hotspot/share/runtime/vm_version.cpp +++ b/src/hotspot/share/runtime/vm_version.cpp @@ -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") diff --git a/src/hotspot/share/shark/llvmHeaders.hpp b/src/hotspot/share/shark/llvmHeaders.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/llvmHeaders.hpp +++ /dev/null @@ -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 -#include - -// includes specific to each version -#if SHARK_LLVM_VERSION <= 31 -#include -#include -#include -#include -#include -#include -#include -#include -#elif SHARK_LLVM_VERSION <= 32 -#include -#include -#include -#include -#include -#include -#include -#include -#else // SHARK_LLVM_VERSION <= 34 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif - -// common includes -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#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 diff --git a/src/hotspot/share/shark/llvmValue.hpp b/src/hotspot/share/shark/llvmValue.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/llvmValue.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkBlock.cpp b/src/hotspot/share/shark/sharkBlock.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkBlock.cpp +++ /dev/null @@ -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 - // 33: ifeq 52 - // 36: aload 9 - // 38: checkcast - // - // 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(); -} diff --git a/src/hotspot/share/shark/sharkBlock.hpp b/src/hotspot/share/shark/sharkBlock.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkBlock.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkBuilder.cpp b/src/hotspot/share/shark/sharkBuilder.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkBuilder.cpp +++ /dev/null @@ -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 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(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(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); -} diff --git a/src/hotspot/share/shark/sharkBuilder.hpp b/src/hotspot/share/shark/sharkBuilder.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkBuilder.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkCacheDecache.cpp b/src/hotspot/share/shark/sharkCacheDecache.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkCacheDecache.cpp +++ /dev/null @@ -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(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(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(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)); -} diff --git a/src/hotspot/share/shark/sharkCacheDecache.hpp b/src/hotspot/share/shark/sharkCacheDecache.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkCacheDecache.hpp +++ /dev/null @@ -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* _exparray; - GrowableArray* _monarray; - GrowableArray* _locarray; - - private: - int pc_offset() const { - return _pc_offset; - } - OopMap* oopmap() const { - return _oopmap; - } - GrowableArray* exparray() const { - return _exparray; - } - GrowableArray* monarray() const { - return _monarray; - } - GrowableArray* 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 diff --git a/src/hotspot/share/shark/sharkCodeBuffer.hpp b/src/hotspot/share/shark/sharkCodeBuffer.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkCodeBuffer.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkCompiler.cpp b/src/hotspot/share/shark/sharkCompiler.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkCompiler.cpp +++ /dev/null @@ -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 - -using namespace llvm; - -namespace { - cl::opt - MCPU("mcpu"); - - cl::list - 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 Features; - bool gotCpuFeatures = llvm::sys::getHostCPUFeatures(Features); - std::string cpu("-mcpu=" + llvm::sys::getHostCPUName()); - - std::vector args; - args.push_back(""); // program name - args.push_back(cpu.c_str()); - - std::string mattr("-mattr="); - if(gotCpuFeatures){ - for(StringMap::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 -} diff --git a/src/hotspot/share/shark/sharkCompiler.hpp b/src/hotspot/share/shark/sharkCompiler.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkCompiler.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkConstant.cpp b/src/hotspot/share/shark/sharkConstant.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkConstant.cpp +++ /dev/null @@ -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; -} diff --git a/src/hotspot/share/shark/sharkConstant.hpp b/src/hotspot/share/shark/sharkConstant.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkConstant.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkContext.cpp b/src/hotspot/share/shark/sharkContext.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkContext.cpp +++ /dev/null @@ -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 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 { - 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; -} diff --git a/src/hotspot/share/shark/sharkContext.hpp b/src/hotspot/share/shark/sharkContext.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkContext.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkEntry.hpp b/src/hotspot/share/shark/sharkEntry.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkEntry.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkFunction.cpp b/src/hotspot/share/shark/sharkFunction.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkFunction.cpp +++ /dev/null @@ -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(); -} diff --git a/src/hotspot/share/shark/sharkFunction.hpp b/src/hotspot/share/shark/sharkFunction.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkFunction.hpp +++ /dev/null @@ -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 _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* 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 diff --git a/src/hotspot/share/shark/sharkInliner.cpp b/src/hotspot/share/shark/sharkInliner.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkInliner.cpp +++ /dev/null @@ -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. which we can't inline. - // Note that this catches too, but why would - // we be compiling that? - if (target->is_initializer()) - return false; - - // Mustn't inline Object. - // 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; -} diff --git a/src/hotspot/share/shark/sharkInliner.hpp b/src/hotspot/share/shark/sharkInliner.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkInliner.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkIntrinsics.cpp b/src/hotspot/share/shark/sharkIntrinsics.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkIntrinsics.cpp +++ /dev/null @@ -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)); -} diff --git a/src/hotspot/share/shark/sharkIntrinsics.hpp b/src/hotspot/share/shark/sharkIntrinsics.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkIntrinsics.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkInvariants.cpp b/src/hotspot/share/shark/sharkInvariants.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkInvariants.cpp +++ /dev/null @@ -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; -} diff --git a/src/hotspot/share/shark/sharkInvariants.hpp b/src/hotspot/share/shark/sharkInvariants.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkInvariants.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkMemoryManager.cpp b/src/hotspot/share/shark/sharkMemoryManager.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkMemoryManager.cpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkMemoryManager.hpp b/src/hotspot/share/shark/sharkMemoryManager.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkMemoryManager.hpp +++ /dev/null @@ -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 _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 diff --git a/src/hotspot/share/shark/sharkNativeWrapper.cpp b/src/hotspot/share/shark/sharkNativeWrapper.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkNativeWrapper.cpp +++ /dev/null @@ -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 param_types; - std::vector 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)); -} diff --git a/src/hotspot/share/shark/sharkNativeWrapper.hpp b/src/hotspot/share/shark/sharkNativeWrapper.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkNativeWrapper.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkRuntime.cpp b/src/hotspot/share/shark/sharkRuntime.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkRuntime.cpp +++ /dev/null @@ -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; -} diff --git a/src/hotspot/share/shark/sharkRuntime.hpp b/src/hotspot/share/shark/sharkRuntime.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkRuntime.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkStack.cpp b/src/hotspot/share/shark/sharkStack.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkStack.cpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkStack.hpp b/src/hotspot/share/shark/sharkStack.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkStack.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkState.cpp b/src/hotspot/share/shark/sharkState.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkState.cpp +++ /dev/null @@ -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"); -} diff --git a/src/hotspot/share/shark/sharkState.hpp b/src/hotspot/share/shark/sharkState.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkState.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkStateScanner.cpp b/src/hotspot/share/shark/sharkStateScanner.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkStateScanner.cpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkStateScanner.hpp b/src/hotspot/share/shark/sharkStateScanner.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkStateScanner.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkTopLevelBlock.cpp b/src/hotspot/share/shark/sharkTopLevelBlock.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkTopLevelBlock.cpp +++ /dev/null @@ -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(exc_count); - _exceptions = new GrowableArray(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); -} diff --git a/src/hotspot/share/shark/sharkTopLevelBlock.hpp b/src/hotspot/share/shark/sharkTopLevelBlock.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkTopLevelBlock.hpp +++ /dev/null @@ -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* _exc_handlers; - GrowableArray* _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 diff --git a/src/hotspot/share/shark/sharkType.hpp b/src/hotspot/share/shark/sharkType.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkType.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/sharkValue.cpp b/src/hotspot/share/shark/sharkValue.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkValue.cpp +++ /dev/null @@ -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; -} diff --git a/src/hotspot/share/shark/sharkValue.hpp b/src/hotspot/share/shark/sharkValue.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/sharkValue.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/shark/shark_globals.cpp b/src/hotspot/share/shark/shark_globals.cpp deleted file mode 100644 --- a/src/hotspot/share/shark/shark_globals.cpp +++ /dev/null @@ -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) diff --git a/src/hotspot/share/shark/shark_globals.hpp b/src/hotspot/share/shark/shark_globals.hpp deleted file mode 100644 --- a/src/hotspot/share/shark/shark_globals.hpp +++ /dev/null @@ -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 diff --git a/src/hotspot/share/utilities/macros.hpp b/src/hotspot/share/utilities/macros.hpp --- a/src/hotspot/share/utilities/macros.hpp +++ b/src/hotspot/share/utilities/macros.hpp @@ -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 diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -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();