8171853: Remove Shark compiler

Reviewed-by: dholmes, kvn, erikj, ihse
This commit is contained in:
Roman Kennke 2017-10-15 22:54:03 +02:00
parent 50c759f20e
commit 7030019135
98 changed files with 55 additions and 12538 deletions
doc
make
src/hotspot
cpu
share
test/hotspot/jtreg/compiler/whitebox

@ -463,7 +463,7 @@ tar -xzf freetype-2.5.3.tar.gz</code></pre>
<li><code>--with-native-debug-symbols=&lt;method&gt;</code> - Specify if and how native debug symbols should be built. Available methods are <code>none</code>, <code>internal</code>, <code>external</code>, <code>zipped</code>. Default behavior depends on platform. See <a href="#native-debug-symbols">Native Debug Symbols</a> for more details.</li>
<li><code>--with-version-string=&lt;string&gt;</code> - Specify the version string this build will be identified with.</li>
<li><code>--with-version-&lt;part&gt;=&lt;value&gt;</code> - A group of options, where <code>&lt;part&gt;</code> can be any of <code>pre</code>, <code>opt</code>, <code>build</code>, <code>major</code>, <code>minor</code>, <code>security</code> or <code>patch</code>. Use these options to modify just the corresponding part of the version string from the default, or the value provided by <code>--with-version-string</code>.</li>
<li><code>--with-jvm-variants=&lt;variant&gt;[,&lt;variant&gt;...]</code> - Build the specified variant (or variants) of Hotspot. Valid variants are: <code>server</code>, <code>client</code>, <code>minimal</code>, <code>core</code>, <code>zero</code>, <code>zeroshark</code>, <code>custom</code>. Note that not all variants are possible to combine in a single build.</li>
<li><code>--with-jvm-variants=&lt;variant&gt;[,&lt;variant&gt;...]</code> - Build the specified variant (or variants) of Hotspot. Valid variants are: <code>server</code>, <code>client</code>, <code>minimal</code>, <code>core</code>, <code>zero</code>, <code>custom</code>. Note that not all variants are possible to combine in a single build.</li>
<li><code>--with-jvm-features=&lt;feature&gt;[,&lt;feature&gt;...]</code> - Use the specified JVM features when building Hotspot. The list of features will be enabled on top of the default list. For the <code>custom</code> JVM variant, this default list is empty. A complete list of available JVM features can be found using <code>bash configure --help</code>.</li>
<li><code>--with-target-bits=&lt;bits&gt;</code> - Create a target binary suitable for running on a <code>&lt;bits&gt;</code> platform. Use this to create 32-bit output on a 64-bit build platform, instead of doing a full cross-compile. (This is known as a <em>reduced</em> build.)</li>
</ul>

@ -668,7 +668,7 @@ features, use `bash configure --help=short` instead.)
from the default, or the value provided by `--with-version-string`.
* `--with-jvm-variants=<variant>[,<variant>...]` - Build the specified variant
(or variants) of Hotspot. Valid variants are: `server`, `client`,
`minimal`, `core`, `zero`, `zeroshark`, `custom`. Note that not all
`minimal`, `core`, `zero`, `custom`. Note that not all
variants are possible to combine in a single build.
* `--with-jvm-features=<feature>[,<feature>...]` - Use the specified JVM
features when building Hotspot. The list of features will be enabled on top

@ -1097,7 +1097,7 @@ AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER],
]
)
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

@ -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 @@ AC_DEFUN([HOTSPOT_CHECK_JVM_FEATURE],
# 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_DEFUN_ONCE([HOTSPOT_SETUP_JVM_VARIANTS],
AC_SUBST(VALID_JVM_VARIANTS)
AC_SUBST(JVM_VARIANT_MAIN)
if HOTSPOT_CHECK_JVM_VARIANT(zero) || HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
if HOTSPOT_CHECK_JVM_VARIANT(zero); then
# zero behaves as a platform and rewrites these values. This is really weird. :(
# We are guaranteed that we do not build any other variants when building zero.
HOTSPOT_TARGET_CPU=zero
@ -325,15 +324,9 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES],
fi
fi
if ! HOTSPOT_CHECK_JVM_VARIANT(zero) && ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
if ! HOTSPOT_CHECK_JVM_VARIANT(zero); then
if HOTSPOT_CHECK_JVM_FEATURE(zero); then
AC_MSG_ERROR([To enable zero/zeroshark, you must use --with-jvm-variants=zero/zeroshark])
fi
fi
if ! HOTSPOT_CHECK_JVM_VARIANT(zeroshark); then
if HOTSPOT_CHECK_JVM_FEATURE(shark); then
AC_MSG_ERROR([To enable shark, you must use --with-jvm-variants=zeroshark])
AC_MSG_ERROR([To enable zero, you must use --with-jvm-variants=zero])
fi
fi
@ -408,7 +401,6 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES],
JVM_FEATURES_core="$NON_MINIMAL_FEATURES $JVM_FEATURES"
JVM_FEATURES_minimal="compiler1 minimal $JVM_FEATURES $JVM_FEATURES_link_time_opt"
JVM_FEATURES_zero="zero $NON_MINIMAL_FEATURES $JVM_FEATURES"
JVM_FEATURES_zeroshark="zero shark $NON_MINIMAL_FEATURES $JVM_FEATURES"
JVM_FEATURES_custom="$JVM_FEATURES"
AC_SUBST(JVM_FEATURES_server)
@ -416,7 +408,6 @@ AC_DEFUN_ONCE([HOTSPOT_SETUP_JVM_FEATURES],
AC_SUBST(JVM_FEATURES_core)
AC_SUBST(JVM_FEATURES_minimal)
AC_SUBST(JVM_FEATURES_zero)
AC_SUBST(JVM_FEATURES_zeroshark)
AC_SUBST(JVM_FEATURES_custom)
# Used for verification of Makefiles by check-jvm-feature
@ -437,7 +428,6 @@ AC_DEFUN_ONCE([HOTSPOT_VALIDATE_JVM_FEATURES],
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

@ -232,7 +232,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_OPTIONS],
# 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

@ -65,8 +65,7 @@ AC_DEFUN_ONCE([LIB_SETUP_STD_LIBS],
# 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"

@ -68,7 +68,7 @@ AC_DEFUN_ONCE([LIB_DETERMINE_DEPENDENCIES],
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,69 +86,11 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES],
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
################################################################################

@ -222,7 +222,6 @@ JVM_FEATURES_client := @JVM_FEATURES_client@
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_ASFLAGS := @JVM_ASFLAGS@
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@

@ -87,7 +87,7 @@ endif
#
# 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 @@ else
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 @@ else
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

@ -75,7 +75,6 @@ ifeq ($(OPENJDK_TARGET_OS), windows)
-ignorePath linux \
-ignorePath posix \
-ignorePath ppc \
-ignorePath shark \
-ignorePath solaris \
-ignorePath sparc \
-ignorePath x86_32 \

@ -52,14 +52,6 @@ ifeq ($(call check-jvm-feature, zero), true)
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)

@ -300,7 +300,7 @@ LIBJLI_SRC_DIRS := $(call FindSrcDirsForLib, java.base, jli)
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)

@ -42,10 +42,6 @@
#ifdef COMPILER2
#include "opto/runtime.hpp"
#endif
#ifdef SHARK
#include "compiler/compileBroker.hpp"
#include "shark/sharkCompiler.hpp"
#endif
#define __ masm->

@ -43,7 +43,7 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
#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

@ -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

@ -46,7 +46,7 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
// 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

@ -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

