提交 4f7a01e7 编写于 作者: T twisti

6976186: integrate Shark HotSpot changes

Summary: Shark is a JIT compiler for Zero that uses the LLVM compiler infrastructure.
Reviewed-by: kvn, twisti
Contributed-by: NGary Benson <gbenson@redhat.com>
上级 18c95895
......@@ -85,6 +85,7 @@ C1_VM_TARGETS=product1 fastdebug1 optimized1 jvmg1
C2_VM_TARGETS=product fastdebug optimized jvmg
KERNEL_VM_TARGETS=productkernel fastdebugkernel optimizedkernel jvmgkernel
ZERO_VM_TARGETS=productzero fastdebugzero optimizedzero jvmgzero
SHARK_VM_TARGETS=productshark fastdebugshark optimizedshark jvmgshark
# JDK directory list
JDK_DIRS=bin include jre lib demo
......@@ -107,6 +108,12 @@ all_fastdebugzero: fastdebugzero docs export_fastdebug
all_debugzero: jvmgzero docs export_debug
all_optimizedzero: optimizedzero docs export_optimized
allshark: all_productshark all_fastdebugshark
all_productshark: productshark docs export_product
all_fastdebugshark: fastdebugshark docs export_fastdebug
all_debugshark: jvmgshark docs export_debug
all_optimizedshark: optimizedshark docs export_optimized
# Do everything
world: all create_jdk
......@@ -137,6 +144,10 @@ $(ZERO_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
$(MAKE) VM_TARGET=$@ generic_buildzero $(ALT_OUT)
$(SHARK_VM_TARGETS):
$(CD) $(GAMMADIR)/make; \
$(MAKE) VM_TARGET=$@ generic_buildshark $(ALT_OUT)
# Build compiler1 (client) rule, different for platforms
generic_build1:
$(MKDIR) -p $(OUTPUTDIR)
......@@ -203,6 +214,12 @@ generic_buildzero:
$(MAKE) -f $(ABS_OS_MAKEFILE) \
$(MAKE_ARGS) $(VM_TARGET)
generic_buildshark:
$(MKDIR) -p $(OUTPUTDIR)
$(CD) $(OUTPUTDIR); \
$(MAKE) -f $(ABS_OS_MAKEFILE) \
$(MAKE_ARGS) $(VM_TARGET)
# Export file rule
generic_export: $(EXPORT_LIST)
export_product:
......@@ -234,15 +251,22 @@ C1_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler1
C2_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_compiler2
KERNEL_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_kernel
ZERO_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_zero
SHARK_BASE_DIR=$(OUTPUTDIR)/$(VM_PLATFORM)_shark
C1_DIR=$(C1_BASE_DIR)/$(VM_SUBDIR)
C2_DIR=$(C2_BASE_DIR)/$(VM_SUBDIR)
KERNEL_DIR=$(KERNEL_BASE_DIR)/$(VM_SUBDIR)
ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR)
SHARK_DIR=$(SHARK_BASE_DIR)/$(VM_SUBDIR)
# Misc files and generated files need to come from C1 or C2 area
ifeq ($(ZERO_BUILD), true)
ifeq ($(SHARK_BUILD), true)
MISC_DIR=$(SHARK_DIR)
GEN_DIR=$(SHARK_BASE_DIR)/generated
else
MISC_DIR=$(ZERO_DIR)
GEN_DIR=$(ZERO_BASE_DIR)/generated
endif
else
ifeq ($(ARCH_DATA_MODEL), 32)
MISC_DIR=$(C1_DIR)
......@@ -296,10 +320,17 @@ endif
# Shared Library
ifneq ($(OSNAME),windows)
ifeq ($(ZERO_BUILD), true)
ifeq ($(SHARK_BUILD), true)
$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(SHARK_DIR)/%.so
$(install-file)
$(EXPORT_SERVER_DIR)/%.so: $(SHARK_DIR)/%.so
$(install-file)
else
$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(ZERO_DIR)/%.so
$(install-file)
$(EXPORT_SERVER_DIR)/%.so: $(ZERO_DIR)/%.so
$(install-file)
endif
else
$(EXPORT_JRE_LIB_ARCH_DIR)/%.so: $(C1_DIR)/%.so
$(install-file)
......@@ -356,6 +387,7 @@ clean_build:
$(RM) -r $(C2_DIR)
$(RM) -r $(KERNEL_DIR)
$(RM) -r $(ZERO_DIR)
$(RM) -r $(SHARK_DIR)
clean_export:
$(RM) -r $(EXPORT_PATH)
clean_jdk:
......
#
# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -168,6 +168,13 @@ VARIANTARCH = $(subst i386,i486,$(ZERO_LIBARCH))
# profiledzero zero <os>_<arch>_zero/profiled
# productzero zero <os>_<arch>_zero/product
#
# debugshark shark <os>_<arch>_shark/debug
# fastdebugshark shark <os>_<arch>_shark/fastdebug
# jvmgshark shark <os>_<arch>_shark/jvmg
# optimizedshark shark <os>_<arch>_shark/optimized
# profiledshark shark <os>_<arch>_shark/profiled
# productshark shark <os>_<arch>_shark/product
#
# What you get with each target:
#
# debug* - "thin" libjvm_g - debug info linked into the gamma_g launcher
......@@ -191,12 +198,14 @@ SUBDIRS_C2 = $(addprefix $(OSNAME)_$(BUILDARCH)_compiler2/,$(TARGETS))
SUBDIRS_TIERED = $(addprefix $(OSNAME)_$(BUILDARCH)_tiered/,$(TARGETS))
SUBDIRS_CORE = $(addprefix $(OSNAME)_$(BUILDARCH)_core/,$(TARGETS))
SUBDIRS_ZERO = $(addprefix $(OSNAME)_$(VARIANTARCH)_zero/,$(TARGETS))
SUBDIRS_SHARK = $(addprefix $(OSNAME)_$(VARIANTARCH)_shark/,$(TARGETS))
TARGETS_C2 = $(TARGETS)
TARGETS_C1 = $(addsuffix 1,$(TARGETS))
TARGETS_TIERED = $(addsuffix tiered,$(TARGETS))
TARGETS_CORE = $(addsuffix core,$(TARGETS))
TARGETS_ZERO = $(addsuffix zero,$(TARGETS))
TARGETS_SHARK = $(addsuffix shark,$(TARGETS))
BUILDTREE_MAKE = $(GAMMADIR)/make/$(OSNAME)/makefiles/buildtree.make
BUILDTREE_VARS = GAMMADIR=$(GAMMADIR) OS_FAMILY=$(OSNAME) ARCH=$(SRCARCH) BUILDARCH=$(BUILDARCH) LIBARCH=$(LIBARCH)
......@@ -213,6 +222,7 @@ all:
@echo " $(TARGETS_C1)"
@echo " $(TARGETS_CORE)"
@echo " $(TARGETS_ZERO)"
@echo " $(TARGETS_SHARK)"
checks: check_os_version check_j2se_version
......@@ -266,6 +276,10 @@ $(SUBDIRS_ZERO): $(BUILDTREE_MAKE) platform_zero
$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
$(BUILDTREE) VARIANT=zero VARIANTARCH=$(VARIANTARCH)
$(SUBDIRS_SHARK): $(BUILDTREE_MAKE) platform_zero
$(QUIETLY) $(MAKE) -f $(GAMMADIR)/make/$(OSNAME)/Makefile checks
$(BUILDTREE) VARIANT=shark VARIANTARCH=$(VARIANTARCH)
platform_zero: $(GAMMADIR)/make/$(OSNAME)/platform_zero.in
$(SED) 's/@ZERO_ARCHDEF@/$(ZERO_ARCHDEF)/g;s/@ZERO_LIBARCH@/$(ZERO_LIBARCH)/g;' < $< > $@
......@@ -306,11 +320,19 @@ ifdef INSTALL
cd $(OSNAME)_$(VARIANTARCH)_zero/$(patsubst %zero,%,$@) && $(MAKE) $(MFLAGS) install
endif
$(TARGETS_SHARK): $(SUBDIRS_SHARK)
cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS)
cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && ./test_gamma
ifdef INSTALL
cd $(OSNAME)_$(VARIANTARCH)_shark/$(patsubst %shark,%,$@) && $(MAKE) $(MFLAGS) install
endif
# Just build the tree, and nothing else:
tree: $(SUBDIRS_C2)
tree1: $(SUBDIRS_C1)
treecore: $(SUBDIRS_CORE)
treezero: $(SUBDIRS_ZERO)
treeshark: $(SUBDIRS_SHARK)
# Doc target. This is the same for all build options.
# Hence create a docs directory beside ...$(ARCH)_[...]
......@@ -327,20 +349,22 @@ core: jvmgcore productcore
zero: jvmgzero productzero
shark: jvmgshark productshark
clean_docs:
rm -rf $(SUBDIR_DOCS)
clean_compiler1 clean_compiler2 clean_core clean_zero:
clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark:
rm -rf $(OSNAME)_$(BUILDARCH)_$(subst clean_,,$@)
clean: clean_compiler2 clean_compiler1 clean_core clean_zero clean_docs
clean: clean_compiler2 clean_compiler1 clean_core clean_zero clean_shark clean_docs
include $(GAMMADIR)/make/$(OSNAME)/makefiles/cscope.make
#-------------------------------------------------------------------------------
.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO)
.PHONY: tree tree1 treecore treezero
.PHONY: all compiler1 compiler2 core zero
.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero docs clean_docs
.PHONY: $(TARGETS_C2) $(TARGETS_C1) $(TARGETS_CORE) $(TARGETS_ZERO) $(TARGETS_SHARK)
.PHONY: tree tree1 treecore treezero treeshark
.PHONY: all compiler1 compiler2 core zero shark
.PHONY: clean clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark docs clean_docs
.PHONY: checks check_os_version check_j2se_version
#
# Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -61,6 +61,9 @@ VM_PICFLAG = $(VM_PICFLAG/$(LINK_INTO))
ifeq ($(ZERO_BUILD), true)
CFLAGS += $(LIBFFI_CFLAGS)
endif
ifeq ($(SHARK_BUILD), true)
CFLAGS += $(LLVM_CFLAGS)
endif
CFLAGS += $(VM_PICFLAG)
CFLAGS += -fno-rtti
CFLAGS += -fno-exceptions
......
#
# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
# Copyright 2008, 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.
#
#
# Sets make macros for making Shark version of VM
TYPE = SHARK
VM_SUBDIR = server
CFLAGS += -DSHARK
#
# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -75,6 +75,7 @@ Include_DBs/COMPILER1 = $(Include_DBs/CORE) $(VM)/includeDB_compiler1
Include_DBs/COMPILER2 = $(Include_DBs/CORE) $(VM)/includeDB_compiler2
Include_DBs/TIERED = $(Include_DBs/CORE) $(VM)/includeDB_compiler1 $(VM)/includeDB_compiler2
Include_DBs/ZERO = $(Include_DBs/CORE) $(VM)/includeDB_zero
Include_DBs/SHARK = $(Include_DBs/ZERO) $(VM)/includeDB_shark
Include_DBs = $(Include_DBs/$(TYPE))
Cached_plat = $(GENERATED)/platform.current
......
#
# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
......@@ -137,10 +137,14 @@ mapfile_reorder : mapfile $(REORDERFILE)
vm.def: $(Res_Files) $(Obj_Files)
sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
ifeq ($(ZERO_LIBARCH), ppc64)
ifeq ($(SHARK_BUILD), true)
STATIC_CXX = false
else
STATIC_CXX = true
ifeq ($(ZERO_LIBARCH), ppc64)
STATIC_CXX = false
else
STATIC_CXX = true
endif
endif
ifeq ($(LINK_INTO),AOUT)
......@@ -168,6 +172,10 @@ endif
ifeq ($(ZERO_BUILD), true)
LIBS_VM += $(LIBFFI_LIBS)
endif
ifeq ($(SHARK_BUILD), true)
LFLAGS_VM += $(LLVM_LDFLAGS)
LIBS_VM += $(LLVM_LIBS)
endif
LINK_VM = $(LINK_LIB.c)
......
/*
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
* Copyright 2007 Red Hat, Inc.
* Copyright 2007, 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
......@@ -23,13 +23,10 @@
*
*/
// The disassembler prints out zero code annotated
// with Java specific information.
static int pd_instruction_alignment() {
ShouldNotCallThis();
return 1;
}
static const char* pd_cpu_opts() {
ShouldNotCallThis();
return "";
}
/*
* Copyright (c) 2000, 2007, 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.
*
*/
// 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, BackEdgeThreshold, 100000);
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(intx, InlineSmallCode, 1000 );
define_pd_global(intx, NewRatio, 12 );
define_pd_global(intx, NewSizeThreadIncrease, 4*K );
define_pd_global(intx, InitialCodeCacheSize, 160*K);
define_pd_global(intx, ReservedCodeCacheSize, 32*M );
define_pd_global(bool, ProfileInterpreter, false);
define_pd_global(intx, CodeCacheExpansionSize, 32*K );
define_pd_global(uintx, CodeCacheMinBlockLength, 1 );
define_pd_global(uintx, PermSize, 12*M );
define_pd_global(uintx, MaxPermSize, 64*M );
define_pd_global(bool, NeverActAsServerClassMachine, true );
define_pd_global(uint64_t, MaxRAM, 1ULL*G);
define_pd_global(bool, CICompileOSR, true );
......@@ -55,10 +55,10 @@ ciMethod::ciMethod(methodHandle h_m) : ciObject(h_m) {
_exception_handlers = NULL;
_liveness = NULL;
_method_blocks = NULL;
#ifdef COMPILER2
#if defined(COMPILER2) || defined(SHARK)
_flow = NULL;
_bcea = NULL;
#endif // COMPILER2
#endif // COMPILER2 || SHARK
ciEnv *env = CURRENT_ENV;
if (env->jvmti_can_hotswap_or_post_breakpoint() && _is_compilable) {
......@@ -123,10 +123,10 @@ ciMethod::ciMethod(ciInstanceKlass* holder,
_can_be_statically_bound = false;
_method_blocks = NULL;
_method_data = NULL;
#ifdef COMPILER2
#if defined(COMPILER2) || defined(SHARK)
_flow = NULL;
_bcea = NULL;
#endif // COMPILER2
#endif // COMPILER2 || SHARK
}
......@@ -229,6 +229,20 @@ 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;
return klassItable::compute_itable_index(get_methodOop());
}
#endif // SHARK
// ------------------------------------------------------------------
// ciMethod::native_entry
//
......@@ -294,34 +308,34 @@ bool ciMethod::has_balanced_monitors() {
// ------------------------------------------------------------------
// ciMethod::get_flow_analysis
ciTypeFlow* ciMethod::get_flow_analysis() {
#ifdef COMPILER2
#if defined(COMPILER2) || defined(SHARK)
if (_flow == NULL) {
ciEnv* env = CURRENT_ENV;
_flow = new (env->arena()) ciTypeFlow(env, this);
_flow->do_flow();
}
return _flow;
#else // COMPILER2
#else // COMPILER2 || SHARK
ShouldNotReachHere();
return NULL;
#endif // COMPILER2
#endif // COMPILER2 || SHARK
}
// ------------------------------------------------------------------
// ciMethod::get_osr_flow_analysis
ciTypeFlow* ciMethod::get_osr_flow_analysis(int osr_bci) {
#ifdef COMPILER2
#if defined(COMPILER2) || defined(SHARK)
// 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
#else // COMPILER2 || SHARK
ShouldNotReachHere();
return NULL;
#endif // COMPILER2
#endif // COMPILER2 || SHARK
}
// ------------------------------------------------------------------
......
......@@ -70,7 +70,7 @@ class ciMethod : public ciObject {
// Optional liveness analyzer.
MethodLiveness* _liveness;
#ifdef COMPILER2
#if defined(COMPILER2) || defined(SHARK)
ciTypeFlow* _flow;
BCEscapeAnalyzer* _bcea;
#endif
......@@ -141,6 +141,9 @@ class ciMethod : public ciObject {
// Runtime information.
int vtable_index();
#ifdef SHARK
int itable_index();
#endif // SHARK
address native_entry();
address interpreter_entry();
......
......@@ -65,6 +65,11 @@ bool nmethod::is_compiled_by_c2() const {
if (is_native_method()) return false;
return compiler()->is_c2();
}
bool nmethod::is_compiled_by_shark() const {
if (is_native_method()) return false;
assert(compiler() != NULL, "must be");
return compiler()->is_shark();
}
......@@ -1353,6 +1358,10 @@ void nmethod::flush() {
CodeCache::remove_saved_code(this);
}
#ifdef SHARK
((SharkCompiler *) compiler())->free_compiled_method(instructions_begin());
#endif // SHARK
((CodeBlob*)(this))->flush();
CodeCache::free(this);
......@@ -1769,6 +1778,7 @@ bool nmethod::detect_scavenge_root_oops() {
// Method that knows how to preserve outgoing arguments at call. This method must be
// called with a frame corresponding to a Java invoke
void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) {
#ifndef SHARK
if (!method()->is_native()) {
SimpleScopeDesc ssd(this, fr.pc());
Bytecode_invoke* call = Bytecode_invoke_at(ssd.method(), ssd.bci());
......@@ -1776,6 +1786,7 @@ void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map
symbolOop signature = call->signature();
fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
}
#endif // !SHARK
}
......@@ -2279,6 +2290,8 @@ 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 {
tty->print("(nm) ");
}
......
......@@ -329,6 +329,7 @@ class nmethod : public CodeBlob {
bool is_compiled_by_c1() const;
bool is_compiled_by_c2() const;
bool is_compiled_by_shark() const;
// boundaries for different parts
address code_begin () const { return _entry_point; }
......
/*
* Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -45,18 +45,26 @@ class AbstractCompiler : public CHeapObj {
// Missing feature tests
virtual bool supports_native() { return true; }
virtual bool supports_osr () { return true; }
#if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2))
#if defined(TIERED) || ( !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK))
virtual bool is_c1 () { return false; }
virtual bool is_c2 () { return false; }
virtual bool is_shark() { return false; }
#else
#ifdef COMPILER1
bool is_c1 () { return true; }
bool is_c2 () { return false; }
bool is_shark() { return false; }
#endif // COMPILER1
#ifdef COMPILER2
bool is_c1 () { return false; }
bool is_c2 () { return true; }
bool is_shark() { return false; }
#endif // COMPILER2
#ifdef SHARK
bool is_c1 () { return false; }
bool is_c2 () { return false; }
bool is_shark() { return true; }
#endif // SHARK
#endif // TIERED
// Customization
......
......@@ -568,6 +568,14 @@ void CompileBroker::compilation_init() {
#endif
#endif // COMPILER2
#ifdef SHARK
#if defined(COMPILER1) || defined(COMPILER2)
#error "Can't use COMPILER1 or COMPILER2 with shark"
#endif
_compilers[0] = new SharkCompiler();
_compilers[1] = _compilers[0];
#endif
// Initialize the CompileTask free list
_task_free_list = NULL;
......
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -423,8 +423,14 @@ void Disassembler::decode(nmethod* nm, outputStream* st) {
env.output()->print_cr("Decoding compiled method " INTPTR_FORMAT ":", nm);
env.output()->print_cr("Code:");
#ifdef SHARK
SharkEntry* entry = (SharkEntry *) nm->instructions_begin();
unsigned char* p = entry->code_start();
unsigned char* end = entry->code_limit();
#else
unsigned char* p = nm->instructions_begin();
unsigned char* end = nm->instructions_end();
#endif // SHARK
// If there has been profiling, print the buckets.
if (FlatProfiler::bucket_start_for(p) != NULL) {
......
//
// Copyright (c) 1999, 2007, 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.
//
//
// NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps!
ciMethod.cpp ciTypeFlow.hpp
ciMethod.cpp methodOop.hpp
ciTypeFlow.cpp allocation.inline.hpp
ciTypeFlow.cpp bytecode.hpp
ciTypeFlow.cpp bytecodes.hpp
ciTypeFlow.cpp ciConstant.hpp
ciTypeFlow.cpp ciField.hpp
ciTypeFlow.cpp ciMethod.hpp
ciTypeFlow.cpp ciMethodData.hpp
ciTypeFlow.cpp ciObjArrayKlass.hpp
ciTypeFlow.cpp ciStreams.hpp
ciTypeFlow.cpp ciTypeArrayKlass.hpp
ciTypeFlow.cpp ciTypeFlow.hpp
ciTypeFlow.cpp compileLog.hpp
ciTypeFlow.cpp deoptimization.hpp
ciTypeFlow.cpp growableArray.hpp
ciTypeFlow.cpp shark_globals.hpp
ciTypeFlow.hpp ciEnv.hpp
ciTypeFlow.hpp ciKlass.hpp
ciTypeFlow.hpp ciMethodBlocks.hpp
cppInterpreter_<arch>.cpp shark_globals.hpp
compileBroker.cpp sharkCompiler.hpp
disassembler.cpp sharkEntry.hpp
globals.hpp shark_globals_<arch>.hpp
globals.cpp shark_globals.hpp
llvmValue.hpp llvmHeaders.hpp
llvmValue.hpp sharkContext.hpp
llvmValue.hpp sharkType.hpp
nmethod.cpp sharkCompiler.hpp
sharedRuntime_<arch>.cpp compileBroker.hpp
sharedRuntime_<arch>.cpp sharkCompiler.hpp
shark_globals.cpp shark_globals.hpp
shark_globals.hpp shark_globals_<arch>.hpp
shark_globals.hpp globals.hpp
sharkBlock.cpp debug.hpp
sharkBlock.cpp bytecodes.hpp
sharkBlock.cpp llvmHeaders.hpp
sharkBlock.cpp llvmValue.hpp
sharkBlock.cpp shark_globals.hpp
sharkBlock.cpp sharkBlock.hpp
sharkBlock.cpp sharkBuilder.hpp
sharkBlock.cpp sharkConstant.hpp
sharkBlock.cpp sharkState.hpp
sharkBlock.cpp sharkValue.hpp
sharkBlock.hpp allocation.hpp
sharkBlock.hpp ciMethod.hpp
sharkBlock.hpp ciStreams.hpp
sharkBlock.hpp debug.hpp
sharkBlock.hpp llvmHeaders.hpp
sharkBlock.hpp sharkBuilder.hpp
sharkBlock.hpp sharkConstant.hpp
sharkBlock.hpp sharkInvariants.hpp
sharkBlock.hpp sharkState.hpp
sharkBlock.hpp sharkValue.hpp
sharkBuilder.cpp ciMethod.hpp
sharkBuilder.cpp debug.hpp
sharkBuilder.cpp llvmHeaders.hpp
sharkBuilder.cpp llvmValue.hpp
sharkBuilder.cpp methodOop.hpp
sharkBuilder.cpp os.hpp
sharkBuilder.cpp resourceArea.hpp
sharkBuilder.cpp llvmHeaders.hpp
sharkBuilder.cpp sharkBuilder.hpp
sharkBuilder.cpp sharkContext.hpp
sharkBuilder.cpp sharkRuntime.hpp
sharkBuilder.cpp synchronizer.hpp
sharkBuilder.cpp thread.hpp
sharkBuilder.hpp barrierSet.hpp
sharkBuilder.hpp cardTableModRefBS.hpp
sharkBuilder.hpp ciType.hpp
sharkBuilder.hpp debug.hpp
sharkBuilder.hpp llvmHeaders.hpp
sharkBuilder.hpp llvmValue.hpp
sharkBuilder.hpp sizes.hpp
sharkBuilder.hpp sharkCodeBuffer.hpp
sharkBuilder.hpp sharkType.hpp
sharkBuilder.hpp sharkValue.hpp
sharkBuilder.hpp sharkEntry.hpp
sharkCacheDecache.cpp ciMethod.hpp
sharkCacheDecache.cpp debugInfoRec.hpp
sharkCacheDecache.cpp llvmValue.hpp
sharkCacheDecache.cpp sharkBuilder.hpp
sharkCacheDecache.cpp sharkCacheDecache.hpp
sharkCacheDecache.cpp sharkFunction.hpp
sharkCacheDecache.cpp sharkState.hpp
sharkCacheDecache.hpp ciMethod.hpp
sharkCacheDecache.hpp debugInfoRec.hpp
sharkCacheDecache.hpp sharkBuilder.hpp
sharkCacheDecache.hpp sharkFunction.hpp
sharkCacheDecache.hpp sharkStateScanner.hpp
sharkCodeBuffer.hpp allocation.hpp
sharkCodeBuffer.hpp codeBuffer.hpp
sharkCodeBuffer.hpp llvmHeaders.hpp
sharkCompiler.cpp abstractCompiler.hpp
sharkCompiler.cpp ciEnv.hpp
sharkCompiler.cpp ciMethod.hpp
sharkCompiler.cpp debug.hpp
sharkCompiler.cpp debugInfoRec.hpp
sharkCompiler.cpp dependencies.hpp
sharkCompiler.cpp exceptionHandlerTable.hpp
sharkCompiler.cpp llvmHeaders.hpp
sharkCompiler.cpp oopMap.hpp
sharkCompiler.cpp oopRecorder.hpp
sharkCompiler.cpp shark_globals.hpp
sharkCompiler.cpp sharkBuilder.hpp
sharkCompiler.cpp sharkCodeBuffer.hpp
sharkCompiler.cpp sharkCompiler.hpp
sharkCompiler.cpp sharkContext.hpp
sharkCompiler.cpp sharkEntry.hpp
sharkCompiler.cpp sharkFunction.hpp
sharkCompiler.cpp sharkMemoryManager.hpp
sharkCompiler.cpp sharkNativeWrapper.hpp
sharkCompiler.hpp abstractCompiler.hpp
sharkCompiler.hpp ciEnv.hpp
sharkCompiler.hpp ciMethod.hpp
sharkCompiler.hpp compileBroker.hpp
sharkCompiler.hpp llvmHeaders.hpp
sharkCompiler.hpp sharkMemoryManager.hpp
sharkContext.cpp arrayOop.hpp
sharkContext.cpp globalDefinitions.hpp
sharkContext.cpp llvmHeaders.hpp
sharkContext.cpp oop.hpp
sharkContext.cpp sharkContext.hpp
sharkContext.hpp llvmHeaders.hpp
sharkContext.hpp sharkCompiler.hpp
sharkConstant.cpp ciInstance.hpp
sharkConstant.cpp ciStreams.hpp
sharkConstant.cpp sharkBuilder.hpp
sharkConstant.cpp sharkConstant.hpp
sharkConstant.cpp sharkValue.hpp
sharkConstant.hpp allocation.hpp
sharkConstant.hpp ciStreams.hpp
sharkConstant.hpp sharkBuilder.hpp
sharkConstant.hpp sharkValue.hpp
sharkEntry.hpp llvmHeaders.hpp
sharkFunction.cpp allocation.hpp
sharkFunction.cpp ciTypeFlow.hpp
sharkFunction.cpp debug.hpp
sharkFunction.cpp llvmHeaders.hpp
sharkFunction.cpp llvmValue.hpp
sharkFunction.cpp shark_globals.hpp
sharkFunction.cpp sharkBuilder.hpp
sharkFunction.cpp sharkEntry.hpp
sharkFunction.cpp sharkFunction.hpp
sharkFunction.cpp sharkState.hpp
sharkFunction.cpp sharkTopLevelBlock.hpp
sharkFunction.hpp allocation.hpp
sharkFunction.hpp ciEnv.hpp
sharkFunction.hpp ciStreams.hpp
sharkFunction.hpp ciTypeFlow.hpp
sharkFunction.hpp llvmHeaders.hpp
sharkFunction.hpp llvmValue.hpp
sharkFunction.hpp sharkBuilder.hpp
sharkFunction.hpp sharkContext.hpp
sharkFunction.hpp sharkInvariants.hpp
sharkFunction.hpp sharkStack.hpp
sharkInliner.cpp allocation.hpp
sharkInliner.cpp bytecodes.hpp
sharkInliner.cpp ciField.hpp
sharkInliner.cpp ciMethod.hpp
sharkInliner.cpp ciStreams.hpp
sharkInliner.cpp shark_globals.hpp
sharkInliner.cpp sharkBlock.hpp
sharkInliner.cpp sharkConstant.hpp
sharkInliner.cpp sharkInliner.hpp
sharkInliner.cpp sharkIntrinsics.hpp
sharkInliner.cpp sharkState.hpp
sharkInliner.cpp sharkValue.hpp
sharkInliner.hpp allocation.hpp
sharkInliner.hpp ciMethod.hpp
sharkInliner.hpp llvmHeaders.hpp
sharkInliner.hpp sharkState.hpp
sharkIntrinsics.cpp ciMethod.hpp
sharkIntrinsics.cpp llvmHeaders.hpp
sharkIntrinsics.cpp shark_globals.hpp
sharkIntrinsics.cpp sharkIntrinsics.hpp
sharkIntrinsics.cpp sharkState.hpp
sharkIntrinsics.cpp sharkValue.hpp
sharkIntrinsics.hpp allocation.hpp
sharkIntrinsics.hpp ciMethod.hpp
sharkIntrinsics.hpp llvmHeaders.hpp
sharkIntrinsics.hpp sharkState.hpp
sharkInvariants.cpp sharkInvariants.hpp
sharkInvariants.hpp allocation.hpp
sharkInvariants.hpp ciEnv.hpp
sharkInvariants.hpp ciMethod.hpp
sharkInvariants.hpp ciInstanceKlass.hpp
sharkInvariants.hpp ciTypeFlow.hpp
sharkInvariants.hpp debugInfoRec.hpp
sharkInvariants.hpp dependencies.hpp
sharkInvariants.hpp llvmHeaders.hpp
sharkInvariants.hpp sharkBuilder.hpp
sharkMemoryManager.hpp llvmHeaders.hpp
sharkMemoryManager.hpp sharkEntry.hpp
sharkMemoryManager.cpp llvmHeaders.hpp
sharkMemoryManager.cpp sharkEntry.hpp
sharkMemoryManager.cpp sharkMemoryManager.hpp
sharkNativeWrapper.cpp llvmHeaders.hpp
sharkNativeWrapper.cpp sharkNativeWrapper.hpp
sharkNativeWrapper.cpp sharkType.hpp
sharkNativeWrapper.hpp handles.hpp
sharkNativeWrapper.hpp llvmHeaders.hpp
sharkNativeWrapper.hpp sharkBuilder.hpp
sharkNativeWrapper.hpp sharkContext.hpp
sharkNativeWrapper.hpp sharkInvariants.hpp
sharkNativeWrapper.hpp sharkStack.hpp
sharkRuntime.cpp biasedLocking.hpp
sharkRuntime.cpp deoptimization.hpp
sharkRuntime.cpp llvmHeaders.hpp
sharkRuntime.cpp klassOop.hpp
sharkRuntime.cpp sharkRuntime.hpp
sharkRuntime.cpp stack_<arch>.inline.hpp
sharkRuntime.cpp thread.hpp
sharkRuntime.hpp allocation.hpp
sharkRuntime.hpp llvmHeaders.hpp
sharkRuntime.hpp llvmValue.hpp
sharkRuntime.hpp klassOop.hpp
sharkRuntime.hpp thread.hpp
sharkStack.cpp llvmHeaders.hpp
sharkStack.cpp sharkFunction.hpp
sharkStack.cpp sharkNativeWrapper.hpp
sharkStack.cpp sharkStack.hpp
sharkStack.cpp sharkType.hpp
sharkStack.hpp llvmHeaders.hpp
sharkStack.hpp sharkInvariants.hpp
sharkStack.hpp sharkType.hpp
sharkState.cpp allocation.hpp
sharkState.cpp ciType.hpp
sharkState.cpp ciTypeFlow.hpp
sharkState.cpp sharkBuilder.hpp
sharkState.cpp sharkCacheDecache.hpp
sharkState.cpp sharkState.hpp
sharkState.cpp sharkTopLevelBlock.hpp
sharkState.cpp sharkType.hpp
sharkState.cpp sharkValue.hpp
sharkState.hpp allocation.hpp
sharkState.hpp ciMethod.hpp
sharkState.hpp llvmHeaders.hpp
sharkState.hpp sharkBuilder.hpp
sharkState.hpp sharkInvariants.hpp
sharkState.hpp sharkValue.hpp
sharkStateScanner.cpp sharkState.hpp
sharkStateScanner.cpp sharkStateScanner.hpp
sharkStateScanner.hpp allocation.hpp
sharkStateScanner.hpp llvmHeaders.hpp
sharkStateScanner.hpp sharkFunction.hpp
sharkStateScanner.hpp sharkInvariants.hpp
sharkTopLevelBlock.cpp allocation.hpp
sharkTopLevelBlock.cpp bytecodes.hpp
sharkTopLevelBlock.cpp ciField.hpp
sharkTopLevelBlock.cpp ciInstance.hpp
sharkTopLevelBlock.cpp ciObjArrayKlass.hpp
sharkTopLevelBlock.cpp ciStreams.hpp
sharkTopLevelBlock.cpp ciType.hpp
sharkTopLevelBlock.cpp ciTypeFlow.hpp
sharkTopLevelBlock.cpp debug.hpp
sharkTopLevelBlock.cpp deoptimization.hpp
sharkTopLevelBlock.cpp llvmHeaders.hpp
sharkTopLevelBlock.cpp llvmValue.hpp
sharkTopLevelBlock.cpp shark_globals.hpp
sharkTopLevelBlock.cpp sharkCacheDecache.hpp
sharkTopLevelBlock.cpp sharkTopLevelBlock.hpp
sharkTopLevelBlock.cpp sharkBuilder.hpp
sharkTopLevelBlock.cpp sharkConstant.hpp
sharkTopLevelBlock.cpp sharkInliner.hpp
sharkTopLevelBlock.cpp sharkState.hpp
sharkTopLevelBlock.cpp sharkValue.hpp
sharkTopLevelBlock.hpp allocation.hpp
sharkTopLevelBlock.hpp bytecodes.hpp
sharkTopLevelBlock.hpp ciStreams.hpp
sharkTopLevelBlock.hpp ciType.hpp
sharkTopLevelBlock.hpp ciTypeFlow.hpp
sharkTopLevelBlock.hpp llvmHeaders.hpp
sharkTopLevelBlock.hpp sharkBlock.hpp
sharkTopLevelBlock.hpp sharkBuilder.hpp
sharkTopLevelBlock.hpp sharkFunction.hpp
sharkTopLevelBlock.hpp sharkState.hpp
sharkTopLevelBlock.hpp sharkValue.hpp
sharkType.hpp allocation.hpp
sharkType.hpp ciType.hpp
sharkType.hpp globalDefinitions.hpp
sharkType.hpp llvmHeaders.hpp
sharkType.hpp sharkContext.hpp
sharkValue.cpp ciType.hpp
sharkValue.cpp llvmHeaders.hpp
sharkValue.cpp llvmValue.hpp
sharkValue.cpp sharkBuilder.hpp
sharkValue.cpp sharkValue.hpp
sharkValue.hpp allocation.hpp
sharkValue.hpp ciType.hpp
sharkValue.hpp llvmHeaders.hpp
sharkValue.hpp llvmValue.hpp
sharkValue.hpp sharkType.hpp
/*
* Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -44,6 +44,7 @@ class CardTableModRefBS: public ModRefBarrierSet {
friend class VMStructs;
friend class CardTableRS;
friend class CheckForUnmarkedOops; // Needs access to raw card bytes.
friend class SharkBuilder;
#ifndef PRODUCT
// For debugging.
friend class GuaranteeNotModClosure;
......
......@@ -751,10 +751,14 @@ void methodOopDesc::set_code(methodHandle mh, nmethod *code) {
}
OrderAccess::storestore();
#ifdef SHARK
mh->_from_interpreted_entry = code->instructions_begin();
#else
mh->_from_compiled_entry = code->verified_entry_point();
OrderAccess::storestore();
// Instantly compiled code can execute.
mh->_from_interpreted_entry = mh->get_i2c_entry();
#endif // SHARK
}
......
......@@ -254,6 +254,7 @@ 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
......@@ -270,6 +271,10 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
assert(cb->is_deoptimization_stub() || cb->is_uncommon_trap_stub(), "just checking");
Events::log("fetch unroll sp " INTPTR_FORMAT, unpack_sp);
#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
// where it will be very difficult to figure out what went wrong. Better
......@@ -380,7 +385,9 @@ 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
UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord,
caller_adjustment * BytesPerWord,
......@@ -1073,7 +1080,7 @@ JRT_LEAF(void, Deoptimization::popframe_preserve_args(JavaThread* thread, int by
JRT_END
#ifdef COMPILER2
#if defined(COMPILER2) || defined(SHARK)
void Deoptimization::load_class_by_index(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()) {
......@@ -1835,7 +1842,7 @@ void Deoptimization::print_statistics() {
if (xtty != NULL) xtty->tail("statistics");
}
}
#else // COMPILER2
#else // COMPILER2 || SHARK
// Stubs for C1 only system.
......@@ -1871,4 +1878,4 @@ const char* Deoptimization::format_trap_state(char* buf, size_t buflen,
return buf;
}
#endif // COMPILER2
#endif // COMPILER2 || SHARK
......@@ -1100,6 +1100,10 @@ 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();
}
......
/*
* Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -181,6 +181,18 @@ void Flag::print_as_flag(outputStream* st) {
#define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{C2 notproduct}", DEFAULT },
#endif
#define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark product}", DEFAULT },
#define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, "{Shark pd product}", DEFAULT },
#define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark diagnostic}", DEFAULT },
#ifdef PRODUCT
#define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
#define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc) /* flag is constant */
#define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
#else
#define SHARK_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark}", DEFAULT },
#define SHARK_PD_DEVELOP_FLAG_STRUCT(type, name, doc) { #type, XSTR(name), &name, "{Shark pd}", DEFAULT },
#define SHARK_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, "{Shark notproduct}", DEFAULT },
#endif
static Flag flagTable[] = {
RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, RUNTIME_PD_DEVELOP_FLAG_STRUCT, RUNTIME_PRODUCT_FLAG_STRUCT, RUNTIME_PD_PRODUCT_FLAG_STRUCT, RUNTIME_DIAGNOSTIC_FLAG_STRUCT, RUNTIME_EXPERIMENTAL_FLAG_STRUCT, RUNTIME_NOTPRODUCT_FLAG_STRUCT, RUNTIME_MANAGEABLE_FLAG_STRUCT, RUNTIME_PRODUCT_RW_FLAG_STRUCT, RUNTIME_LP64_PRODUCT_FLAG_STRUCT)
......@@ -193,6 +205,9 @@ static Flag flagTable[] = {
#endif
#ifdef COMPILER2
C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, C2_PD_DEVELOP_FLAG_STRUCT, C2_PRODUCT_FLAG_STRUCT, C2_PD_PRODUCT_FLAG_STRUCT, C2_DIAGNOSTIC_FLAG_STRUCT, C2_EXPERIMENTAL_FLAG_STRUCT, C2_NOTPRODUCT_FLAG_STRUCT)
#endif
#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_NOTPRODUCT_FLAG_STRUCT)
#endif
{0, NULL, NULL}
};
......
......@@ -22,7 +22,7 @@
*
*/
#if !defined(COMPILER1) && !defined(COMPILER2)
#if !defined(COMPILER1) && !defined(COMPILER2) && !defined(SHARK)
define_pd_global(bool, BackgroundCompilation, false);
define_pd_global(bool, UseTLAB, false);
define_pd_global(bool, CICompileOSR, false);
......
/*
* Copyright (c) 1998, 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
......@@ -95,7 +95,11 @@ void Abstract_VM_Version::initialize() {
#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")
......
/*
* Copyright (c) 1999, 2007, 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.
*
*/
#ifdef assert
#undef assert
#endif
#ifdef DEBUG
#define SHARK_DEBUG
#undef DEBUG
#endif
#include <llvm/Argument.h>
#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/Instructions.h>
#include <llvm/LLVMContext.h>
#include <llvm/Module.h>
#if SHARK_LLVM_VERSION < 27
#include <llvm/ModuleProvider.h>
#endif
#include <llvm/Support/IRBuilder.h>
#include <llvm/System/Threading.h>
#include <llvm/Target/TargetSelect.h>
#include <llvm/Type.h>
#include <llvm/ExecutionEngine/JITMemoryManager.h>
#include <llvm/Support/CommandLine.h>
#if SHARK_LLVM_VERSION >= 27
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ADT/StringMap.h>
#include <llvm/Support/Debug.h>
#include <llvm/System/Host.h>
#endif
#include <map>
#ifdef assert
#undef assert
#endif
// from hotspot/src/share/vm/utilities/debug.hpp
#ifdef ASSERT
#ifndef USE_REPEATED_ASSERTS
#define assert(p, msg) \
do { \
if (!(p)) { \
report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg); \
BREAKPOINT; \
} \
} while (0)
#else // #ifndef USE_REPEATED_ASSERTS
#define assert(p, msg)
do { \
for (int __i = 0; __i < AssertRepeat; __i++) { \
if (!(p)) { \
report_vm_error(__FILE__, __LINE__, "assert(" #p ") failed", msg); \
BREAKPOINT; \
} \
} \
} while (0)
#endif // #ifndef USE_REPEATED_ASSERTS
#else
#define assert(p, msg)
#endif
#ifdef DEBUG
#undef DEBUG
#endif
#ifdef SHARK_DEBUG
#define DEBUG
#undef SHARK_DEBUG
#endif
/*
* Copyright (c) 1999, 2007, 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.
*
*/
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());
}
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);
}
};
此差异已折叠。
/*
* Copyright (c) 1999, 2007, 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.
*
*/
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();
};
/*
* Copyright (c) 1999, 2007, 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 "incls/_precompiled.incl"
#include "incls/_sharkBuilder.cpp.incl"
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,
const Type* type,
const char* name) {
return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name);
}
LoadInst* SharkBuilder::CreateValueOfStructEntry(Value* base,
ByteSize offset,
const 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,
const 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.
const 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();
// Miscellaneous
case 'v':
assert(void_ok, "should be");
return SharkType::void_type();
case '1':
return SharkType::bit_type();
default:
ShouldNotReachHere();
}
}
const FunctionType* SharkBuilder::make_ftype(const char* params,
const char* ret) {
std::vector<const Type*> param_types;
for (const char* c = params; *c; c++)
param_types.push_back(make_type(*c, false));
assert(strlen(ret) == 1, "should be");
const 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, "OO", "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() {
extern jlong Unsafe_field_offset_to_byte_offset(jlong field_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");
}
// Low-level non-VM calls
// The ARM-specific code here is to work around unimplemented
// atomic exchange and memory barrier intrinsics in LLVM.
//
// Delegating to external functions for these would normally
// incur a speed penalty, but Linux on ARM is a special case
// in that atomic operations on that platform are handled by
// external functions anyway. It would be *preferable* for
// the calls to be hidden away in LLVM, but it's not hurting
// performance so having the calls here is acceptable.
//
// If you are building Shark on a platform without atomic
// exchange and/or memory barrier intrinsics then it is only
// acceptable to mimic this approach if your platform cannot
// perform these operations without delegating to a function.
#ifdef ARM
static jint zero_cmpxchg_int(volatile jint *ptr, jint oldval, jint newval) {
return Atomic::cmpxchg(newval, ptr, oldval);
}
#endif // ARM
Value* SharkBuilder::cmpxchg_int() {
return make_function(
#ifdef ARM
(address) zero_cmpxchg_int,
#else
"llvm.atomic.cmp.swap.i32.p0i32",
#endif // ARM
"Iii", "i");
}
#ifdef ARM
static intptr_t zero_cmpxchg_ptr(volatile intptr_t* ptr,
intptr_t oldval,
intptr_t newval) {
return Atomic::cmpxchg_ptr(newval, ptr, oldval);
}
#endif // ARM
Value* SharkBuilder::cmpxchg_ptr() {
return make_function(
#ifdef ARM
(address) zero_cmpxchg_ptr,
#else
"llvm.atomic.cmp.swap.i" LP64_ONLY("64") NOT_LP64("32") ".p0i" LP64_ONLY("64") NOT_LP64("32"),
#endif // ARM
"Xxx", "x");
}
Value* SharkBuilder::frame_address() {
return make_function("llvm.frameaddress", "i", "C");
}
Value* SharkBuilder::memory_barrier() {
return make_function(
#ifdef ARM
(address) 0xffff0fa0, // __kernel_dmb
#else
"llvm.memory.barrier",
#endif // ARM
"11111", "v");
}
Value* SharkBuilder::memset() {
#if SHARK_LLVM_VERSION >= 28
// LLVM 2.8 added a fifth isVolatile field for memset
// introduced with LLVM r100304
return make_function("llvm.memset.i32", "Cciii", "v");
#else
return make_function("llvm.memset.i32", "Ccii", "v");
#endif
}
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::CreateCmpxchgInt(Value* exchange_value,
Value* dst,
Value* compare_value) {
return CreateCall3(cmpxchg_int(), dst, compare_value, exchange_value);
}
CallInst* SharkBuilder::CreateCmpxchgPtr(Value* exchange_value,
Value* dst,
Value* compare_value) {
return CreateCall3(cmpxchg_ptr(), dst, compare_value, exchange_value);
}
CallInst* SharkBuilder::CreateGetFrameAddress() {
return CreateCall(frame_address(), LLVMValue::jint_constant(0));
}
CallInst *SharkBuilder::CreateMemoryBarrier(int flags) {
Value *args[] = {
LLVMValue::bit_constant((flags & BARRIER_LOADLOAD) ? 1 : 0),
LLVMValue::bit_constant((flags & BARRIER_LOADSTORE) ? 1 : 0),
LLVMValue::bit_constant((flags & BARRIER_STORELOAD) ? 1 : 0),
LLVMValue::bit_constant((flags & BARRIER_STORESTORE) ? 1 : 0),
LLVMValue::bit_constant(1)};
return CreateCall(memory_barrier(), args, args + 5);
}
CallInst* SharkBuilder::CreateMemset(Value* dst,
Value* value,
Value* len,
Value* align) {
#if SHARK_LLVM_VERSION >= 28
return CreateCall5(memset(), dst, value, len, align,
LLVMValue::jint_constant(0));
#else
return CreateCall4(memset(), dst, value, len, align);
#endif
}
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 = 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()->
#if SHARK_LLVM_VERSION >= 27
isIntegerTy()
#else
isInteger()
#endif
)
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::CardTableModRef)
Unimplemented();
CreateStore(
LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card),
CreateIntToPtr(
CreateAdd(
LLVMValue::intptr_constant(
(intptr_t) ((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::CreateInlineData(void* data,
size_t size,
const 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);
}
/*
* Copyright (c) 1999, 2007, 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.
*
*/
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;
}
// Helpers for accessing structures.
public:
llvm::Value* CreateAddressOfStructEntry(llvm::Value* base,
ByteSize offset,
const llvm::Type* type,
const char *name = "");
llvm::LoadInst* CreateValueOfStructEntry(llvm::Value* base,
ByteSize offset,
const llvm::Type* type,
const char *name = "");
// Helpers for accessing arrays.
public:
llvm::LoadInst* CreateArrayLength(llvm::Value* arrayoop);
llvm::Value* CreateArrayAddress(llvm::Value* arrayoop,
const 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 const llvm::Type* make_type(char type, bool void_ok);
static const 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* memory_barrier();
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* CreateCmpxchgInt(llvm::Value* exchange_value,
llvm::Value* dst,
llvm::Value* compare_value);
llvm::CallInst* CreateCmpxchgPtr(llvm::Value* exchange_value,
llvm::Value* dst,
llvm::Value* compare_value);
llvm::CallInst* CreateGetFrameAddress();
llvm::CallInst* CreateMemoryBarrier(int flags);
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));
// Flags for CreateMemoryBarrier.
public:
enum BarrierFlags {
BARRIER_LOADLOAD = 1,
BARRIER_LOADSTORE = 2,
BARRIER_STORELOAD = 4,
BARRIER_STORESTORE = 8
};
// 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* CreateInlineData(void* data,
size_t size,
const 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;
};
/*
* Copyright (c) 1999, 2007, 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 "incls/_precompiled.incl"
#include "incls/_sharkCacheDecache.cpp.incl"
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::methodOop_type(),
*value,
offset);
oopmap()->set_oop(slot2reg(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
debug_info()->describe_scope(
pc_offset(),
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::methodOop_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,
const 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(const Type* type,
Value* value,
int offset) {
builder()->CreateStore(value, stack()->slot_addr(offset, type));
}
Value* SharkCacher::read_value_from_frame(const Type* type, int offset) {
return builder()->CreateLoad(stack()->slot_addr(offset, type));
}
/*
* Copyright (c) 1999, 2007, 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.
*
*/
// 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(const 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(const 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, const llvm::Type* type);
};
/*
* Copyright (c) 1999, 2007, 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.
*
*/
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;
}
// 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;
}
};
/*
* Copyright (c) 1999, 2007, 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 "incls/_precompiled.incl"
#include "incls/_sharkCompiler.cpp.incl"
#include <fnmatch.h>
using namespace llvm;
#if SHARK_LLVM_VERSION >= 27
namespace {
cl::opt<std::string>
MCPU("mcpu");
cl::list<std::string>
MAttrs("mattr",
cl::CommaSeparated);
}
#endif
SharkCompiler::SharkCompiler()
: AbstractCompiler() {
// 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();
// 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();
#if SHARK_LLVM_VERSION >= 27
// 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);
_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());
#else
_execution_engine = ExecutionEngine::createJIT(
_normal_context->module_provider(),
NULL, memory_manager(), CodeGenOpt::Default);
execution_engine()->addModuleProvider(
_native_context->module_provider());
#endif
// All done
mark_initialized();
}
void SharkCompiler::initialize() {
ShouldNotCallThis();
}
void SharkCompiler::compile_method(ciEnv* env,
ciMethod* target,
int entry_bci) {
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);
// 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,
env->comp_level(),
false,
false);
}
nmethod* SharkCompiler::generate_native_wrapper(MacroAssembler* masm,
methodHandle target,
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,
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();
}
// Compile to native code
address code = NULL;
context()->add_function(function);
{
MutexLocker locker(execution_engine_lock());
free_queued_methods();
if (SharkPrintAsmOf != NULL) {
#if SHARK_LLVM_VERSION >= 27
#ifndef NDEBUG
if (!fnmatch(SharkPrintAsmOf, name, 0)) {
llvm::SetCurrentDebugType(X86_ONLY("x86-emitter") NOT_X86("jit"));
llvm::DebugFlag = true;
}
else {
llvm::SetCurrentDebugType("");
llvm::DebugFlag = false;
}
#endif // !NDEBUG
#else
// NB you need to patch LLVM with http://tinyurl.com/yf3baln for this
std::vector<const char*> args;
args.push_back(""); // program name
if (!fnmatch(SharkPrintAsmOf, name, 0))
args.push_back("-debug-only=x86-emitter");
else
args.push_back("-debug-only=none");
args.push_back(0); // terminator
cl::ParseCommandLineOptions(args.size() - 1, (char **) &args[0]);
#endif // SHARK_LLVM_VERSION
}
memory_manager()->set_entry_for_function(function, entry);
code = (address) execution_engine()->getPointerToFunction(function);
}
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_VM_thread(), "must be called by VM thread");
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
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;
}
/*
* Copyright (c) 1999, 2007, 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.
*
*/
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; }
// Customization
bool needs_adapters() { return false; }
bool needs_stubs() { return false; }
// Initialization
void initialize();
// Compile a normal (bytecode) method and install it in the VM
void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
// Generate a wrapper for a native (JNI) method
nmethod* generate_native_wrapper(MacroAssembler* masm,
methodHandle target,
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_fast_compile);
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();
};
/*
* Copyright (c) 1999, 2007, 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 "incls/_precompiled.incl"
#include "incls/_sharkConstant.cpp.incl"
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();
if (constant.as_object()->is_klass())
type = env->Class_klass();
else
type = env->String_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_klass()) {
// The constant returned for a klass is the ciKlass
// for the entry, but we want the java_mirror.
ciKlass *klass = object->as_klass();
if (!klass->is_loaded()) {
_is_loaded = false;
return;
}
object = klass->java_mirror();
}
if (object->is_null_object() || !object->can_be_constant()) {
_is_loaded = false;
return;
}
_value = NULL;
_object = object;
_type = type;
_is_loaded = true;
_is_nonzero = true;
_is_two_word = false;
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
/*
* Copyright (c) 1999, 2007, 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.
*
*/
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;
}
};
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册