@ -71,7 +71,6 @@ frame frame::sender_for_entry_frame(RegisterMap *map) const {
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 @@ void frame::patch_pc(Thread* thread, address pc) {
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 @@ void ZeroFrame::identify_word(int frame_index,
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 @@ void ZeroFrame::identify_word(int frame_index,
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 @@ void InterpreterFrame::identify_word(int frame_index,
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,

@ -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;

@ -56,18 +56,6 @@ inline frame::frame(ZeroFrame* zf, intptr_t* sp) {
_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::entry_frame_argument_at(int offset) const {
}
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

@ -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:

@ -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,

@ -50,7 +50,7 @@ address Relocation::pd_get_address_from_code() {
}
address* Relocation::pd_address_in_code() {
// Relocations in Shark are just stored directly
ShouldNotCallThis();
return (address *) addr();
}

@ -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 @@ nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
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,

@ -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

@ -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

@ -52,9 +52,6 @@ void ZeroStack::handle_overflow(TRAPS) {
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();

@ -121,7 +121,6 @@ class ZeroStack {
class EntryFrame;
class InterpreterFrame;
class SharkFrame;
class FakeStubFrame;
//
@ -151,7 +150,6 @@ class ZeroFrame {
enum FrameType {
ENTRY_FRAME = 1,
INTERPRETER_FRAME,
SHARK_FRAME,
FAKE_STUB_FRAME
};
@ -180,9 +178,6 @@ class ZeroFrame {
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 @@ class ZeroFrame {
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;

@ -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) {

@ -1218,12 +1218,12 @@ void ciEnv::dump_compile_data(outputStream* out) {
method->signature()->as_quoted_ascii(),
entry_bci, comp_level);
if (compiler_data() != NULL) {
if (is_c2_compile(comp_level)) { // C2 or Shark
if (is_c2_compile(comp_level)) {
#ifdef COMPILER2
// Dump C2 inlining data.
((Compile*)compiler_data())->dump_inline_data(out);
#endif
} else if (is_c1_compile(comp_level)) { // C1
} else if (is_c1_compile(comp_level)) {
#ifdef COMPILER1
// Dump C1 inlining data.
((Compilation*)compiler_data())->dump_inline_data(out);

@ -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 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) :
_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 @@ ciMethod::ciMethod(ciInstanceKlass* holder,
_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 @@ int ciMethod::vtable_index() {
}
#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 @@ bool ciMethod::has_balanced_monitors() {
// ------------------------------------------------------------------
// 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
}
// ------------------------------------------------------------------

@ -96,7 +96,7 @@ class ciMethod : public ciMetadata {
// Optional liveness analyzer.
MethodLiveness* _liveness;
#if defined(COMPILER2) || defined(SHARK)
#if defined(COMPILER2)
ciTypeFlow* _flow;
BCEscapeAnalyzer* _bcea;
#endif
@ -216,9 +216,6 @@ class ciMethod : public ciMetadata {
// Runtime information.
int vtable_index();
#ifdef SHARK
int itable_index();
#endif // SHARK
address native_entry();
address interpreter_entry();

@ -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 {

@ -125,7 +125,6 @@ public:
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

@ -294,7 +294,6 @@ int CompiledMethod::verify_icholder_relocations() {
// 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 @@ void CompiledMethod::preserve_callee_argument_oops(frame fr, const RegisterMap *
fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f);
}
#endif // !SHARK
}
Method* CompiledMethod::attached_method(address call_instr) {

@ -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 @@ static java_nmethod_stats_struct c2_java_nmethod_stats;
#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;
@ -223,11 +217,6 @@ static void note_java_nmethod(nmethod* nm) {
if (nm->is_compiled_by_jvmci()) {
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 @@ void nmethod::flush() {
CodeCache::drop_scavenge_root_nmethod(this);
}
#ifdef SHARK
((SharkCompiler *) compiler())->free_compiled_method(insts_begin());
#endif // SHARK
CodeBlob::flush();
CodeCache::free(this);
}
@ -2241,8 +2226,6 @@ void nmethod::print() const {
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 {
@ -2863,9 +2846,6 @@ void nmethod::print_statistics() {
#endif
#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();

@ -152,7 +152,6 @@ class AbstractCompiler : public CHeapObj<mtCompiler> {
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.

@ -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 @@ void CompileBroker::compilation_init(TRAPS) {
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 @@ void CompileBroker::compilation_init(TRAPS) {
}
#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 @@ JavaThread* CompileBroker::make_thread(const char* name, CompileQueue* queue, Co
void CompileBroker::init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count) {
EXCEPTION_MARK;
#if !defined(ZERO) && !defined(SHARK)
#if !defined(ZERO)
assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?");
#endif // !ZERO && !SHARK
#endif // !ZERO
// Initialize the compilation queue
if (c2_compiler_count > 0) {
const char* name = JVMCI_ONLY(UseJVMCICompiler ? "JVMCI compile queue" :) "C2 compile queue";
@ -796,7 +785,6 @@ void CompileBroker::init_compiler_sweeper_threads(int c1_compiler_count, int c2_
// Create a name for our thread.
sprintf(name_buffer, "%s CompilerThread%d", _compilers[1]->name(), i);
CompilerCounters* counters = new CompilerCounters();
// Shark and C2
make_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], compiler_thread, CHECK);
}
@ -1100,7 +1088,7 @@ nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
assert(!HAS_PENDING_EXCEPTION, "No exception should be present");
// some prerequisites that are compiler specific
if (comp->is_c2() || comp->is_shark()) {
if (comp->is_c2()) {
method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NULL);
// Resolve all classes seen in the signature of the method
// we are compiling.
@ -1490,10 +1478,8 @@ bool CompileBroker::init_compiler_runtime() {
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()) {

@ -31,11 +31,10 @@ const char* compilertype2name_tab[compiler_number_of_types] = {
"",
"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_highest_tier = CompLevel_none;
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;

@ -33,7 +33,6 @@ enum CompilerType {
compiler_c1,
compiler_c2,
compiler_jvmci,
compiler_shark,
compiler_number_of_types
};
@ -54,7 +53,7 @@ enum CompLevel {
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;

@ -171,7 +171,7 @@ DirectiveSet* CompilerDirectives::get_for(AbstractCompiler *comp) {
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;
}
}

@ -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 @@ void Disassembler::decode(nmethod* nm, outputStream* st) {
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(".");

@ -478,9 +478,7 @@ BytecodeInterpreter::run(interpreterState istate) {
#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;

@ -1165,15 +1165,11 @@ void Method::set_code(const methodHandle& mh, CompiledMethod *code) {
}
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
}

@ -64,7 +64,7 @@ Flag::Error AliasLevelConstraintFunc(intx value, bool verbose) {
*/
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)) {

@ -339,7 +339,6 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
}
#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 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
strcmp("Stub<UncommonTrapStub.uncommonTrapHandler>", cb->name()) == 0,
"unexpected code blob: %s", cb->name());
#endif
#else
intptr_t* unpack_sp = stub_frame.sender(&dummy_map).unextended_sp();
#endif // !SHARK
// This is a guarantee instead of an assert because if vframe doesn't match
// we will unpack the wrong deoptimized frame and wind up in strange places
@ -488,9 +484,7 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
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 @@ Deoptimization::get_method_data(JavaThread* thread, const methodHandle& m,
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 @@ void Deoptimization::print_statistics() {
if (xtty != NULL) xtty->tail("statistics");
}
}
#else // COMPILER2 || SHARK || INCLUDE_JVMCI
#else // COMPILER2 || INCLUDE_JVMCI
// Stubs for C1 only system.
@ -2402,4 +2396,4 @@ const char* Deoptimization::format_trap_state(char* buf, size_t buflen,
return buf;
}
#endif // COMPILER2 || SHARK || INCLUDE_JVMCI
#endif // COMPILER2 || INCLUDE_JVMCI

@ -1115,10 +1115,6 @@ void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* ma
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();
}

@ -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)

@ -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 @@ void Flag::print_kind_and_origin(outputStream* st) {
{ 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 @@ const char* Flag::flag_error_str(Flag::Error error) {
#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 @@ static Flag flagTable[] = {
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, \

@ -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 @@ struct Flag {
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)
};

@ -3724,7 +3724,7 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
}
// 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

@ -95,11 +95,7 @@ bool Abstract_VM_Version::_parallel_worker_threads_initialized = false;
#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")

@ -1,100 +0,0 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_SHARK_LLVMHEADERS_HPP
#define SHARE_VM_SHARK_LLVMHEADERS_HPP
#ifdef assert
#undef assert
#endif
#ifdef DEBUG
#define SHARK_DEBUG
#undef DEBUG
#endif
#include <llvm/Analysis/Verifier.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
// includes specific to each version
#if SHARK_LLVM_VERSION <= 31
#include <llvm/Support/IRBuilder.h>
#include <llvm/Type.h>
#include <llvm/Argument.h>
#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Instructions.h>
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#elif SHARK_LLVM_VERSION <= 32
#include <llvm/IRBuilder.h>
#include <llvm/Type.h>
#include <llvm/Argument.h>
#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
#include <llvm/Instructions.h>
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#else // SHARK_LLVM_VERSION <= 34
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Argument.h>
#include <llvm/IR/Constants.h>
#include <llvm/IR/DerivedTypes.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/IR/Instructions.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/ADT/StringRef.h>
#include <llvm/IR/Type.h>
#endif
// common includes
#include <llvm/Support/Threading.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/ExecutionEngine/JITMemoryManager.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ADT/StringMap.h>
#include <llvm/Support/Debug.h>
#include <llvm/Support/Host.h>
#include <map>
#ifdef assert
#undef assert
#endif
#define assert(p, msg) vmassert(p, msg)
#ifdef DEBUG
#undef DEBUG
#endif
#ifdef SHARK_DEBUG
#define DEBUG
#undef SHARK_DEBUG
#endif
#endif // SHARE_VM_SHARK_LLVMHEADERS_HPP

@ -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

File diff suppressed because it is too large Load Diff

@ -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

@ -1,530 +0,0 @@
/*
* Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "ci/ciMethod.hpp"
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/cardTableModRefBS.hpp"
#include "memory/resourceArea.hpp"
#include "oops/method.hpp"
#include "prims/unsafe.hpp"
#include "runtime/os.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/thread.hpp"
#include "shark/llvmHeaders.hpp"
#include "shark/llvmValue.hpp"
#include "shark/sharkBuilder.hpp"
#include "shark/sharkContext.hpp"
#include "shark/sharkRuntime.hpp"
#include "utilities/debug.hpp"
using namespace llvm;
SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer)
: IRBuilder<>(SharkContext::current()),
_code_buffer(code_buffer) {
}
// Helpers for accessing structures
Value* SharkBuilder::CreateAddressOfStructEntry(Value* base,
ByteSize offset,
Type* type,
const char* name) {
return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name);
}
LoadInst* SharkBuilder::CreateValueOfStructEntry(Value* base,
ByteSize offset,
Type* type,
const char* name) {
return CreateLoad(
CreateAddressOfStructEntry(
base, offset, PointerType::getUnqual(type)),
name);
}
// Helpers for accessing arrays
LoadInst* SharkBuilder::CreateArrayLength(Value* arrayoop) {
return CreateValueOfStructEntry(
arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()),
SharkType::jint_type(), "length");
}
Value* SharkBuilder::CreateArrayAddress(Value* arrayoop,
Type* element_type,
int element_bytes,
ByteSize base_offset,
Value* index,
const char* name) {
Value* offset = CreateIntCast(index, SharkType::intptr_type(), false);
if (element_bytes != 1)
offset = CreateShl(
offset,
LLVMValue::intptr_constant(exact_log2(element_bytes)));
offset = CreateAdd(
LLVMValue::intptr_constant(in_bytes(base_offset)), offset);
return CreateIntToPtr(
CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset),
PointerType::getUnqual(element_type),
name);
}
Value* SharkBuilder::CreateArrayAddress(Value* arrayoop,
BasicType basic_type,
ByteSize base_offset,
Value* index,
const char* name) {
return CreateArrayAddress(
arrayoop,
SharkType::to_arrayType(basic_type),
type2aelembytes(basic_type),
base_offset, index, name);
}
Value* SharkBuilder::CreateArrayAddress(Value* arrayoop,
BasicType basic_type,
Value* index,
const char* name) {
return CreateArrayAddress(
arrayoop, basic_type,
in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)),
index, name);
}
// Helpers for creating intrinsics and external functions.
Type* SharkBuilder::make_type(char type, bool void_ok) {
switch (type) {
// Primitive types
case 'c':
return SharkType::jbyte_type();
case 'i':
return SharkType::jint_type();
case 'l':
return SharkType::jlong_type();
case 'x':
return SharkType::intptr_type();
case 'f':
return SharkType::jfloat_type();
case 'd':
return SharkType::jdouble_type();
// Pointers to primitive types
case 'C':
case 'I':
case 'L':
case 'X':
case 'F':
case 'D':
return PointerType::getUnqual(make_type(tolower(type), false));
// VM objects
case 'T':
return SharkType::thread_type();
case 'M':
return PointerType::getUnqual(SharkType::monitor_type());
case 'O':
return SharkType::oop_type();
case 'K':
return SharkType::klass_type();
// Miscellaneous
case 'v':
assert(void_ok, "should be");
return SharkType::void_type();
case '1':
return SharkType::bit_type();
default:
ShouldNotReachHere();
}
}
FunctionType* SharkBuilder::make_ftype(const char* params,
const char* ret) {
std::vector<Type*> param_types;
for (const char* c = params; *c; c++)
param_types.push_back(make_type(*c, false));
assert(strlen(ret) == 1, "should be");
Type *return_type = make_type(*ret, true);
return FunctionType::get(return_type, param_types, false);
}
// Create an object representing an intrinsic or external function by
// referencing the symbol by name. This is the LLVM-style approach,
// but it cannot be used on functions within libjvm.so its symbols
// are not exported. Note that you cannot make this work simply by
// exporting the symbols, as some symbols have the same names as
// symbols in the standard libraries (eg, atan2, fabs) and would
// obscure them were they visible.
Value* SharkBuilder::make_function(const char* name,
const char* params,
const char* ret) {
return SharkContext::current().get_external(name, make_ftype(params, ret));
}
// Create an object representing an external function by inlining a
// function pointer in the code. This is not the LLVM way, but it's
// the only way to access functions in libjvm.so and functions like
// __kernel_dmb on ARM which is accessed via an absolute address.
Value* SharkBuilder::make_function(address func,
const char* params,
const char* ret) {
return CreateIntToPtr(
LLVMValue::intptr_constant((intptr_t) func),
PointerType::getUnqual(make_ftype(params, ret)));
}
// VM calls
Value* SharkBuilder::find_exception_handler() {
return make_function(
(address) SharkRuntime::find_exception_handler, "TIi", "i");
}
Value* SharkBuilder::monitorenter() {
return make_function((address) SharkRuntime::monitorenter, "TM", "v");
}
Value* SharkBuilder::monitorexit() {
return make_function((address) SharkRuntime::monitorexit, "TM", "v");
}
Value* SharkBuilder::new_instance() {
return make_function((address) SharkRuntime::new_instance, "Ti", "v");
}
Value* SharkBuilder::newarray() {
return make_function((address) SharkRuntime::newarray, "Tii", "v");
}
Value* SharkBuilder::anewarray() {
return make_function((address) SharkRuntime::anewarray, "Tii", "v");
}
Value* SharkBuilder::multianewarray() {
return make_function((address) SharkRuntime::multianewarray, "TiiI", "v");
}
Value* SharkBuilder::register_finalizer() {
return make_function((address) SharkRuntime::register_finalizer, "TO", "v");
}
Value* SharkBuilder::safepoint() {
return make_function((address) SafepointSynchronize::block, "T", "v");
}
Value* SharkBuilder::throw_ArithmeticException() {
return make_function(
(address) SharkRuntime::throw_ArithmeticException, "TCi", "v");
}
Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() {
return make_function(
(address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v");
}
Value* SharkBuilder::throw_ClassCastException() {
return make_function(
(address) SharkRuntime::throw_ClassCastException, "TCi", "v");
}
Value* SharkBuilder::throw_NullPointerException() {
return make_function(
(address) SharkRuntime::throw_NullPointerException, "TCi", "v");
}
// High-level non-VM calls
Value* SharkBuilder::f2i() {
return make_function((address) SharedRuntime::f2i, "f", "i");
}
Value* SharkBuilder::f2l() {
return make_function((address) SharedRuntime::f2l, "f", "l");
}
Value* SharkBuilder::d2i() {
return make_function((address) SharedRuntime::d2i, "d", "i");
}
Value* SharkBuilder::d2l() {
return make_function((address) SharedRuntime::d2l, "d", "l");
}
Value* SharkBuilder::is_subtype_of() {
return make_function((address) SharkRuntime::is_subtype_of, "KK", "c");
}
Value* SharkBuilder::current_time_millis() {
return make_function((address) os::javaTimeMillis, "", "l");
}
Value* SharkBuilder::sin() {
return make_function("llvm.sin.f64", "d", "d");
}
Value* SharkBuilder::cos() {
return make_function("llvm.cos.f64", "d", "d");
}
Value* SharkBuilder::tan() {
return make_function((address) ::tan, "d", "d");
}
Value* SharkBuilder::atan2() {
return make_function((address) ::atan2, "dd", "d");
}
Value* SharkBuilder::sqrt() {
return make_function("llvm.sqrt.f64", "d", "d");
}
Value* SharkBuilder::log() {
return make_function("llvm.log.f64", "d", "d");
}
Value* SharkBuilder::log10() {
return make_function("llvm.log10.f64", "d", "d");
}
Value* SharkBuilder::pow() {
return make_function("llvm.pow.f64", "dd", "d");
}
Value* SharkBuilder::exp() {
return make_function("llvm.exp.f64", "d", "d");
}
Value* SharkBuilder::fabs() {
return make_function((address) ::fabs, "d", "d");
}
Value* SharkBuilder::unsafe_field_offset_to_byte_offset() {
return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l");
}
Value* SharkBuilder::osr_migration_end() {
return make_function((address) SharedRuntime::OSR_migration_end, "C", "v");
}
// Semi-VM calls
Value* SharkBuilder::throw_StackOverflowError() {
return make_function((address) ZeroStack::handle_overflow, "T", "v");
}
Value* SharkBuilder::uncommon_trap() {
return make_function((address) SharkRuntime::uncommon_trap, "Ti", "i");
}
Value* SharkBuilder::deoptimized_entry_point() {
return make_function((address) CppInterpreter::main_loop, "iT", "v");
}
// Native-Java transition
Value* SharkBuilder::check_special_condition_for_native_trans() {
return make_function(
(address) JavaThread::check_special_condition_for_native_trans,
"T", "v");
}
Value* SharkBuilder::frame_address() {
return make_function("llvm.frameaddress", "i", "C");
}
Value* SharkBuilder::memset() {
// LLVM 2.8 added a fifth isVolatile field for memset
// introduced with LLVM r100304
return make_function("llvm.memset.p0i8.i32", "Cciii", "v");
}
Value* SharkBuilder::unimplemented() {
return make_function((address) report_unimplemented, "Ci", "v");
}
Value* SharkBuilder::should_not_reach_here() {
return make_function((address) report_should_not_reach_here, "Ci", "v");
}
Value* SharkBuilder::dump() {
return make_function((address) SharkRuntime::dump, "Cx", "v");
}
// Public interface to low-level non-VM calls
CallInst* SharkBuilder::CreateGetFrameAddress() {
return CreateCall(frame_address(), LLVMValue::jint_constant(0));
}
CallInst* SharkBuilder::CreateMemset(Value* dst,
Value* value,
Value* len,
Value* align) {
return CreateCall5(memset(), dst, value, len, align,
LLVMValue::jint_constant(0));
}
CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) {
return CreateCall2(
unimplemented(),
CreateIntToPtr(
LLVMValue::intptr_constant((intptr_t) file),
PointerType::getUnqual(SharkType::jbyte_type())),
LLVMValue::jint_constant(line));
}
CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line) {
return CreateCall2(
should_not_reach_here(),
CreateIntToPtr(
LLVMValue::intptr_constant((intptr_t) file),
PointerType::getUnqual(SharkType::jbyte_type())),
LLVMValue::jint_constant(line));
}
#ifndef PRODUCT
CallInst* SharkBuilder::CreateDump(Value* value) {
const char *name;
if (value->hasName())
// XXX this leaks, but it's only debug code
name = os::strdup(value->getName().str().c_str());
else
name = "unnamed_value";
if (isa<PointerType>(value->getType()))
value = CreatePtrToInt(value, SharkType::intptr_type());
else if (value->getType()->
isIntegerTy()
)
value = CreateIntCast(value, SharkType::intptr_type(), false);
else
Unimplemented();
return CreateCall2(
dump(),
CreateIntToPtr(
LLVMValue::intptr_constant((intptr_t) name),
PointerType::getUnqual(SharkType::jbyte_type())),
value);
}
#endif // PRODUCT
// HotSpot memory barriers
void SharkBuilder::CreateUpdateBarrierSet(BarrierSet* bs, Value* field) {
if (bs->kind() != BarrierSet::CardTableForRS &&
bs->kind() != BarrierSet::CardTableExtension) {
Unimplemented();
}
CreateStore(
LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card_val()),
CreateIntToPtr(
CreateAdd(
LLVMValue::intptr_constant(
(intptr_t) (barrier_set_cast<CardTableModRefBS>(bs)->byte_map_base)),
CreateLShr(
CreatePtrToInt(field, SharkType::intptr_type()),
LLVMValue::intptr_constant(CardTableModRefBS::card_shift))),
PointerType::getUnqual(SharkType::jbyte_type())));
}
// Helpers for accessing the code buffer
Value* SharkBuilder::code_buffer_address(int offset) {
return CreateAdd(
code_buffer()->base_pc(),
LLVMValue::intptr_constant(offset));
}
Value* SharkBuilder::CreateInlineOop(jobject object, const char* name) {
return CreateLoad(
CreateIntToPtr(
code_buffer_address(code_buffer()->inline_oop(object)),
PointerType::getUnqual(SharkType::oop_type())),
name);
}
Value* SharkBuilder::CreateInlineMetadata(Metadata* metadata, llvm::PointerType* type, const char* name) {
assert(metadata != NULL, "inlined metadata must not be NULL");
assert(metadata->is_metaspace_object(), "sanity check");
return CreateLoad(
CreateIntToPtr(
code_buffer_address(code_buffer()->inline_Metadata(metadata)),
PointerType::getUnqual(type)),
name);
}
Value* SharkBuilder::CreateInlineData(void* data,
size_t size,
Type* type,
const char* name) {
return CreateIntToPtr(
code_buffer_address(code_buffer()->inline_data(data, size)),
type,
name);
}
// Helpers for creating basic blocks.
BasicBlock* SharkBuilder::GetBlockInsertionPoint() const {
BasicBlock *cur = GetInsertBlock();
// BasicBlock::Create takes an insertBefore argument, so
// we need to find the block _after_ the current block
Function::iterator iter = cur->getParent()->begin();
Function::iterator end = cur->getParent()->end();
while (iter != end) {
iter++;
if (&*iter == cur) {
iter++;
break;
}
}
if (iter == end)
return NULL;
else
return iter;
}
BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const {
return BasicBlock::Create(
SharkContext::current(), name, GetInsertBlock()->getParent(), ip);
}
LoadInst* SharkBuilder::CreateAtomicLoad(Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) {
return Insert(new LoadInst(ptr, name, isVolatile, align, ordering, synchScope), name);
}
StoreInst* SharkBuilder::CreateAtomicStore(Value* val, Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) {
return Insert(new StoreInst(val, ptr, isVolatile, align, ordering, synchScope), name);
}

@ -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

@ -1,266 +0,0 @@
/*
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright 2008, 2009 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "ci/ciMethod.hpp"
#include "code/debugInfoRec.hpp"
#include "shark/llvmValue.hpp"
#include "shark/sharkBuilder.hpp"
#include "shark/sharkCacheDecache.hpp"
#include "shark/sharkFunction.hpp"
#include "shark/sharkState.hpp"
using namespace llvm;
void SharkDecacher::start_frame() {
// Start recording the debug information
_pc_offset = code_buffer()->create_unique_offset();
_oopmap = new OopMap(
oopmap_slot_munge(stack()->oopmap_frame_size()),
oopmap_slot_munge(arg_size()));
debug_info()->add_safepoint(pc_offset(), oopmap());
}
void SharkDecacher::start_stack(int stack_depth) {
// Create the array we'll record our stack slots in
_exparray = new GrowableArray<ScopeValue*>(stack_depth);
// Set the stack pointer
stack()->CreateStoreStackPointer(
builder()->CreatePtrToInt(
stack()->slot_addr(
stack()->stack_slots_offset() + max_stack() - stack_depth),
SharkType::intptr_type()));
}
void SharkDecacher::process_stack_slot(int index,
SharkValue** addr,
int offset) {
SharkValue *value = *addr;
// Write the value to the frame if necessary
if (stack_slot_needs_write(index, value)) {
write_value_to_frame(
SharkType::to_stackType(value->basic_type()),
value->generic_value(),
adjusted_offset(value, offset));
}
// Record the value in the oopmap if necessary
if (stack_slot_needs_oopmap(index, value)) {
oopmap()->set_oop(slot2reg(offset));
}
// Record the value in the debuginfo if necessary
if (stack_slot_needs_debuginfo(index, value)) {
exparray()->append(slot2lv(offset, stack_location_type(index, addr)));
}
}
void SharkDecacher::start_monitors(int num_monitors) {
// Create the array we'll record our monitors in
_monarray = new GrowableArray<MonitorValue*>(num_monitors);
}
void SharkDecacher::process_monitor(int index, int box_offset, int obj_offset) {
oopmap()->set_oop(slot2reg(obj_offset));
monarray()->append(new MonitorValue(
slot2lv (obj_offset, Location::oop),
slot2loc(box_offset, Location::normal)));
}
void SharkDecacher::process_oop_tmp_slot(Value** value, int offset) {
// Decache the temporary oop slot
if (*value) {
write_value_to_frame(
SharkType::oop_type(),
*value,
offset);
oopmap()->set_oop(slot2reg(offset));
}
}
void SharkDecacher::process_method_slot(Value** value, int offset) {
// Decache the method pointer
write_value_to_frame(
SharkType::Method_type(),
*value,
offset);
}
void SharkDecacher::process_pc_slot(int offset) {
// Record the PC
builder()->CreateStore(
builder()->code_buffer_address(pc_offset()),
stack()->slot_addr(offset));
}
void SharkDecacher::start_locals() {
// Create the array we'll record our local variables in
_locarray = new GrowableArray<ScopeValue*>(max_locals());}
void SharkDecacher::process_local_slot(int index,
SharkValue** addr,
int offset) {
SharkValue *value = *addr;
// Write the value to the frame if necessary
if (local_slot_needs_write(index, value)) {
write_value_to_frame(
SharkType::to_stackType(value->basic_type()),
value->generic_value(),
adjusted_offset(value, offset));
}
// Record the value in the oopmap if necessary
if (local_slot_needs_oopmap(index, value)) {
oopmap()->set_oop(slot2reg(offset));
}
// Record the value in the debuginfo if necessary
if (local_slot_needs_debuginfo(index, value)) {
locarray()->append(slot2lv(offset, local_location_type(index, addr)));
}
}
void SharkDecacher::end_frame() {
// Record the scope
methodHandle null_mh;
debug_info()->describe_scope(
pc_offset(),
null_mh,
target(),
bci(),
true,
false,
false,
debug_info()->create_scope_values(locarray()),
debug_info()->create_scope_values(exparray()),
debug_info()->create_monitor_values(monarray()));
// Finish recording the debug information
debug_info()->end_safepoint(pc_offset());
}
void SharkCacher::process_stack_slot(int index,
SharkValue** addr,
int offset) {
SharkValue *value = *addr;
// Read the value from the frame if necessary
if (stack_slot_needs_read(index, value)) {
*addr = SharkValue::create_generic(
value->type(),
read_value_from_frame(
SharkType::to_stackType(value->basic_type()),
adjusted_offset(value, offset)),
value->zero_checked());
}
}
void SharkOSREntryCacher::process_monitor(int index,
int box_offset,
int obj_offset) {
// Copy the monitor from the OSR buffer to the frame
int src_offset = max_locals() + index * 2;
builder()->CreateStore(
builder()->CreateLoad(
CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())),
stack()->slot_addr(box_offset, SharkType::intptr_type()));
builder()->CreateStore(
builder()->CreateLoad(
CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())),
stack()->slot_addr(obj_offset, SharkType::oop_type()));
}
void SharkCacher::process_oop_tmp_slot(Value** value, int offset) {
// Cache the temporary oop
if (*value)
*value = read_value_from_frame(SharkType::oop_type(), offset);
}
void SharkCacher::process_method_slot(Value** value, int offset) {
// Cache the method pointer
*value = read_value_from_frame(SharkType::Method_type(), offset);
}
void SharkFunctionEntryCacher::process_method_slot(Value** value, int offset) {
// "Cache" the method pointer
*value = method();
}
void SharkCacher::process_local_slot(int index,
SharkValue** addr,
int offset) {
SharkValue *value = *addr;
// Read the value from the frame if necessary
if (local_slot_needs_read(index, value)) {
*addr = SharkValue::create_generic(
value->type(),
read_value_from_frame(
SharkType::to_stackType(value->basic_type()),
adjusted_offset(value, offset)),
value->zero_checked());
}
}
Value* SharkOSREntryCacher::CreateAddressOfOSRBufEntry(int offset,
Type* type) {
Value *result = builder()->CreateStructGEP(osr_buf(), offset);
if (type != SharkType::intptr_type())
result = builder()->CreateBitCast(result, PointerType::getUnqual(type));
return result;
}
void SharkOSREntryCacher::process_local_slot(int index,
SharkValue** addr,
int offset) {
SharkValue *value = *addr;
// Read the value from the OSR buffer if necessary
if (local_slot_needs_read(index, value)) {
*addr = SharkValue::create_generic(
value->type(),
builder()->CreateLoad(
CreateAddressOfOSRBufEntry(
adjusted_offset(value, max_locals() - 1 - index),
SharkType::to_stackType(value->basic_type()))),
value->zero_checked());
}
}
void SharkDecacher::write_value_to_frame(Type* type,
Value* value,
int offset) {
builder()->CreateStore(value, stack()->slot_addr(offset, type));
}
Value* SharkCacher::read_value_from_frame(Type* type, int offset) {
return builder()->CreateLoad(stack()->slot_addr(offset, type));
}

@ -1,428 +0,0 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2008, 2009 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP
#define SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP
#include "ci/ciMethod.hpp"
#include "code/debugInfoRec.hpp"
#include "shark/sharkBuilder.hpp"
#include "shark/sharkFunction.hpp"
#include "shark/sharkStateScanner.hpp"
// Class hierarchy:
// - SharkStateScanner
// - SharkCacherDecacher
// - SharkDecacher
// - SharkJavaCallDecacher
// - SharkVMCallDecacher
// - SharkTrapDecacher
// - SharkCacher
// - SharkJavaCallCacher
// - SharkVMCallCacher
// - SharkFunctionEntryCacher
// - SharkNormalEntryCacher
// - SharkOSREntryCacher
class SharkCacherDecacher : public SharkStateScanner {
protected:
SharkCacherDecacher(SharkFunction* function)
: SharkStateScanner(function) {}
// Helper
protected:
static int adjusted_offset(SharkValue* value, int offset) {
if (value->is_two_word())
offset--;
return offset;
}
};
class SharkDecacher : public SharkCacherDecacher {
protected:
SharkDecacher(SharkFunction* function, int bci)
: SharkCacherDecacher(function), _bci(bci) {}
private:
int _bci;
protected:
int bci() const {
return _bci;
}
private:
int _pc_offset;
OopMap* _oopmap;
GrowableArray<ScopeValue*>* _exparray;
GrowableArray<MonitorValue*>* _monarray;
GrowableArray<ScopeValue*>* _locarray;
private:
int pc_offset() const {
return _pc_offset;
}
OopMap* oopmap() const {
return _oopmap;
}
GrowableArray<ScopeValue*>* exparray() const {
return _exparray;
}
GrowableArray<MonitorValue*>* monarray() const {
return _monarray;
}
GrowableArray<ScopeValue*>* locarray() const {
return _locarray;
}
// Callbacks
protected:
void start_frame();
void start_stack(int stack_depth);
void process_stack_slot(int index, SharkValue** value, int offset);
void start_monitors(int num_monitors);
void process_monitor(int index, int box_offset, int obj_offset);
void process_oop_tmp_slot(llvm::Value** value, int offset);
void process_method_slot(llvm::Value** value, int offset);
void process_pc_slot(int offset);
void start_locals();
void process_local_slot(int index, SharkValue** value, int offset);
void end_frame();
// oopmap and debuginfo helpers
private:
static int oopmap_slot_munge(int offset) {
return SharkStack::oopmap_slot_munge(offset);
}
static VMReg slot2reg(int offset) {
return SharkStack::slot2reg(offset);
}
static Location slot2loc(int offset, Location::Type type) {
return Location::new_stk_loc(type, offset * wordSize);
}
static LocationValue* slot2lv(int offset, Location::Type type) {
return new LocationValue(slot2loc(offset, type));
}
static Location::Type location_type(SharkValue** addr, bool maybe_two_word) {
// low addresses this end
// Type 32-bit 64-bit
// ----------------------------------------------------
// stack[0] local[3] jobject oop oop
// stack[1] local[2] NULL normal lng
// stack[2] local[1] jlong normal invalid
// stack[3] local[0] jint normal normal
//
// high addresses this end
SharkValue *value = *addr;
if (value) {
if (value->is_jobject())
return Location::oop;
#ifdef _LP64
if (value->is_two_word())
return Location::invalid;
#endif // _LP64
return Location::normal;
}
else {
if (maybe_two_word) {
value = *(addr - 1);
if (value && value->is_two_word()) {
#ifdef _LP64
if (value->is_jlong())
return Location::lng;
if (value->is_jdouble())
return Location::dbl;
ShouldNotReachHere();
#else
return Location::normal;
#endif // _LP64
}
}
return Location::invalid;
}
}
// Stack slot helpers
protected:
virtual bool stack_slot_needs_write(int index, SharkValue* value) = 0;
virtual bool stack_slot_needs_oopmap(int index, SharkValue* value) = 0;
virtual bool stack_slot_needs_debuginfo(int index, SharkValue* value) = 0;
static Location::Type stack_location_type(int index, SharkValue** addr) {
return location_type(addr, *addr == NULL);
}
// Local slot helpers
protected:
virtual bool local_slot_needs_write(int index, SharkValue* value) = 0;
virtual bool local_slot_needs_oopmap(int index, SharkValue* value) = 0;
virtual bool local_slot_needs_debuginfo(int index, SharkValue* value) = 0;
static Location::Type local_location_type(int index, SharkValue** addr) {
return location_type(addr, index > 0);
}
// Writer helper
protected:
void write_value_to_frame(llvm::Type* type,
llvm::Value* value,
int offset);
};
class SharkJavaCallDecacher : public SharkDecacher {
public:
SharkJavaCallDecacher(SharkFunction* function, int bci, ciMethod* callee)
: SharkDecacher(function, bci), _callee(callee) {}
private:
ciMethod* _callee;
protected:
ciMethod* callee() const {
return _callee;
}
// Stack slot helpers
protected:
bool stack_slot_needs_write(int index, SharkValue* value) {
return value && (index < callee()->arg_size() || value->is_jobject());
}
bool stack_slot_needs_oopmap(int index, SharkValue* value) {
return value && value->is_jobject() && index >= callee()->arg_size();
}
bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
return index >= callee()->arg_size();
}
// Local slot helpers
protected:
bool local_slot_needs_write(int index, SharkValue* value) {
return value && value->is_jobject();
}
bool local_slot_needs_oopmap(int index, SharkValue* value) {
return value && value->is_jobject();
}
bool local_slot_needs_debuginfo(int index, SharkValue* value) {
return true;
}
};
class SharkVMCallDecacher : public SharkDecacher {
public:
SharkVMCallDecacher(SharkFunction* function, int bci)
: SharkDecacher(function, bci) {}
// Stack slot helpers
protected:
bool stack_slot_needs_write(int index, SharkValue* value) {
return value && value->is_jobject();
}
bool stack_slot_needs_oopmap(int index, SharkValue* value) {
return value && value->is_jobject();
}
bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
return true;
}
// Local slot helpers
protected:
bool local_slot_needs_write(int index, SharkValue* value) {
return value && value->is_jobject();
}
bool local_slot_needs_oopmap(int index, SharkValue* value) {
return value && value->is_jobject();
}
bool local_slot_needs_debuginfo(int index, SharkValue* value) {
return true;
}
};
class SharkTrapDecacher : public SharkDecacher {
public:
SharkTrapDecacher(SharkFunction* function, int bci)
: SharkDecacher(function, bci) {}
// Stack slot helpers
protected:
bool stack_slot_needs_write(int index, SharkValue* value) {
return value != NULL;
}
bool stack_slot_needs_oopmap(int index, SharkValue* value) {
return value && value->is_jobject();
}
bool stack_slot_needs_debuginfo(int index, SharkValue* value) {
return true;
}
// Local slot helpers
protected:
bool local_slot_needs_write(int index, SharkValue* value) {
return value != NULL;
}
bool local_slot_needs_oopmap(int index, SharkValue* value) {
return value && value->is_jobject();
}
bool local_slot_needs_debuginfo(int index, SharkValue* value) {
return true;
}
};
class SharkCacher : public SharkCacherDecacher {
protected:
SharkCacher(SharkFunction* function)
: SharkCacherDecacher(function) {}
// Callbacks
protected:
void process_stack_slot(int index, SharkValue** value, int offset);
void process_oop_tmp_slot(llvm::Value** value, int offset);
virtual void process_method_slot(llvm::Value** value, int offset);
virtual void process_local_slot(int index, SharkValue** value, int offset);
// Stack slot helper
protected:
virtual bool stack_slot_needs_read(int index, SharkValue* value) = 0;
// Local slot helper
protected:
virtual bool local_slot_needs_read(int index, SharkValue* value) {
return value && value->is_jobject();
}
// Writer helper
protected:
llvm::Value* read_value_from_frame(llvm::Type* type, int offset);
};
class SharkJavaCallCacher : public SharkCacher {
public:
SharkJavaCallCacher(SharkFunction* function, ciMethod* callee)
: SharkCacher(function), _callee(callee) {}
private:
ciMethod* _callee;
protected:
ciMethod* callee() const {
return _callee;
}
// Stack slot helper
protected:
bool stack_slot_needs_read(int index, SharkValue* value) {
return value && (index < callee()->return_type()->size() ||
value->is_jobject());
}
};
class SharkVMCallCacher : public SharkCacher {
public:
SharkVMCallCacher(SharkFunction* function)
: SharkCacher(function) {}
// Stack slot helper
protected:
bool stack_slot_needs_read(int index, SharkValue* value) {
return value && value->is_jobject();
}
};
class SharkFunctionEntryCacher : public SharkCacher {
public:
SharkFunctionEntryCacher(SharkFunction* function, llvm::Value* method)
: SharkCacher(function), _method(method) {}
private:
llvm::Value* _method;
private:
llvm::Value* method() const {
return _method;
}
// Method slot callback
protected:
void process_method_slot(llvm::Value** value, int offset);
// Stack slot helper
protected:
bool stack_slot_needs_read(int index, SharkValue* value) {
ShouldNotReachHere(); // entry block shouldn't have stack
}
// Local slot helper
protected:
bool local_slot_needs_read(int index, SharkValue* value) {
return value != NULL;
}
};
class SharkNormalEntryCacher : public SharkFunctionEntryCacher {
public:
SharkNormalEntryCacher(SharkFunction* function, llvm::Value* method)
: SharkFunctionEntryCacher(function, method) {}
};
class SharkOSREntryCacher : public SharkFunctionEntryCacher {
public:
SharkOSREntryCacher(SharkFunction* function,
llvm::Value* method,
llvm::Value* osr_buf)
: SharkFunctionEntryCacher(function, method),
_osr_buf(
builder()->CreateBitCast(
osr_buf,
llvm::PointerType::getUnqual(
llvm::ArrayType::get(
SharkType::intptr_type(),
max_locals() + max_monitors() * 2)))) {}
private:
llvm::Value* _osr_buf;
private:
llvm::Value* osr_buf() const {
return _osr_buf;
}
// Callbacks
protected:
void process_monitor(int index, int box_offset, int obj_offset);
void process_local_slot(int index, SharkValue** value, int offset);
// Helper
private:
llvm::Value* CreateAddressOfOSRBufEntry(int offset, llvm::Type* type);
};
#endif // SHARE_VM_SHARK_SHARKCACHEDECACHE_HPP

@ -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

@ -1,372 +0,0 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright 2008, 2009, 2010, 2011 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "ci/ciEnv.hpp"
#include "ci/ciMethod.hpp"
#include "code/debugInfoRec.hpp"
#include "code/dependencies.hpp"
#include "code/exceptionHandlerTable.hpp"
#include "code/oopRecorder.hpp"
#include "compiler/abstractCompiler.hpp"
#include "compiler/oopMap.hpp"
#include "memory/resourceArea.hpp"
#include "shark/llvmHeaders.hpp"
#include "shark/sharkBuilder.hpp"
#include "shark/sharkCodeBuffer.hpp"
#include "shark/sharkCompiler.hpp"
#include "shark/sharkContext.hpp"
#include "shark/sharkEntry.hpp"
#include "shark/sharkFunction.hpp"
#include "shark/sharkMemoryManager.hpp"
#include "shark/sharkNativeWrapper.hpp"
#include "shark/shark_globals.hpp"
#include "utilities/debug.hpp"
#include <fnmatch.h>
using namespace llvm;
namespace {
cl::opt<std::string>
MCPU("mcpu");
cl::list<std::string>
MAttrs("mattr",
cl::CommaSeparated);
}
SharkCompiler::SharkCompiler()
: AbstractCompiler(shark) {
// Create the lock to protect the memory manager and execution engine
_execution_engine_lock = new Monitor(Mutex::leaf, "SharkExecutionEngineLock");
MutexLocker locker(execution_engine_lock());
// Make LLVM safe for multithreading
if (!llvm_start_multithreaded())
fatal("llvm_start_multithreaded() failed");
// Initialize the native target
InitializeNativeTarget();
// MCJIT require a native AsmPrinter
InitializeNativeTargetAsmPrinter();
// Create the two contexts which we'll use
_normal_context = new SharkContext("normal");
_native_context = new SharkContext("native");
// Create the memory manager
_memory_manager = new SharkMemoryManager();
// Finetune LLVM for the current host CPU.
StringMap<bool> Features;
bool gotCpuFeatures = llvm::sys::getHostCPUFeatures(Features);
std::string cpu("-mcpu=" + llvm::sys::getHostCPUName());
std::vector<const char*> args;
args.push_back(""); // program name
args.push_back(cpu.c_str());
std::string mattr("-mattr=");
if(gotCpuFeatures){
for(StringMap<bool>::iterator I = Features.begin(),
E = Features.end(); I != E; ++I){
if(I->second){
std::string attr(I->first());
mattr+="+"+attr+",";
}
}
args.push_back(mattr.c_str());
}
args.push_back(0); // terminator
cl::ParseCommandLineOptions(args.size() - 1, (char **) &args[0]);
// Create the JIT
std::string ErrorMsg;
EngineBuilder builder(_normal_context->module());
builder.setMCPU(MCPU);
builder.setMAttrs(MAttrs);
builder.setJITMemoryManager(memory_manager());
builder.setEngineKind(EngineKind::JIT);
builder.setErrorStr(&ErrorMsg);
if (! fnmatch(SharkOptimizationLevel, "None", 0)) {
tty->print_cr("Shark optimization level set to: None");
builder.setOptLevel(llvm::CodeGenOpt::None);
} else if (! fnmatch(SharkOptimizationLevel, "Less", 0)) {
tty->print_cr("Shark optimization level set to: Less");
builder.setOptLevel(llvm::CodeGenOpt::Less);
} else if (! fnmatch(SharkOptimizationLevel, "Aggressive", 0)) {
tty->print_cr("Shark optimization level set to: Aggressive");
builder.setOptLevel(llvm::CodeGenOpt::Aggressive);
} // else Default is selected by, well, default :-)
_execution_engine = builder.create();
if (!execution_engine()) {
if (!ErrorMsg.empty())
printf("Error while creating Shark JIT: %s\n",ErrorMsg.c_str());
else
printf("Unknown error while creating Shark JIT\n");
exit(1);
}
execution_engine()->addModule(_native_context->module());
// All done
set_state(initialized);
}
void SharkCompiler::initialize() {
ShouldNotCallThis();
}
void SharkCompiler::compile_method(ciEnv* env,
ciMethod* target,
int entry_bci,
DirectiveSet* directive) {
assert(is_initialized(), "should be");
ResourceMark rm;
const char *name = methodname(
target->holder()->name()->as_utf8(), target->name()->as_utf8());
// Do the typeflow analysis
ciTypeFlow *flow;
if (entry_bci == InvocationEntryBci)
flow = target->get_flow_analysis();
else
flow = target->get_osr_flow_analysis(entry_bci);
if (flow->failing())
return;
if (SharkPrintTypeflowOf != NULL) {
if (!fnmatch(SharkPrintTypeflowOf, name, 0))
flow->print_on(tty);
}
// Create the recorders
Arena arena;
env->set_oop_recorder(new OopRecorder(&arena));
OopMapSet oopmaps;
env->set_debug_info(new DebugInformationRecorder(env->oop_recorder()));
env->debug_info()->set_oopmaps(&oopmaps);
env->set_dependencies(new Dependencies(env));
// Create the code buffer and builder
CodeBuffer hscb("Shark", 256 * K, 64 * K);
hscb.initialize_oop_recorder(env->oop_recorder());
MacroAssembler *masm = new MacroAssembler(&hscb);
SharkCodeBuffer cb(masm);
SharkBuilder builder(&cb);
// Emit the entry point
SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry));
// Build the LLVM IR for the method
Function *function = SharkFunction::build(env, &builder, flow, name);
if (env->failing()) {
return;
}
// Generate native code. It's unpleasant that we have to drop into
// the VM to do this -- it blocks safepoints -- but I can't see any
// other way to handle the locking.
{
ThreadInVMfromNative tiv(JavaThread::current());
generate_native_code(entry, function, name);
}
// Install the method into the VM
CodeOffsets offsets;
offsets.set_value(CodeOffsets::Deopt, 0);
offsets.set_value(CodeOffsets::Exceptions, 0);
offsets.set_value(CodeOffsets::Verified_Entry,
target->is_static() ? 0 : wordSize);
ExceptionHandlerTable handler_table;
ImplicitExceptionTable inc_table;
env->register_method(target,
entry_bci,
&offsets,
0,
&hscb,
0,
&oopmaps,
&handler_table,
&inc_table,
this,
false,
directive(),
false);
}
nmethod* SharkCompiler::generate_native_wrapper(MacroAssembler* masm,
const methodHandle& target,
int compile_id,
BasicType* arg_types,
BasicType return_type) {
assert(is_initialized(), "should be");
ResourceMark rm;
const char *name = methodname(
target->klass_name()->as_utf8(), target->name()->as_utf8());
// Create the code buffer and builder
SharkCodeBuffer cb(masm);
SharkBuilder builder(&cb);
// Emit the entry point
SharkEntry *entry = (SharkEntry *) cb.malloc(sizeof(SharkEntry));
// Build the LLVM IR for the method
SharkNativeWrapper *wrapper = SharkNativeWrapper::build(
&builder, target, name, arg_types, return_type);
// Generate native code
generate_native_code(entry, wrapper->function(), name);
// Return the nmethod for installation in the VM
return nmethod::new_native_nmethod(target,
compile_id,
masm->code(),
0,
0,
wrapper->frame_size(),
wrapper->receiver_offset(),
wrapper->lock_offset(),
wrapper->oop_maps());
}
void SharkCompiler::generate_native_code(SharkEntry* entry,
Function* function,
const char* name) {
// Print the LLVM bitcode, if requested
if (SharkPrintBitcodeOf != NULL) {
if (!fnmatch(SharkPrintBitcodeOf, name, 0))
function->dump();
}
if (SharkVerifyFunction != NULL) {
if (!fnmatch(SharkVerifyFunction, name, 0)) {
verifyFunction(*function);
}
}
// Compile to native code
address code = NULL;
context()->add_function(function);
{
MutexLocker locker(execution_engine_lock());
free_queued_methods();
#ifndef NDEBUG
#if SHARK_LLVM_VERSION <= 31
#define setCurrentDebugType SetCurrentDebugType
#endif
if (SharkPrintAsmOf != NULL) {
if (!fnmatch(SharkPrintAsmOf, name, 0)) {
llvm::setCurrentDebugType(X86_ONLY("x86-emitter") NOT_X86("jit"));
llvm::DebugFlag = true;
}
else {
llvm::setCurrentDebugType("");
llvm::DebugFlag = false;
}
}
#ifdef setCurrentDebugType
#undef setCurrentDebugType
#endif
#endif // !NDEBUG
memory_manager()->set_entry_for_function(function, entry);
code = (address) execution_engine()->getPointerToFunction(function);
}
assert(code != NULL, "code must be != NULL");
entry->set_entry_point(code);
entry->set_function(function);
entry->set_context(context());
address code_start = entry->code_start();
address code_limit = entry->code_limit();
// Register generated code for profiling, etc
if (JvmtiExport::should_post_dynamic_code_generated())
JvmtiExport::post_dynamic_code_generated(name, code_start, code_limit);
// Print debug information, if requested
if (SharkTraceInstalls) {
tty->print_cr(
" [%p-%p): %s (%d bytes code)",
code_start, code_limit, name, code_limit - code_start);
}
}
void SharkCompiler::free_compiled_method(address code) {
// This method may only be called when the VM is at a safepoint.
// All _thread_in_vm threads will be waiting for the safepoint to
// finish with the exception of the VM thread, so we can consider
// ourself the owner of the execution engine lock even though we
// can't actually acquire it at this time.
assert(Thread::current()->is_Compiler_thread(), "must be called by compiler thread");
assert_locked_or_safepoint(CodeCache_lock);
SharkEntry *entry = (SharkEntry *) code;
entry->context()->push_to_free_queue(entry->function());
}
void SharkCompiler::free_queued_methods() {
// The free queue is protected by the execution engine lock
assert(execution_engine_lock()->owned_by_self(), "should be");
while (true) {
Function *function = context()->pop_from_free_queue();
if (function == NULL)
break;
execution_engine()->freeMachineCodeForFunction(function);
function->eraseFromParent();
}
}
const char* SharkCompiler::methodname(const char* klass, const char* method) {
char *buf = NEW_RESOURCE_ARRAY(char, strlen(klass) + 2 + strlen(method) + 1);
char *dst = buf;
for (const char *c = klass; *c; c++) {
if (*c == '/')
*(dst++) = '.';
else
*(dst++) = *c;
}
*(dst++) = ':';
*(dst++) = ':';
for (const char *c = method; *c; c++) {
*(dst++) = *c;
}
*(dst++) = '\0';
return buf;
}
void SharkCompiler::print_timers() {
// do nothing
}

@ -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

@ -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;
}

@ -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

@ -1,188 +0,0 @@
/*
* Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "oops/arrayOop.hpp"
#include "oops/oop.hpp"
#include "shark/llvmHeaders.hpp"
#include "shark/sharkContext.hpp"
#include "utilities/globalDefinitions.hpp"
#include "memory/allocation.hpp"
using namespace llvm;
SharkContext::SharkContext(const char* name)
: LLVMContext(),
_free_queue(NULL) {
// Create a module to build our functions into
_module = new Module(name, *this);
// Create basic types
_void_type = Type::getVoidTy(*this);
_bit_type = Type::getInt1Ty(*this);
_jbyte_type = Type::getInt8Ty(*this);
_jshort_type = Type::getInt16Ty(*this);
_jint_type = Type::getInt32Ty(*this);
_jlong_type = Type::getInt64Ty(*this);
_jfloat_type = Type::getFloatTy(*this);
_jdouble_type = Type::getDoubleTy(*this);
// Create compound types
_itableOffsetEntry_type = PointerType::getUnqual(
ArrayType::get(jbyte_type(), itableOffsetEntry::size() * wordSize));
_Metadata_type = PointerType::getUnqual(
ArrayType::get(jbyte_type(), sizeof(Metadata)));
_klass_type = PointerType::getUnqual(
ArrayType::get(jbyte_type(), sizeof(Klass)));
_jniEnv_type = PointerType::getUnqual(
ArrayType::get(jbyte_type(), sizeof(JNIEnv)));
_jniHandleBlock_type = PointerType::getUnqual(
ArrayType::get(jbyte_type(), sizeof(JNIHandleBlock)));
_Method_type = PointerType::getUnqual(
ArrayType::get(jbyte_type(), sizeof(Method)));
_monitor_type = ArrayType::get(
jbyte_type(), frame::interpreter_frame_monitor_size() * wordSize);
_oop_type = PointerType::getUnqual(
ArrayType::get(jbyte_type(), sizeof(oopDesc)));
_thread_type = PointerType::getUnqual(
ArrayType::get(jbyte_type(), sizeof(JavaThread)));
_zeroStack_type = PointerType::getUnqual(
ArrayType::get(jbyte_type(), sizeof(ZeroStack)));
std::vector<Type*> params;
params.push_back(Method_type());
params.push_back(intptr_type());
params.push_back(thread_type());
_entry_point_type = FunctionType::get(jint_type(), params, false);
params.clear();
params.push_back(Method_type());
params.push_back(PointerType::getUnqual(jbyte_type()));
params.push_back(intptr_type());
params.push_back(thread_type());
_osr_entry_point_type = FunctionType::get(jint_type(), params, false);
// Create mappings
for (int i = 0; i < T_CONFLICT; i++) {
switch (i) {
case T_BOOLEAN:
_to_stackType[i] = jint_type();
_to_arrayType[i] = jbyte_type();
break;
case T_BYTE:
_to_stackType[i] = jint_type();
_to_arrayType[i] = jbyte_type();
break;
case T_CHAR:
_to_stackType[i] = jint_type();
_to_arrayType[i] = jshort_type();
break;
case T_SHORT:
_to_stackType[i] = jint_type();
_to_arrayType[i] = jshort_type();
break;
case T_INT:
_to_stackType[i] = jint_type();
_to_arrayType[i] = jint_type();
break;
case T_LONG:
_to_stackType[i] = jlong_type();
_to_arrayType[i] = jlong_type();
break;
case T_FLOAT:
_to_stackType[i] = jfloat_type();
_to_arrayType[i] = jfloat_type();
break;
case T_DOUBLE:
_to_stackType[i] = jdouble_type();
_to_arrayType[i] = jdouble_type();
break;
case T_OBJECT:
case T_ARRAY:
_to_stackType[i] = oop_type();
_to_arrayType[i] = oop_type();
break;
case T_ADDRESS:
_to_stackType[i] = intptr_type();
_to_arrayType[i] = NULL;
break;
default:
_to_stackType[i] = NULL;
_to_arrayType[i] = NULL;
}
}
}
class SharkFreeQueueItem : public CHeapObj<mtNone> {
public:
SharkFreeQueueItem(llvm::Function* function, SharkFreeQueueItem *next)
: _function(function), _next(next) {}
private:
llvm::Function* _function;
SharkFreeQueueItem* _next;
public:
llvm::Function* function() const {
return _function;
}
SharkFreeQueueItem* next() const {
return _next;
}
};
void SharkContext::push_to_free_queue(Function* function) {
_free_queue = new SharkFreeQueueItem(function, _free_queue);
}
Function* SharkContext::pop_from_free_queue() {
if (_free_queue == NULL)
return NULL;
SharkFreeQueueItem *item = _free_queue;
Function *function = item->function();
_free_queue = item->next();
delete item;
return function;
}

@ -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

@ -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

@ -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();
}

@ -1,127 +0,0 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2008, 2009 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_SHARK_SHARKFUNCTION_HPP
#define SHARE_VM_SHARK_SHARKFUNCTION_HPP
#include "ci/ciEnv.hpp"
#include "ci/ciStreams.hpp"
#include "ci/ciTypeFlow.hpp"
#include "memory/allocation.hpp"
#include "shark/llvmHeaders.hpp"
#include "shark/llvmValue.hpp"
#include "shark/sharkBuilder.hpp"
#include "shark/sharkContext.hpp"
#include "shark/sharkInvariants.hpp"
#include "shark/sharkStack.hpp"
class SharkTopLevelBlock;
class DeferredZeroCheck;
class SharkFunction : public SharkTargetInvariants {
friend class SharkStackWithNormalFrame;
public:
static llvm::Function* build(ciEnv* env,
SharkBuilder* builder,
ciTypeFlow* flow,
const char* name) {
SharkFunction function(env, builder, flow, name);
return function.function();
}
private:
SharkFunction(ciEnv* env,
SharkBuilder* builder,
ciTypeFlow* flow,
const char* name)
: SharkTargetInvariants(env, builder, flow) { initialize(name); }
private:
void initialize(const char* name);
private:
llvm::Function* _function;
SharkTopLevelBlock** _blocks;
GrowableArray<DeferredZeroCheck*> _deferred_zero_checks;
SharkStack* _stack;
public:
llvm::Function* function() const {
return _function;
}
int block_count() const {
return flow()->block_count();
}
SharkTopLevelBlock* block(int i) const {
assert(i < block_count(), "should be");
return _blocks[i];
}
GrowableArray<DeferredZeroCheck*>* deferred_zero_checks() {
return &_deferred_zero_checks;
}
SharkStack* stack() const {
return _stack;
}
// On-stack replacement
private:
bool is_osr() const {
return flow()->is_osr_flow();
}
llvm::FunctionType* entry_point_type() const {
if (is_osr())
return SharkType::osr_entry_point_type();
else
return SharkType::entry_point_type();
}
// Block management
private:
llvm::BasicBlock* _block_insertion_point;
void set_block_insertion_point(llvm::BasicBlock* block_insertion_point) {
_block_insertion_point = block_insertion_point;
}
llvm::BasicBlock* block_insertion_point() const {
return _block_insertion_point;
}
public:
llvm::BasicBlock* CreateBlock(const char* name = "") const {
return llvm::BasicBlock::Create(
SharkContext::current(), name, function(), block_insertion_point());
}
// Deferred zero checks
public:
void add_deferred_zero_check(SharkTopLevelBlock* block,
SharkValue* value);
private:
void do_deferred_zero_checks();
};
#endif // SHARE_VM_SHARK_SHARKFUNCTION_HPP

@ -1,765 +0,0 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "ci/ciField.hpp"
#include "ci/ciMethod.hpp"
#include "ci/ciStreams.hpp"
#include "interpreter/bytecodes.hpp"
#include "memory/allocation.hpp"
#include "memory/resourceArea.hpp"
#include "shark/sharkBlock.hpp"
#include "shark/sharkConstant.hpp"
#include "shark/sharkInliner.hpp"
#include "shark/sharkIntrinsics.hpp"
#include "shark/sharkState.hpp"
#include "shark/sharkValue.hpp"
#include "shark/shark_globals.hpp"
using namespace llvm;
class SharkInlineBlock : public SharkBlock {
public:
SharkInlineBlock(ciMethod* target, SharkState* state)
: SharkBlock(state, target),
_outer_state(state),
_entry_state(new SharkState(this)) {
for (int i = target->max_locals() - 1; i >= 0; i--) {
SharkValue *value = NULL;
if (i < target->arg_size())
value = outer_state()->pop();
entry_state()->set_local(i, value);
}
}
private:
SharkState* _outer_state;
SharkState* _entry_state;
private:
SharkState* outer_state() {
return _outer_state;
}
SharkState* entry_state() {
return _entry_state;
}
public:
void emit_IR() {
parse_bytecode(0, target()->code_size());
}
private:
void do_return(BasicType type) {
if (type != T_VOID) {
SharkValue *result = pop_result(type);
outer_state()->push(result);
if (result->is_two_word())
outer_state()->push(NULL);
}
}
};
class SharkInlinerHelper : public StackObj {
public:
SharkInlinerHelper(ciMethod* target, SharkState* entry_state)
: _target(target),
_entry_state(entry_state),
_iter(target) {}
private:
ciBytecodeStream _iter;
SharkState* _entry_state;
ciMethod* _target;
public:
ciBytecodeStream* iter() {
return &_iter;
}
SharkState* entry_state() const {
return _entry_state;
}
ciMethod* target() const {
return _target;
}
public:
Bytecodes::Code bc() {
return iter()->cur_bc();
}
int max_locals() const {
return target()->max_locals();
}
int max_stack() const {
return target()->max_stack();
}
// Inlinability check
public:
bool is_inlinable();
private:
void initialize_for_check();
bool do_getstatic() {
return do_field_access(true, false);
}
bool do_getfield() {
return do_field_access(true, true);
}
bool do_putfield() {
return do_field_access(false, true);
}
bool do_field_access(bool is_get, bool is_field);
// Local variables for inlinability check
private:
bool* _locals;
public:
bool* local_addr(int index) const {
assert(index >= 0 && index < max_locals(), "bad local variable index");
return &_locals[index];
}
bool local(int index) const {
return *local_addr(index);
}
void set_local(int index, bool value) {
*local_addr(index) = value;
}
// Expression stack for inlinability check
private:
bool* _stack;
bool* _sp;
public:
int stack_depth() const {
return _sp - _stack;
}
bool* stack_addr(int slot) const {
assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
return &_sp[-(slot + 1)];
}
void push(bool value) {
assert(stack_depth() < max_stack(), "stack overrun");
*(_sp++) = value;
}
bool pop() {
assert(stack_depth() > 0, "stack underrun");
return *(--_sp);
}
// Methods for two-word locals
public:
void push_pair_local(int index) {
push(local(index));
push(local(index + 1));
}
void pop_pair_local(int index) {
set_local(index + 1, pop());
set_local(index, pop());
}
// Code generation
public:
void do_inline() {
(new SharkInlineBlock(target(), entry_state()))->emit_IR();
}
};
// Quick checks so we can bail out before doing too much
bool SharkInliner::may_be_inlinable(ciMethod *target) {
// We can't inline native methods
if (target->is_native())
return false;
// Not much point inlining abstract ones, and in any
// case we'd need a stack frame to throw the exception
if (target->is_abstract())
return false;
// Don't inline anything huge
if (target->code_size() > SharkMaxInlineSize)
return false;
// Monitors aren't allowed without a frame to put them in
if (target->is_synchronized() || target->has_monitor_bytecodes())
return false;
// We don't do control flow
if (target->has_exception_handlers() || target->has_jsrs())
return false;
// Don't try to inline constructors, as they must
// eventually call Object.<init> which we can't inline.
// Note that this catches <clinit> too, but why would
// we be compiling that?
if (target->is_initializer())
return false;
// Mustn't inline Object.<init>
// Should be caught by the above, but just in case...
if (target->intrinsic_id() == vmIntrinsics::_Object_init)
return false;
return true;
}
// Full-on detailed check, for methods that pass the quick checks
// Inlined methods have no stack frame, so we can't do anything
// that would require one. This means no safepoints (and hence
// no loops) and no VM calls. No VM calls means, amongst other
// things, that no exceptions can be created, which means no null
// checks or divide-by-zero checks are allowed. The lack of null
// checks in particular would eliminate practically everything,
// but we can get around that restriction by relying on the zero-
// check eliminator to strip the checks. To do that, we need to
// walk through the method, tracking which values are and are not
// zero-checked.
bool SharkInlinerHelper::is_inlinable() {
ResourceMark rm;
initialize_for_check();
SharkConstant *sc;
bool a, b, c, d;
iter()->reset_to_bci(0);
while (iter()->next() != ciBytecodeStream::EOBC()) {
switch (bc()) {
case Bytecodes::_nop:
break;
case Bytecodes::_aconst_null:
push(false);
break;
case Bytecodes::_iconst_0:
push(false);
break;
case Bytecodes::_iconst_m1:
case Bytecodes::_iconst_1:
case Bytecodes::_iconst_2:
case Bytecodes::_iconst_3:
case Bytecodes::_iconst_4:
case Bytecodes::_iconst_5:
push(true);
break;
case Bytecodes::_lconst_0:
push(false);
push(false);
break;
case Bytecodes::_lconst_1:
push(true);
push(false);
break;
case Bytecodes::_fconst_0:
case Bytecodes::_fconst_1:
case Bytecodes::_fconst_2:
push(false);
break;
case Bytecodes::_dconst_0:
case Bytecodes::_dconst_1:
push(false);
push(false);
break;
case Bytecodes::_bipush:
push(iter()->get_constant_u1() != 0);
break;
case Bytecodes::_sipush:
push(iter()->get_constant_u2() != 0);
break;
case Bytecodes::_ldc:
case Bytecodes::_ldc_w:
case Bytecodes::_ldc2_w:
sc = SharkConstant::for_ldc(iter());
if (!sc->is_loaded())
return false;
push(sc->is_nonzero());
if (sc->is_two_word())
push(false);
break;
case Bytecodes::_iload_0:
case Bytecodes::_fload_0:
case Bytecodes::_aload_0:
push(local(0));
break;
case Bytecodes::_lload_0:
case Bytecodes::_dload_0:
push_pair_local(0);
break;
case Bytecodes::_iload_1:
case Bytecodes::_fload_1:
case Bytecodes::_aload_1:
push(local(1));
break;
case Bytecodes::_lload_1:
case Bytecodes::_dload_1:
push_pair_local(1);
break;
case Bytecodes::_iload_2:
case Bytecodes::_fload_2:
case Bytecodes::_aload_2:
push(local(2));
break;
case Bytecodes::_lload_2:
case Bytecodes::_dload_2:
push_pair_local(2);
break;
case Bytecodes::_iload_3:
case Bytecodes::_fload_3:
case Bytecodes::_aload_3:
push(local(3));
break;
case Bytecodes::_lload_3:
case Bytecodes::_dload_3:
push_pair_local(3);
break;
case Bytecodes::_iload:
case Bytecodes::_fload:
case Bytecodes::_aload:
push(local(iter()->get_index()));
break;
case Bytecodes::_lload:
case Bytecodes::_dload:
push_pair_local(iter()->get_index());
break;
case Bytecodes::_istore_0:
case Bytecodes::_fstore_0:
case Bytecodes::_astore_0:
set_local(0, pop());
break;
case Bytecodes::_lstore_0:
case Bytecodes::_dstore_0:
pop_pair_local(0);
break;
case Bytecodes::_istore_1:
case Bytecodes::_fstore_1:
case Bytecodes::_astore_1:
set_local(1, pop());
break;
case Bytecodes::_lstore_1:
case Bytecodes::_dstore_1:
pop_pair_local(1);
break;
case Bytecodes::_istore_2:
case Bytecodes::_fstore_2:
case Bytecodes::_astore_2:
set_local(2, pop());
break;
case Bytecodes::_lstore_2:
case Bytecodes::_dstore_2:
pop_pair_local(2);
break;
case Bytecodes::_istore_3:
case Bytecodes::_fstore_3:
case Bytecodes::_astore_3:
set_local(3, pop());
break;
case Bytecodes::_lstore_3:
case Bytecodes::_dstore_3:
pop_pair_local(3);
break;
case Bytecodes::_istore:
case Bytecodes::_fstore:
case Bytecodes::_astore:
set_local(iter()->get_index(), pop());
break;
case Bytecodes::_lstore:
case Bytecodes::_dstore:
pop_pair_local(iter()->get_index());
break;
case Bytecodes::_pop:
pop();
break;
case Bytecodes::_pop2:
pop();
pop();
break;
case Bytecodes::_swap:
a = pop();
b = pop();
push(a);
push(b);
break;
case Bytecodes::_dup:
a = pop();
push(a);
push(a);
break;
case Bytecodes::_dup_x1:
a = pop();
b = pop();
push(a);
push(b);
push(a);
break;
case Bytecodes::_dup_x2:
a = pop();
b = pop();
c = pop();
push(a);
push(c);
push(b);
push(a);
break;
case Bytecodes::_dup2:
a = pop();
b = pop();
push(b);
push(a);
push(b);
push(a);
break;
case Bytecodes::_dup2_x1:
a = pop();
b = pop();
c = pop();
push(b);
push(a);
push(c);
push(b);
push(a);
break;
case Bytecodes::_dup2_x2:
a = pop();
b = pop();
c = pop();
d = pop();
push(b);
push(a);
push(d);
push(c);
push(b);
push(a);
break;
case Bytecodes::_getfield:
if (!do_getfield())
return false;
break;
case Bytecodes::_getstatic:
if (!do_getstatic())
return false;
break;
case Bytecodes::_putfield:
if (!do_putfield())
return false;
break;
case Bytecodes::_iadd:
case Bytecodes::_isub:
case Bytecodes::_imul:
case Bytecodes::_iand:
case Bytecodes::_ixor:
case Bytecodes::_ishl:
case Bytecodes::_ishr:
case Bytecodes::_iushr:
pop();
pop();
push(false);
break;
case Bytecodes::_ior:
a = pop();
b = pop();
push(a && b);
break;
case Bytecodes::_idiv:
case Bytecodes::_irem:
if (!pop())
return false;
pop();
push(false);
break;
case Bytecodes::_ineg:
break;
case Bytecodes::_ladd:
case Bytecodes::_lsub:
case Bytecodes::_lmul:
case Bytecodes::_land:
case Bytecodes::_lxor:
pop();
pop();
pop();
pop();
push(false);
push(false);
break;
case Bytecodes::_lor:
a = pop();
b = pop();
push(a && b);
break;
case Bytecodes::_ldiv:
case Bytecodes::_lrem:
pop();
if (!pop())
return false;
pop();
pop();
push(false);
push(false);
break;
case Bytecodes::_lneg:
break;
case Bytecodes::_lshl:
case Bytecodes::_lshr:
case Bytecodes::_lushr:
pop();
pop();
pop();
push(false);
push(false);
break;
case Bytecodes::_fadd:
case Bytecodes::_fsub:
case Bytecodes::_fmul:
case Bytecodes::_fdiv:
case Bytecodes::_frem:
pop();
pop();
push(false);
break;
case Bytecodes::_fneg:
break;
case Bytecodes::_dadd:
case Bytecodes::_dsub:
case Bytecodes::_dmul:
case Bytecodes::_ddiv:
case Bytecodes::_drem:
pop();
pop();
pop();
pop();
push(false);
push(false);
break;
case Bytecodes::_dneg:
break;
case Bytecodes::_iinc:
set_local(iter()->get_index(), false);
break;
case Bytecodes::_lcmp:
pop();
pop();
pop();
pop();
push(false);
break;
case Bytecodes::_fcmpl:
case Bytecodes::_fcmpg:
pop();
pop();
push(false);
break;
case Bytecodes::_dcmpl:
case Bytecodes::_dcmpg:
pop();
pop();
pop();
pop();
push(false);
break;
case Bytecodes::_i2l:
push(false);
break;
case Bytecodes::_i2f:
pop();
push(false);
break;
case Bytecodes::_i2d:
pop();
push(false);
push(false);
break;
case Bytecodes::_l2i:
case Bytecodes::_l2f:
pop();
pop();
push(false);
break;
case Bytecodes::_l2d:
pop();
pop();
push(false);
push(false);
break;
case Bytecodes::_f2i:
pop();
push(false);
break;
case Bytecodes::_f2l:
case Bytecodes::_f2d:
pop();
push(false);
push(false);
break;
case Bytecodes::_d2i:
case Bytecodes::_d2f:
pop();
pop();
push(false);
break;
case Bytecodes::_d2l:
pop();
pop();
push(false);
push(false);
break;
case Bytecodes::_i2b:
case Bytecodes::_i2c:
case Bytecodes::_i2s:
pop();
push(false);
break;
case Bytecodes::_return:
case Bytecodes::_ireturn:
case Bytecodes::_lreturn:
case Bytecodes::_freturn:
case Bytecodes::_dreturn:
case Bytecodes::_areturn:
break;
default:
return false;
}
}
return true;
}
void SharkInlinerHelper::initialize_for_check() {
_locals = NEW_RESOURCE_ARRAY(bool, max_locals());
_stack = NEW_RESOURCE_ARRAY(bool, max_stack());
memset(_locals, 0, max_locals() * sizeof(bool));
for (int i = 0; i < target()->arg_size(); i++) {
SharkValue *arg = entry_state()->stack(target()->arg_size() - 1 - i);
if (arg && arg->zero_checked())
set_local(i, true);
}
_sp = _stack;
}
bool SharkInlinerHelper::do_field_access(bool is_get, bool is_field) {
assert(is_get || is_field, "can't inline putstatic");
// If the holder isn't linked then there isn't a lot we can do
if (!target()->holder()->is_linked())
return false;
// Get the field
bool will_link;
ciField *field = iter()->get_field(will_link);
if (!will_link)
return false;
// If the field is mismatched then an exception needs throwing
if (is_field == field->is_static())
return false;
// Pop the value off the stack if necessary
if (!is_get) {
pop();
if (field->type()->is_two_word())
pop();
}
// Pop and null-check the receiver if necessary
if (is_field) {
if (!pop())
return false;
}
// Push the result if necessary
if (is_get) {
bool result_pushed = false;
if (field->is_constant() && field->is_static()) {
SharkConstant *sc = SharkConstant::for_field(iter());
if (sc->is_loaded()) {
push(sc->is_nonzero());
result_pushed = true;
}
}
if (!result_pushed)
push(false);
if (field->type()->is_two_word())
push(false);
}
return true;
}
bool SharkInliner::attempt_inline(ciMethod *target, SharkState *state) {
if (!Inline) {
return false;
}
if (SharkIntrinsics::is_intrinsic(target)) {
SharkIntrinsics::inline_intrinsic(target, state);
return true;
}
if (may_be_inlinable(target)) {
SharkInlinerHelper inliner(target, state);
if (inliner.is_inlinable()) {
inliner.do_inline();
return true;
}
}
return false;
}

@ -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

@ -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));
}

@ -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

@ -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;
}

@ -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

@ -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

@ -1,100 +0,0 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_SHARK_SHARKMEMORYMANAGER_HPP
#define SHARE_VM_SHARK_SHARKMEMORYMANAGER_HPP
#include "shark/llvmHeaders.hpp"
#include "shark/sharkEntry.hpp"
// SharkMemoryManager wraps the LLVM JIT Memory Manager. We could use
// this to run our own memory allocation policies, but for now all we
// use it for is figuring out where the resulting native code ended up.
class SharkMemoryManager : public llvm::JITMemoryManager {
public:
SharkMemoryManager()
: _mm(llvm::JITMemoryManager::CreateDefaultMemManager()) {}
private:
llvm::JITMemoryManager* _mm;
private:
llvm::JITMemoryManager* mm() const {
return _mm;
}
private:
std::map<const llvm::Function*, SharkEntry*> _entry_map;
public:
void set_entry_for_function(const llvm::Function* function,
SharkEntry* entry) {
_entry_map[function] = entry;
}
SharkEntry* get_entry_for_function(const llvm::Function* function) {
return _entry_map[function];
}
public:
void AllocateGOT();
unsigned char* getGOTBase() const;
unsigned char* allocateStub(const llvm::GlobalValue* F,
unsigned StubSize,
unsigned Alignment);
unsigned char* startFunctionBody(const llvm::Function* F,
uintptr_t& ActualSize);
void endFunctionBody(const llvm::Function* F,
unsigned char* FunctionStart,
unsigned char* FunctionEnd);
void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true);
void setPoisonMemory(bool);
uint8_t* allocateGlobal(uintptr_t, unsigned int);
void setMemoryWritable();
void setMemoryExecutable();
void deallocateFunctionBody(void *ptr);
unsigned char *allocateSpace(intptr_t Size,
unsigned int Alignment);
#if SHARK_LLVM_VERSION <= 32
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID);
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID);
unsigned char* startExceptionTable(const llvm::Function* F,
uintptr_t& ActualSize);
void deallocateExceptionTable(void *ptr);
void endExceptionTable(const llvm::Function* F,
unsigned char* TableStart,
unsigned char* TableEnd,
unsigned char* FrameRegister);
#else
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName);
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, llvm::StringRef SectionName, bool IsReadOnly);
bool finalizeMemory(std::string *ErrMsg = 0);
#endif
};
#endif // SHARE_VM_SHARK_SHARKMEMORYMANAGER_HPP

@ -1,354 +0,0 @@
/*
* Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "shark/llvmHeaders.hpp"
#include "shark/sharkNativeWrapper.hpp"
#include "shark/sharkType.hpp"
using namespace llvm;
void SharkNativeWrapper::initialize(const char *name) {
// Create the function
_function = Function::Create(
SharkType::entry_point_type(),
GlobalVariable::InternalLinkage,
name);
// Get our arguments
Function::arg_iterator ai = function()->arg_begin();
Argument *method = ai++;
method->setName("method");
Argument *base_pc = ai++;
base_pc->setName("base_pc");
code_buffer()->set_base_pc(base_pc);
Argument *thread = ai++;
thread->setName("thread");
set_thread(thread);
// Create and push our stack frame
builder()->SetInsertPoint(CreateBlock());
_stack = SharkStack::CreateBuildAndPushFrame(this, method);
NOT_PRODUCT(method = NULL);
// Create the oopmap. We use the one oopmap for every call site in
// the wrapper, which results in the odd mild inefficiency but is a
// damn sight easier to code.
OopMap *oopmap = new OopMap(
SharkStack::oopmap_slot_munge(stack()->oopmap_frame_size()),
SharkStack::oopmap_slot_munge(arg_size()));
// Set up the oop_tmp slot if required:
// - For static methods we use it to handlize the class argument
// for the call, and to protect the same during slow path locks
// (if synchronized).
// - For methods returning oops, we use it to protect the return
// value across safepoints or slow path unlocking.
if (is_static() || is_returning_oop()) {
_oop_tmp_slot = stack()->slot_addr(
stack()->oop_tmp_slot_offset(),
SharkType::oop_type(),
"oop_tmp_slot");
oopmap->set_oop(SharkStack::slot2reg(stack()->oop_tmp_slot_offset()));
}
// Set up the monitor slot, for synchronized methods
if (is_synchronized()) {
Unimplemented();
_lock_slot_offset = 23;
}
// Start building the argument list
std::vector<Type*> param_types;
std::vector<Value*> param_values;
PointerType *box_type = PointerType::getUnqual(SharkType::oop_type());
// First argument is the JNIEnv
param_types.push_back(SharkType::jniEnv_type());
param_values.push_back(
builder()->CreateAddressOfStructEntry(
thread,
JavaThread::jni_environment_offset(),
SharkType::jniEnv_type(),
"jni_environment"));
// For static methods, the second argument is the class
if (is_static()) {
builder()->CreateStore(
builder()->CreateInlineOop(
JNIHandles::make_local(
target()->method_holder()->java_mirror())),
oop_tmp_slot());
param_types.push_back(box_type);
param_values.push_back(oop_tmp_slot());
_receiver_slot_offset = stack()->oop_tmp_slot_offset();
}
else if (is_returning_oop()) {
// The oop_tmp slot is registered in the oopmap,
// so we need to clear it. This is one of the
// mild inefficiencies I mentioned earlier.
builder()->CreateStore(LLVMValue::null(), oop_tmp_slot());
}
// Parse the arguments
for (int i = 0; i < arg_size(); i++) {
int slot_offset = stack()->locals_slots_offset() + arg_size() - 1 - i;
int adjusted_offset = slot_offset;
BasicBlock *null, *not_null, *merge;
Value *box;
PHINode *phi;
switch (arg_type(i)) {
case T_VOID:
break;
case T_OBJECT:
case T_ARRAY:
null = CreateBlock("null");
not_null = CreateBlock("not_null");
merge = CreateBlock("merge");
box = stack()->slot_addr(slot_offset, SharkType::oop_type());
builder()->CreateCondBr(
builder()->CreateICmp(
ICmpInst::ICMP_EQ,
builder()->CreateLoad(box),
LLVMValue::null()),
null, not_null);
builder()->SetInsertPoint(null);
builder()->CreateBr(merge);
builder()->SetInsertPoint(not_null);
builder()->CreateBr(merge);
builder()->SetInsertPoint(merge);
phi = builder()->CreatePHI(box_type, 0, "boxed_object");
phi->addIncoming(ConstantPointerNull::get(box_type), null);
phi->addIncoming(box, not_null);
box = phi;
param_types.push_back(box_type);
param_values.push_back(box);
oopmap->set_oop(SharkStack::slot2reg(slot_offset));
if (i == 0 && !is_static())
_receiver_slot_offset = slot_offset;
break;
case T_LONG:
case T_DOUBLE:
adjusted_offset--;
// fall through
default:
Type *param_type = SharkType::to_stackType(arg_type(i));
param_types.push_back(param_type);
param_values.push_back(
builder()->CreateLoad(stack()->slot_addr(adjusted_offset, param_type)));
}
}
// The oopmap is now complete, and everything is written
// into the frame except the PC.
int pc_offset = code_buffer()->create_unique_offset();
_oop_maps = new OopMapSet();
oop_maps()->add_gc_map(pc_offset, oopmap);
builder()->CreateStore(
builder()->code_buffer_address(pc_offset),
stack()->slot_addr(stack()->pc_slot_offset()));
// Set up the Java frame anchor
stack()->CreateSetLastJavaFrame();
// Lock if necessary
if (is_synchronized())
Unimplemented();
// Change the thread state to _thread_in_native
CreateSetThreadState(_thread_in_native);
// Make the call
BasicType result_type = target()->result_type();
Type* return_type;
if (result_type == T_VOID)
return_type = SharkType::void_type();
else if (is_returning_oop())
return_type = box_type;
else
return_type = SharkType::to_arrayType(result_type);
Value* native_function = builder()->CreateIntToPtr(
LLVMValue::intptr_constant((intptr_t) target()->native_function()),
PointerType::getUnqual(
FunctionType::get(return_type, param_types, false)));
Value *result = builder()->CreateCall(
native_function, llvm::makeArrayRef(param_values));
// Start the transition back to _thread_in_Java
CreateSetThreadState(_thread_in_native_trans);
// Make sure new state is visible in the GC thread
if (os::is_MP()) {
if (UseMembar)
builder()->CreateFence(llvm::SequentiallyConsistent, llvm::CrossThread);
else
CreateWriteMemorySerializePage();
}
// Handle safepoint operations, pending suspend requests,
// and pending asynchronous exceptions.
BasicBlock *check_thread = CreateBlock("check_thread");
BasicBlock *do_safepoint = CreateBlock("do_safepoint");
BasicBlock *safepointed = CreateBlock("safepointed");
Value *global_state = builder()->CreateLoad(
builder()->CreateIntToPtr(
LLVMValue::intptr_constant(
(intptr_t) SafepointSynchronize::address_of_state()),
PointerType::getUnqual(SharkType::jint_type())),
"global_state");
builder()->CreateCondBr(
builder()->CreateICmpNE(
global_state,
LLVMValue::jint_constant(SafepointSynchronize::_not_synchronized)),
do_safepoint, check_thread);
builder()->SetInsertPoint(check_thread);
Value *thread_state = builder()->CreateValueOfStructEntry(
thread,
JavaThread::suspend_flags_offset(),
SharkType::jint_type(),
"thread_state");
builder()->CreateCondBr(
builder()->CreateICmpNE(
thread_state,
LLVMValue::jint_constant(0)),
do_safepoint, safepointed);
builder()->SetInsertPoint(do_safepoint);
builder()->CreateCall(
builder()->check_special_condition_for_native_trans(), thread);
builder()->CreateBr(safepointed);
// Finally we can change the thread state to _thread_in_Java
builder()->SetInsertPoint(safepointed);
CreateSetThreadState(_thread_in_Java);
// Clear the frame anchor
stack()->CreateResetLastJavaFrame();
// If there is a pending exception then we can just unwind and
// return. It seems totally wrong that unlocking is skipped here
// but apparently the template interpreter does this so we do too.
BasicBlock *exception = CreateBlock("exception");
BasicBlock *no_exception = CreateBlock("no_exception");
builder()->CreateCondBr(
builder()->CreateICmpEQ(
CreateLoadPendingException(),
LLVMValue::null()),
no_exception, exception);
builder()->SetInsertPoint(exception);
CreateResetHandleBlock();
stack()->CreatePopFrame(0);
builder()->CreateRet(LLVMValue::jint_constant(0));
builder()->SetInsertPoint(no_exception);
// If the result was an oop then unbox it before
// releasing the handle it might be protected by
if (is_returning_oop()) {
BasicBlock *null = builder()->GetInsertBlock();
BasicBlock *not_null = CreateBlock("not_null");
BasicBlock *merge = CreateBlock("merge");
builder()->CreateCondBr(
builder()->CreateICmpNE(result, ConstantPointerNull::get(box_type)),
not_null, merge);
builder()->SetInsertPoint(not_null);
#error Needs to be updated for tagged jweak; see JNIHandles.
Value *unboxed_result = builder()->CreateLoad(result);
builder()->CreateBr(merge);
builder()->SetInsertPoint(merge);
PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), 0, "result");
phi->addIncoming(LLVMValue::null(), null);
phi->addIncoming(unboxed_result, not_null);
result = phi;
}
// Reset handle block
CreateResetHandleBlock();
// Unlock if necessary.
if (is_synchronized())
Unimplemented();
// Unwind and return
Value *result_addr = stack()->CreatePopFrame(type2size[result_type]);
if (result_type != T_VOID) {
bool needs_cast = false;
bool is_signed = false;
switch (result_type) {
case T_BOOLEAN:
result = builder()->CreateICmpNE(result, LLVMValue::jbyte_constant(0));
needs_cast = true;
break;
case T_CHAR:
needs_cast = true;
break;
case T_BYTE:
case T_SHORT:
needs_cast = true;
is_signed = true;
break;
}
if (needs_cast) {
result = builder()->CreateIntCast(
result, SharkType::to_stackType(result_type), is_signed);
}
builder()->CreateStore(
result,
builder()->CreateIntToPtr(
result_addr,
PointerType::getUnqual(SharkType::to_stackType(result_type))));
}
builder()->CreateRet(LLVMValue::jint_constant(0));
}

@ -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

@ -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;
}

@ -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

@ -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

@ -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

@ -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");
}

@ -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

@ -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

@ -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

File diff suppressed because it is too large Load Diff

@ -1,447 +0,0 @@
/*
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP
#define SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP
#include "ci/ciStreams.hpp"
#include "ci/ciType.hpp"
#include "ci/ciTypeFlow.hpp"
#include "interpreter/bytecodes.hpp"
#include "memory/allocation.hpp"
#include "shark/llvmHeaders.hpp"
#include "shark/sharkBlock.hpp"
#include "shark/sharkBuilder.hpp"
#include "shark/sharkFunction.hpp"
#include "shark/sharkState.hpp"
#include "shark/sharkValue.hpp"
class SharkTopLevelBlock : public SharkBlock {
public:
SharkTopLevelBlock(SharkFunction* function, ciTypeFlow::Block* ciblock)
: SharkBlock(function),
_function(function),
_ciblock(ciblock),
_entered(false),
_has_trap(false),
_needs_phis(false),
_entry_state(NULL),
_entry_block(NULL) {}
private:
SharkFunction* _function;
ciTypeFlow::Block* _ciblock;
public:
SharkFunction* function() const {
return _function;
}
ciTypeFlow::Block* ciblock() const {
return _ciblock;
}
// Function properties
public:
SharkStack* stack() const {
return function()->stack();
}
// Typeflow properties
public:
int index() const {
return ciblock()->pre_order();
}
bool is_backedge_copy() const {
return ciblock()->is_backedge_copy();
}
int stack_depth_at_entry() const {
return ciblock()->stack_size();
}
ciType* local_type_at_entry(int index) const {
return ciblock()->local_type_at(index);
}
ciType* stack_type_at_entry(int slot) const {
return ciblock()->stack_type_at(slot);
}
int start() const {
return ciblock()->start();
}
int limit() const {
return ciblock()->limit();
}
bool falls_through() const {
return ciblock()->control() == ciBlock::fall_through_bci;
}
int num_successors() const {
return ciblock()->successors()->length();
}
SharkTopLevelBlock* successor(int index) const {
return function()->block(ciblock()->successors()->at(index)->pre_order());
}
SharkTopLevelBlock* bci_successor(int bci) const;
// Exceptions
private:
GrowableArray<ciExceptionHandler*>* _exc_handlers;
GrowableArray<SharkTopLevelBlock*>* _exceptions;
private:
void compute_exceptions();
private:
int num_exceptions() const {
return _exc_handlers->length();
}
ciExceptionHandler* exc_handler(int index) const {
return _exc_handlers->at(index);
}
SharkTopLevelBlock* exception(int index) const {
return _exceptions->at(index);
}
// Traps
private:
bool _has_trap;
int _trap_request;
int _trap_bci;
void set_trap(int trap_request, int trap_bci) {
assert(!has_trap(), "shouldn't have");
_has_trap = true;
_trap_request = trap_request;
_trap_bci = trap_bci;
}
private:
bool has_trap() {
return _has_trap;
}
int trap_request() {
assert(has_trap(), "should have");
return _trap_request;
}
int trap_bci() {
assert(has_trap(), "should have");
return _trap_bci;
}
private:
void scan_for_traps();
private:
bool static_field_ok_in_clinit(ciField* field);
// Entry state
private:
bool _entered;
bool _needs_phis;
public:
bool entered() const {
return _entered;
}
bool needs_phis() const {
return _needs_phis;
}
private:
void enter(SharkTopLevelBlock* predecessor, bool is_exception);
public:
void enter() {
enter(NULL, false);
}
private:
SharkState* _entry_state;
private:
SharkState* entry_state();
private:
llvm::BasicBlock* _entry_block;
public:
llvm::BasicBlock* entry_block() const {
return _entry_block;
}
public:
void initialize();
public:
void add_incoming(SharkState* incoming_state);
// Method
public:
llvm::Value* method() {
return current_state()->method();
}
// Temporary oop storage
public:
void set_oop_tmp(llvm::Value* value) {
assert(value, "value must be non-NULL (will be reset by get_oop_tmp)");
assert(!current_state()->oop_tmp(), "oop_tmp gets and sets must match");
current_state()->set_oop_tmp(value);
}
llvm::Value* get_oop_tmp() {
llvm::Value* value = current_state()->oop_tmp();
assert(value, "oop_tmp gets and sets must match");
current_state()->set_oop_tmp(NULL);
return value;
}
// Cache and decache
private:
void decache_for_Java_call(ciMethod* callee);
void cache_after_Java_call(ciMethod* callee);
void decache_for_VM_call();
void cache_after_VM_call();
void decache_for_trap();
// Monitors
private:
int num_monitors() {
return current_state()->num_monitors();
}
int set_num_monitors(int num_monitors) {
current_state()->set_num_monitors(num_monitors);
}
// Code generation
public:
void emit_IR();
// Branch helpers
private:
void do_branch(int successor_index);
// Zero checks
private:
void do_zero_check(SharkValue* value);
void zero_check_value(SharkValue* value, llvm::BasicBlock* continue_block);
public:
void do_deferred_zero_check(SharkValue* value,
int bci,
SharkState* saved_state,
llvm::BasicBlock* continue_block);
// Exceptions
private:
llvm::Value* pending_exception_address() const {
return builder()->CreateAddressOfStructEntry(
thread(), Thread::pending_exception_offset(),
llvm::PointerType::getUnqual(SharkType::oop_type()),
"pending_exception_addr");
}
llvm::LoadInst* get_pending_exception() const {
return builder()->CreateLoad(
pending_exception_address(), "pending_exception");
}
void clear_pending_exception() const {
builder()->CreateStore(LLVMValue::null(), pending_exception_address());
}
public:
enum ExceptionActionMask {
// The actual bitmasks that things test against
EAM_CHECK = 1, // whether to check for pending exceptions
EAM_HANDLE = 2, // whether to attempt to handle pending exceptions
EAM_MONITOR_FUDGE = 4, // whether the monitor count needs adjusting
// More convenient values for passing
EX_CHECK_NONE = 0,
EX_CHECK_NO_CATCH = EAM_CHECK,
EX_CHECK_FULL = EAM_CHECK | EAM_HANDLE
};
void check_pending_exception(int action);
void handle_exception(llvm::Value* exception, int action);
void marshal_exception_fast(int num_options);
void marshal_exception_slow(int num_options);
llvm::BasicBlock* handler_for_exception(int index);
// VM calls
private:
llvm::CallInst* call_vm(llvm::Value* callee,
llvm::Value** args_start,
llvm::Value** args_end,
int exception_action) {
decache_for_VM_call();
stack()->CreateSetLastJavaFrame();
llvm::CallInst *res = builder()->CreateCall(callee, llvm::makeArrayRef(args_start, args_end));
stack()->CreateResetLastJavaFrame();
cache_after_VM_call();
if (exception_action & EAM_CHECK) {
check_pending_exception(exception_action);
current_state()->set_has_safepointed(true);
}
return res;
}
public:
llvm::CallInst* call_vm(llvm::Value* callee,
int exception_action) {
llvm::Value *args[] = {thread()};
return call_vm(callee, args, args + 1, exception_action);
}
llvm::CallInst* call_vm(llvm::Value* callee,
llvm::Value* arg1,
int exception_action) {
llvm::Value *args[] = {thread(), arg1};
return call_vm(callee, args, args + 2, exception_action);
}
llvm::CallInst* call_vm(llvm::Value* callee,
llvm::Value* arg1,
llvm::Value* arg2,
int exception_action) {
llvm::Value *args[] = {thread(), arg1, arg2};
return call_vm(callee, args, args + 3, exception_action);
}
llvm::CallInst* call_vm(llvm::Value* callee,
llvm::Value* arg1,
llvm::Value* arg2,
llvm::Value* arg3,
int exception_action) {
llvm::Value *args[] = {thread(), arg1, arg2, arg3};
return call_vm(callee, args, args + 4, exception_action);
}
// VM call oop return handling
private:
llvm::LoadInst* get_vm_result() const {
llvm::Value *addr = builder()->CreateAddressOfStructEntry(
thread(), JavaThread::vm_result_offset(),
llvm::PointerType::getUnqual(SharkType::oop_type()),
"vm_result_addr");
llvm::LoadInst *result = builder()->CreateLoad(addr, "vm_result");
builder()->CreateStore(LLVMValue::null(), addr);
return result;
}
// Synchronization
private:
void acquire_lock(llvm::Value* lockee, int exception_action);
void release_lock(int exception_action);
public:
void acquire_method_lock();
// Bounds checks
private:
void check_bounds(SharkValue* array, SharkValue* index);
// Safepoints
private:
void maybe_add_safepoint();
void maybe_add_backedge_safepoint();
// Loop safepoint removal
private:
bool _can_reach_visited;
bool can_reach(SharkTopLevelBlock* other);
bool can_reach_helper(SharkTopLevelBlock* other);
// Traps
private:
llvm::BasicBlock* make_trap(int trap_bci, int trap_request);
void do_trap(int trap_request);
// Returns
private:
void call_register_finalizer(llvm::Value* receiver);
void handle_return(BasicType type, llvm::Value* exception);
// arraylength
private:
void do_arraylength();
// *aload and *astore
private:
void do_aload(BasicType basic_type);
void do_astore(BasicType basic_type);
// *return and athrow
private:
void do_return(BasicType type);
void do_athrow();
// goto*
private:
void do_goto();
// jsr* and ret
private:
void do_jsr();
void do_ret();
// if*
private:
void do_if_helper(llvm::ICmpInst::Predicate p,
llvm::Value* b,
llvm::Value* a,
SharkState* if_taken_state,
SharkState* not_taken_state);
void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a);
// tableswitch and lookupswitch
private:
void do_switch();
// invoke*
private:
ciMethod* improve_virtual_call(ciMethod* caller,
ciInstanceKlass* klass,
ciMethod* dest_method,
ciType* receiver_type);
llvm::Value* get_direct_callee(ciMethod* method);
llvm::Value* get_virtual_callee(SharkValue* receiver, int vtable_index);
llvm::Value* get_interface_callee(SharkValue* receiver, ciMethod* method);
void do_call();
// checkcast and instanceof
private:
bool static_subtype_check(ciKlass* check_klass, ciKlass* object_klass);
void do_full_instance_check(ciKlass* klass);
void do_trapping_instance_check(ciKlass* klass);
void do_instance_check();
bool maybe_do_instanceof_if();
// new and *newarray
private:
void do_new();
void do_newarray();
void do_anewarray();
void do_multianewarray();
// monitorenter and monitorexit
private:
void do_monitorenter();
void do_monitorexit();
};
#endif // SHARE_VM_SHARK_SHARKTOPLEVELBLOCK_HPP

@ -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

@ -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;
}

@ -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

@ -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)

@ -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

@ -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

@ -189,20 +189,10 @@ void VMError::print_stack_trace(outputStream* st, JavaThread* jt,
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();

@ -51,7 +51,7 @@ public abstract class CompilerWhiteBoxTest {
public static final int COMP_LEVEL_LIMITED_PROFILE = 2;
/** {@code CompLevel::CompLevel_full_profile} -- C1, invocation &amp; backedge counters + mdo */
public static final int COMP_LEVEL_FULL_PROFILE = 3;
/** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */
/** {@code CompLevel::CompLevel_full_optimization} -- C2 */
public static final int COMP_LEVEL_FULL_OPTIMIZATION = 4;
/** Maximal value for CompLevel */
public static final int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION;