6976186: integrate Shark HotSpot changes
authortwisti
Wed, 11 Aug 2010 05:51:21 -0700
changeset 6187 4fa7845f7c14
parent 6186 7eef4cda471c
child 6188 95ea4d66089a
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: Gary Benson <gbenson@redhat.com>
hotspot/make/Makefile
hotspot/make/linux/Makefile
hotspot/make/linux/makefiles/gcc.make
hotspot/make/linux/makefiles/shark.make
hotspot/make/linux/makefiles/top.make
hotspot/make/linux/makefiles/vm.make
hotspot/src/cpu/zero/vm/disassembler_zero.hpp
hotspot/src/cpu/zero/vm/shark_globals_zero.hpp
hotspot/src/share/vm/ci/ciMethod.cpp
hotspot/src/share/vm/ci/ciMethod.hpp
hotspot/src/share/vm/code/nmethod.cpp
hotspot/src/share/vm/code/nmethod.hpp
hotspot/src/share/vm/compiler/abstractCompiler.hpp
hotspot/src/share/vm/compiler/compileBroker.cpp
hotspot/src/share/vm/compiler/disassembler.cpp
hotspot/src/share/vm/includeDB_shark
hotspot/src/share/vm/memory/cardTableModRefBS.hpp
hotspot/src/share/vm/oops/methodOop.cpp
hotspot/src/share/vm/runtime/deoptimization.cpp
hotspot/src/share/vm/runtime/frame.cpp
hotspot/src/share/vm/runtime/globals.cpp
hotspot/src/share/vm/runtime/globals.hpp
hotspot/src/share/vm/runtime/vm_version.cpp
hotspot/src/share/vm/shark/llvmHeaders.hpp
hotspot/src/share/vm/shark/llvmValue.hpp
hotspot/src/share/vm/shark/sharkBlock.cpp
hotspot/src/share/vm/shark/sharkBlock.hpp
hotspot/src/share/vm/shark/sharkBuilder.cpp
hotspot/src/share/vm/shark/sharkBuilder.hpp
hotspot/src/share/vm/shark/sharkCacheDecache.cpp
hotspot/src/share/vm/shark/sharkCacheDecache.hpp
hotspot/src/share/vm/shark/sharkCodeBuffer.hpp
hotspot/src/share/vm/shark/sharkCompiler.cpp
hotspot/src/share/vm/shark/sharkCompiler.hpp
hotspot/src/share/vm/shark/sharkConstant.cpp
hotspot/src/share/vm/shark/sharkConstant.hpp
hotspot/src/share/vm/shark/sharkContext.cpp
hotspot/src/share/vm/shark/sharkContext.hpp
hotspot/src/share/vm/shark/sharkEntry.hpp
hotspot/src/share/vm/shark/sharkFunction.cpp
hotspot/src/share/vm/shark/sharkFunction.hpp
hotspot/src/share/vm/shark/sharkInliner.cpp
hotspot/src/share/vm/shark/sharkInliner.hpp
hotspot/src/share/vm/shark/sharkIntrinsics.cpp
hotspot/src/share/vm/shark/sharkIntrinsics.hpp
hotspot/src/share/vm/shark/sharkInvariants.cpp
hotspot/src/share/vm/shark/sharkInvariants.hpp
hotspot/src/share/vm/shark/sharkMemoryManager.cpp
hotspot/src/share/vm/shark/sharkMemoryManager.hpp
hotspot/src/share/vm/shark/sharkNativeWrapper.cpp
hotspot/src/share/vm/shark/sharkNativeWrapper.hpp
hotspot/src/share/vm/shark/sharkRuntime.cpp
hotspot/src/share/vm/shark/sharkRuntime.hpp
hotspot/src/share/vm/shark/sharkStack.cpp
hotspot/src/share/vm/shark/sharkStack.hpp
hotspot/src/share/vm/shark/sharkState.cpp
hotspot/src/share/vm/shark/sharkState.hpp
hotspot/src/share/vm/shark/sharkStateScanner.cpp
hotspot/src/share/vm/shark/sharkStateScanner.hpp
hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp
hotspot/src/share/vm/shark/sharkType.hpp
hotspot/src/share/vm/shark/sharkValue.cpp
hotspot/src/share/vm/shark/sharkValue.hpp
hotspot/src/share/vm/shark/shark_globals.cpp
hotspot/src/share/vm/shark/shark_globals.hpp
hotspot/src/share/vm/utilities/macros.hpp
--- a/hotspot/make/Makefile	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/make/Makefile	Wed Aug 11 05:51:21 2010 -0700
@@ -85,6 +85,7 @@
 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_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 @@
 	$(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 @@
 		$(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 @@
 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 @@
 # 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 @@
 	$(RM) -r $(C2_DIR)
 	$(RM) -r $(KERNEL_DIR)
 	$(RM) -r $(ZERO_DIR)
+	$(RM) -r $(SHARK_DIR)
 clean_export:
 	$(RM) -r $(EXPORT_PATH)
 clean_jdk:
--- a/hotspot/make/linux/Makefile	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/make/linux/Makefile	Wed Aug 11 05:51:21 2010 -0700
@@ -1,5 +1,5 @@
 #
-# 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 @@
 #       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_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 @@
 	@echo "  $(TARGETS_C1)"
 	@echo "  $(TARGETS_CORE)"
 	@echo "  $(TARGETS_ZERO)"
+	@echo "  $(TARGETS_SHARK)"
 
 checks: check_os_version check_j2se_version
 
@@ -266,6 +276,10 @@
 	$(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 @@
 	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 @@
 
 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
--- a/hotspot/make/linux/makefiles/gcc.make	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/make/linux/makefiles/gcc.make	Wed Aug 11 05:51:21 2010 -0700
@@ -1,5 +1,5 @@
 #
-# 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 @@
 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/linux/makefiles/shark.make	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,32 @@
+#
+# 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
--- a/hotspot/make/linux/makefiles/top.make	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/make/linux/makefiles/top.make	Wed Aug 11 05:51:21 2010 -0700
@@ -1,5 +1,5 @@
 #
-# 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/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
--- a/hotspot/make/linux/makefiles/vm.make	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/make/linux/makefiles/vm.make	Wed Aug 11 05:51:21 2010 -0700
@@ -1,5 +1,5 @@
 #
-# 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 @@
 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 @@
 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)
 
--- a/hotspot/src/cpu/zero/vm/disassembler_zero.hpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/cpu/zero/vm/disassembler_zero.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -1,6 +1,6 @@
 /*
  * 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 "";
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/cpu/zero/vm/shark_globals_zero.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,62 @@
+/*
+ * 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 );
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -55,10 +55,10 @@
   _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 @@
   _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 @@
 }
 
 
+#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 @@
 // ------------------------------------------------------------------
 // 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
 }
 
 // ------------------------------------------------------------------
--- a/hotspot/src/share/vm/ci/ciMethod.hpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -70,7 +70,7 @@
 
   // Optional liveness analyzer.
   MethodLiveness* _liveness;
-#ifdef COMPILER2
+#if defined(COMPILER2) || defined(SHARK)
   ciTypeFlow*         _flow;
   BCEscapeAnalyzer*   _bcea;
 #endif
@@ -141,6 +141,9 @@
 
   // Runtime information.
   int           vtable_index();
+#ifdef SHARK
+  int           itable_index();
+#endif // SHARK
   address       native_entry();
   address       interpreter_entry();
 
--- a/hotspot/src/share/vm/code/nmethod.cpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/code/nmethod.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -65,6 +65,11 @@
   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 @@
     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 @@
 // 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 @@
     symbolOop signature = call->signature();
     fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
   }
+#endif // !SHARK
 }
 
 
@@ -2279,6 +2290,8 @@
     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) ");
   }
--- a/hotspot/src/share/vm/code/nmethod.hpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/code/nmethod.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -329,6 +329,7 @@
 
   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; }
--- a/hotspot/src/share/vm/compiler/abstractCompiler.hpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/compiler/abstractCompiler.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * 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 @@
   // 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
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -568,6 +568,14 @@
 #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;
 
--- a/hotspot/src/share/vm/compiler/disassembler.cpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * 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 @@
   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) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/includeDB_shark	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,371 @@
+//
+// 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
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * 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 @@
   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;
--- a/hotspot/src/share/vm/oops/methodOop.cpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/oops/methodOop.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -751,10 +751,14 @@
   }
 
   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
 
 }
 
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -254,6 +254,7 @@
 
   }
 
+#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 @@
   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 @@
 
   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_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 @@
     if (xtty != NULL)  xtty->tail("statistics");
   }
 }
-#else // COMPILER2
+#else // COMPILER2 || SHARK
 
 
 // Stubs for C1 only system.
@@ -1871,4 +1878,4 @@
   return buf;
 }
 
-#endif // COMPILER2
+#endif // COMPILER2 || SHARK
--- a/hotspot/src/share/vm/runtime/frame.cpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/runtime/frame.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -1100,6 +1100,10 @@
     oops_entry_do(f, map);
   } else if (CodeCache::contains(pc())) {
     oops_code_blob_do(f, cf, map);
+#ifdef SHARK
+  } else if (is_fake_stub_frame()) {
+    // nothing to do
+#endif // SHARK
   } else {
     ShouldNotReachHere();
   }
--- a/hotspot/src/share/vm/runtime/globals.cpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/runtime/globals.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * 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 @@
   #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)
@@ -194,6 +206,9 @@
 #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}
 };
 
--- a/hotspot/src/share/vm/runtime/globals.hpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -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);
--- a/hotspot/src/share/vm/runtime/vm_version.cpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * 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 @@
   #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")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/llvmHeaders.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,95 @@
+/*
+ * 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/llvmValue.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,62 @@
+/*
+ * 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);
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkBlock.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,1260 @@
+/*
+ * 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/_sharkBlock.cpp.incl"
+
+using namespace llvm;
+
+void SharkBlock::parse_bytecode(int start, int limit) {
+  SharkValue *a, *b, *c, *d;
+  int i;
+
+  // Ensure the current state is initialized before we emit any code,
+  // so that any setup code for the state is at the start of the block
+  current_state();
+
+  // Parse the bytecodes
+  iter()->reset_to_bci(start);
+  while (iter()->next_bci() < limit) {
+    NOT_PRODUCT(a = b = c = d = NULL);
+    iter()->next();
+
+    if (SharkTraceBytecodes)
+      tty->print_cr("%4d: %s", bci(), Bytecodes::name(bc()));
+
+    if (has_trap() && trap_bci() == bci()) {
+      do_trap(trap_request());
+      return;
+    }
+
+    if (UseLoopSafepoints) {
+      // XXX if a lcmp is followed by an if_?? then C2 maybe-inserts
+      // the safepoint before the lcmp rather than before the if.
+      // Maybe we should do this too.  See parse2.cpp for details.
+      switch (bc()) {
+      case Bytecodes::_goto:
+      case Bytecodes::_ifnull:
+      case Bytecodes::_ifnonnull:
+      case Bytecodes::_if_acmpeq:
+      case Bytecodes::_if_acmpne:
+      case Bytecodes::_ifeq:
+      case Bytecodes::_ifne:
+      case Bytecodes::_iflt:
+      case Bytecodes::_ifle:
+      case Bytecodes::_ifgt:
+      case Bytecodes::_ifge:
+      case Bytecodes::_if_icmpeq:
+      case Bytecodes::_if_icmpne:
+      case Bytecodes::_if_icmplt:
+      case Bytecodes::_if_icmple:
+      case Bytecodes::_if_icmpgt:
+      case Bytecodes::_if_icmpge:
+        if (iter()->get_dest() <= bci())
+          maybe_add_backedge_safepoint();
+        break;
+
+      case Bytecodes::_goto_w:
+        if (iter()->get_far_dest() <= bci())
+          maybe_add_backedge_safepoint();
+        break;
+
+      case Bytecodes::_tableswitch:
+      case Bytecodes::_lookupswitch:
+        if (switch_default_dest() <= bci()) {
+          maybe_add_backedge_safepoint();
+          break;
+        }
+        int len = switch_table_length();
+        for (int i = 0; i < len; i++) {
+          if (switch_dest(i) <= bci()) {
+            maybe_add_backedge_safepoint();
+            break;
+          }
+        }
+        break;
+      }
+    }
+
+    switch (bc()) {
+    case Bytecodes::_nop:
+      break;
+
+    case Bytecodes::_aconst_null:
+      push(SharkValue::null());
+      break;
+
+    case Bytecodes::_iconst_m1:
+      push(SharkValue::jint_constant(-1));
+      break;
+    case Bytecodes::_iconst_0:
+      push(SharkValue::jint_constant(0));
+      break;
+    case Bytecodes::_iconst_1:
+      push(SharkValue::jint_constant(1));
+      break;
+    case Bytecodes::_iconst_2:
+      push(SharkValue::jint_constant(2));
+      break;
+    case Bytecodes::_iconst_3:
+      push(SharkValue::jint_constant(3));
+      break;
+    case Bytecodes::_iconst_4:
+      push(SharkValue::jint_constant(4));
+      break;
+    case Bytecodes::_iconst_5:
+      push(SharkValue::jint_constant(5));
+      break;
+
+    case Bytecodes::_lconst_0:
+      push(SharkValue::jlong_constant(0));
+      break;
+    case Bytecodes::_lconst_1:
+      push(SharkValue::jlong_constant(1));
+      break;
+
+    case Bytecodes::_fconst_0:
+      push(SharkValue::jfloat_constant(0));
+      break;
+    case Bytecodes::_fconst_1:
+      push(SharkValue::jfloat_constant(1));
+      break;
+    case Bytecodes::_fconst_2:
+      push(SharkValue::jfloat_constant(2));
+      break;
+
+    case Bytecodes::_dconst_0:
+      push(SharkValue::jdouble_constant(0));
+      break;
+    case Bytecodes::_dconst_1:
+      push(SharkValue::jdouble_constant(1));
+      break;
+
+    case Bytecodes::_bipush:
+      push(SharkValue::jint_constant(iter()->get_constant_u1()));
+      break;
+    case Bytecodes::_sipush:
+      push(SharkValue::jint_constant(iter()->get_constant_u2()));
+      break;
+
+    case Bytecodes::_ldc:
+    case Bytecodes::_ldc_w:
+    case Bytecodes::_ldc2_w:
+      push(SharkConstant::for_ldc(iter())->value(builder()));
+      break;
+
+    case Bytecodes::_iload_0:
+    case Bytecodes::_lload_0:
+    case Bytecodes::_fload_0:
+    case Bytecodes::_dload_0:
+    case Bytecodes::_aload_0:
+      push(local(0));
+      break;
+    case Bytecodes::_iload_1:
+    case Bytecodes::_lload_1:
+    case Bytecodes::_fload_1:
+    case Bytecodes::_dload_1:
+    case Bytecodes::_aload_1:
+      push(local(1));
+      break;
+    case Bytecodes::_iload_2:
+    case Bytecodes::_lload_2:
+    case Bytecodes::_fload_2:
+    case Bytecodes::_dload_2:
+    case Bytecodes::_aload_2:
+      push(local(2));
+      break;
+    case Bytecodes::_iload_3:
+    case Bytecodes::_lload_3:
+    case Bytecodes::_fload_3:
+    case Bytecodes::_dload_3:
+    case Bytecodes::_aload_3:
+      push(local(3));
+      break;
+    case Bytecodes::_iload:
+    case Bytecodes::_lload:
+    case Bytecodes::_fload:
+    case Bytecodes::_dload:
+    case Bytecodes::_aload:
+      push(local(iter()->get_index()));
+      break;
+
+    case Bytecodes::_baload:
+      do_aload(T_BYTE);
+      break;
+    case Bytecodes::_caload:
+      do_aload(T_CHAR);
+      break;
+    case Bytecodes::_saload:
+      do_aload(T_SHORT);
+      break;
+    case Bytecodes::_iaload:
+      do_aload(T_INT);
+      break;
+    case Bytecodes::_laload:
+      do_aload(T_LONG);
+      break;
+    case Bytecodes::_faload:
+      do_aload(T_FLOAT);
+      break;
+    case Bytecodes::_daload:
+      do_aload(T_DOUBLE);
+      break;
+    case Bytecodes::_aaload:
+      do_aload(T_OBJECT);
+      break;
+
+    case Bytecodes::_istore_0:
+    case Bytecodes::_lstore_0:
+    case Bytecodes::_fstore_0:
+    case Bytecodes::_dstore_0:
+    case Bytecodes::_astore_0:
+      set_local(0, pop());
+      break;
+    case Bytecodes::_istore_1:
+    case Bytecodes::_lstore_1:
+    case Bytecodes::_fstore_1:
+    case Bytecodes::_dstore_1:
+    case Bytecodes::_astore_1:
+      set_local(1, pop());
+      break;
+    case Bytecodes::_istore_2:
+    case Bytecodes::_lstore_2:
+    case Bytecodes::_fstore_2:
+    case Bytecodes::_dstore_2:
+    case Bytecodes::_astore_2:
+      set_local(2, pop());
+      break;
+    case Bytecodes::_istore_3:
+    case Bytecodes::_lstore_3:
+    case Bytecodes::_fstore_3:
+    case Bytecodes::_dstore_3:
+    case Bytecodes::_astore_3:
+      set_local(3, pop());
+      break;
+    case Bytecodes::_istore:
+    case Bytecodes::_lstore:
+    case Bytecodes::_fstore:
+    case Bytecodes::_dstore:
+    case Bytecodes::_astore:
+      set_local(iter()->get_index(), pop());
+      break;
+
+    case Bytecodes::_bastore:
+      do_astore(T_BYTE);
+      break;
+    case Bytecodes::_castore:
+      do_astore(T_CHAR);
+      break;
+    case Bytecodes::_sastore:
+      do_astore(T_SHORT);
+      break;
+    case Bytecodes::_iastore:
+      do_astore(T_INT);
+      break;
+    case Bytecodes::_lastore:
+      do_astore(T_LONG);
+      break;
+    case Bytecodes::_fastore:
+      do_astore(T_FLOAT);
+      break;
+    case Bytecodes::_dastore:
+      do_astore(T_DOUBLE);
+      break;
+    case Bytecodes::_aastore:
+      do_astore(T_OBJECT);
+      break;
+
+    case Bytecodes::_pop:
+      xpop();
+      break;
+    case Bytecodes::_pop2:
+      xpop();
+      xpop();
+      break;
+    case Bytecodes::_swap:
+      a = xpop();
+      b = xpop();
+      xpush(a);
+      xpush(b);
+      break;
+    case Bytecodes::_dup:
+      a = xpop();
+      xpush(a);
+      xpush(a);
+      break;
+    case Bytecodes::_dup_x1:
+      a = xpop();
+      b = xpop();
+      xpush(a);
+      xpush(b);
+      xpush(a);
+      break;
+    case Bytecodes::_dup_x2:
+      a = xpop();
+      b = xpop();
+      c = xpop();
+      xpush(a);
+      xpush(c);
+      xpush(b);
+      xpush(a);
+      break;
+    case Bytecodes::_dup2:
+      a = xpop();
+      b = xpop();
+      xpush(b);
+      xpush(a);
+      xpush(b);
+      xpush(a);
+      break;
+    case Bytecodes::_dup2_x1:
+      a = xpop();
+      b = xpop();
+      c = xpop();
+      xpush(b);
+      xpush(a);
+      xpush(c);
+      xpush(b);
+      xpush(a);
+      break;
+    case Bytecodes::_dup2_x2:
+      a = xpop();
+      b = xpop();
+      c = xpop();
+      d = xpop();
+      xpush(b);
+      xpush(a);
+      xpush(d);
+      xpush(c);
+      xpush(b);
+      xpush(a);
+      break;
+
+    case Bytecodes::_arraylength:
+      do_arraylength();
+      break;
+
+    case Bytecodes::_getfield:
+      do_getfield();
+      break;
+    case Bytecodes::_getstatic:
+      do_getstatic();
+      break;
+    case Bytecodes::_putfield:
+      do_putfield();
+      break;
+    case Bytecodes::_putstatic:
+      do_putstatic();
+      break;
+
+    case Bytecodes::_iadd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateAdd(a->jint_value(), b->jint_value()), false));
+      break;
+    case Bytecodes::_isub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateSub(a->jint_value(), b->jint_value()), false));
+      break;
+    case Bytecodes::_imul:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateMul(a->jint_value(), b->jint_value()), false));
+      break;
+    case Bytecodes::_idiv:
+      do_idiv();
+      break;
+    case Bytecodes::_irem:
+      do_irem();
+      break;
+    case Bytecodes::_ineg:
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateNeg(a->jint_value()), a->zero_checked()));
+      break;
+    case Bytecodes::_ishl:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateShl(
+          a->jint_value(),
+          builder()->CreateAnd(
+            b->jint_value(), LLVMValue::jint_constant(0x1f))), false));
+      break;
+    case Bytecodes::_ishr:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateAShr(
+          a->jint_value(),
+          builder()->CreateAnd(
+            b->jint_value(), LLVMValue::jint_constant(0x1f))), false));
+      break;
+    case Bytecodes::_iushr:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateLShr(
+          a->jint_value(),
+          builder()->CreateAnd(
+            b->jint_value(), LLVMValue::jint_constant(0x1f))), false));
+      break;
+    case Bytecodes::_iand:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateAnd(a->jint_value(), b->jint_value()), false));
+      break;
+    case Bytecodes::_ior:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateOr(a->jint_value(), b->jint_value()),
+        a->zero_checked() && b->zero_checked()));
+      break;
+    case Bytecodes::_ixor:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateXor(a->jint_value(), b->jint_value()), false));
+      break;
+
+    case Bytecodes::_ladd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateAdd(a->jlong_value(), b->jlong_value()), false));
+      break;
+    case Bytecodes::_lsub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateSub(a->jlong_value(), b->jlong_value()), false));
+      break;
+    case Bytecodes::_lmul:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateMul(a->jlong_value(), b->jlong_value()), false));
+      break;
+    case Bytecodes::_ldiv:
+      do_ldiv();
+      break;
+    case Bytecodes::_lrem:
+      do_lrem();
+      break;
+    case Bytecodes::_lneg:
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateNeg(a->jlong_value()), a->zero_checked()));
+      break;
+    case Bytecodes::_lshl:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateShl(
+          a->jlong_value(),
+          builder()->CreateIntCast(
+            builder()->CreateAnd(
+              b->jint_value(), LLVMValue::jint_constant(0x3f)),
+            SharkType::jlong_type(), true)), false));
+      break;
+    case Bytecodes::_lshr:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateAShr(
+          a->jlong_value(),
+          builder()->CreateIntCast(
+            builder()->CreateAnd(
+              b->jint_value(), LLVMValue::jint_constant(0x3f)),
+            SharkType::jlong_type(), true)), false));
+      break;
+    case Bytecodes::_lushr:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateLShr(
+          a->jlong_value(),
+          builder()->CreateIntCast(
+            builder()->CreateAnd(
+              b->jint_value(), LLVMValue::jint_constant(0x3f)),
+            SharkType::jlong_type(), true)), false));
+      break;
+    case Bytecodes::_land:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateAnd(a->jlong_value(), b->jlong_value()), false));
+      break;
+    case Bytecodes::_lor:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateOr(a->jlong_value(), b->jlong_value()),
+        a->zero_checked() && b->zero_checked()));
+      break;
+    case Bytecodes::_lxor:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateXor(a->jlong_value(), b->jlong_value()), false));
+      break;
+
+    case Bytecodes::_fadd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFAdd(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fsub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFSub(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fmul:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFMul(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fdiv:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFDiv(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_frem:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFRem(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fneg:
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateFNeg(a->jfloat_value())));
+      break;
+
+    case Bytecodes::_dadd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFAdd(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_dsub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFSub(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_dmul:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFMul(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_ddiv:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFDiv(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_drem:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFRem(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_dneg:
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateFNeg(a->jdouble_value())));
+      break;
+
+    case Bytecodes::_iinc:
+      i = iter()->get_index();
+      set_local(
+        i,
+        SharkValue::create_jint(
+          builder()->CreateAdd(
+            LLVMValue::jint_constant(iter()->get_iinc_con()),
+            local(i)->jint_value()), false));
+      break;
+
+    case Bytecodes::_lcmp:
+      do_lcmp();
+      break;
+
+    case Bytecodes::_fcmpl:
+      do_fcmp(false, false);
+      break;
+    case Bytecodes::_fcmpg:
+      do_fcmp(false, true);
+      break;
+    case Bytecodes::_dcmpl:
+      do_fcmp(true, false);
+      break;
+    case Bytecodes::_dcmpg:
+      do_fcmp(true, true);
+      break;
+
+    case Bytecodes::_i2l:
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateIntCast(
+          a->jint_value(), SharkType::jlong_type(), true), a->zero_checked()));
+      break;
+    case Bytecodes::_i2f:
+      push(SharkValue::create_jfloat(
+        builder()->CreateSIToFP(
+          pop()->jint_value(), SharkType::jfloat_type())));
+      break;
+    case Bytecodes::_i2d:
+      push(SharkValue::create_jdouble(
+        builder()->CreateSIToFP(
+          pop()->jint_value(), SharkType::jdouble_type())));
+      break;
+
+    case Bytecodes::_l2i:
+      push(SharkValue::create_jint(
+        builder()->CreateIntCast(
+          pop()->jlong_value(), SharkType::jint_type(), true), false));
+      break;
+    case Bytecodes::_l2f:
+      push(SharkValue::create_jfloat(
+        builder()->CreateSIToFP(
+          pop()->jlong_value(), SharkType::jfloat_type())));
+      break;
+    case Bytecodes::_l2d:
+      push(SharkValue::create_jdouble(
+        builder()->CreateSIToFP(
+          pop()->jlong_value(), SharkType::jdouble_type())));
+      break;
+
+    case Bytecodes::_f2i:
+      push(SharkValue::create_jint(
+        builder()->CreateCall(
+          builder()->f2i(), pop()->jfloat_value()), false));
+      break;
+    case Bytecodes::_f2l:
+      push(SharkValue::create_jlong(
+        builder()->CreateCall(
+          builder()->f2l(), pop()->jfloat_value()), false));
+      break;
+    case Bytecodes::_f2d:
+      push(SharkValue::create_jdouble(
+        builder()->CreateFPExt(
+          pop()->jfloat_value(), SharkType::jdouble_type())));
+      break;
+
+    case Bytecodes::_d2i:
+      push(SharkValue::create_jint(
+        builder()->CreateCall(
+          builder()->d2i(), pop()->jdouble_value()), false));
+      break;
+    case Bytecodes::_d2l:
+      push(SharkValue::create_jlong(
+        builder()->CreateCall(
+          builder()->d2l(), pop()->jdouble_value()), false));
+      break;
+    case Bytecodes::_d2f:
+      push(SharkValue::create_jfloat(
+        builder()->CreateFPTrunc(
+          pop()->jdouble_value(), SharkType::jfloat_type())));
+      break;
+
+    case Bytecodes::_i2b:
+      push(SharkValue::create_jint(
+        builder()->CreateAShr(
+          builder()->CreateShl(
+            pop()->jint_value(),
+            LLVMValue::jint_constant(24)),
+          LLVMValue::jint_constant(24)), false));
+      break;
+    case Bytecodes::_i2c:
+      push(SharkValue::create_jint(
+        builder()->CreateAnd(
+            pop()->jint_value(),
+            LLVMValue::jint_constant(0xffff)), false));
+      break;
+    case Bytecodes::_i2s:
+      push(SharkValue::create_jint(
+        builder()->CreateAShr(
+          builder()->CreateShl(
+            pop()->jint_value(),
+            LLVMValue::jint_constant(16)),
+          LLVMValue::jint_constant(16)), false));
+      break;
+
+    case Bytecodes::_return:
+      do_return(T_VOID);
+      break;
+    case Bytecodes::_ireturn:
+      do_return(T_INT);
+      break;
+    case Bytecodes::_lreturn:
+      do_return(T_LONG);
+      break;
+    case Bytecodes::_freturn:
+      do_return(T_FLOAT);
+      break;
+    case Bytecodes::_dreturn:
+      do_return(T_DOUBLE);
+      break;
+    case Bytecodes::_areturn:
+      do_return(T_OBJECT);
+      break;
+
+    case Bytecodes::_athrow:
+      do_athrow();
+      break;
+
+    case Bytecodes::_goto:
+    case Bytecodes::_goto_w:
+      do_goto();
+      break;
+
+    case Bytecodes::_jsr:
+    case Bytecodes::_jsr_w:
+      do_jsr();
+      break;
+
+    case Bytecodes::_ret:
+      do_ret();
+      break;
+
+    case Bytecodes::_ifnull:
+      do_if(ICmpInst::ICMP_EQ, SharkValue::null(), pop());
+      break;
+    case Bytecodes::_ifnonnull:
+      do_if(ICmpInst::ICMP_NE, SharkValue::null(), pop());
+      break;
+    case Bytecodes::_if_acmpeq:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_EQ, b, a);
+      break;
+    case Bytecodes::_if_acmpne:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_NE, b, a);
+      break;
+    case Bytecodes::_ifeq:
+      do_if(ICmpInst::ICMP_EQ, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_ifne:
+      do_if(ICmpInst::ICMP_NE, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_iflt:
+      do_if(ICmpInst::ICMP_SLT, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_ifle:
+      do_if(ICmpInst::ICMP_SLE, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_ifgt:
+      do_if(ICmpInst::ICMP_SGT, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_ifge:
+      do_if(ICmpInst::ICMP_SGE, SharkValue::jint_constant(0), pop());
+      break;
+    case Bytecodes::_if_icmpeq:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_EQ, b, a);
+      break;
+    case Bytecodes::_if_icmpne:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_NE, b, a);
+      break;
+    case Bytecodes::_if_icmplt:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_SLT, b, a);
+      break;
+    case Bytecodes::_if_icmple:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_SLE, b, a);
+      break;
+    case Bytecodes::_if_icmpgt:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_SGT, b, a);
+      break;
+    case Bytecodes::_if_icmpge:
+      b = pop();
+      a = pop();
+      do_if(ICmpInst::ICMP_SGE, b, a);
+      break;
+
+    case Bytecodes::_tableswitch:
+    case Bytecodes::_lookupswitch:
+      do_switch();
+      break;
+
+    case Bytecodes::_invokestatic:
+    case Bytecodes::_invokespecial:
+    case Bytecodes::_invokevirtual:
+    case Bytecodes::_invokeinterface:
+      do_call();
+      break;
+
+    case Bytecodes::_instanceof:
+      // This is a very common construct:
+      //
+      //  if (object instanceof Klass) {
+      //    something = (Klass) object;
+      //    ...
+      //  }
+      //
+      // which gets compiled to something like this:
+      //
+      //  28: aload 9
+      //  30: instanceof <Class Klass>
+      //  33: ifeq 52
+      //  36: aload 9
+      //  38: checkcast <Class Klass>
+      //
+      // Handling both bytecodes at once allows us
+      // to eliminate the checkcast.
+      if (iter()->next_bci() < limit &&
+          (iter()->next_bc() == Bytecodes::_ifeq ||
+           iter()->next_bc() == Bytecodes::_ifne) &&
+          (!UseLoopSafepoints ||
+           iter()->next_get_dest() > iter()->next_bci())) {
+        if (maybe_do_instanceof_if()) {
+          iter()->next();
+          if (SharkTraceBytecodes)
+            tty->print_cr("%4d: %s", bci(), Bytecodes::name(bc()));
+          break;
+        }
+      }
+      // fall through
+    case Bytecodes::_checkcast:
+      do_instance_check();
+      break;
+
+    case Bytecodes::_new:
+      do_new();
+      break;
+    case Bytecodes::_newarray:
+      do_newarray();
+      break;
+    case Bytecodes::_anewarray:
+      do_anewarray();
+      break;
+    case Bytecodes::_multianewarray:
+      do_multianewarray();
+      break;
+
+    case Bytecodes::_monitorenter:
+      do_monitorenter();
+      break;
+    case Bytecodes::_monitorexit:
+      do_monitorexit();
+      break;
+
+    default:
+      ShouldNotReachHere();
+    }
+  }
+}
+
+SharkState* SharkBlock::initial_current_state() {
+  return entry_state()->copy();
+}
+
+int SharkBlock::switch_default_dest() {
+  return iter()->get_dest_table(0);
+}
+
+int SharkBlock::switch_table_length() {
+  switch(bc()) {
+  case Bytecodes::_tableswitch:
+    return iter()->get_int_table(2) - iter()->get_int_table(1) + 1;
+
+  case Bytecodes::_lookupswitch:
+    return iter()->get_int_table(1);
+
+  default:
+    ShouldNotReachHere();
+  }
+}
+
+int SharkBlock::switch_key(int i) {
+  switch(bc()) {
+  case Bytecodes::_tableswitch:
+    return iter()->get_int_table(1) + i;
+
+  case Bytecodes::_lookupswitch:
+    return iter()->get_int_table(2 + 2 * i);
+
+  default:
+    ShouldNotReachHere();
+  }
+}
+
+int SharkBlock::switch_dest(int i) {
+  switch(bc()) {
+  case Bytecodes::_tableswitch:
+    return iter()->get_dest_table(i + 3);
+
+  case Bytecodes::_lookupswitch:
+    return iter()->get_dest_table(2 + 2 * i + 1);
+
+  default:
+    ShouldNotReachHere();
+  }
+}
+
+void SharkBlock::do_div_or_rem(bool is_long, bool is_rem) {
+  SharkValue *sb = pop();
+  SharkValue *sa = pop();
+
+  check_divide_by_zero(sb);
+
+  Value *a, *b, *p, *q;
+  if (is_long) {
+    a = sa->jlong_value();
+    b = sb->jlong_value();
+    p = LLVMValue::jlong_constant(0x8000000000000000LL);
+    q = LLVMValue::jlong_constant(-1);
+  }
+  else {
+    a = sa->jint_value();
+    b = sb->jint_value();
+    p = LLVMValue::jint_constant(0x80000000);
+    q = LLVMValue::jint_constant(-1);
+  }
+
+  BasicBlock *ip           = builder()->GetBlockInsertionPoint();
+  BasicBlock *special_case = builder()->CreateBlock(ip, "special_case");
+  BasicBlock *general_case = builder()->CreateBlock(ip, "general_case");
+  BasicBlock *done         = builder()->CreateBlock(ip, "done");
+
+  builder()->CreateCondBr(
+    builder()->CreateAnd(
+      builder()->CreateICmpEQ(a, p),
+      builder()->CreateICmpEQ(b, q)),
+    special_case, general_case);
+
+  builder()->SetInsertPoint(special_case);
+  Value *special_result;
+  if (is_rem) {
+    if (is_long)
+      special_result = LLVMValue::jlong_constant(0);
+    else
+      special_result = LLVMValue::jint_constant(0);
+  }
+  else {
+    special_result = a;
+  }
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(general_case);
+  Value *general_result;
+  if (is_rem)
+    general_result = builder()->CreateSRem(a, b);
+  else
+    general_result = builder()->CreateSDiv(a, b);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  PHINode *result;
+  if (is_long)
+    result = builder()->CreatePHI(SharkType::jlong_type(), "result");
+  else
+    result = builder()->CreatePHI(SharkType::jint_type(), "result");
+  result->addIncoming(special_result, special_case);
+  result->addIncoming(general_result, general_case);
+
+  if (is_long)
+    push(SharkValue::create_jlong(result, false));
+  else
+    push(SharkValue::create_jint(result, false));
+}
+
+void SharkBlock::do_field_access(bool is_get, bool is_field) {
+  bool will_link;
+  ciField *field = iter()->get_field(will_link);
+  assert(will_link, "typeflow responsibility");
+  assert(is_field != field->is_static(), "mismatch");
+
+  // Pop the value off the stack where necessary
+  SharkValue *value = NULL;
+  if (!is_get)
+    value = pop();
+
+  // Find the object we're accessing, if necessary
+  Value *object = NULL;
+  if (is_field) {
+    SharkValue *value = pop();
+    check_null(value);
+    object = value->generic_value();
+  }
+  if (is_get && field->is_constant()) {
+    SharkConstant *constant = SharkConstant::for_field(iter());
+    if (constant->is_loaded())
+      value = constant->value(builder());
+  }
+  if (!is_get || value == NULL) {
+    if (!is_field)
+      object = builder()->CreateInlineOop(field->holder());
+
+    BasicType   basic_type = field->type()->basic_type();
+    const Type *stack_type = SharkType::to_stackType(basic_type);
+    const Type *field_type = SharkType::to_arrayType(basic_type);
+
+    Value *addr = builder()->CreateAddressOfStructEntry(
+      object, in_ByteSize(field->offset_in_bytes()),
+      PointerType::getUnqual(field_type),
+      "addr");
+
+    // Do the access
+    if (is_get) {
+      Value *field_value = builder()->CreateLoad(addr);
+
+      if (field_type != stack_type) {
+        field_value = builder()->CreateIntCast(
+          field_value, stack_type, basic_type != T_CHAR);
+      }
+
+      value = SharkValue::create_generic(field->type(), field_value, false);
+    }
+    else {
+      Value *field_value = value->generic_value();
+
+      if (field_type != stack_type) {
+        field_value = builder()->CreateIntCast(
+          field_value, field_type, basic_type != T_CHAR);
+      }
+
+      builder()->CreateStore(field_value, addr);
+
+      if (!field->type()->is_primitive_type())
+        builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr);
+
+      if (field->is_volatile())
+        builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD);
+    }
+  }
+
+  // Push the value onto the stack where necessary
+  if (is_get)
+    push(value);
+}
+
+void SharkBlock::do_lcmp() {
+  Value *b = pop()->jlong_value();
+  Value *a = pop()->jlong_value();
+
+  BasicBlock *ip   = builder()->GetBlockInsertionPoint();
+  BasicBlock *ne   = builder()->CreateBlock(ip, "lcmp_ne");
+  BasicBlock *lt   = builder()->CreateBlock(ip, "lcmp_lt");
+  BasicBlock *gt   = builder()->CreateBlock(ip, "lcmp_gt");
+  BasicBlock *done = builder()->CreateBlock(ip, "done");
+
+  BasicBlock *eq = builder()->GetInsertBlock();
+  builder()->CreateCondBr(builder()->CreateICmpEQ(a, b), done, ne);
+
+  builder()->SetInsertPoint(ne);
+  builder()->CreateCondBr(builder()->CreateICmpSLT(a, b), lt, gt);
+
+  builder()->SetInsertPoint(lt);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(gt);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  PHINode *result = builder()->CreatePHI(SharkType::jint_type(), "result");
+  result->addIncoming(LLVMValue::jint_constant(-1), lt);
+  result->addIncoming(LLVMValue::jint_constant(0),  eq);
+  result->addIncoming(LLVMValue::jint_constant(1),  gt);
+
+  push(SharkValue::create_jint(result, false));
+}
+
+void SharkBlock::do_fcmp(bool is_double, bool unordered_is_greater) {
+  Value *a, *b;
+  if (is_double) {
+    b = pop()->jdouble_value();
+    a = pop()->jdouble_value();
+  }
+  else {
+    b = pop()->jfloat_value();
+    a = pop()->jfloat_value();
+  }
+
+  BasicBlock *ip      = builder()->GetBlockInsertionPoint();
+  BasicBlock *ordered = builder()->CreateBlock(ip, "ordered");
+  BasicBlock *ge      = builder()->CreateBlock(ip, "fcmp_ge");
+  BasicBlock *lt      = builder()->CreateBlock(ip, "fcmp_lt");
+  BasicBlock *eq      = builder()->CreateBlock(ip, "fcmp_eq");
+  BasicBlock *gt      = builder()->CreateBlock(ip, "fcmp_gt");
+  BasicBlock *done    = builder()->CreateBlock(ip, "done");
+
+  builder()->CreateCondBr(
+    builder()->CreateFCmpUNO(a, b),
+    unordered_is_greater ? gt : lt, ordered);
+
+  builder()->SetInsertPoint(ordered);
+  builder()->CreateCondBr(builder()->CreateFCmpULT(a, b), lt, ge);
+
+  builder()->SetInsertPoint(ge);
+  builder()->CreateCondBr(builder()->CreateFCmpUGT(a, b), gt, eq);
+
+  builder()->SetInsertPoint(lt);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(gt);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(eq);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  PHINode *result = builder()->CreatePHI(SharkType::jint_type(), "result");
+  result->addIncoming(LLVMValue::jint_constant(-1), lt);
+  result->addIncoming(LLVMValue::jint_constant(0),  eq);
+  result->addIncoming(LLVMValue::jint_constant(1),  gt);
+
+  push(SharkValue::create_jint(result, false));
+}
+
+void SharkBlock::emit_IR() {
+  ShouldNotCallThis();
+}
+
+SharkState* SharkBlock::entry_state() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_zero_check(SharkValue* value) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::maybe_add_backedge_safepoint() {
+  ShouldNotCallThis();
+}
+
+bool SharkBlock::has_trap() {
+  return false;
+}
+
+int SharkBlock::trap_request() {
+  ShouldNotCallThis();
+}
+
+int SharkBlock::trap_bci() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_trap(int trap_request) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_arraylength() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_aload(BasicType basic_type) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_astore(BasicType basic_type) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_return(BasicType type) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_athrow() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_goto() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_jsr() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_ret() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_if(ICmpInst::Predicate p, SharkValue* b, SharkValue* a) {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_switch() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_call() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_instance_check() {
+  ShouldNotCallThis();
+}
+
+bool SharkBlock::maybe_do_instanceof_if() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_new() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_newarray() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_anewarray() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_multianewarray() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_monitorenter() {
+  ShouldNotCallThis();
+}
+
+void SharkBlock::do_monitorexit() {
+  ShouldNotCallThis();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkBlock.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,281 @@
+/*
+ * 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();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkBuilder.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,591 @@
+/*
+ * 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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkBuilder.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,209 @@
+/*
+ * 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;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkCacheDecache.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,259 @@
+/*
+ * 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));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkCacheDecache.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,417 @@
+/*
+ * 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);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,87 @@
+/*
+ * 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;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkCompiler.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,340 @@
+/*
+ * 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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkCompiler.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,119 @@
+/*
+ * 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();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkConstant.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,128 @@
+/*
+ * 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;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkConstant.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,64 @@
+/*
+ * 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 SharkConstant : public ResourceObj {
+ public:
+  static SharkConstant* for_ldc(ciBytecodeStream* iter);
+  static SharkConstant* for_field(ciBytecodeStream* iter);
+
+ private:
+  SharkConstant(ciConstant constant, ciType* type);
+
+ private:
+  SharkValue* _value;
+  ciObject*   _object;
+  ciType*     _type;
+  bool        _is_loaded;
+  bool        _is_nonzero;
+  bool        _is_two_word;
+
+ public:
+  bool is_loaded() const {
+    return _is_loaded;
+  }
+  bool is_nonzero() const {
+    assert(is_loaded(), "should be");
+    return _is_nonzero;
+  }
+  bool is_two_word() const {
+    assert(is_loaded(), "should be");
+    return _is_two_word;
+  }
+
+ public:
+  SharkValue* value(SharkBuilder* builder) {
+    assert(is_loaded(), "should be");
+    if (_value == NULL) {
+      _value = SharkValue::create_generic(
+        _type, builder->CreateInlineOop(_object), _is_nonzero);
+    }
+    return _value;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkContext.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkContext.cpp.incl"
+
+using namespace llvm;
+
+SharkContext::SharkContext(const char* name)
+  : LLVMContext(),
+    _free_queue(NULL) {
+  // Create a module to build our functions into
+  _module = new Module(name, *this);
+
+  // Create basic types
+  _void_type    = Type::getVoidTy(*this);
+  _bit_type     = Type::getInt1Ty(*this);
+  _jbyte_type   = Type::getInt8Ty(*this);
+  _jshort_type  = Type::getInt16Ty(*this);
+  _jint_type    = Type::getInt32Ty(*this);
+  _jlong_type   = Type::getInt64Ty(*this);
+  _jfloat_type  = Type::getFloatTy(*this);
+  _jdouble_type = Type::getDoubleTy(*this);
+
+  // Create compound types
+  _itableOffsetEntry_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), itableOffsetEntry::size() * wordSize));
+
+  _klass_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(Klass)));
+
+  _jniEnv_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(JNIEnv)));
+
+  _jniHandleBlock_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(JNIHandleBlock)));
+
+  _methodOop_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(methodOopDesc)));
+
+  _monitor_type = ArrayType::get(
+    jbyte_type(), frame::interpreter_frame_monitor_size() * wordSize);
+
+  _oop_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(oopDesc)));
+
+  _thread_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(JavaThread)));
+
+  _zeroStack_type = PointerType::getUnqual(
+    ArrayType::get(jbyte_type(), sizeof(ZeroStack)));
+
+  std::vector<const Type*> params;
+  params.push_back(methodOop_type());
+  params.push_back(intptr_type());
+  params.push_back(thread_type());
+  _entry_point_type = FunctionType::get(jint_type(), params, false);
+
+  params.clear();
+  params.push_back(methodOop_type());
+  params.push_back(PointerType::getUnqual(jbyte_type()));
+  params.push_back(intptr_type());
+  params.push_back(thread_type());
+  _osr_entry_point_type = FunctionType::get(jint_type(), params, false);
+
+  // Create mappings
+  for (int i = 0; i < T_CONFLICT; i++) {
+    switch (i) {
+    case T_BOOLEAN:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jbyte_type();
+      break;
+
+    case T_BYTE:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jbyte_type();
+      break;
+
+    case T_CHAR:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jshort_type();
+      break;
+
+    case T_SHORT:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jshort_type();
+      break;
+
+    case T_INT:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jint_type();
+      break;
+
+    case T_LONG:
+      _to_stackType[i] = jlong_type();
+      _to_arrayType[i] = jlong_type();
+      break;
+
+    case T_FLOAT:
+      _to_stackType[i] = jfloat_type();
+      _to_arrayType[i] = jfloat_type();
+      break;
+
+    case T_DOUBLE:
+      _to_stackType[i] = jdouble_type();
+      _to_arrayType[i] = jdouble_type();
+      break;
+
+    case T_OBJECT:
+    case T_ARRAY:
+      _to_stackType[i] = oop_type();
+      _to_arrayType[i] = oop_type();
+      break;
+
+    case T_ADDRESS:
+      _to_stackType[i] = intptr_type();
+      _to_arrayType[i] = NULL;
+      break;
+
+    default:
+      _to_stackType[i] = NULL;
+      _to_arrayType[i] = NULL;
+    }
+  }
+}
+
+class SharkFreeQueueItem : public CHeapObj {
+ public:
+  SharkFreeQueueItem(llvm::Function* function, SharkFreeQueueItem *next)
+    : _function(function), _next(next) {}
+
+ private:
+  llvm::Function*     _function;
+  SharkFreeQueueItem* _next;
+
+ public:
+  llvm::Function* function() const {
+    return _function;
+  }
+  SharkFreeQueueItem* next() const {
+    return _next;
+  }
+};
+
+void SharkContext::push_to_free_queue(Function* function) {
+  _free_queue = new SharkFreeQueueItem(function, _free_queue);
+}
+
+Function* SharkContext::pop_from_free_queue() {
+  if (_free_queue == NULL)
+    return NULL;
+
+  SharkFreeQueueItem *item = _free_queue;
+  Function *function = item->function();
+  _free_queue = item->next();
+  delete item;
+  return function;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkContext.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+// The LLVMContext class allows multiple instances of LLVM to operate
+// independently of each other in a multithreaded context.  We extend
+// this here to store things in Shark that are LLVMContext-specific.
+
+class SharkFreeQueueItem;
+
+class SharkContext : public llvm::LLVMContext {
+ public:
+  SharkContext(const char* name);
+
+ private:
+  llvm::Module* _module;
+
+#if SHARK_LLVM_VERSION >= 27
+ public:
+#else
+ private:
+#endif
+  llvm::Module* module() const {
+    return _module;
+  }
+
+  // Get this thread's SharkContext
+ public:
+  static SharkContext& current() {
+    return *SharkCompiler::compiler()->context();
+  }
+
+  // Module accessors
+ public:
+#if SHARK_LLVM_VERSION < 27
+  llvm::ModuleProvider* module_provider() const {
+    return new llvm::ExistingModuleProvider(module());
+  }
+#endif
+  void add_function(llvm::Function* function) const {
+    module()->getFunctionList().push_back(function);
+  }
+  llvm::Constant* get_external(const char*               name,
+                               const llvm::FunctionType* sig) {
+    return module()->getOrInsertFunction(name, sig);
+  }
+
+  // Basic types
+ private:
+  const llvm::Type*        _void_type;
+  const llvm::IntegerType* _bit_type;
+  const llvm::IntegerType* _jbyte_type;
+  const llvm::IntegerType* _jshort_type;
+  const llvm::IntegerType* _jint_type;
+  const llvm::IntegerType* _jlong_type;
+  const llvm::Type*        _jfloat_type;
+  const llvm::Type*        _jdouble_type;
+
+ public:
+  const llvm::Type* void_type() const {
+    return _void_type;
+  }
+  const llvm::IntegerType* bit_type() const {
+    return _bit_type;
+  }
+  const llvm::IntegerType* jbyte_type() const {
+    return _jbyte_type;
+  }
+  const llvm::IntegerType* jshort_type() const {
+    return _jshort_type;
+  }
+  const llvm::IntegerType* jint_type() const {
+    return _jint_type;
+  }
+  const llvm::IntegerType* jlong_type() const {
+    return _jlong_type;
+  }
+  const llvm::Type* jfloat_type() const {
+    return _jfloat_type;
+  }
+  const llvm::Type* jdouble_type() const {
+    return _jdouble_type;
+  }
+  const llvm::IntegerType* intptr_type() const {
+    return LP64_ONLY(jlong_type()) NOT_LP64(jint_type());
+  }
+
+  // Compound types
+ private:
+  const llvm::PointerType*  _itableOffsetEntry_type;
+  const llvm::PointerType*  _jniEnv_type;
+  const llvm::PointerType*  _jniHandleBlock_type;
+  const llvm::PointerType*  _klass_type;
+  const llvm::PointerType*  _methodOop_type;
+  const llvm::ArrayType*    _monitor_type;
+  const llvm::PointerType*  _oop_type;
+  const llvm::PointerType*  _thread_type;
+  const llvm::PointerType*  _zeroStack_type;
+  const llvm::FunctionType* _entry_point_type;
+  const llvm::FunctionType* _osr_entry_point_type;
+
+ public:
+  const llvm::PointerType* itableOffsetEntry_type() const {
+    return _itableOffsetEntry_type;
+  }
+  const llvm::PointerType* jniEnv_type() const {
+    return _jniEnv_type;
+  }
+  const llvm::PointerType* jniHandleBlock_type() const {
+    return _jniHandleBlock_type;
+  }
+  const llvm::PointerType* klass_type() const {
+    return _klass_type;
+  }
+  const llvm::PointerType* methodOop_type() const {
+    return _methodOop_type;
+  }
+  const llvm::ArrayType* monitor_type() const {
+    return _monitor_type;
+  }
+  const llvm::PointerType* oop_type() const {
+    return _oop_type;
+  }
+  const llvm::PointerType* thread_type() const {
+    return _thread_type;
+  }
+  const llvm::PointerType* zeroStack_type() const {
+    return _zeroStack_type;
+  }
+  const llvm::FunctionType* entry_point_type() const {
+    return _entry_point_type;
+  }
+  const llvm::FunctionType* osr_entry_point_type() const {
+    return _osr_entry_point_type;
+  }
+
+  // Mappings
+ private:
+  const llvm::Type* _to_stackType[T_CONFLICT];
+  const llvm::Type* _to_arrayType[T_CONFLICT];
+
+ private:
+  const llvm::Type* map_type(const llvm::Type* const* table,
+                             BasicType                type) const {
+    assert(type >= 0 && type < T_CONFLICT, "unhandled type");
+    const llvm::Type* result = table[type];
+    assert(type != NULL, "unhandled type");
+    return result;
+  }
+
+ public:
+  const llvm::Type* to_stackType(BasicType type) const {
+    return map_type(_to_stackType, type);
+  }
+  const llvm::Type* to_arrayType(BasicType type) const {
+    return map_type(_to_arrayType, type);
+  }
+
+  // Functions queued for freeing
+ private:
+  SharkFreeQueueItem* _free_queue;
+
+ public:
+  void push_to_free_queue(llvm::Function* function);
+  llvm::Function* pop_from_free_queue();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkEntry.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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;
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkFunction.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,188 @@
+/*
+ * 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/_sharkFunction.cpp.incl"
+
+using namespace llvm;
+
+void SharkFunction::initialize(const char *name) {
+  // Create the function
+  _function = Function::Create(
+    entry_point_type(),
+    GlobalVariable::InternalLinkage,
+    name);
+
+  // Get our arguments
+  Function::arg_iterator ai = function()->arg_begin();
+  Argument *method = ai++;
+  method->setName("method");
+  Argument *osr_buf = NULL;
+  if (is_osr()) {
+    osr_buf = ai++;
+    osr_buf->setName("osr_buf");
+  }
+  Argument *base_pc = ai++;
+  base_pc->setName("base_pc");
+  code_buffer()->set_base_pc(base_pc);
+  Argument *thread = ai++;
+  thread->setName("thread");
+  set_thread(thread);
+
+  // Create the list of blocks
+  set_block_insertion_point(NULL);
+  _blocks = NEW_RESOURCE_ARRAY(SharkTopLevelBlock*, block_count());
+  for (int i = 0; i < block_count(); i++) {
+    ciTypeFlow::Block *b = flow()->pre_order_at(i);
+
+    // Work around a bug in pre_order_at() that does not return
+    // the correct pre-ordering.  If pre_order_at() were correct
+    // this line could simply be:
+    // _blocks[i] = new SharkTopLevelBlock(this, b);
+    _blocks[b->pre_order()] = new SharkTopLevelBlock(this, b);
+  }
+
+  // Walk the tree from the start block to determine which
+  // blocks are entered and which blocks require phis
+  SharkTopLevelBlock *start_block = block(flow()->start_block_num());
+  assert(start_block->start() == flow()->start_bci(), "blocks out of order");
+  start_block->enter();
+
+  // Initialize all entered blocks
+  for (int i = 0; i < block_count(); i++) {
+    if (block(i)->entered())
+      block(i)->initialize();
+  }
+
+  // Create and push our stack frame
+  set_block_insertion_point(&function()->front());
+  builder()->SetInsertPoint(CreateBlock());
+  _stack = SharkStack::CreateBuildAndPushFrame(this, method);
+
+  // Create the entry state
+  SharkState *entry_state;
+  if (is_osr()) {
+    entry_state = new SharkOSREntryState(start_block, method, osr_buf);
+
+    // Free the OSR buffer
+    builder()->CreateCall(builder()->osr_migration_end(), osr_buf);
+  }
+  else {
+    entry_state = new SharkNormalEntryState(start_block, method);
+
+    // Lock if necessary
+    if (is_synchronized()) {
+      SharkTopLevelBlock *locker =
+        new SharkTopLevelBlock(this, start_block->ciblock());
+      locker->add_incoming(entry_state);
+
+      set_block_insertion_point(start_block->entry_block());
+      locker->acquire_method_lock();
+
+      entry_state = locker->current_state();
+    }
+  }
+
+  // Transition into the method proper
+  start_block->add_incoming(entry_state);
+  builder()->CreateBr(start_block->entry_block());
+
+  // Parse the blocks
+  for (int i = 0; i < block_count(); i++) {
+    if (!block(i)->entered())
+      continue;
+
+    if (i + 1 < block_count())
+      set_block_insertion_point(block(i + 1)->entry_block());
+    else
+      set_block_insertion_point(NULL);
+
+    block(i)->emit_IR();
+  }
+  do_deferred_zero_checks();
+}
+
+class DeferredZeroCheck : public SharkTargetInvariants {
+ public:
+  DeferredZeroCheck(SharkTopLevelBlock* block, SharkValue* value)
+    : SharkTargetInvariants(block),
+      _block(block),
+      _value(value),
+      _bci(block->bci()),
+      _state(block->current_state()->copy()),
+      _check_block(builder()->GetInsertBlock()),
+      _continue_block(function()->CreateBlock("not_zero")) {
+    builder()->SetInsertPoint(continue_block());
+  }
+
+ private:
+  SharkTopLevelBlock* _block;
+  SharkValue*         _value;
+  int                 _bci;
+  SharkState*         _state;
+  BasicBlock*         _check_block;
+  BasicBlock*         _continue_block;
+
+ public:
+  SharkTopLevelBlock* block() const {
+    return _block;
+  }
+  SharkValue* value() const {
+    return _value;
+  }
+  int bci() const {
+    return _bci;
+  }
+  SharkState* state() const {
+    return _state;
+  }
+  BasicBlock* check_block() const {
+    return _check_block;
+  }
+  BasicBlock* continue_block() const {
+    return _continue_block;
+  }
+
+ public:
+  SharkFunction* function() const {
+    return block()->function();
+  }
+
+ public:
+  void process() const {
+    builder()->SetInsertPoint(check_block());
+    block()->do_deferred_zero_check(value(), bci(), state(), continue_block());
+  }
+};
+
+void SharkFunction::add_deferred_zero_check(SharkTopLevelBlock* block,
+                                            SharkValue*         value) {
+  deferred_zero_checks()->append(new DeferredZeroCheck(block, value));
+}
+
+void SharkFunction::do_deferred_zero_checks() {
+  for (int i = 0; i < deferred_zero_checks()->length(); i++)
+    deferred_zero_checks()->at(i)->process();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkFunction.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,111 @@
+/*
+ * 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 SharkTopLevelBlock;
+class DeferredZeroCheck;
+
+class SharkFunction : public SharkTargetInvariants {
+ friend class SharkStackWithNormalFrame;
+
+ public:
+  static llvm::Function* build(ciEnv*        env,
+                               SharkBuilder* builder,
+                               ciTypeFlow*   flow,
+                               const char*   name) {
+    SharkFunction function(env, builder, flow, name);
+    return function.function();
+  }
+
+ private:
+  SharkFunction(ciEnv*        env,
+                SharkBuilder* builder,
+                ciTypeFlow*   flow,
+                const char*   name)
+    : SharkTargetInvariants(env, builder, flow) { initialize(name); }
+
+ private:
+  void initialize(const char* name);
+
+ private:
+  llvm::Function*                   _function;
+  SharkTopLevelBlock**              _blocks;
+  GrowableArray<DeferredZeroCheck*> _deferred_zero_checks;
+  SharkStack*                       _stack;
+
+ public:
+  llvm::Function* function() const {
+    return _function;
+  }
+  int block_count() const {
+    return flow()->block_count();
+  }
+  SharkTopLevelBlock* block(int i) const {
+    assert(i < block_count(), "should be");
+    return _blocks[i];
+  }
+  GrowableArray<DeferredZeroCheck*>* deferred_zero_checks() {
+    return &_deferred_zero_checks;
+  }
+  SharkStack* stack() const {
+    return _stack;
+  }
+
+  // On-stack replacement
+ private:
+  bool is_osr() const {
+    return flow()->is_osr_flow();
+  }
+  const llvm::FunctionType* entry_point_type() const {
+    if (is_osr())
+      return SharkType::osr_entry_point_type();
+    else
+      return SharkType::entry_point_type();
+  }
+
+  // Block management
+ private:
+  llvm::BasicBlock* _block_insertion_point;
+
+  void set_block_insertion_point(llvm::BasicBlock* block_insertion_point) {
+    _block_insertion_point = block_insertion_point;
+  }
+  llvm::BasicBlock* block_insertion_point() const {
+    return _block_insertion_point;
+  }
+
+ public:
+  llvm::BasicBlock* CreateBlock(const char* name = "") const {
+    return llvm::BasicBlock::Create(
+      SharkContext::current(), name, function(), block_insertion_point());
+  }
+
+  // Deferred zero checks
+ public:
+  void add_deferred_zero_check(SharkTopLevelBlock* block,
+                               SharkValue*         value);
+
+ private:
+  void do_deferred_zero_checks();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkInliner.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,749 @@
+/*
+ * 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/_sharkInliner.cpp.incl"
+
+using namespace llvm;
+
+class SharkInlineBlock : public SharkBlock {
+ public:
+  SharkInlineBlock(ciMethod* target, SharkState* state)
+    : SharkBlock(state, target),
+      _outer_state(state),
+      _entry_state(new SharkState(this)) {
+    for (int i = target->max_locals() - 1; i >= 0; i--) {
+      SharkValue *value = NULL;
+      if (i < target->arg_size())
+        value = outer_state()->pop();
+      entry_state()->set_local(i, value);
+    }
+  }
+
+ private:
+  SharkState* _outer_state;
+  SharkState* _entry_state;
+
+ private:
+  SharkState* outer_state() {
+    return _outer_state;
+  }
+  SharkState* entry_state() {
+    return _entry_state;
+  }
+
+ public:
+  void emit_IR() {
+    parse_bytecode(0, target()->code_size());
+  }
+
+ private:
+  void do_return(BasicType type) {
+    if (type != T_VOID) {
+      SharkValue *result = pop_result(type);
+      outer_state()->push(result);
+      if (result->is_two_word())
+        outer_state()->push(NULL);
+    }
+  }
+};
+
+class SharkInlinerHelper : public StackObj {
+ public:
+  SharkInlinerHelper(ciMethod* target, SharkState* entry_state)
+    : _target(target),
+      _entry_state(entry_state),
+      _iter(target) {}
+
+ private:
+  ciBytecodeStream _iter;
+  SharkState*      _entry_state;
+  ciMethod*        _target;
+
+ public:
+  ciBytecodeStream* iter() {
+    return &_iter;
+  }
+  SharkState* entry_state() const {
+    return _entry_state;
+  }
+  ciMethod* target() const {
+    return _target;
+  }
+
+ public:
+  Bytecodes::Code bc() {
+    return iter()->cur_bc();
+  }
+  int max_locals() const {
+    return target()->max_locals();
+  }
+  int max_stack() const {
+    return target()->max_stack();
+  }
+
+  // Inlinability check
+ public:
+  bool is_inlinable();
+
+ private:
+  void initialize_for_check();
+
+  bool do_getstatic() {
+    return do_field_access(true, false);
+  }
+  bool do_getfield() {
+    return do_field_access(true, true);
+  }
+  bool do_putfield() {
+    return do_field_access(false, true);
+  }
+  bool do_field_access(bool is_get, bool is_field);
+
+  // Local variables for inlinability check
+ private:
+  bool* _locals;
+
+ public:
+  bool* local_addr(int index) const {
+    assert(index >= 0 && index < max_locals(), "bad local variable index");
+    return &_locals[index];
+  }
+  bool local(int index) const {
+    return *local_addr(index);
+  }
+  void set_local(int index, bool value) {
+    *local_addr(index) = value;
+  }
+
+  // Expression stack for inlinability check
+ private:
+  bool* _stack;
+  bool* _sp;
+
+ public:
+  int stack_depth() const {
+    return _sp - _stack;
+  }
+  bool* stack_addr(int slot) const {
+    assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
+    return &_sp[-(slot + 1)];
+  }
+  void push(bool value) {
+    assert(stack_depth() < max_stack(), "stack overrun");
+    *(_sp++) = value;
+  }
+  bool pop() {
+    assert(stack_depth() > 0, "stack underrun");
+    return *(--_sp);
+  }
+
+  // Methods for two-word locals
+ public:
+  void push_pair_local(int index) {
+    push(local(index));
+    push(local(index + 1));
+  }
+  void pop_pair_local(int index) {
+    set_local(index + 1, pop());
+    set_local(index, pop());
+  }
+
+  // Code generation
+ public:
+  void do_inline() {
+    (new SharkInlineBlock(target(), entry_state()))->emit_IR();
+  }
+};
+
+// Quick checks so we can bail out before doing too much
+bool SharkInliner::may_be_inlinable(ciMethod *target) {
+  // We can't inline native methods
+  if (target->is_native())
+    return false;
+
+  // Not much point inlining abstract ones, and in any
+  // case we'd need a stack frame to throw the exception
+  if (target->is_abstract())
+    return false;
+
+  // Don't inline anything huge
+  if (target->code_size() > SharkMaxInlineSize)
+    return false;
+
+  // Monitors aren't allowed without a frame to put them in
+  if (target->is_synchronized() || target->has_monitor_bytecodes())
+    return false;
+
+  // We don't do control flow
+  if (target->has_exception_handlers() || target->has_jsrs())
+    return false;
+
+  // Don't try to inline constructors, as they must
+  // eventually call Object.<init> which we can't inline.
+  // Note that this catches <clinit> too, but why would
+  // we be compiling that?
+  if (target->is_initializer())
+    return false;
+
+  // Mustn't inline Object.<init>
+  // Should be caught by the above, but just in case...
+  if (target->intrinsic_id() == vmIntrinsics::_Object_init)
+    return false;
+
+  return true;
+}
+
+// Full-on detailed check, for methods that pass the quick checks
+// Inlined methods have no stack frame, so we can't do anything
+// that would require one.  This means no safepoints (and hence
+// no loops) and no VM calls.  No VM calls means, amongst other
+// things, that no exceptions can be created, which means no null
+// checks or divide-by-zero checks are allowed.  The lack of null
+// checks in particular would eliminate practically everything,
+// but we can get around that restriction by relying on the zero-
+// check eliminator to strip the checks.  To do that, we need to
+// walk through the method, tracking which values are and are not
+// zero-checked.
+bool SharkInlinerHelper::is_inlinable() {
+  ResourceMark rm;
+  initialize_for_check();
+
+  SharkConstant *sc;
+  bool a, b, c, d;
+
+  iter()->reset_to_bci(0);
+  while (iter()->next() != ciBytecodeStream::EOBC()) {
+    switch (bc()) {
+    case Bytecodes::_nop:
+      break;
+
+    case Bytecodes::_aconst_null:
+      push(false);
+      break;
+
+    case Bytecodes::_iconst_0:
+      push(false);
+      break;
+    case Bytecodes::_iconst_m1:
+    case Bytecodes::_iconst_1:
+    case Bytecodes::_iconst_2:
+    case Bytecodes::_iconst_3:
+    case Bytecodes::_iconst_4:
+    case Bytecodes::_iconst_5:
+      push(true);
+      break;
+
+    case Bytecodes::_lconst_0:
+      push(false);
+      push(false);
+      break;
+    case Bytecodes::_lconst_1:
+      push(true);
+      push(false);
+      break;
+
+    case Bytecodes::_fconst_0:
+    case Bytecodes::_fconst_1:
+    case Bytecodes::_fconst_2:
+      push(false);
+      break;
+
+    case Bytecodes::_dconst_0:
+    case Bytecodes::_dconst_1:
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_bipush:
+      push(iter()->get_constant_u1() != 0);
+      break;
+    case Bytecodes::_sipush:
+      push(iter()->get_constant_u2() != 0);
+      break;
+
+    case Bytecodes::_ldc:
+    case Bytecodes::_ldc_w:
+    case Bytecodes::_ldc2_w:
+      sc = SharkConstant::for_ldc(iter());
+      if (!sc->is_loaded())
+        return false;
+      push(sc->is_nonzero());
+      if (sc->is_two_word())
+        push(false);
+      break;
+
+    case Bytecodes::_iload_0:
+    case Bytecodes::_fload_0:
+    case Bytecodes::_aload_0:
+      push(local(0));
+      break;
+    case Bytecodes::_lload_0:
+    case Bytecodes::_dload_0:
+      push_pair_local(0);
+      break;
+
+    case Bytecodes::_iload_1:
+    case Bytecodes::_fload_1:
+    case Bytecodes::_aload_1:
+      push(local(1));
+      break;
+    case Bytecodes::_lload_1:
+    case Bytecodes::_dload_1:
+      push_pair_local(1);
+      break;
+
+    case Bytecodes::_iload_2:
+    case Bytecodes::_fload_2:
+    case Bytecodes::_aload_2:
+      push(local(2));
+      break;
+    case Bytecodes::_lload_2:
+    case Bytecodes::_dload_2:
+      push_pair_local(2);
+      break;
+
+    case Bytecodes::_iload_3:
+    case Bytecodes::_fload_3:
+    case Bytecodes::_aload_3:
+      push(local(3));
+      break;
+    case Bytecodes::_lload_3:
+    case Bytecodes::_dload_3:
+      push_pair_local(3);
+      break;
+
+    case Bytecodes::_iload:
+    case Bytecodes::_fload:
+    case Bytecodes::_aload:
+      push(local(iter()->get_index()));
+      break;
+    case Bytecodes::_lload:
+    case Bytecodes::_dload:
+      push_pair_local(iter()->get_index());
+      break;
+
+    case Bytecodes::_istore_0:
+    case Bytecodes::_fstore_0:
+    case Bytecodes::_astore_0:
+      set_local(0, pop());
+      break;
+    case Bytecodes::_lstore_0:
+    case Bytecodes::_dstore_0:
+      pop_pair_local(0);
+      break;
+
+    case Bytecodes::_istore_1:
+    case Bytecodes::_fstore_1:
+    case Bytecodes::_astore_1:
+      set_local(1, pop());
+      break;
+    case Bytecodes::_lstore_1:
+    case Bytecodes::_dstore_1:
+      pop_pair_local(1);
+      break;
+
+    case Bytecodes::_istore_2:
+    case Bytecodes::_fstore_2:
+    case Bytecodes::_astore_2:
+      set_local(2, pop());
+      break;
+    case Bytecodes::_lstore_2:
+    case Bytecodes::_dstore_2:
+      pop_pair_local(2);
+      break;
+
+    case Bytecodes::_istore_3:
+    case Bytecodes::_fstore_3:
+    case Bytecodes::_astore_3:
+      set_local(3, pop());
+      break;
+    case Bytecodes::_lstore_3:
+    case Bytecodes::_dstore_3:
+      pop_pair_local(3);
+      break;
+
+    case Bytecodes::_istore:
+    case Bytecodes::_fstore:
+    case Bytecodes::_astore:
+      set_local(iter()->get_index(), pop());
+      break;
+    case Bytecodes::_lstore:
+    case Bytecodes::_dstore:
+      pop_pair_local(iter()->get_index());
+      break;
+
+    case Bytecodes::_pop:
+      pop();
+      break;
+    case Bytecodes::_pop2:
+      pop();
+      pop();
+      break;
+    case Bytecodes::_swap:
+      a = pop();
+      b = pop();
+      push(a);
+      push(b);
+      break;
+    case Bytecodes::_dup:
+      a = pop();
+      push(a);
+      push(a);
+      break;
+    case Bytecodes::_dup_x1:
+      a = pop();
+      b = pop();
+      push(a);
+      push(b);
+      push(a);
+      break;
+    case Bytecodes::_dup_x2:
+      a = pop();
+      b = pop();
+      c = pop();
+      push(a);
+      push(c);
+      push(b);
+      push(a);
+      break;
+    case Bytecodes::_dup2:
+      a = pop();
+      b = pop();
+      push(b);
+      push(a);
+      push(b);
+      push(a);
+      break;
+    case Bytecodes::_dup2_x1:
+      a = pop();
+      b = pop();
+      c = pop();
+      push(b);
+      push(a);
+      push(c);
+      push(b);
+      push(a);
+      break;
+    case Bytecodes::_dup2_x2:
+      a = pop();
+      b = pop();
+      c = pop();
+      d = pop();
+      push(b);
+      push(a);
+      push(d);
+      push(c);
+      push(b);
+      push(a);
+      break;
+
+    case Bytecodes::_getfield:
+      if (!do_getfield())
+        return false;
+      break;
+    case Bytecodes::_getstatic:
+      if (!do_getstatic())
+        return false;
+      break;
+    case Bytecodes::_putfield:
+      if (!do_putfield())
+        return false;
+      break;
+
+    case Bytecodes::_iadd:
+    case Bytecodes::_isub:
+    case Bytecodes::_imul:
+    case Bytecodes::_iand:
+    case Bytecodes::_ixor:
+    case Bytecodes::_ishl:
+    case Bytecodes::_ishr:
+    case Bytecodes::_iushr:
+      pop();
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_ior:
+      a = pop();
+      b = pop();
+      push(a && b);
+      break;
+    case Bytecodes::_idiv:
+    case Bytecodes::_irem:
+      if (!pop())
+        return false;
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_ineg:
+      break;
+
+    case Bytecodes::_ladd:
+    case Bytecodes::_lsub:
+    case Bytecodes::_lmul:
+    case Bytecodes::_land:
+    case Bytecodes::_lxor:
+      pop();
+      pop();
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+    case Bytecodes::_lor:
+      a = pop();
+      b = pop();
+      push(a && b);
+      break;
+    case Bytecodes::_ldiv:
+    case Bytecodes::_lrem:
+      pop();
+      if (!pop())
+        return false;
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+    case Bytecodes::_lneg:
+      break;
+    case Bytecodes::_lshl:
+    case Bytecodes::_lshr:
+    case Bytecodes::_lushr:
+      pop();
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_fadd:
+    case Bytecodes::_fsub:
+    case Bytecodes::_fmul:
+    case Bytecodes::_fdiv:
+    case Bytecodes::_frem:
+      pop();
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_fneg:
+      break;
+
+    case Bytecodes::_dadd:
+    case Bytecodes::_dsub:
+    case Bytecodes::_dmul:
+    case Bytecodes::_ddiv:
+    case Bytecodes::_drem:
+      pop();
+      pop();
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+    case Bytecodes::_dneg:
+      break;
+
+    case Bytecodes::_iinc:
+      set_local(iter()->get_index(), false);
+      break;
+
+    case Bytecodes::_lcmp:
+      pop();
+      pop();
+      pop();
+      pop();
+      push(false);
+      break;
+
+    case Bytecodes::_fcmpl:
+    case Bytecodes::_fcmpg:
+      pop();
+      pop();
+      push(false);
+      break;
+
+    case Bytecodes::_dcmpl:
+    case Bytecodes::_dcmpg:
+      pop();
+      pop();
+      pop();
+      pop();
+      push(false);
+      break;
+
+    case Bytecodes::_i2l:
+      push(false);
+      break;
+    case Bytecodes::_i2f:
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_i2d:
+      pop();
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_l2i:
+    case Bytecodes::_l2f:
+      pop();
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_l2d:
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_f2i:
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_f2l:
+    case Bytecodes::_f2d:
+      pop();
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_d2i:
+    case Bytecodes::_d2f:
+      pop();
+      pop();
+      push(false);
+      break;
+    case Bytecodes::_d2l:
+      pop();
+      pop();
+      push(false);
+      push(false);
+      break;
+
+    case Bytecodes::_i2b:
+    case Bytecodes::_i2c:
+    case Bytecodes::_i2s:
+      pop();
+      push(false);
+      break;
+
+    case Bytecodes::_return:
+    case Bytecodes::_ireturn:
+    case Bytecodes::_lreturn:
+    case Bytecodes::_freturn:
+    case Bytecodes::_dreturn:
+    case Bytecodes::_areturn:
+      break;
+
+    default:
+      return false;
+    }
+  }
+
+  return true;
+}
+
+void SharkInlinerHelper::initialize_for_check() {
+  _locals = NEW_RESOURCE_ARRAY(bool, max_locals());
+  _stack = NEW_RESOURCE_ARRAY(bool, max_stack());
+
+  memset(_locals, 0, max_locals() * sizeof(bool));
+  for (int i = 0; i < target()->arg_size(); i++) {
+    SharkValue *arg = entry_state()->stack(target()->arg_size() - 1 - i);
+    if (arg && arg->zero_checked())
+      set_local(i, true);
+  }
+
+  _sp = _stack;
+}
+
+bool SharkInlinerHelper::do_field_access(bool is_get, bool is_field) {
+  assert(is_get || is_field, "can't inline putstatic");
+
+  // If the holder isn't linked then there isn't a lot we can do
+  if (!target()->holder()->is_linked())
+    return false;
+
+  // Get the field
+  bool will_link;
+  ciField *field = iter()->get_field(will_link);
+  if (!will_link)
+    return false;
+
+  // If the field is mismatched then an exception needs throwing
+  if (is_field == field->is_static())
+    return false;
+
+  // Pop the value off the stack if necessary
+  if (!is_get) {
+    pop();
+    if (field->type()->is_two_word())
+      pop();
+  }
+
+  // Pop and null-check the receiver if necessary
+  if (is_field) {
+    if (!pop())
+      return false;
+  }
+
+  // Push the result if necessary
+  if (is_get) {
+    bool result_pushed = false;
+    if (field->is_constant()) {
+      SharkConstant *sc = SharkConstant::for_field(iter());
+      if (sc->is_loaded()) {
+        push(sc->is_nonzero());
+        result_pushed = true;
+      }
+    }
+
+    if (!result_pushed)
+      push(false);
+
+    if (field->type()->is_two_word())
+      push(false);
+  }
+
+  return true;
+}
+
+bool SharkInliner::attempt_inline(ciMethod *target, SharkState *state) {
+  if (SharkIntrinsics::is_intrinsic(target)) {
+    SharkIntrinsics::inline_intrinsic(target, state);
+    return true;
+  }
+
+  if (may_be_inlinable(target)) {
+    SharkInlinerHelper inliner(target, state);
+    if (inliner.is_inlinable()) {
+      inliner.do_inline();
+      return true;
+    }
+  }
+  return false;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkInliner.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,32 @@
+/*
+ * 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 SharkInliner : public AllStatic {
+ public:
+  static bool attempt_inline(ciMethod* target, SharkState* state);
+
+ private:
+  static bool may_be_inlinable(ciMethod* target);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkIntrinsics.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,277 @@
+/*
+ * 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/_sharkIntrinsics.cpp.incl"
+
+using namespace llvm;
+
+bool SharkIntrinsics::is_intrinsic(ciMethod *target) {
+  switch (target->intrinsic_id()) {
+  case vmIntrinsics::_none:
+    return false;
+
+    // java.lang.Math
+  case vmIntrinsics::_min:
+  case vmIntrinsics::_max:
+  case vmIntrinsics::_dabs:
+  case vmIntrinsics::_dsin:
+  case vmIntrinsics::_dcos:
+  case vmIntrinsics::_dtan:
+  case vmIntrinsics::_datan2:
+  case vmIntrinsics::_dsqrt:
+  case vmIntrinsics::_dlog:
+  case vmIntrinsics::_dlog10:
+  case vmIntrinsics::_dpow:
+  case vmIntrinsics::_dexp:
+    return true;
+
+    // java.lang.Object
+  case vmIntrinsics::_getClass:
+    return true;
+
+    // java.lang.System
+  case vmIntrinsics::_currentTimeMillis:
+    return true;
+
+    // java.lang.Thread
+  case vmIntrinsics::_currentThread:
+    return true;
+
+    // sun.misc.Unsafe
+  case vmIntrinsics::_compareAndSwapInt:
+    return true;
+
+  default:
+    if (SharkPerformanceWarnings) {
+      warning(
+        "unhandled intrinsic vmIntrinsic::%s",
+        vmIntrinsics::name_at(target->intrinsic_id()));
+    }
+  }
+  return false;
+}
+
+void SharkIntrinsics::inline_intrinsic(ciMethod *target, SharkState *state) {
+  SharkIntrinsics intrinsic(state, target);
+  intrinsic.do_intrinsic();
+}
+
+void SharkIntrinsics::do_intrinsic() {
+  switch (target()->intrinsic_id()) {
+    // java.lang.Math
+  case vmIntrinsics::_min:
+    do_Math_minmax(llvm::ICmpInst::ICMP_SLE);
+    break;
+  case vmIntrinsics::_max:
+    do_Math_minmax(llvm::ICmpInst::ICMP_SGE);
+    break;
+  case vmIntrinsics::_dabs:
+    do_Math_1to1(builder()->fabs());
+    break;
+  case vmIntrinsics::_dsin:
+    do_Math_1to1(builder()->sin());
+    break;
+  case vmIntrinsics::_dcos:
+    do_Math_1to1(builder()->cos());
+    break;
+  case vmIntrinsics::_dtan:
+    do_Math_1to1(builder()->tan());
+    break;
+  case vmIntrinsics::_datan2:
+    do_Math_2to1(builder()->atan2());
+    break;
+  case vmIntrinsics::_dsqrt:
+    do_Math_1to1(builder()->sqrt());
+    break;
+  case vmIntrinsics::_dlog:
+    do_Math_1to1(builder()->log());
+    break;
+  case vmIntrinsics::_dlog10:
+    do_Math_1to1(builder()->log10());
+    break;
+  case vmIntrinsics::_dpow:
+    do_Math_2to1(builder()->pow());
+    break;
+  case vmIntrinsics::_dexp:
+    do_Math_1to1(builder()->exp());
+    break;
+
+    // java.lang.Object
+  case vmIntrinsics::_getClass:
+    do_Object_getClass();
+    break;
+
+    // java.lang.System
+  case vmIntrinsics::_currentTimeMillis:
+    do_System_currentTimeMillis();
+    break;
+
+    // java.lang.Thread
+  case vmIntrinsics::_currentThread:
+    do_Thread_currentThread();
+    break;
+
+    // sun.misc.Unsafe
+  case vmIntrinsics::_compareAndSwapInt:
+    do_Unsafe_compareAndSwapInt();
+    break;
+
+  default:
+    ShouldNotReachHere();
+  }
+}
+
+void SharkIntrinsics::do_Math_minmax(ICmpInst::Predicate p) {
+  // Pop the arguments
+  SharkValue *sb = state()->pop();
+  SharkValue *sa = state()->pop();
+  Value *a = sa->jint_value();
+  Value *b = sb->jint_value();
+
+  // Perform the test
+  BasicBlock *ip       = builder()->GetBlockInsertionPoint();
+  BasicBlock *return_a = builder()->CreateBlock(ip, "return_a");
+  BasicBlock *return_b = builder()->CreateBlock(ip, "return_b");
+  BasicBlock *done     = builder()->CreateBlock(ip, "done");
+
+  builder()->CreateCondBr(builder()->CreateICmp(p, a, b), return_a, return_b);
+
+  builder()->SetInsertPoint(return_a);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(return_b);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  PHINode *phi = builder()->CreatePHI(a->getType(), "result");
+  phi->addIncoming(a, return_a);
+  phi->addIncoming(b, return_b);
+
+  // Push the result
+  state()->push(
+    SharkValue::create_jint(
+      phi,
+      sa->zero_checked() && sb->zero_checked()));
+}
+
+void SharkIntrinsics::do_Math_1to1(Value *function) {
+  SharkValue *empty = state()->pop();
+  assert(empty == NULL, "should be");
+  state()->push(
+    SharkValue::create_jdouble(
+      builder()->CreateCall(
+        function, state()->pop()->jdouble_value())));
+  state()->push(NULL);
+}
+
+void SharkIntrinsics::do_Math_2to1(Value *function) {
+  SharkValue *empty = state()->pop();
+  assert(empty == NULL, "should be");
+  Value *y = state()->pop()->jdouble_value();
+  empty = state()->pop();
+  assert(empty == NULL, "should be");
+  Value *x = state()->pop()->jdouble_value();
+
+  state()->push(
+    SharkValue::create_jdouble(
+      builder()->CreateCall2(function, x, y)));
+  state()->push(NULL);
+}
+
+void SharkIntrinsics::do_Object_getClass() {
+  Value *klass = builder()->CreateValueOfStructEntry(
+    state()->pop()->jobject_value(),
+    in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "klass");
+
+  Value *klass_part = builder()->CreateAddressOfStructEntry(
+    klass,
+    in_ByteSize(klassOopDesc::klass_part_offset_in_bytes()),
+    SharkType::klass_type(),
+    "klass_part");
+
+  state()->push(
+    SharkValue::create_jobject(
+      builder()->CreateValueOfStructEntry(
+        klass_part,
+        in_ByteSize(Klass::java_mirror_offset_in_bytes()),
+        SharkType::oop_type(),
+        "java_mirror"),
+      true));
+}
+
+void SharkIntrinsics::do_System_currentTimeMillis() {
+  state()->push(
+    SharkValue::create_jlong(
+      builder()->CreateCall(builder()->current_time_millis()),
+      false));
+  state()->push(NULL);
+}
+
+void SharkIntrinsics::do_Thread_currentThread() {
+  state()->push(
+    SharkValue::create_jobject(
+      builder()->CreateValueOfStructEntry(
+        thread(), JavaThread::threadObj_offset(),
+        SharkType::oop_type(),
+        "threadObj"),
+      true));
+}
+
+void SharkIntrinsics::do_Unsafe_compareAndSwapInt() {
+  // Pop the arguments
+  Value *x      = state()->pop()->jint_value();
+  Value *e      = state()->pop()->jint_value();
+  SharkValue *empty = state()->pop();
+  assert(empty == NULL, "should be");
+  Value *offset = state()->pop()->jlong_value();
+  Value *object = state()->pop()->jobject_value();
+  Value *unsafe = state()->pop()->jobject_value();
+
+  // Convert the offset
+  offset = builder()->CreateCall(
+    builder()->unsafe_field_offset_to_byte_offset(),
+    offset);
+
+  // Locate the field
+  Value *addr = builder()->CreateIntToPtr(
+    builder()->CreateAdd(
+      builder()->CreatePtrToInt(object, SharkType::intptr_type()),
+      builder()->CreateIntCast(offset, SharkType::intptr_type(), true)),
+    PointerType::getUnqual(SharkType::jint_type()),
+    "addr");
+
+  // Perform the operation
+  Value *result = builder()->CreateCmpxchgInt(x, addr, e);
+
+  // Push the result
+  state()->push(
+    SharkValue::create_jint(
+      builder()->CreateIntCast(
+        builder()->CreateICmpEQ(result, e), SharkType::jint_type(), true),
+      false));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkIntrinsics.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,54 @@
+/*
+ * 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 SharkIntrinsics : public SharkTargetInvariants {
+ public:
+  static bool is_intrinsic(ciMethod* target);
+  static void inline_intrinsic(ciMethod* target, SharkState* state);
+
+ private:
+  SharkIntrinsics(SharkState* state, ciMethod* target)
+    : SharkTargetInvariants(state, target), _state(state) {}
+
+ private:
+  SharkState* _state;
+
+ private:
+  SharkState* state() const {
+    return _state;
+  }
+
+ private:
+  void do_intrinsic();
+
+ private:
+  void do_Math_minmax(llvm::ICmpInst::Predicate p);
+  void do_Math_1to1(llvm::Value* function);
+  void do_Math_2to1(llvm::Value* function);
+  void do_Object_getClass();
+  void do_System_currentTimeMillis();
+  void do_Thread_currentThread();
+  void do_Unsafe_compareAndSwapInt();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkInvariants.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,37 @@
+/*
+ * 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/_sharkInvariants.cpp.incl"
+
+int SharkTargetInvariants::count_monitors() {
+  int result = 0;
+  if (is_synchronized() || target()->has_monitor_bytecodes()) {
+    for (int i = 0; i < flow()->block_count(); i++) {
+      result = MAX2(result, flow()->pre_order_at(i)->monitor_count());
+    }
+  }
+  return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkInvariants.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,167 @@
+/*
+ * 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.
+ *
+ */
+
+// Base classes used to track various values through the compilation.
+// SharkCompileInvariants is used to track values which remain the
+// same for the top-level method and any inlined methods it may have
+// (ie for the whole compilation).  SharkTargetInvariants is used to
+// track values which differ between methods.
+
+class SharkCompileInvariants : public ResourceObj {
+ protected:
+  SharkCompileInvariants(ciEnv* env, SharkBuilder* builder)
+    : _env(env),
+      _builder(builder),
+      _thread(NULL) {}
+
+  SharkCompileInvariants(const SharkCompileInvariants* parent)
+    : _env(parent->_env),
+      _builder(parent->_builder),
+      _thread(parent->_thread) {}
+
+ private:
+  ciEnv*        _env;
+  SharkBuilder* _builder;
+  llvm::Value*  _thread;
+
+  // Top-level broker for HotSpot's Compiler Interface.
+  //
+  // Its main purpose is to allow the various CI classes to access
+  // oops in the VM without having to worry about safepointing.  In
+  // addition to this it acts as a holder for various recorders and
+  // memory allocators.
+  //
+  // Accessing this directly is kind of ugly, so it's private.  Add
+  // new accessors below if you need something from it.
+ private:
+  ciEnv* env() const {
+    assert(_env != NULL, "env not available");
+    return _env;
+  }
+
+  // The SharkBuilder that is used to build LLVM IR.
+ protected:
+  SharkBuilder* builder() const {
+    return _builder;
+  }
+
+  // Pointer to this thread's JavaThread object.  This is not
+  // available until a short way into SharkFunction creation
+  // so a setter is required.  Assertions are used to enforce
+  // invariance.
+ protected:
+  llvm::Value* thread() const {
+    assert(_thread != NULL, "thread not available");
+    return _thread;
+  }
+  void set_thread(llvm::Value* thread) {
+    assert(_thread == NULL, "thread already set");
+    _thread = thread;
+  }
+
+  // Objects that handle various aspects of the compilation.
+ protected:
+  DebugInformationRecorder* debug_info() const {
+    return env()->debug_info();
+  }
+  Dependencies* dependencies() const {
+    return env()->dependencies();
+  }
+  SharkCodeBuffer* code_buffer() const {
+    return builder()->code_buffer();
+  }
+
+  // Commonly used classes
+ protected:
+  ciInstanceKlass* java_lang_Object_klass() const {
+    return env()->Object_klass();
+  }
+  ciInstanceKlass* java_lang_Throwable_klass() const {
+    return env()->Throwable_klass();
+  }
+};
+
+class SharkTargetInvariants : public SharkCompileInvariants {
+ protected:
+  SharkTargetInvariants(ciEnv* env, SharkBuilder* builder, ciTypeFlow* flow)
+    : SharkCompileInvariants(env, builder),
+      _target(flow->method()),
+      _flow(flow),
+      _max_monitors(count_monitors()) {}
+
+  SharkTargetInvariants(const SharkCompileInvariants* parent, ciMethod* target)
+    : SharkCompileInvariants(parent),
+      _target(target),
+      _flow(NULL),
+      _max_monitors(count_monitors()) {}
+
+  SharkTargetInvariants(const SharkTargetInvariants* parent)
+    : SharkCompileInvariants(parent),
+      _target(parent->_target),
+      _flow(parent->_flow),
+      _max_monitors(parent->_max_monitors) {}
+
+ private:
+  int count_monitors();
+
+ private:
+  ciMethod*   _target;
+  ciTypeFlow* _flow;
+  int         _max_monitors;
+
+  // The method being compiled.
+ protected:
+  ciMethod* target() const {
+    return _target;
+  }
+
+  // Typeflow analysis of the method being compiled.
+ protected:
+  ciTypeFlow* flow() const {
+    assert(_flow != NULL, "typeflow not available");
+    return _flow;
+  }
+
+  // Properties of the method.
+ protected:
+  int max_locals() const {
+    return target()->max_locals();
+  }
+  int max_stack() const {
+    return target()->max_stack();
+  }
+  int max_monitors() const {
+    return _max_monitors;
+  }
+  int arg_size() const {
+    return target()->arg_size();
+  }
+  bool is_static() const {
+    return target()->is_static();
+  }
+  bool is_synchronized() const {
+    return target()->is_synchronized();
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkMemoryManager.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,116 @@
+/*
+ * 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/_sharkMemoryManager.cpp.incl"
+
+using namespace llvm;
+
+void SharkMemoryManager::AllocateGOT() {
+  mm()->AllocateGOT();
+}
+
+unsigned char* SharkMemoryManager::getGOTBase() const {
+  return mm()->getGOTBase();
+}
+
+unsigned char* SharkMemoryManager::allocateStub(const GlobalValue* F,
+                                                unsigned StubSize,
+                                                unsigned Alignment) {
+  return mm()->allocateStub(F, StubSize, Alignment);
+}
+
+unsigned char* SharkMemoryManager::startFunctionBody(const Function* F,
+                                                     uintptr_t& ActualSize) {
+  return mm()->startFunctionBody(F, ActualSize);
+}
+
+void SharkMemoryManager::endFunctionBody(const Function* F,
+                                         unsigned char* FunctionStart,
+                                         unsigned char* FunctionEnd) {
+  mm()->endFunctionBody(F, FunctionStart, FunctionEnd);
+
+  SharkEntry *entry = get_entry_for_function(F);
+  if (entry != NULL)
+    entry->set_code_limit(FunctionEnd);
+}
+
+unsigned char* SharkMemoryManager::startExceptionTable(const Function* F,
+                                                       uintptr_t& ActualSize) {
+  return mm()->startExceptionTable(F, ActualSize);
+}
+
+void SharkMemoryManager::endExceptionTable(const Function* F,
+                                           unsigned char* TableStart,
+                                           unsigned char* TableEnd,
+                                           unsigned char* FrameRegister) {
+  mm()->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
+}
+
+void SharkMemoryManager::setMemoryWritable() {
+  mm()->setMemoryWritable();
+}
+
+void SharkMemoryManager::setMemoryExecutable() {
+  mm()->setMemoryExecutable();
+}
+
+#if SHARK_LLVM_VERSION >= 27
+void SharkMemoryManager::deallocateExceptionTable(void *ptr) {
+  mm()->deallocateExceptionTable(ptr);
+}
+
+void SharkMemoryManager::deallocateFunctionBody(void *ptr) {
+  mm()->deallocateFunctionBody(ptr);
+}
+#else
+void SharkMemoryManager::deallocateMemForFunction(const Function* F) {
+  return mm()->deallocateMemForFunction(F);
+}
+#endif
+
+uint8_t* SharkMemoryManager::allocateGlobal(uintptr_t Size,
+                                            unsigned int Alignment) {
+  return mm()->allocateGlobal(Size, Alignment);
+}
+
+#if SHARK_LLVM_VERSION < 27
+void* SharkMemoryManager::getDlsymTable() const {
+  return mm()->getDlsymTable();
+}
+
+void SharkMemoryManager::SetDlsymTable(void *ptr) {
+  mm()->SetDlsymTable(ptr);
+}
+#endif
+
+void SharkMemoryManager::setPoisonMemory(bool poison) {
+  mm()->setPoisonMemory(poison);
+}
+
+unsigned char *SharkMemoryManager::allocateSpace(intptr_t Size,
+                                                 unsigned int Alignment) {
+  return mm()->allocateSpace(Size, Alignment);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkMemoryManager.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,88 @@
+/*
+ * 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.
+ *
+ */
+
+// SharkMemoryManager wraps the LLVM JIT Memory Manager.  We could use
+// this to run our own memory allocation policies, but for now all we
+// use it for is figuring out where the resulting native code ended up.
+
+class SharkMemoryManager : public llvm::JITMemoryManager {
+ public:
+  SharkMemoryManager()
+    : _mm(llvm::JITMemoryManager::CreateDefaultMemManager()) {}
+
+ private:
+  llvm::JITMemoryManager* _mm;
+
+ private:
+  llvm::JITMemoryManager* mm() const {
+    return _mm;
+  }
+
+ private:
+  std::map<const llvm::Function*, SharkEntry*> _entry_map;
+
+ public:
+  void set_entry_for_function(const llvm::Function* function,
+                              SharkEntry*           entry) {
+    _entry_map[function] = entry;
+  }
+  SharkEntry* get_entry_for_function(const llvm::Function* function) {
+    return _entry_map[function];
+  }
+
+ public:
+  void AllocateGOT();
+  unsigned char* getGOTBase() const;
+  unsigned char* allocateStub(const llvm::GlobalValue* F,
+                              unsigned StubSize,
+                              unsigned Alignment);
+  unsigned char* startFunctionBody(const llvm::Function* F,
+                                   uintptr_t& ActualSize);
+  void endFunctionBody(const llvm::Function* F,
+                       unsigned char* FunctionStart,
+                       unsigned char* FunctionEnd);
+  unsigned char* startExceptionTable(const llvm::Function* F,
+                                     uintptr_t& ActualSize);
+  void endExceptionTable(const llvm::Function* F,
+                         unsigned char* TableStart,
+                         unsigned char* TableEnd,
+                         unsigned char* FrameRegister);
+#if SHARK_LLVM_VERSION < 27
+  void* getDlsymTable() const;
+  void SetDlsymTable(void *ptr);
+#endif
+  void setPoisonMemory(bool);
+  uint8_t* allocateGlobal(uintptr_t, unsigned int);
+  void setMemoryWritable();
+  void setMemoryExecutable();
+#if SHARK_LLVM_VERSION >= 27
+  void deallocateExceptionTable(void *ptr);
+  void deallocateFunctionBody(void *ptr);
+#else
+  void deallocateMemForFunction(const llvm::Function* F);
+#endif
+  unsigned char *allocateSpace(intptr_t Size,
+                               unsigned int Alignment);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2009, 2010 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_sharkNativeWrapper.cpp.incl"
+
+using namespace llvm;
+
+void SharkNativeWrapper::initialize(const char *name) {
+  // Create the function
+  _function = Function::Create(
+    SharkType::entry_point_type(),
+    GlobalVariable::InternalLinkage,
+    name);
+
+  // Get our arguments
+  Function::arg_iterator ai = function()->arg_begin();
+  Argument *method = ai++;
+  method->setName("method");
+  Argument *base_pc = ai++;
+  base_pc->setName("base_pc");
+  code_buffer()->set_base_pc(base_pc);
+  Argument *thread = ai++;
+  thread->setName("thread");
+  set_thread(thread);
+
+  // Create and push our stack frame
+  builder()->SetInsertPoint(CreateBlock());
+  _stack = SharkStack::CreateBuildAndPushFrame(this, method);
+  NOT_PRODUCT(method = NULL);
+
+  // Create the oopmap.  We use the one oopmap for every call site in
+  // the wrapper, which results in the odd mild inefficiency but is a
+  // damn sight easier to code.
+  OopMap *oopmap = new OopMap(
+    SharkStack::oopmap_slot_munge(stack()->oopmap_frame_size()),
+    SharkStack::oopmap_slot_munge(arg_size()));
+  oopmap->set_oop(SharkStack::slot2reg(stack()->method_slot_offset()));
+
+  // Set up the oop_tmp slot if required:
+  //  - For static methods we use it to handlize the class argument
+  //    for the call, and to protect the same during slow path locks
+  //    (if synchronized).
+  //  - For methods returning oops, we use it to protect the return
+  //    value across safepoints or slow path unlocking.
+  if (is_static() || is_returning_oop()) {
+    _oop_tmp_slot = stack()->slot_addr(
+      stack()->oop_tmp_slot_offset(),
+      SharkType::oop_type(),
+      "oop_tmp_slot");
+
+    oopmap->set_oop(SharkStack::slot2reg(stack()->oop_tmp_slot_offset()));
+  }
+
+  // Set up the monitor slot, for synchronized methods
+  if (is_synchronized()) {
+    Unimplemented();
+    _lock_slot_offset = 23;
+  }
+
+  // Start building the argument list
+  std::vector<const Type*> param_types;
+  std::vector<Value*> param_values;
+  const PointerType *box_type = PointerType::getUnqual(SharkType::oop_type());
+
+  // First argument is the JNIEnv
+  param_types.push_back(SharkType::jniEnv_type());
+  param_values.push_back(
+    builder()->CreateAddressOfStructEntry(
+      thread,
+      JavaThread::jni_environment_offset(),
+      SharkType::jniEnv_type(),
+      "jni_environment"));
+
+  // For static methods, the second argument is the class
+  if (is_static()) {
+    builder()->CreateStore(
+      builder()->CreateInlineOop(
+        JNIHandles::make_local(
+          target()->method_holder()->klass_part()->java_mirror())),
+      oop_tmp_slot());
+
+    param_types.push_back(box_type);
+    param_values.push_back(oop_tmp_slot());
+
+    _receiver_slot_offset = stack()->oop_tmp_slot_offset();
+  }
+  else if (is_returning_oop()) {
+    // The oop_tmp slot is registered in the oopmap,
+    // so we need to clear it.  This is one of the
+    // mild inefficiencies I mentioned earlier.
+    builder()->CreateStore(LLVMValue::null(), oop_tmp_slot());
+  }
+
+  // Parse the arguments
+  for (int i = 0; i < arg_size(); i++) {
+    int slot_offset = stack()->locals_slots_offset() + arg_size() - 1 - i;
+    int adjusted_offset = slot_offset;
+    BasicBlock *null, *not_null, *merge;
+    Value *box;
+    PHINode *phi;
+
+    switch (arg_type(i)) {
+    case T_VOID:
+      break;
+
+    case T_OBJECT:
+    case T_ARRAY:
+      null     = CreateBlock("null");
+      not_null = CreateBlock("not_null");
+      merge    = CreateBlock("merge");
+
+      box = stack()->slot_addr(slot_offset, SharkType::oop_type());
+      builder()->CreateCondBr(
+        builder()->CreateICmp(
+          ICmpInst::ICMP_EQ,
+          builder()->CreateLoad(box),
+          LLVMValue::null()),
+        null, not_null);
+
+      builder()->SetInsertPoint(null);
+      builder()->CreateBr(merge);
+
+      builder()->SetInsertPoint(not_null);
+      builder()->CreateBr(merge);
+
+      builder()->SetInsertPoint(merge);
+      phi = builder()->CreatePHI(box_type, "boxed_object");
+      phi->addIncoming(ConstantPointerNull::get(box_type), null);
+      phi->addIncoming(box, not_null);
+      box = phi;
+
+      param_types.push_back(box_type);
+      param_values.push_back(box);
+
+      oopmap->set_oop(SharkStack::slot2reg(slot_offset));
+
+      if (i == 0 && !is_static())
+        _receiver_slot_offset = slot_offset;
+
+      break;
+
+    case T_LONG:
+    case T_DOUBLE:
+      adjusted_offset--;
+      // fall through
+
+    default:
+      const Type *param_type = SharkType::to_stackType(arg_type(i));
+
+      param_types.push_back(param_type);
+      param_values.push_back(
+        builder()->CreateLoad(stack()->slot_addr(adjusted_offset, param_type)));
+    }
+  }
+
+  // The oopmap is now complete, and everything is written
+  // into the frame except the PC.
+  int pc_offset = code_buffer()->create_unique_offset();
+
+  _oop_maps = new OopMapSet();
+  oop_maps()->add_gc_map(pc_offset, oopmap);
+
+  builder()->CreateStore(
+    builder()->code_buffer_address(pc_offset),
+    stack()->slot_addr(stack()->pc_slot_offset()));
+
+  // Set up the Java frame anchor
+  stack()->CreateSetLastJavaFrame();
+
+  // Lock if necessary
+  if (is_synchronized())
+    Unimplemented();
+
+  // Change the thread state to _thread_in_native
+  CreateSetThreadState(_thread_in_native);
+
+  // Make the call
+  BasicType result_type = target()->result_type();
+  const Type* return_type;
+  if (result_type == T_VOID)
+    return_type = SharkType::void_type();
+  else if (is_returning_oop())
+    return_type = box_type;
+  else
+    return_type = SharkType::to_arrayType(result_type);
+  Value* native_function = builder()->CreateIntToPtr(
+     LLVMValue::intptr_constant((intptr_t) target()->native_function()),
+     PointerType::getUnqual(
+       FunctionType::get(return_type, param_types, false)));
+  Value *result = builder()->CreateCall(
+    native_function, param_values.begin(), param_values.end());
+
+  // Start the transition back to _thread_in_Java
+  CreateSetThreadState(_thread_in_native_trans);
+
+  // Make sure new state is visible in the GC thread
+  if (os::is_MP()) {
+    if (UseMembar)
+      builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD);
+    else
+      CreateWriteMemorySerializePage();
+  }
+
+  // Handle safepoint operations, pending suspend requests,
+  // and pending asynchronous exceptions.
+  BasicBlock *check_thread = CreateBlock("check_thread");
+  BasicBlock *do_safepoint = CreateBlock("do_safepoint");
+  BasicBlock *safepointed  = CreateBlock("safepointed");
+
+  Value *global_state = builder()->CreateLoad(
+    builder()->CreateIntToPtr(
+      LLVMValue::intptr_constant(
+        (intptr_t) SafepointSynchronize::address_of_state()),
+      PointerType::getUnqual(SharkType::jint_type())),
+    "global_state");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(
+      global_state,
+      LLVMValue::jint_constant(SafepointSynchronize::_not_synchronized)),
+    do_safepoint, check_thread);
+
+  builder()->SetInsertPoint(check_thread);
+  Value *thread_state = builder()->CreateValueOfStructEntry(
+    thread,
+    JavaThread::suspend_flags_offset(),
+    SharkType::jint_type(),
+    "thread_state");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(
+      thread_state,
+      LLVMValue::jint_constant(0)),
+    do_safepoint, safepointed);
+
+  builder()->SetInsertPoint(do_safepoint);
+  builder()->CreateCall(
+    builder()->check_special_condition_for_native_trans(), thread);
+  builder()->CreateBr(safepointed);
+
+  // Finally we can change the thread state to _thread_in_Java
+  builder()->SetInsertPoint(safepointed);
+  CreateSetThreadState(_thread_in_Java);
+
+  // Clear the frame anchor
+  stack()->CreateResetLastJavaFrame();
+
+  // If there is a pending exception then we can just unwind and
+  // return.  It seems totally wrong that unlocking is skipped here
+  // but apparently the template interpreter does this so we do too.
+  BasicBlock *exception    = CreateBlock("exception");
+  BasicBlock *no_exception = CreateBlock("no_exception");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(
+      CreateLoadPendingException(),
+      LLVMValue::null()),
+    no_exception, exception);
+
+  builder()->SetInsertPoint(exception);
+  CreateResetHandleBlock();
+  stack()->CreatePopFrame(0);
+  builder()->CreateRet(LLVMValue::jint_constant(0));
+
+  builder()->SetInsertPoint(no_exception);
+
+  // If the result was an oop then unbox it before
+  // releasing the handle it might be protected by
+  if (is_returning_oop()) {
+    BasicBlock *null     = builder()->GetInsertBlock();
+    BasicBlock *not_null = CreateBlock("not_null");
+    BasicBlock *merge    = CreateBlock("merge");
+
+    builder()->CreateCondBr(
+      builder()->CreateICmpNE(result, ConstantPointerNull::get(box_type)),
+      not_null, merge);
+
+    builder()->SetInsertPoint(not_null);
+    Value *unboxed_result = builder()->CreateLoad(result);
+    builder()->CreateBr(merge);
+
+    builder()->SetInsertPoint(merge);
+    PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "result");
+    phi->addIncoming(LLVMValue::null(), null);
+    phi->addIncoming(unboxed_result, not_null);
+    result = phi;
+  }
+
+  // Reset handle block
+  CreateResetHandleBlock();
+
+  // Unlock if necessary.
+  if (is_synchronized())
+    Unimplemented();
+
+  // Unwind and return
+  Value *result_addr = stack()->CreatePopFrame(type2size[result_type]);
+  if (result_type != T_VOID) {
+    bool needs_cast = false;
+    bool is_signed = false;
+    switch (result_type) {
+    case T_BOOLEAN:
+      result = builder()->CreateICmpNE(result, LLVMValue::jbyte_constant(0));
+      needs_cast = true;
+      break;
+
+    case T_CHAR:
+      needs_cast = true;
+      break;
+
+    case T_BYTE:
+    case T_SHORT:
+      needs_cast = true;
+      is_signed = true;
+      break;
+    }
+    if (needs_cast) {
+      result = builder()->CreateIntCast(
+        result, SharkType::to_stackType(result_type), is_signed);
+    }
+
+    builder()->CreateStore(
+      result,
+      builder()->CreateIntToPtr(
+        result_addr,
+        PointerType::getUnqual(SharkType::to_stackType(result_type))));
+  }
+  builder()->CreateRet(LLVMValue::jint_constant(0));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkNativeWrapper.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,182 @@
+/*
+ * 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 SharkNativeWrapper : public SharkCompileInvariants {
+  friend class SharkStackWithNativeFrame;
+
+ public:
+  static SharkNativeWrapper* build(SharkBuilder* builder,
+                                   methodHandle  target,
+                                   const char*   name,
+                                   BasicType*    arg_types,
+                                   BasicType     return_type) {
+    return new SharkNativeWrapper(builder,
+                                  target,
+                                  name,
+                                  arg_types,
+                                  return_type);
+  }
+
+ private:
+  SharkNativeWrapper(SharkBuilder* builder,
+                     methodHandle  target,
+                     const char*   name,
+                     BasicType*    arg_types,
+                     BasicType     return_type)
+    : SharkCompileInvariants(NULL, builder),
+      _target(target),
+      _arg_types(arg_types),
+      _return_type(return_type),
+      _lock_slot_offset(0) { initialize(name); }
+
+ private:
+  void initialize(const char* name);
+
+ private:
+  methodHandle    _target;
+  BasicType*      _arg_types;
+  BasicType       _return_type;
+  llvm::Function* _function;
+  SharkStack*     _stack;
+  llvm::Value*    _oop_tmp_slot;
+  OopMapSet*      _oop_maps;
+  int             _receiver_slot_offset;
+  int             _lock_slot_offset;
+
+  // The method being compiled.
+ protected:
+  methodHandle target() const {
+    return _target;
+  }
+
+  // Properties of the method.
+ protected:
+  int arg_size() const {
+    return target()->size_of_parameters();
+  }
+  BasicType arg_type(int i) const {
+    return _arg_types[i];
+  }
+  BasicType return_type() const {
+    return _return_type;
+  }
+  bool is_static() const {
+    return target()->is_static();
+  }
+  bool is_synchronized() const {
+    return target()->is_synchronized();
+  }
+  bool is_returning_oop() const {
+    return target()->is_returning_oop();
+  }
+
+  // The LLVM function we are building.
+ public:
+  llvm::Function* function() const {
+    return _function;
+  }
+
+  // The Zero stack and our frame on it.
+ protected:
+  SharkStack* stack() const {
+    return _stack;
+  }
+
+  // Temporary oop storage.
+ protected:
+  llvm::Value* oop_tmp_slot() const {
+    assert(is_static() || is_returning_oop(), "should be");
+    return _oop_tmp_slot;
+  }
+
+  // Information required by nmethod::new_native_nmethod().
+ public:
+  int frame_size() const {
+    return stack()->oopmap_frame_size();
+  }
+  ByteSize receiver_offset() const {
+    return in_ByteSize(_receiver_slot_offset * wordSize);
+  }
+  ByteSize lock_offset() const {
+    return in_ByteSize(_lock_slot_offset * wordSize);
+  }
+  OopMapSet* oop_maps() const {
+    return _oop_maps;
+  }
+
+  // Helpers.
+ private:
+  llvm::BasicBlock* CreateBlock(const char* name = "") const {
+    return llvm::BasicBlock::Create(SharkContext::current(), name, function());
+  }
+  llvm::Value* thread_state_address() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(), JavaThread::thread_state_offset(),
+      llvm::PointerType::getUnqual(SharkType::jint_type()),
+      "thread_state_address");
+  }
+  llvm::Value* pending_exception_address() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(), Thread::pending_exception_offset(),
+      llvm::PointerType::getUnqual(SharkType::oop_type()),
+      "pending_exception_address");
+  }
+  void CreateSetThreadState(JavaThreadState state) const {
+    builder()->CreateStore(
+      LLVMValue::jint_constant(state), thread_state_address());
+  }
+  void CreateWriteMemorySerializePage() const {
+    builder()->CreateStore(
+      LLVMValue::jint_constant(1),
+      builder()->CreateIntToPtr(
+        builder()->CreateAdd(
+          LLVMValue::intptr_constant(
+            (intptr_t) os::get_memory_serialize_page()),
+          builder()->CreateAnd(
+            builder()->CreateLShr(
+              builder()->CreatePtrToInt(thread(), SharkType::intptr_type()),
+              LLVMValue::intptr_constant(os::get_serialize_page_shift_count())),
+            LLVMValue::intptr_constant(os::get_serialize_page_mask()))),
+        llvm::PointerType::getUnqual(SharkType::jint_type())));
+  }
+  void CreateResetHandleBlock() const {
+    llvm::Value *active_handles = builder()->CreateValueOfStructEntry(
+      thread(),
+      JavaThread::active_handles_offset(),
+      SharkType::jniHandleBlock_type(),
+      "active_handles");
+    builder()->CreateStore(
+      LLVMValue::intptr_constant(0),
+      builder()->CreateAddressOfStructEntry(
+        active_handles,
+        in_ByteSize(JNIHandleBlock::top_offset_in_bytes()),
+        llvm::PointerType::getUnqual(SharkType::intptr_type()),
+        "top"));
+  }
+  llvm::LoadInst* CreateLoadPendingException() const {
+    return builder()->CreateLoad(
+      pending_exception_address(), "pending_exception");
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkRuntime.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,251 @@
+/*
+ * 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/_sharkRuntime.cpp.incl"
+
+using namespace llvm;
+
+JRT_ENTRY(int, SharkRuntime::find_exception_handler(JavaThread* thread,
+                                                    int*        indexes,
+                                                    int         num_indexes))
+  constantPoolHandle pool(thread, method(thread)->constants());
+  KlassHandle exc_klass(thread, ((oop) tos_at(thread, 0))->klass());
+
+  for (int i = 0; i < num_indexes; i++) {
+    klassOop tmp = pool->klass_at(indexes[i], CHECK_0);
+    KlassHandle chk_klass(thread, tmp);
+
+    if (exc_klass() == chk_klass())
+      return i;
+
+    if (exc_klass()->klass_part()->is_subtype_of(chk_klass()))
+      return i;
+  }
+
+  return -1;
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::monitorenter(JavaThread*      thread,
+                                           BasicObjectLock* lock))
+  if (PrintBiasedLockingStatistics)
+    Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
+
+  Handle object(thread, lock->obj());
+  assert(Universe::heap()->is_in_reserved_or_null(object()), "should be");
+  if (UseBiasedLocking) {
+    // Retry fast entry if bias is revoked to avoid unnecessary inflation
+    ObjectSynchronizer::fast_enter(object, lock->lock(), true, CHECK);
+  } else {
+    ObjectSynchronizer::slow_enter(object, lock->lock(), CHECK);
+  }
+  assert(Universe::heap()->is_in_reserved_or_null(lock->obj()), "should be");
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::monitorexit(JavaThread*      thread,
+                                          BasicObjectLock* lock))
+  Handle object(thread, lock->obj());
+  assert(Universe::heap()->is_in_reserved_or_null(object()), "should be");
+  if (lock == NULL || object()->is_unlocked()) {
+    THROW(vmSymbols::java_lang_IllegalMonitorStateException());
+  }
+  ObjectSynchronizer::slow_exit(object(), lock->lock(), thread);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::new_instance(JavaThread* thread, int index))
+  klassOop k_oop = method(thread)->constants()->klass_at(index, CHECK);
+  instanceKlassHandle klass(THREAD, k_oop);
+
+  // Make sure we are not instantiating an abstract klass
+  klass->check_valid_for_instantiation(true, CHECK);
+
+  // Make sure klass is initialized
+  klass->initialize(CHECK);
+
+  // At this point the class may not be fully initialized
+  // because of recursive initialization. If it is fully
+  // initialized & has_finalized is not set, we rewrite
+  // it into its fast version (Note: no locking is needed
+  // here since this is an atomic byte write and can be
+  // done more than once).
+  //
+  // Note: In case of classes with has_finalized we don't
+  //       rewrite since that saves us an extra check in
+  //       the fast version which then would call the
+  //       slow version anyway (and do a call back into
+  //       Java).
+  //       If we have a breakpoint, then we don't rewrite
+  //       because the _breakpoint bytecode would be lost.
+  oop obj = klass->allocate_instance(CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::newarray(JavaThread* thread,
+                                       BasicType   type,
+                                       int         size))
+  oop obj = oopFactory::new_typeArray(type, size, CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::anewarray(JavaThread* thread,
+                                        int         index,
+                                        int         size))
+  klassOop klass = method(thread)->constants()->klass_at(index, CHECK);
+  objArrayOop obj = oopFactory::new_objArray(klass, size, CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::multianewarray(JavaThread* thread,
+                                             int         index,
+                                             int         ndims,
+                                             int*        dims))
+  klassOop klass = method(thread)->constants()->klass_at(index, CHECK);
+  oop obj = arrayKlass::cast(klass)->multi_allocate(ndims, dims, CHECK);
+  thread->set_vm_result(obj);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::register_finalizer(JavaThread* thread,
+                                                 oop         object))
+  assert(object->is_oop(), "should be");
+  assert(object->klass()->klass_part()->has_finalizer(), "should have");
+  instanceKlass::register_finalizer(instanceOop(object), CHECK);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::throw_ArithmeticException(JavaThread* thread,
+                                                        const char* file,
+                                                        int         line))
+  Exceptions::_throw_msg(
+    thread, file, line,
+    vmSymbols::java_lang_ArithmeticException(),
+    "");
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::throw_ArrayIndexOutOfBoundsException(
+                                                     JavaThread* thread,
+                                                     const char* file,
+                                                     int         line,
+                                                     int         index))
+  char msg[jintAsStringSize];
+  snprintf(msg, sizeof(msg), "%d", index);
+  Exceptions::_throw_msg(
+    thread, file, line,
+    vmSymbols::java_lang_ArrayIndexOutOfBoundsException(),
+    msg);
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::throw_ClassCastException(JavaThread* thread,
+                                                       const char* file,
+                                                       int         line))
+  Exceptions::_throw_msg(
+    thread, file, line,
+    vmSymbols::java_lang_ClassCastException(),
+    "");
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::throw_NullPointerException(JavaThread* thread,
+                                                         const char* file,
+                                                         int         line))
+  Exceptions::_throw_msg(
+    thread, file, line,
+    vmSymbols::java_lang_NullPointerException(),
+    "");
+JRT_END
+
+// Non-VM calls
+// Nothing in these must ever GC!
+
+void SharkRuntime::dump(const char *name, intptr_t value) {
+  oop valueOop = (oop) value;
+  tty->print("%s = ", name);
+  if (valueOop->is_oop(true))
+    valueOop->print_on(tty);
+  else if (value >= ' ' && value <= '~')
+    tty->print("'%c' (%d)", value, value);
+  else
+    tty->print("%p", value);
+  tty->print_cr("");
+}
+
+bool SharkRuntime::is_subtype_of(klassOop check_klass, klassOop object_klass) {
+  return object_klass->klass_part()->is_subtype_of(check_klass);
+}
+
+int SharkRuntime::uncommon_trap(JavaThread* thread, int trap_request) {
+  Thread *THREAD = thread;
+
+  // In C2, uncommon_trap_blob creates a frame, so all the various
+  // deoptimization functions expect to find the frame of the method
+  // being deopted one frame down on the stack.  We create a dummy
+  // frame to mirror this.
+  FakeStubFrame *stubframe = FakeStubFrame::build(CHECK_0);
+  thread->push_zero_frame(stubframe);
+
+  // Initiate the trap
+  thread->set_last_Java_frame();
+  Deoptimization::UnrollBlock *urb =
+    Deoptimization::uncommon_trap(thread, trap_request);
+  thread->reset_last_Java_frame();
+
+  // Pop our dummy frame and the frame being deoptimized
+  thread->pop_zero_frame();
+  thread->pop_zero_frame();
+
+  // Push skeleton frames
+  int number_of_frames = urb->number_of_frames();
+  for (int i = 0; i < number_of_frames; i++) {
+    intptr_t size = urb->frame_sizes()[i];
+    InterpreterFrame *frame = InterpreterFrame::build(size, CHECK_0);
+    thread->push_zero_frame(frame);
+  }
+
+  // Push another dummy frame
+  stubframe = FakeStubFrame::build(CHECK_0);
+  thread->push_zero_frame(stubframe);
+
+  // Fill in the skeleton frames
+  thread->set_last_Java_frame();
+  Deoptimization::unpack_frames(thread, Deoptimization::Unpack_uncommon_trap);
+  thread->reset_last_Java_frame();
+
+  // Pop our dummy frame
+  thread->pop_zero_frame();
+
+  // Fall back into the interpreter
+  return number_of_frames;
+}
+
+FakeStubFrame* FakeStubFrame::build(TRAPS) {
+  ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack();
+  stack->overflow_check(header_words, CHECK_NULL);
+
+  stack->push(0); // next_frame, filled in later
+  intptr_t *fp = stack->sp();
+  assert(fp - stack->sp() == next_frame_off, "should be");
+
+  stack->push(FAKE_STUB_FRAME);
+  assert(fp - stack->sp() == frame_type_off, "should be");
+
+  return (FakeStubFrame *) fp;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkRuntime.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,83 @@
+/*
+ * 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 SharkRuntime : public AllStatic {
+  // VM calls
+ public:
+  static int find_exception_handler(JavaThread* thread,
+                                    int*        indexes,
+                                    int         num_indexes);
+
+  static void monitorenter(JavaThread* thread, BasicObjectLock* lock);
+  static void monitorexit(JavaThread* thread, BasicObjectLock* lock);
+
+  static void new_instance(JavaThread* thread, int index);
+  static void newarray(JavaThread* thread, BasicType type, int size);
+  static void anewarray(JavaThread* thread, int index, int size);
+  static void multianewarray(JavaThread* thread,
+                             int         index,
+                             int         ndims,
+                             int*        dims);
+
+  static void register_finalizer(JavaThread* thread, oop object);
+
+  static void throw_ArithmeticException(JavaThread* thread,
+                                        const char* file,
+                                        int         line);
+  static void throw_ArrayIndexOutOfBoundsException(JavaThread* thread,
+                                                   const char* file,
+                                                   int         line,
+                                                   int         index);
+  static void throw_ClassCastException(JavaThread* thread,
+                                       const char* file,
+                                       int         line);
+  static void throw_NullPointerException(JavaThread* thread,
+                                         const char* file,
+                                         int         line);
+
+  // Helpers for VM calls
+ private:
+  static const SharkFrame* last_frame(JavaThread *thread) {
+    return thread->last_frame().zero_sharkframe();
+  }
+  static methodOop method(JavaThread *thread) {
+    return last_frame(thread)->method();
+  }
+  static address bcp(JavaThread *thread, int bci) {
+    return method(thread)->code_base() + bci;
+  }
+  static int two_byte_index(JavaThread *thread, int bci) {
+    return Bytes::get_Java_u2(bcp(thread, bci) + 1);
+  }
+  static intptr_t tos_at(JavaThread *thread, int offset) {
+    return *(thread->zero_stack()->sp() + offset);
+  }
+
+  // Non-VM calls
+ public:
+  static void dump(const char *name, intptr_t value);
+  static bool is_subtype_of(klassOop check_klass, klassOop object_klass);
+  static int uncommon_trap(JavaThread* thread, int trap_request);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkStack.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,263 @@
+/*
+ * 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/_sharkStack.cpp.incl"
+
+using namespace llvm;
+
+void SharkStack::initialize(Value* method) {
+  bool setup_sp_and_method = (method != NULL);
+
+  int locals_words  = max_locals();
+  int extra_locals  = locals_words - arg_size();
+  int header_words  = SharkFrame::header_words;
+  int monitor_words = max_monitors()*frame::interpreter_frame_monitor_size();
+  int stack_words   = max_stack();
+  int frame_words   = header_words + monitor_words + stack_words;
+
+  _extended_frame_size = frame_words + locals_words;
+
+  // Update the stack pointer
+  Value *stack_pointer = builder()->CreateSub(
+    CreateLoadStackPointer(),
+    LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize));
+  CreateStackOverflowCheck(stack_pointer);
+  if (setup_sp_and_method)
+    CreateStoreStackPointer(stack_pointer);
+
+  // Create the frame
+  _frame = builder()->CreateIntToPtr(
+    stack_pointer,
+    PointerType::getUnqual(
+      ArrayType::get(SharkType::intptr_type(), extended_frame_size())),
+    "frame");
+  int offset = 0;
+
+  // Expression stack
+  _stack_slots_offset = offset;
+  offset += stack_words;
+
+  // Monitors
+  _monitors_slots_offset = offset;
+  offset += monitor_words;
+
+  // Temporary oop slot
+  _oop_tmp_slot_offset = offset++;
+
+  // Method pointer
+  _method_slot_offset = offset++;
+  if (setup_sp_and_method) {
+    builder()->CreateStore(
+      method, slot_addr(method_slot_offset(), SharkType::methodOop_type()));
+  }
+
+  // Unextended SP
+  builder()->CreateStore(stack_pointer, slot_addr(offset++));
+
+  // PC
+  _pc_slot_offset = offset++;
+
+  // Frame header
+  builder()->CreateStore(
+    LLVMValue::intptr_constant(ZeroFrame::SHARK_FRAME), slot_addr(offset++));
+  Value *fp = slot_addr(offset++);
+
+  // Local variables
+  _locals_slots_offset = offset;
+  offset += locals_words;
+
+  // Push the frame
+  assert(offset == extended_frame_size(), "should do");
+  builder()->CreateStore(CreateLoadFramePointer(), fp);
+  CreateStoreFramePointer(
+    builder()->CreatePtrToInt(fp, SharkType::intptr_type()));
+}
+
+// This function should match ZeroStack::overflow_check
+void SharkStack::CreateStackOverflowCheck(Value* sp) {
+  BasicBlock *zero_ok  = CreateBlock("zero_stack_ok");
+  BasicBlock *overflow = CreateBlock("stack_overflow");
+  BasicBlock *abi_ok   = CreateBlock("abi_stack_ok");
+
+  // Check the Zero stack
+  builder()->CreateCondBr(
+    builder()->CreateICmpULT(sp, stack_base()),
+    overflow, zero_ok);
+
+  // Check the ABI stack
+  builder()->SetInsertPoint(zero_ok);
+  Value *stack_top = builder()->CreateSub(
+    builder()->CreateValueOfStructEntry(
+      thread(),
+      Thread::stack_base_offset(),
+      SharkType::intptr_type(),
+      "abi_base"),
+    builder()->CreateValueOfStructEntry(
+      thread(),
+      Thread::stack_size_offset(),
+      SharkType::intptr_type(),
+      "abi_size"));
+  Value *free_stack = builder()->CreateSub(
+    builder()->CreatePtrToInt(
+      builder()->CreateGetFrameAddress(),
+      SharkType::intptr_type(),
+      "abi_sp"),
+    stack_top);
+  builder()->CreateCondBr(
+    builder()->CreateICmpULT(
+      free_stack,
+      LLVMValue::intptr_constant(StackShadowPages * os::vm_page_size())),
+    overflow, abi_ok);
+
+  // Handle overflows
+  builder()->SetInsertPoint(overflow);
+  builder()->CreateCall(builder()->throw_StackOverflowError(), thread());
+  builder()->CreateRet(LLVMValue::jint_constant(0));
+
+  builder()->SetInsertPoint(abi_ok);
+}
+
+Value* SharkStack::CreatePopFrame(int result_slots) {
+  assert(result_slots >= 0 && result_slots <= 2, "should be");
+  int locals_to_pop = max_locals() - result_slots;
+
+  Value *fp = CreateLoadFramePointer();
+  Value *sp = builder()->CreateAdd(
+    fp,
+    LLVMValue::intptr_constant((1 + locals_to_pop) * wordSize));
+
+  CreateStoreStackPointer(sp);
+  CreateStoreFramePointer(
+    builder()->CreateLoad(
+      builder()->CreateIntToPtr(
+        fp, PointerType::getUnqual(SharkType::intptr_type()))));
+
+  return sp;
+}
+
+Value* SharkStack::slot_addr(int         offset,
+                             const Type* type,
+                             const char* name) const {
+  bool needs_cast = type && type != SharkType::intptr_type();
+
+  Value* result = builder()->CreateStructGEP(
+    _frame, offset, needs_cast ? "" : name);
+
+  if (needs_cast) {
+    result = builder()->CreateBitCast(
+      result, PointerType::getUnqual(type), name);
+  }
+  return result;
+}
+
+// The bits that differentiate stacks with normal and native frames on top
+
+SharkStack* SharkStack::CreateBuildAndPushFrame(SharkFunction* function,
+                                                Value*         method) {
+  return new SharkStackWithNormalFrame(function, method);
+}
+SharkStack* SharkStack::CreateBuildAndPushFrame(SharkNativeWrapper* wrapper,
+                                                Value*              method) {
+  return new SharkStackWithNativeFrame(wrapper, method);
+}
+
+SharkStackWithNormalFrame::SharkStackWithNormalFrame(SharkFunction* function,
+                                                     Value*         method)
+  : SharkStack(function), _function(function) {
+  // For normal frames, the stack pointer and the method slot will
+  // be set during each decache, so it is not necessary to do them
+  // at the time the frame is created.  However, we set them for
+  // non-PRODUCT builds to make crash dumps easier to understand.
+  initialize(PRODUCT_ONLY(NULL) NOT_PRODUCT(method));
+}
+SharkStackWithNativeFrame::SharkStackWithNativeFrame(SharkNativeWrapper* wrp,
+                                                     Value*              method)
+  : SharkStack(wrp), _wrapper(wrp) {
+  initialize(method);
+}
+
+int SharkStackWithNormalFrame::arg_size() const {
+  return function()->arg_size();
+}
+int SharkStackWithNativeFrame::arg_size() const {
+  return wrapper()->arg_size();
+}
+
+int SharkStackWithNormalFrame::max_locals() const {
+  return function()->max_locals();
+}
+int SharkStackWithNativeFrame::max_locals() const {
+  return wrapper()->arg_size();
+}
+
+int SharkStackWithNormalFrame::max_stack() const {
+  return function()->max_stack();
+}
+int SharkStackWithNativeFrame::max_stack() const {
+  return 0;
+}
+
+int SharkStackWithNormalFrame::max_monitors() const {
+  return function()->max_monitors();
+}
+int SharkStackWithNativeFrame::max_monitors() const {
+  return wrapper()->is_synchronized() ? 1 : 0;
+}
+
+BasicBlock* SharkStackWithNormalFrame::CreateBlock(const char* name) const {
+  return function()->CreateBlock(name);
+}
+BasicBlock* SharkStackWithNativeFrame::CreateBlock(const char* name) const {
+  return wrapper()->CreateBlock(name);
+}
+
+address SharkStackWithNormalFrame::interpreter_entry_point() const {
+  return (address) CppInterpreter::normal_entry;
+}
+address SharkStackWithNativeFrame::interpreter_entry_point() const {
+  return (address) CppInterpreter::native_entry;
+}
+
+#ifndef PRODUCT
+void SharkStack::CreateAssertLastJavaSPIsNull() const {
+#ifdef ASSERT
+  BasicBlock *fail = CreateBlock("assert_failed");
+  BasicBlock *pass = CreateBlock("assert_ok");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(
+      builder()->CreateLoad(last_Java_sp_addr()),
+      LLVMValue::intptr_constant(0)),
+    pass, fail);
+
+  builder()->SetInsertPoint(fail);
+  builder()->CreateShouldNotReachHere(__FILE__, __LINE__);
+  builder()->CreateUnreachable();
+
+  builder()->SetInsertPoint(pass);
+#endif // ASSERT
+}
+#endif // !PRODUCT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkStack.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,290 @@
+/*
+ * 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 SharkFunction;
+class SharkNativeWrapper;
+class SharkStackWithNormalFrame;
+class SharkStackWithNativeFrame;
+
+class SharkStack : public SharkCompileInvariants {
+ public:
+  static SharkStack* CreateBuildAndPushFrame(
+    SharkFunction* function, llvm::Value* method);
+  static SharkStack* CreateBuildAndPushFrame(
+    SharkNativeWrapper* wrapper, llvm::Value* method);
+
+ protected:
+  SharkStack(const SharkCompileInvariants* parent)
+    : SharkCompileInvariants(parent) {}
+
+ protected:
+  void initialize(llvm::Value* method);
+
+ protected:
+  void CreateStackOverflowCheck(llvm::Value* sp);
+
+  // Properties of the method being compiled
+ protected:
+  virtual int arg_size() const = 0;
+  virtual int max_locals() const = 0;
+  virtual int max_stack() const = 0;
+  virtual int max_monitors() const = 0;
+
+  // BasicBlock creation
+ protected:
+  virtual llvm::BasicBlock* CreateBlock(const char* name = "") const = 0;
+
+  // Interpreter entry point for bailouts
+ protected:
+  virtual address interpreter_entry_point() const = 0;
+
+  // Interface with the Zero stack
+ private:
+  llvm::Value* zero_stack() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(),
+      JavaThread::zero_stack_offset(),
+      SharkType::zeroStack_type(),
+      "zero_stack");
+  }
+  llvm::Value* stack_base() const {
+    return builder()->CreateValueOfStructEntry(
+      zero_stack(),
+      ZeroStack::base_offset(),
+      SharkType::intptr_type(),
+      "stack_base");
+  }
+  llvm::Value* stack_pointer_addr() const {
+    return builder()->CreateAddressOfStructEntry(
+      zero_stack(),
+      ZeroStack::sp_offset(),
+      llvm::PointerType::getUnqual(SharkType::intptr_type()),
+      "stack_pointer_addr");
+  }
+  llvm::Value* frame_pointer_addr() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(),
+      JavaThread::top_zero_frame_offset(),
+      llvm::PointerType::getUnqual(SharkType::intptr_type()),
+      "frame_pointer_addr");
+  }
+
+ public:
+  llvm::LoadInst* CreateLoadStackPointer(const char *name = "") {
+    return builder()->CreateLoad(stack_pointer_addr(), name);
+  }
+  llvm::StoreInst* CreateStoreStackPointer(llvm::Value* value) {
+    return builder()->CreateStore(value, stack_pointer_addr());
+  }
+  llvm::LoadInst* CreateLoadFramePointer(const char *name = "") {
+    return builder()->CreateLoad(frame_pointer_addr(), name);
+  }
+  llvm::StoreInst* CreateStoreFramePointer(llvm::Value* value) {
+    return builder()->CreateStore(value, frame_pointer_addr());
+  }
+  llvm::Value* CreatePopFrame(int result_slots);
+
+  // Interface with the frame anchor
+ private:
+  llvm::Value* last_Java_sp_addr() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(),
+      JavaThread::last_Java_sp_offset(),
+      llvm::PointerType::getUnqual(SharkType::intptr_type()),
+      "last_Java_sp_addr");
+  }
+  llvm::Value* last_Java_fp_addr() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(),
+      JavaThread::last_Java_fp_offset(),
+      llvm::PointerType::getUnqual(SharkType::intptr_type()),
+      "last_Java_fp_addr");
+  }
+
+ public:
+  void CreateSetLastJavaFrame() {
+    // Note that whenever _last_Java_sp != NULL other anchor fields
+    // must be valid.  The profiler apparently depends on this.
+    NOT_PRODUCT(CreateAssertLastJavaSPIsNull());
+    builder()->CreateStore(CreateLoadFramePointer(), last_Java_fp_addr());
+    // XXX There's last_Java_pc as well, but I don't think anything uses it
+    // Also XXX: should we fence here?  Zero doesn't...
+    builder()->CreateStore(CreateLoadStackPointer(), last_Java_sp_addr());
+    // Also also XXX: we could probably cache the sp (and the fp we know??)
+  }
+  void CreateResetLastJavaFrame() {
+    builder()->CreateStore(LLVMValue::intptr_constant(0), last_Java_sp_addr());
+  }
+
+ private:
+  void CreateAssertLastJavaSPIsNull() const PRODUCT_RETURN;
+
+  // Our method's frame
+ private:
+  llvm::Value* _frame;
+  int          _extended_frame_size;
+  int          _stack_slots_offset;
+
+ public:
+  int extended_frame_size() const {
+    return _extended_frame_size;
+  }
+  int oopmap_frame_size() const {
+    return extended_frame_size() - arg_size();
+  }
+
+  // Offsets of things in the frame
+ private:
+  int _monitors_slots_offset;
+  int _oop_tmp_slot_offset;
+  int _method_slot_offset;
+  int _pc_slot_offset;
+  int _locals_slots_offset;
+
+ public:
+  int stack_slots_offset() const {
+    return _stack_slots_offset;
+  }
+  int oop_tmp_slot_offset() const {
+    return _oop_tmp_slot_offset;
+  }
+  int method_slot_offset() const {
+    return _method_slot_offset;
+  }
+  int pc_slot_offset() const {
+    return _pc_slot_offset;
+  }
+  int locals_slots_offset() const {
+    return _locals_slots_offset;
+  }
+  int monitor_offset(int index) const {
+    assert(index >= 0 && index < max_monitors(), "invalid monitor index");
+    return _monitors_slots_offset +
+      (max_monitors() - 1 - index) * frame::interpreter_frame_monitor_size();
+  }
+  int monitor_object_offset(int index) const {
+    return monitor_offset(index) +
+      (BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord);
+  }
+  int monitor_header_offset(int index) const {
+    return monitor_offset(index) +
+      ((BasicObjectLock::lock_offset_in_bytes() +
+        BasicLock::displaced_header_offset_in_bytes()) >> LogBytesPerWord);
+  }
+
+  // Addresses of things in the frame
+ public:
+  llvm::Value* slot_addr(int               offset,
+                         const llvm::Type* type = NULL,
+                         const char*       name = "") const;
+
+  llvm::Value* monitor_addr(int index) const {
+    return slot_addr(
+      monitor_offset(index),
+      SharkType::monitor_type(),
+      "monitor");
+  }
+  llvm::Value* monitor_object_addr(int index) const {
+    return slot_addr(
+      monitor_object_offset(index),
+      SharkType::oop_type(),
+      "object_addr");
+  }
+  llvm::Value* monitor_header_addr(int index) const {
+    return slot_addr(
+      monitor_header_offset(index),
+      SharkType::intptr_type(),
+      "displaced_header_addr");
+  }
+
+  // oopmap helpers
+ public:
+  static int oopmap_slot_munge(int offset) {
+    return offset << (LogBytesPerWord - LogBytesPerInt);
+  }
+  static VMReg slot2reg(int offset) {
+    return VMRegImpl::stack2reg(oopmap_slot_munge(offset));
+  }
+};
+
+class SharkStackWithNormalFrame : public SharkStack {
+  friend class SharkStack;
+
+ protected:
+  SharkStackWithNormalFrame(SharkFunction* function, llvm::Value* method);
+
+ private:
+  SharkFunction* _function;
+
+ private:
+  SharkFunction* function() const {
+    return _function;
+  }
+
+  // Properties of the method being compiled
+ private:
+  int arg_size() const;
+  int max_locals() const;
+  int max_stack() const;
+  int max_monitors() const;
+
+  // BasicBlock creation
+ private:
+  llvm::BasicBlock* CreateBlock(const char* name = "") const;
+
+  // Interpreter entry point for bailouts
+ private:
+  address interpreter_entry_point() const;
+};
+
+class SharkStackWithNativeFrame : public SharkStack {
+  friend class SharkStack;
+
+ protected:
+  SharkStackWithNativeFrame(SharkNativeWrapper* wrapper, llvm::Value* method);
+
+ private:
+  SharkNativeWrapper* _wrapper;
+
+ private:
+  SharkNativeWrapper* wrapper() const {
+    return _wrapper;
+  }
+
+  // Properties of the method being compiled
+ private:
+  int arg_size() const;
+  int max_locals() const;
+  int max_stack() const;
+  int max_monitors() const;
+
+  // BasicBlock creation
+ private:
+  llvm::BasicBlock* CreateBlock(const char* name = "") const;
+
+  // Interpreter entry point for bailouts
+ private:
+  address interpreter_entry_point() const;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkState.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,389 @@
+/*
+ * 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/_sharkState.cpp.incl"
+
+using namespace llvm;
+
+void SharkState::initialize(const SharkState *state) {
+  _locals = NEW_RESOURCE_ARRAY(SharkValue*, max_locals());
+  _stack  = NEW_RESOURCE_ARRAY(SharkValue*, max_stack());
+
+  NOT_PRODUCT(memset(_locals, 23, max_locals() * sizeof(SharkValue *)));
+  NOT_PRODUCT(memset(_stack,  23, max_stack()  * sizeof(SharkValue *)));
+  _sp = _stack;
+
+  if (state) {
+    for (int i = 0; i < max_locals(); i++) {
+      SharkValue *value = state->local(i);
+      if (value)
+        value = value->clone();
+      set_local(i, value);
+    }
+
+    for (int i = state->stack_depth() - 1; i >= 0; i--) {
+      SharkValue *value = state->stack(i);
+      if (value)
+        value = value->clone();
+      push(value);
+    }
+  }
+
+  set_num_monitors(state ? state->num_monitors() : 0);
+}
+
+bool SharkState::equal_to(SharkState *other) {
+  if (target() != other->target())
+    return false;
+
+  if (method() != other->method())
+    return false;
+
+  if (oop_tmp() != other->oop_tmp())
+    return false;
+
+  if (max_locals() != other->max_locals())
+    return false;
+
+  if (stack_depth() != other->stack_depth())
+    return false;
+
+  if (num_monitors() != other->num_monitors())
+    return false;
+
+  if (has_safepointed() != other->has_safepointed())
+    return false;
+
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    SharkValue *value = local(i);
+    SharkValue *other_value = other->local(i);
+
+    if (value == NULL) {
+      if (other_value != NULL)
+        return false;
+    }
+    else {
+      if (other_value == NULL)
+        return false;
+
+      if (!value->equal_to(other_value))
+        return false;
+    }
+  }
+
+  // Expression stack
+  for (int i = 0; i < stack_depth(); i++) {
+    SharkValue *value = stack(i);
+    SharkValue *other_value = other->stack(i);
+
+    if (value == NULL) {
+      if (other_value != NULL)
+        return false;
+    }
+    else {
+      if (other_value == NULL)
+        return false;
+
+      if (!value->equal_to(other_value))
+        return false;
+    }
+  }
+
+  return true;
+}
+
+void SharkState::merge(SharkState* other,
+                       BasicBlock* other_block,
+                       BasicBlock* this_block) {
+  // Method
+  Value *this_method = this->method();
+  Value *other_method = other->method();
+  if (this_method != other_method) {
+    PHINode *phi = builder()->CreatePHI(SharkType::methodOop_type(), "method");
+    phi->addIncoming(this_method, this_block);
+    phi->addIncoming(other_method, other_block);
+    set_method(phi);
+  }
+
+  // Temporary oop slot
+  Value *this_oop_tmp = this->oop_tmp();
+  Value *other_oop_tmp = other->oop_tmp();
+  if (this_oop_tmp != other_oop_tmp) {
+    assert(this_oop_tmp && other_oop_tmp, "can't merge NULL with non-NULL");
+    PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "oop_tmp");
+    phi->addIncoming(this_oop_tmp, this_block);
+    phi->addIncoming(other_oop_tmp, other_block);
+    set_oop_tmp(phi);
+  }
+
+  // Monitors
+  assert(this->num_monitors() == other->num_monitors(), "should be");
+
+  // Local variables
+  assert(this->max_locals() == other->max_locals(), "should be");
+  for (int i = 0; i < max_locals(); i++) {
+    SharkValue *this_value = this->local(i);
+    SharkValue *other_value = other->local(i);
+    assert((this_value == NULL) == (other_value == NULL), "should be");
+    if (this_value != NULL) {
+      char name[18];
+      snprintf(name, sizeof(name), "local_%d_", i);
+      set_local(i, this_value->merge(
+        builder(), other_value, other_block, this_block, name));
+    }
+  }
+
+  // Expression stack
+  assert(this->stack_depth() == other->stack_depth(), "should be");
+  for (int i = 0; i < stack_depth(); i++) {
+    SharkValue *this_value = this->stack(i);
+    SharkValue *other_value = other->stack(i);
+    assert((this_value == NULL) == (other_value == NULL), "should be");
+    if (this_value != NULL) {
+      char name[18];
+      snprintf(name, sizeof(name), "stack_%d_", i);
+      set_stack(i, this_value->merge(
+        builder(), other_value, other_block, this_block, name));
+    }
+  }
+
+  // Safepointed status
+  set_has_safepointed(this->has_safepointed() && other->has_safepointed());
+}
+
+void SharkState::replace_all(SharkValue* old_value, SharkValue* new_value) {
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    if (local(i) == old_value)
+      set_local(i, new_value);
+  }
+
+  // Expression stack
+  for (int i = 0; i < stack_depth(); i++) {
+    if (stack(i) == old_value)
+      set_stack(i, new_value);
+  }
+}
+
+SharkNormalEntryState::SharkNormalEntryState(SharkTopLevelBlock* block,
+                                             Value*              method)
+  : SharkState(block) {
+  assert(!block->stack_depth_at_entry(), "entry block shouldn't have stack");
+
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    ciType *type = block->local_type_at_entry(i);
+
+    SharkValue *value = NULL;
+    switch (type->basic_type()) {
+    case T_INT:
+    case T_LONG:
+    case T_FLOAT:
+    case T_DOUBLE:
+    case T_OBJECT:
+    case T_ARRAY:
+      if (i >= arg_size()) {
+        ShouldNotReachHere();
+      }
+      value = SharkValue::create_generic(type, NULL, i == 0 && !is_static());
+      break;
+
+    case ciTypeFlow::StateVector::T_NULL:
+      value = SharkValue::null();
+      break;
+
+    case ciTypeFlow::StateVector::T_BOTTOM:
+      break;
+
+    case ciTypeFlow::StateVector::T_LONG2:
+    case ciTypeFlow::StateVector::T_DOUBLE2:
+      break;
+
+    default:
+      ShouldNotReachHere();
+    }
+    set_local(i, value);
+  }
+  SharkNormalEntryCacher(block->function(), method).scan(this);
+}
+
+SharkOSREntryState::SharkOSREntryState(SharkTopLevelBlock* block,
+                                       Value*              method,
+                                       Value*              osr_buf)
+  : SharkState(block) {
+  assert(!block->stack_depth_at_entry(), "entry block shouldn't have stack");
+  set_num_monitors(block->ciblock()->monitor_count());
+
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    ciType *type = block->local_type_at_entry(i);
+
+    SharkValue *value = NULL;
+    switch (type->basic_type()) {
+    case T_INT:
+    case T_LONG:
+    case T_FLOAT:
+    case T_DOUBLE:
+    case T_OBJECT:
+    case T_ARRAY:
+      value = SharkValue::create_generic(type, NULL, false);
+      break;
+
+    case ciTypeFlow::StateVector::T_NULL:
+      value = SharkValue::null();
+      break;
+
+    case ciTypeFlow::StateVector::T_BOTTOM:
+      break;
+
+    case ciTypeFlow::StateVector::T_LONG2:
+    case ciTypeFlow::StateVector::T_DOUBLE2:
+      break;
+
+    default:
+      ShouldNotReachHere();
+    }
+    set_local(i, value);
+  }
+  SharkOSREntryCacher(block->function(), method, osr_buf).scan(this);
+}
+
+SharkPHIState::SharkPHIState(SharkTopLevelBlock* block)
+  : SharkState(block), _block(block) {
+  BasicBlock *saved_insert_point = builder()->GetInsertBlock();
+  builder()->SetInsertPoint(block->entry_block());
+  char name[18];
+
+  // Method
+  set_method(builder()->CreatePHI(SharkType::methodOop_type(), "method"));
+
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    ciType *type = block->local_type_at_entry(i);
+    if (type->basic_type() == (BasicType) ciTypeFlow::StateVector::T_NULL) {
+      // XXX we could do all kinds of clever stuff here
+      type = ciType::make(T_OBJECT); // XXX what about T_ARRAY?
+    }
+
+    SharkValue *value = NULL;
+    switch (type->basic_type()) {
+    case T_INT:
+    case T_LONG:
+    case T_FLOAT:
+    case T_DOUBLE:
+    case T_OBJECT:
+    case T_ARRAY:
+      snprintf(name, sizeof(name), "local_%d_", i);
+      value = SharkValue::create_phi(
+        type, builder()->CreatePHI(SharkType::to_stackType(type), name));
+      break;
+
+    case T_ADDRESS:
+      value = SharkValue::address_constant(type->as_return_address()->bci());
+      break;
+
+    case ciTypeFlow::StateVector::T_BOTTOM:
+      break;
+
+    case ciTypeFlow::StateVector::T_LONG2:
+    case ciTypeFlow::StateVector::T_DOUBLE2:
+      break;
+
+    default:
+      ShouldNotReachHere();
+    }
+    set_local(i, value);
+  }
+
+  // Expression stack
+  for (int i = 0; i < block->stack_depth_at_entry(); i++) {
+    ciType *type = block->stack_type_at_entry(i);
+    if (type->basic_type() == (BasicType) ciTypeFlow::StateVector::T_NULL) {
+      // XXX we could do all kinds of clever stuff here
+      type = ciType::make(T_OBJECT); // XXX what about T_ARRAY?
+    }
+
+    SharkValue *value = NULL;
+    switch (type->basic_type()) {
+    case T_INT:
+    case T_LONG:
+    case T_FLOAT:
+    case T_DOUBLE:
+    case T_OBJECT:
+    case T_ARRAY:
+      snprintf(name, sizeof(name), "stack_%d_", i);
+      value = SharkValue::create_phi(
+        type, builder()->CreatePHI(SharkType::to_stackType(type), name));
+      break;
+
+    case T_ADDRESS:
+      value = SharkValue::address_constant(type->as_return_address()->bci());
+      break;
+
+    case ciTypeFlow::StateVector::T_LONG2:
+    case ciTypeFlow::StateVector::T_DOUBLE2:
+      break;
+
+    default:
+      ShouldNotReachHere();
+    }
+    push(value);
+  }
+
+  // Monitors
+  set_num_monitors(block->ciblock()->monitor_count());
+
+  builder()->SetInsertPoint(saved_insert_point);
+}
+
+void SharkPHIState::add_incoming(SharkState* incoming_state) {
+  BasicBlock *predecessor = builder()->GetInsertBlock();
+
+  // Method
+  ((PHINode *) method())->addIncoming(incoming_state->method(), predecessor);
+
+  // Local variables
+  for (int i = 0; i < max_locals(); i++) {
+    if (local(i) != NULL)
+      local(i)->addIncoming(incoming_state->local(i), predecessor);
+  }
+
+  // Expression stack
+  int stack_depth = block()->stack_depth_at_entry();
+  assert(stack_depth == incoming_state->stack_depth(), "should be");
+  for (int i = 0; i < stack_depth; i++) {
+    assert((stack(i) == NULL) == (incoming_state->stack(i) == NULL), "oops");
+    if (stack(i))
+      stack(i)->addIncoming(incoming_state->stack(i), predecessor);
+  }
+
+  // Monitors
+  assert(num_monitors() == incoming_state->num_monitors(), "should be");
+
+  // Temporary oop slot
+  assert(oop_tmp() == incoming_state->oop_tmp(), "should be");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkState.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,188 @@
+/*
+ * 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 : public SharkTargetInvariants {
+ public:
+  SharkState(const SharkTargetInvariants* parent)
+    : SharkTargetInvariants(parent),
+      _method(NULL),
+      _oop_tmp(NULL),
+      _has_safepointed(false) { initialize(NULL); }
+
+  SharkState(const SharkState* state)
+    : SharkTargetInvariants(state),
+      _method(state->_method),
+      _oop_tmp(state->_oop_tmp),
+      _has_safepointed(state->_has_safepointed) { initialize(state); }
+
+ private:
+  void initialize(const SharkState* state);
+
+ private:
+  llvm::Value* _method;
+  SharkValue** _locals;
+  SharkValue** _stack;
+  SharkValue** _sp;
+  int          _num_monitors;
+  llvm::Value* _oop_tmp;
+  bool         _has_safepointed;
+
+  // Method
+ public:
+  llvm::Value** method_addr() {
+    return &_method;
+  }
+  llvm::Value* method() const {
+    return _method;
+  }
+ protected:
+  void set_method(llvm::Value* method) {
+    _method = method;
+  }
+
+  // Local variables
+ public:
+  SharkValue** local_addr(int index) const {
+    assert(index >= 0 && index < max_locals(), "bad local variable index");
+    return &_locals[index];
+  }
+  SharkValue* local(int index) const {
+    return *local_addr(index);
+  }
+  void set_local(int index, SharkValue* value) {
+    *local_addr(index) = value;
+  }
+
+  // Expression stack
+ public:
+  SharkValue** stack_addr(int slot) const {
+    assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
+    return &_sp[-(slot + 1)];
+  }
+  SharkValue* stack(int slot) const {
+    return *stack_addr(slot);
+  }
+ protected:
+  void set_stack(int slot, SharkValue* value) {
+    *stack_addr(slot) = value;
+  }
+ public:
+  int stack_depth() const {
+    return _sp - _stack;
+  }
+  void push(SharkValue* value) {
+    assert(stack_depth() < max_stack(), "stack overrun");
+    *(_sp++) = value;
+  }
+  SharkValue* pop() {
+    assert(stack_depth() > 0, "stack underrun");
+    return *(--_sp);
+  }
+
+  // Monitors
+ public:
+  int num_monitors() const {
+    return _num_monitors;
+  }
+  void set_num_monitors(int num_monitors) {
+    _num_monitors = num_monitors;
+  }
+
+  // Temporary oop slot
+ public:
+  llvm::Value** oop_tmp_addr() {
+    return &_oop_tmp;
+  }
+  llvm::Value* oop_tmp() const {
+    return _oop_tmp;
+  }
+  void set_oop_tmp(llvm::Value* oop_tmp) {
+    _oop_tmp = oop_tmp;
+  }
+
+  // Safepointed status
+ public:
+  bool has_safepointed() const {
+    return _has_safepointed;
+  }
+  void set_has_safepointed(bool has_safepointed) {
+    _has_safepointed = has_safepointed;
+  }
+
+  // Comparison
+ public:
+  bool equal_to(SharkState* other);
+
+  // Copy and merge
+ public:
+  SharkState* copy() const {
+    return new SharkState(this);
+  }
+  void merge(SharkState*       other,
+             llvm::BasicBlock* other_block,
+             llvm::BasicBlock* this_block);
+
+  // Value replacement
+ public:
+  void replace_all(SharkValue* old_value, SharkValue* new_value);
+};
+
+class SharkTopLevelBlock;
+
+// SharkNormalEntryState objects are used to create the state
+// that the method will be entered with for a normal invocation.
+class SharkNormalEntryState : public SharkState {
+ public:
+  SharkNormalEntryState(SharkTopLevelBlock* block,
+                        llvm::Value*        method);
+};
+
+// SharkOSREntryState objects are used to create the state
+// that the method will be entered with for an OSR invocation.
+class SharkOSREntryState : public SharkState {
+ public:
+  SharkOSREntryState(SharkTopLevelBlock* block,
+                     llvm::Value*        method,
+                     llvm::Value*        osr_buf);
+};
+
+// SharkPHIState objects are used to manage the entry state
+// for blocks with more than one entry path or for blocks
+// entered from blocks that will be compiled later.
+class SharkPHIState : public SharkState {
+ public:
+  SharkPHIState(SharkTopLevelBlock* block);
+
+ private:
+  SharkTopLevelBlock* _block;
+
+ private:
+  SharkTopLevelBlock* block() const {
+    return _block;
+  }
+
+ public:
+  void add_incoming(SharkState* incoming_state);
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkStateScanner.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,99 @@
+/*
+ * 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/_sharkStateScanner.cpp.incl"
+
+using namespace llvm;
+
+void SharkStateScanner::scan(SharkState* state) {
+  start_frame();
+
+  // Expression stack
+  stack_integrity_checks(state);
+  start_stack(state->stack_depth());
+  for (int i = state->stack_depth() - 1; i >= 0; i--) {
+    process_stack_slot(
+      i,
+      state->stack_addr(i),
+      stack()->stack_slots_offset() +
+        i + max_stack() - state->stack_depth());
+  }
+  end_stack();
+
+  // Monitors
+  start_monitors(state->num_monitors());
+  for (int i = 0; i < state->num_monitors(); i++) {
+    process_monitor(
+      i,
+      stack()->monitor_offset(i),
+      stack()->monitor_object_offset(i));
+  }
+  end_monitors();
+
+  // Frame header
+  start_frame_header();
+  process_oop_tmp_slot(
+    state->oop_tmp_addr(), stack()->oop_tmp_slot_offset());
+  process_method_slot(state->method_addr(), stack()->method_slot_offset());
+  process_pc_slot(stack()->pc_slot_offset());
+  end_frame_header();
+
+  // Local variables
+  locals_integrity_checks(state);
+  start_locals();
+  for (int i = 0; i < max_locals(); i++) {
+    process_local_slot(
+      i,
+      state->local_addr(i),
+      stack()->locals_slots_offset() + max_locals() - 1 - i);
+  }
+  end_locals();
+
+  end_frame();
+}
+
+#ifndef PRODUCT
+void SharkStateScanner::stack_integrity_checks(SharkState* state) {
+  for (int i = 0; i < state->stack_depth(); i++) {
+    if (state->stack(i)) {
+      if (state->stack(i)->is_two_word())
+        assert(state->stack(i - 1) == NULL, "should be");
+    }
+    else {
+      assert(state->stack(i + 1)->is_two_word(), "should be");
+    }
+  }
+}
+
+void SharkStateScanner::locals_integrity_checks(SharkState* state) {
+  for (int i = 0; i < max_locals(); i++) {
+    if (state->local(i)) {
+      if (state->local(i)->is_two_word())
+        assert(state->local(i + 1) == NULL, "should be");
+    }
+  }
+}
+#endif // !PRODUCT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkStateScanner.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,75 @@
+/*
+ * 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 SharkStateScanner : public SharkTargetInvariants {
+ protected:
+  SharkStateScanner(SharkFunction* function)
+    : SharkTargetInvariants(function), _stack(function->stack()) {}
+
+ private:
+  SharkStack* _stack;
+
+ protected:
+  SharkStack* stack() const {
+    return _stack;
+  }
+
+  // Scan the frame
+ public:
+  void scan(SharkState* state);
+
+  // Callbacks
+  // Note that the offsets supplied to the various process_* callbacks
+  // are specified in wordSize words from the frame's unextended_sp.
+ protected:
+  virtual void start_frame()                                                 {}
+
+  virtual void start_stack(int stack_depth)                                  {}
+  virtual void process_stack_slot(int index, SharkValue** value, int offset) {}
+  virtual void end_stack()                                                   {}
+
+  virtual void start_monitors(int num_monitors)                              {}
+  virtual void process_monitor(int index, int box_offset, int obj_offset)    {}
+  virtual void end_monitors()                                                {}
+
+  virtual void start_frame_header()                                          {}
+  virtual void process_oop_tmp_slot(llvm::Value** value, int offset)         {}
+  virtual void process_method_slot(llvm::Value** value, int offset)          {}
+  virtual void process_pc_slot(int offset)                                   {}
+  virtual void end_frame_header()                                            {}
+
+  virtual void start_locals()                                                {}
+  virtual void process_local_slot(int index, SharkValue** value, int offset) {}
+  virtual void end_locals()                                                  {}
+
+  virtual void end_frame()                                                   {}
+
+  // Integrity checks
+ private:
+  void stack_integrity_checks(SharkState* state) PRODUCT_RETURN;
+  void locals_integrity_checks(SharkState* state) PRODUCT_RETURN;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,1995 @@
+/*
+ * 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/_sharkTopLevelBlock.cpp.incl"
+
+using namespace llvm;
+
+void SharkTopLevelBlock::scan_for_traps() {
+  // If typeflow found a trap then don't scan past it
+  int limit_bci = ciblock()->has_trap() ? ciblock()->trap_bci() : limit();
+
+  // Scan the bytecode for traps that are always hit
+  iter()->reset_to_bci(start());
+  while (iter()->next_bci() < limit_bci) {
+    iter()->next();
+
+    ciField *field;
+    ciMethod *method;
+    ciInstanceKlass *klass;
+    bool will_link;
+    bool is_field;
+
+    switch (bc()) {
+    case Bytecodes::_ldc:
+    case Bytecodes::_ldc_w:
+      if (!SharkConstant::for_ldc(iter())->is_loaded()) {
+        set_trap(
+          Deoptimization::make_trap_request(
+            Deoptimization::Reason_uninitialized,
+            Deoptimization::Action_reinterpret), bci());
+        return;
+      }
+      break;
+
+    case Bytecodes::_getfield:
+    case Bytecodes::_getstatic:
+    case Bytecodes::_putfield:
+    case Bytecodes::_putstatic:
+      field = iter()->get_field(will_link);
+      assert(will_link, "typeflow responsibility");
+      is_field = (bc() == Bytecodes::_getfield || bc() == Bytecodes::_putfield);
+
+      // If the bytecode does not match the field then bail out to
+      // the interpreter to throw an IncompatibleClassChangeError
+      if (is_field == field->is_static()) {
+        set_trap(
+          Deoptimization::make_trap_request(
+            Deoptimization::Reason_unhandled,
+            Deoptimization::Action_none), bci());
+        return;
+      }
+
+      // Bail out if we are trying to access a static variable
+      // before the class initializer has completed.
+      if (!is_field && !field->holder()->is_initialized()) {
+        if (!static_field_ok_in_clinit(field)) {
+          set_trap(
+            Deoptimization::make_trap_request(
+              Deoptimization::Reason_uninitialized,
+              Deoptimization::Action_reinterpret), bci());
+          return;
+        }
+      }
+      break;
+
+    case Bytecodes::_invokestatic:
+    case Bytecodes::_invokespecial:
+    case Bytecodes::_invokevirtual:
+    case Bytecodes::_invokeinterface:
+      method = iter()->get_method(will_link);
+      assert(will_link, "typeflow responsibility");
+
+      if (!method->holder()->is_linked()) {
+        set_trap(
+          Deoptimization::make_trap_request(
+            Deoptimization::Reason_uninitialized,
+            Deoptimization::Action_reinterpret), bci());
+          return;
+      }
+
+      if (bc() == Bytecodes::_invokevirtual) {
+        klass = ciEnv::get_instance_klass_for_declared_method_holder(
+          iter()->get_declared_method_holder());
+        if (!klass->is_linked()) {
+          set_trap(
+            Deoptimization::make_trap_request(
+              Deoptimization::Reason_uninitialized,
+              Deoptimization::Action_reinterpret), bci());
+            return;
+        }
+      }
+      break;
+
+    case Bytecodes::_new:
+      klass = iter()->get_klass(will_link)->as_instance_klass();
+      assert(will_link, "typeflow responsibility");
+
+      // Bail out if the class is unloaded
+      if (iter()->is_unresolved_klass() || !klass->is_initialized()) {
+        set_trap(
+          Deoptimization::make_trap_request(
+            Deoptimization::Reason_uninitialized,
+            Deoptimization::Action_reinterpret), bci());
+        return;
+      }
+
+      // Bail out if the class cannot be instantiated
+      if (klass->is_abstract() || klass->is_interface() ||
+          klass->name() == ciSymbol::java_lang_Class()) {
+        set_trap(
+          Deoptimization::make_trap_request(
+            Deoptimization::Reason_unhandled,
+            Deoptimization::Action_reinterpret), bci());
+        return;
+      }
+      break;
+    }
+  }
+
+  // Trap if typeflow trapped (and we didn't before)
+  if (ciblock()->has_trap()) {
+    set_trap(
+      Deoptimization::make_trap_request(
+        Deoptimization::Reason_unloaded,
+        Deoptimization::Action_reinterpret,
+        ciblock()->trap_index()), ciblock()->trap_bci());
+    return;
+  }
+}
+
+bool SharkTopLevelBlock::static_field_ok_in_clinit(ciField* field) {
+  assert(field->is_static(), "should be");
+
+  // This code is lifted pretty much verbatim from C2's
+  // Parse::static_field_ok_in_clinit() in parse3.cpp.
+  bool access_OK = false;
+  if (target()->holder()->is_subclass_of(field->holder())) {
+    if (target()->is_static()) {
+      if (target()->name() == ciSymbol::class_initializer_name()) {
+        // It's OK to access static fields from the class initializer
+        access_OK = true;
+      }
+    }
+    else {
+      if (target()->name() == ciSymbol::object_initializer_name()) {
+        // It's also OK to access static fields inside a constructor,
+        // because any thread calling the constructor must first have
+        // synchronized on the class by executing a "new" bytecode.
+        access_OK = true;
+      }
+    }
+  }
+  return access_OK;
+}
+
+SharkState* SharkTopLevelBlock::entry_state() {
+  if (_entry_state == NULL) {
+    assert(needs_phis(), "should do");
+    _entry_state = new SharkPHIState(this);
+  }
+  return _entry_state;
+}
+
+void SharkTopLevelBlock::add_incoming(SharkState* incoming_state) {
+  if (needs_phis()) {
+    ((SharkPHIState *) entry_state())->add_incoming(incoming_state);
+  }
+  else if (_entry_state == NULL) {
+    _entry_state = incoming_state;
+  }
+  else {
+    assert(entry_state()->equal_to(incoming_state), "should be");
+  }
+}
+
+void SharkTopLevelBlock::enter(SharkTopLevelBlock* predecessor,
+                               bool is_exception) {
+  // This block requires phis:
+  //  - if it is entered more than once
+  //  - if it is an exception handler, because in which
+  //    case we assume it's entered more than once.
+  //  - if the predecessor will be compiled after this
+  //    block, in which case we can't simple propagate
+  //    the state forward.
+  if (!needs_phis() &&
+      (entered() ||
+       is_exception ||
+       (predecessor && predecessor->index() >= index())))
+    _needs_phis = true;
+
+  // Recurse into the tree
+  if (!entered()) {
+    _entered = true;
+
+    scan_for_traps();
+    if (!has_trap()) {
+      for (int i = 0; i < num_successors(); i++) {
+        successor(i)->enter(this, false);
+      }
+    }
+    compute_exceptions();
+    for (int i = 0; i < num_exceptions(); i++) {
+      SharkTopLevelBlock *handler = exception(i);
+      if (handler)
+        handler->enter(this, true);
+    }
+  }
+}
+
+void SharkTopLevelBlock::initialize() {
+  char name[28];
+  snprintf(name, sizeof(name),
+           "bci_%d%s",
+           start(), is_backedge_copy() ? "_backedge_copy" : "");
+  _entry_block = function()->CreateBlock(name);
+}
+
+void SharkTopLevelBlock::decache_for_Java_call(ciMethod *callee) {
+  SharkJavaCallDecacher(function(), bci(), callee).scan(current_state());
+  for (int i = 0; i < callee->arg_size(); i++)
+    xpop();
+}
+
+void SharkTopLevelBlock::cache_after_Java_call(ciMethod *callee) {
+  if (callee->return_type()->size()) {
+    ciType *type;
+    switch (callee->return_type()->basic_type()) {
+    case T_BOOLEAN:
+    case T_BYTE:
+    case T_CHAR:
+    case T_SHORT:
+      type = ciType::make(T_INT);
+      break;
+
+    default:
+      type = callee->return_type();
+    }
+
+    push(SharkValue::create_generic(type, NULL, false));
+  }
+  SharkJavaCallCacher(function(), callee).scan(current_state());
+}
+
+void SharkTopLevelBlock::decache_for_VM_call() {
+  SharkVMCallDecacher(function(), bci()).scan(current_state());
+}
+
+void SharkTopLevelBlock::cache_after_VM_call() {
+  SharkVMCallCacher(function()).scan(current_state());
+}
+
+void SharkTopLevelBlock::decache_for_trap() {
+  SharkTrapDecacher(function(), bci()).scan(current_state());
+}
+
+void SharkTopLevelBlock::emit_IR() {
+  builder()->SetInsertPoint(entry_block());
+
+  // Parse the bytecode
+  parse_bytecode(start(), limit());
+
+  // If this block falls through to the next then it won't have been
+  // terminated by a bytecode and we have to add the branch ourselves
+  if (falls_through() && !has_trap())
+    do_branch(ciTypeFlow::FALL_THROUGH);
+}
+
+SharkTopLevelBlock* SharkTopLevelBlock::bci_successor(int bci) const {
+  // XXX now with Linear Search Technology (tm)
+  for (int i = 0; i < num_successors(); i++) {
+    ciTypeFlow::Block *successor = ciblock()->successors()->at(i);
+    if (successor->start() == bci)
+      return function()->block(successor->pre_order());
+  }
+  ShouldNotReachHere();
+}
+
+void SharkTopLevelBlock::do_zero_check(SharkValue *value) {
+  if (value->is_phi() && value->as_phi()->all_incomers_zero_checked()) {
+    function()->add_deferred_zero_check(this, value);
+  }
+  else {
+    BasicBlock *continue_block = function()->CreateBlock("not_zero");
+    SharkState *saved_state = current_state();
+    set_current_state(saved_state->copy());
+    zero_check_value(value, continue_block);
+    builder()->SetInsertPoint(continue_block);
+    set_current_state(saved_state);
+  }
+
+  value->set_zero_checked(true);
+}
+
+void SharkTopLevelBlock::do_deferred_zero_check(SharkValue* value,
+                                                int         bci,
+                                                SharkState* saved_state,
+                                                BasicBlock* continue_block) {
+  if (value->as_phi()->all_incomers_zero_checked()) {
+    builder()->CreateBr(continue_block);
+  }
+  else {
+    iter()->force_bci(start());
+    set_current_state(saved_state);
+    zero_check_value(value, continue_block);
+  }
+}
+
+void SharkTopLevelBlock::zero_check_value(SharkValue* value,
+                                          BasicBlock* continue_block) {
+  BasicBlock *zero_block = builder()->CreateBlock(continue_block, "zero");
+
+  Value *a, *b;
+  switch (value->basic_type()) {
+  case T_BYTE:
+  case T_CHAR:
+  case T_SHORT:
+  case T_INT:
+    a = value->jint_value();
+    b = LLVMValue::jint_constant(0);
+    break;
+  case T_LONG:
+    a = value->jlong_value();
+    b = LLVMValue::jlong_constant(0);
+    break;
+  case T_OBJECT:
+  case T_ARRAY:
+    a = value->jobject_value();
+    b = LLVMValue::LLVMValue::null();
+    break;
+  default:
+    tty->print_cr("Unhandled type %s", type2name(value->basic_type()));
+    ShouldNotReachHere();
+  }
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(a, b), continue_block, zero_block);
+
+  builder()->SetInsertPoint(zero_block);
+  if (value->is_jobject()) {
+    call_vm(
+      builder()->throw_NullPointerException(),
+      builder()->CreateIntToPtr(
+        LLVMValue::intptr_constant((intptr_t) __FILE__),
+        PointerType::getUnqual(SharkType::jbyte_type())),
+      LLVMValue::jint_constant(__LINE__),
+      EX_CHECK_NONE);
+  }
+  else {
+    call_vm(
+      builder()->throw_ArithmeticException(),
+      builder()->CreateIntToPtr(
+        LLVMValue::intptr_constant((intptr_t) __FILE__),
+        PointerType::getUnqual(SharkType::jbyte_type())),
+      LLVMValue::jint_constant(__LINE__),
+      EX_CHECK_NONE);
+  }
+
+  Value *pending_exception = get_pending_exception();
+  clear_pending_exception();
+  handle_exception(pending_exception, EX_CHECK_FULL);
+}
+
+void SharkTopLevelBlock::check_bounds(SharkValue* array, SharkValue* index) {
+  BasicBlock *out_of_bounds = function()->CreateBlock("out_of_bounds");
+  BasicBlock *in_bounds     = function()->CreateBlock("in_bounds");
+
+  Value *length = builder()->CreateArrayLength(array->jarray_value());
+  // we use an unsigned comparison to catch negative values
+  builder()->CreateCondBr(
+    builder()->CreateICmpULT(index->jint_value(), length),
+    in_bounds, out_of_bounds);
+
+  builder()->SetInsertPoint(out_of_bounds);
+  SharkState *saved_state = current_state()->copy();
+
+  call_vm(
+    builder()->throw_ArrayIndexOutOfBoundsException(),
+    builder()->CreateIntToPtr(
+      LLVMValue::intptr_constant((intptr_t) __FILE__),
+      PointerType::getUnqual(SharkType::jbyte_type())),
+    LLVMValue::jint_constant(__LINE__),
+    index->jint_value(),
+    EX_CHECK_NONE);
+
+  Value *pending_exception = get_pending_exception();
+  clear_pending_exception();
+  handle_exception(pending_exception, EX_CHECK_FULL);
+
+  set_current_state(saved_state);
+
+  builder()->SetInsertPoint(in_bounds);
+}
+
+void SharkTopLevelBlock::check_pending_exception(int action) {
+  assert(action & EAM_CHECK, "should be");
+
+  BasicBlock *exception    = function()->CreateBlock("exception");
+  BasicBlock *no_exception = function()->CreateBlock("no_exception");
+
+  Value *pending_exception = get_pending_exception();
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(pending_exception, LLVMValue::null()),
+    no_exception, exception);
+
+  builder()->SetInsertPoint(exception);
+  SharkState *saved_state = current_state()->copy();
+  if (action & EAM_MONITOR_FUDGE) {
+    // The top monitor is marked live, but the exception was thrown
+    // while setting it up so we need to mark it dead before we enter
+    // any exception handlers as they will not expect it to be there.
+    set_num_monitors(num_monitors() - 1);
+    action ^= EAM_MONITOR_FUDGE;
+  }
+  clear_pending_exception();
+  handle_exception(pending_exception, action);
+  set_current_state(saved_state);
+
+  builder()->SetInsertPoint(no_exception);
+}
+
+void SharkTopLevelBlock::compute_exceptions() {
+  ciExceptionHandlerStream str(target(), start());
+
+  int exc_count = str.count();
+  _exc_handlers = new GrowableArray<ciExceptionHandler*>(exc_count);
+  _exceptions   = new GrowableArray<SharkTopLevelBlock*>(exc_count);
+
+  int index = 0;
+  for (; !str.is_done(); str.next()) {
+    ciExceptionHandler *handler = str.handler();
+    if (handler->handler_bci() == -1)
+      break;
+    _exc_handlers->append(handler);
+
+    // Try and get this exception's handler from typeflow.  We should
+    // do it this way always, really, except that typeflow sometimes
+    // doesn't record exceptions, even loaded ones, and sometimes it
+    // returns them with a different handler bci.  Why???
+    SharkTopLevelBlock *block = NULL;
+    ciInstanceKlass* klass;
+    if (handler->is_catch_all()) {
+      klass = java_lang_Throwable_klass();
+    }
+    else {
+      klass = handler->catch_klass();
+    }
+    for (int i = 0; i < ciblock()->exceptions()->length(); i++) {
+      if (klass == ciblock()->exc_klasses()->at(i)) {
+        block = function()->block(ciblock()->exceptions()->at(i)->pre_order());
+        if (block->start() == handler->handler_bci())
+          break;
+        else
+          block = NULL;
+      }
+    }
+
+    // If typeflow let us down then try and figure it out ourselves
+    if (block == NULL) {
+      for (int i = 0; i < function()->block_count(); i++) {
+        SharkTopLevelBlock *candidate = function()->block(i);
+        if (candidate->start() == handler->handler_bci()) {
+          if (block != NULL) {
+            NOT_PRODUCT(warning("there may be trouble ahead"));
+            block = NULL;
+            break;
+          }
+          block = candidate;
+        }
+      }
+    }
+    _exceptions->append(block);
+  }
+}
+
+void SharkTopLevelBlock::handle_exception(Value* exception, int action) {
+  if (action & EAM_HANDLE && num_exceptions() != 0) {
+    // Clear the stack and push the exception onto it
+    while (xstack_depth())
+      pop();
+    push(SharkValue::create_jobject(exception, true));
+
+    // Work out how many options we have to check
+    bool has_catch_all = exc_handler(num_exceptions() - 1)->is_catch_all();
+    int num_options = num_exceptions();
+    if (has_catch_all)
+      num_options--;
+
+    // Marshal any non-catch-all handlers
+    if (num_options > 0) {
+      bool all_loaded = true;
+      for (int i = 0; i < num_options; i++) {
+        if (!exc_handler(i)->catch_klass()->is_loaded()) {
+          all_loaded = false;
+          break;
+        }
+      }
+
+      if (all_loaded)
+        marshal_exception_fast(num_options);
+      else
+        marshal_exception_slow(num_options);
+    }
+
+    // Install the catch-all handler, if present
+    if (has_catch_all) {
+      SharkTopLevelBlock* handler = this->exception(num_options);
+      assert(handler != NULL, "catch-all handler cannot be unloaded");
+
+      builder()->CreateBr(handler->entry_block());
+      handler->add_incoming(current_state());
+      return;
+    }
+  }
+
+  // No exception handler was found; unwind and return
+  handle_return(T_VOID, exception);
+}
+
+void SharkTopLevelBlock::marshal_exception_fast(int num_options) {
+  Value *exception_klass = builder()->CreateValueOfStructEntry(
+    xstack(0)->jobject_value(),
+    in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "exception_klass");
+
+  for (int i = 0; i < num_options; i++) {
+    Value *check_klass =
+      builder()->CreateInlineOop(exc_handler(i)->catch_klass());
+
+    BasicBlock *not_exact   = function()->CreateBlock("not_exact");
+    BasicBlock *not_subtype = function()->CreateBlock("not_subtype");
+
+    builder()->CreateCondBr(
+      builder()->CreateICmpEQ(check_klass, exception_klass),
+      handler_for_exception(i), not_exact);
+
+    builder()->SetInsertPoint(not_exact);
+    builder()->CreateCondBr(
+      builder()->CreateICmpNE(
+        builder()->CreateCall2(
+          builder()->is_subtype_of(), check_klass, exception_klass),
+        LLVMValue::jbyte_constant(0)),
+      handler_for_exception(i), not_subtype);
+
+    builder()->SetInsertPoint(not_subtype);
+  }
+}
+
+void SharkTopLevelBlock::marshal_exception_slow(int num_options) {
+  int *indexes = NEW_RESOURCE_ARRAY(int, num_options);
+  for (int i = 0; i < num_options; i++)
+    indexes[i] = exc_handler(i)->catch_klass_index();
+
+  Value *index = call_vm(
+    builder()->find_exception_handler(),
+    builder()->CreateInlineData(
+      indexes,
+      num_options * sizeof(int),
+      PointerType::getUnqual(SharkType::jint_type())),
+    LLVMValue::jint_constant(num_options),
+    EX_CHECK_NO_CATCH);
+
+  BasicBlock *no_handler = function()->CreateBlock("no_handler");
+  SwitchInst *switchinst = builder()->CreateSwitch(
+    index, no_handler, num_options);
+
+  for (int i = 0; i < num_options; i++) {
+    switchinst->addCase(
+      LLVMValue::jint_constant(i),
+      handler_for_exception(i));
+  }
+
+  builder()->SetInsertPoint(no_handler);
+}
+
+BasicBlock* SharkTopLevelBlock::handler_for_exception(int index) {
+  SharkTopLevelBlock *successor = this->exception(index);
+  if (successor) {
+    successor->add_incoming(current_state());
+    return successor->entry_block();
+  }
+  else {
+    return make_trap(
+      exc_handler(index)->handler_bci(),
+      Deoptimization::make_trap_request(
+        Deoptimization::Reason_unhandled,
+        Deoptimization::Action_reinterpret));
+  }
+}
+
+void SharkTopLevelBlock::maybe_add_safepoint() {
+  if (current_state()->has_safepointed())
+    return;
+
+  BasicBlock *orig_block = builder()->GetInsertBlock();
+  SharkState *orig_state = current_state()->copy();
+
+  BasicBlock *do_safepoint = function()->CreateBlock("do_safepoint");
+  BasicBlock *safepointed  = function()->CreateBlock("safepointed");
+
+  Value *state = builder()->CreateLoad(
+    builder()->CreateIntToPtr(
+      LLVMValue::intptr_constant(
+        (intptr_t) SafepointSynchronize::address_of_state()),
+      PointerType::getUnqual(SharkType::jint_type())),
+    "state");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(
+      state,
+      LLVMValue::jint_constant(SafepointSynchronize::_synchronizing)),
+    do_safepoint, safepointed);
+
+  builder()->SetInsertPoint(do_safepoint);
+  call_vm(builder()->safepoint(), EX_CHECK_FULL);
+  BasicBlock *safepointed_block = builder()->GetInsertBlock();
+  builder()->CreateBr(safepointed);
+
+  builder()->SetInsertPoint(safepointed);
+  current_state()->merge(orig_state, orig_block, safepointed_block);
+
+  current_state()->set_has_safepointed(true);
+}
+
+void SharkTopLevelBlock::maybe_add_backedge_safepoint() {
+  if (current_state()->has_safepointed())
+    return;
+
+  for (int i = 0; i < num_successors(); i++) {
+    if (successor(i)->can_reach(this)) {
+      maybe_add_safepoint();
+      break;
+    }
+  }
+}
+
+bool SharkTopLevelBlock::can_reach(SharkTopLevelBlock* other) {
+  for (int i = 0; i < function()->block_count(); i++)
+    function()->block(i)->_can_reach_visited = false;
+
+  return can_reach_helper(other);
+}
+
+bool SharkTopLevelBlock::can_reach_helper(SharkTopLevelBlock* other) {
+  if (this == other)
+    return true;
+
+  if (_can_reach_visited)
+    return false;
+  _can_reach_visited = true;
+
+  if (!has_trap()) {
+    for (int i = 0; i < num_successors(); i++) {
+      if (successor(i)->can_reach_helper(other))
+        return true;
+    }
+  }
+
+  for (int i = 0; i < num_exceptions(); i++) {
+    SharkTopLevelBlock *handler = exception(i);
+    if (handler && handler->can_reach_helper(other))
+      return true;
+  }
+
+  return false;
+}
+
+BasicBlock* SharkTopLevelBlock::make_trap(int trap_bci, int trap_request) {
+  BasicBlock *trap_block = function()->CreateBlock("trap");
+  BasicBlock *orig_block = builder()->GetInsertBlock();
+  builder()->SetInsertPoint(trap_block);
+
+  int orig_bci = bci();
+  iter()->force_bci(trap_bci);
+
+  do_trap(trap_request);
+
+  builder()->SetInsertPoint(orig_block);
+  iter()->force_bci(orig_bci);
+
+  return trap_block;
+}
+
+void SharkTopLevelBlock::do_trap(int trap_request) {
+  decache_for_trap();
+  builder()->CreateRet(
+    builder()->CreateCall2(
+      builder()->uncommon_trap(),
+      thread(),
+      LLVMValue::jint_constant(trap_request)));
+}
+
+void SharkTopLevelBlock::call_register_finalizer(Value *receiver) {
+  BasicBlock *orig_block = builder()->GetInsertBlock();
+  SharkState *orig_state = current_state()->copy();
+
+  BasicBlock *do_call = function()->CreateBlock("has_finalizer");
+  BasicBlock *done    = function()->CreateBlock("done");
+
+  Value *klass = builder()->CreateValueOfStructEntry(
+    receiver,
+    in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "klass");
+
+  Value *klass_part = builder()->CreateAddressOfStructEntry(
+    klass,
+    in_ByteSize(klassOopDesc::klass_part_offset_in_bytes()),
+    SharkType::klass_type(),
+    "klass_part");
+
+  Value *access_flags = builder()->CreateValueOfStructEntry(
+    klass_part,
+    in_ByteSize(Klass::access_flags_offset_in_bytes()),
+    SharkType::jint_type(),
+    "access_flags");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(
+      builder()->CreateAnd(
+        access_flags,
+        LLVMValue::jint_constant(JVM_ACC_HAS_FINALIZER)),
+      LLVMValue::jint_constant(0)),
+    do_call, done);
+
+  builder()->SetInsertPoint(do_call);
+  call_vm(builder()->register_finalizer(), receiver, EX_CHECK_FULL);
+  BasicBlock *branch_block = builder()->GetInsertBlock();
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  current_state()->merge(orig_state, orig_block, branch_block);
+}
+
+void SharkTopLevelBlock::handle_return(BasicType type, Value* exception) {
+  assert (exception == NULL || type == T_VOID, "exception OR result, please");
+
+  if (num_monitors()) {
+    // Protect our exception across possible monitor release decaches
+    if (exception)
+      set_oop_tmp(exception);
+
+    // We don't need to check for exceptions thrown here.  If
+    // we're returning a value then we just carry on as normal:
+    // the caller will see the pending exception and handle it.
+    // If we're returning with an exception then that exception
+    // takes priority and the release_lock one will be ignored.
+    while (num_monitors())
+      release_lock(EX_CHECK_NONE);
+
+    // Reload the exception we're throwing
+    if (exception)
+      exception = get_oop_tmp();
+  }
+
+  if (exception) {
+    builder()->CreateStore(exception, pending_exception_address());
+  }
+
+  Value *result_addr = stack()->CreatePopFrame(type2size[type]);
+  if (type != T_VOID) {
+    builder()->CreateStore(
+      pop_result(type)->generic_value(),
+      builder()->CreateIntToPtr(
+        result_addr,
+        PointerType::getUnqual(SharkType::to_stackType(type))));
+  }
+
+  builder()->CreateRet(LLVMValue::jint_constant(0));
+}
+
+void SharkTopLevelBlock::do_arraylength() {
+  SharkValue *array = pop();
+  check_null(array);
+  Value *length = builder()->CreateArrayLength(array->jarray_value());
+  push(SharkValue::create_jint(length, false));
+}
+
+void SharkTopLevelBlock::do_aload(BasicType basic_type) {
+  SharkValue *index = pop();
+  SharkValue *array = pop();
+
+  check_null(array);
+  check_bounds(array, index);
+
+  Value *value = builder()->CreateLoad(
+    builder()->CreateArrayAddress(
+      array->jarray_value(), basic_type, index->jint_value()));
+
+  const Type *stack_type = SharkType::to_stackType(basic_type);
+  if (value->getType() != stack_type)
+    value = builder()->CreateIntCast(value, stack_type, basic_type != T_CHAR);
+
+  switch (basic_type) {
+  case T_BYTE:
+  case T_CHAR:
+  case T_SHORT:
+  case T_INT:
+    push(SharkValue::create_jint(value, false));
+    break;
+
+  case T_LONG:
+    push(SharkValue::create_jlong(value, false));
+    break;
+
+  case T_FLOAT:
+    push(SharkValue::create_jfloat(value));
+    break;
+
+  case T_DOUBLE:
+    push(SharkValue::create_jdouble(value));
+    break;
+
+  case T_OBJECT:
+    // You might expect that array->type()->is_array_klass() would
+    // always be true, but it isn't.  If ciTypeFlow detects that a
+    // value is always null then that value becomes an untyped null
+    // object.  Shark doesn't presently support this, so a generic
+    // T_OBJECT is created.  In this case we guess the type using
+    // the BasicType we were supplied.  In reality the generated
+    // code will never be used, as the null value will be caught
+    // by the above null pointer check.
+    // http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=324
+    push(
+      SharkValue::create_generic(
+        array->type()->is_array_klass() ?
+          ((ciArrayKlass *) array->type())->element_type() :
+          ciType::make(basic_type),
+        value, false));
+    break;
+
+  default:
+    tty->print_cr("Unhandled type %s", type2name(basic_type));
+    ShouldNotReachHere();
+  }
+}
+
+void SharkTopLevelBlock::do_astore(BasicType basic_type) {
+  SharkValue *svalue = pop();
+  SharkValue *index  = pop();
+  SharkValue *array  = pop();
+
+  check_null(array);
+  check_bounds(array, index);
+
+  Value *value;
+  switch (basic_type) {
+  case T_BYTE:
+  case T_CHAR:
+  case T_SHORT:
+  case T_INT:
+    value = svalue->jint_value();
+    break;
+
+  case T_LONG:
+    value = svalue->jlong_value();
+    break;
+
+  case T_FLOAT:
+    value = svalue->jfloat_value();
+    break;
+
+  case T_DOUBLE:
+    value = svalue->jdouble_value();
+    break;
+
+  case T_OBJECT:
+    value = svalue->jobject_value();
+    // XXX assignability check
+    break;
+
+  default:
+    tty->print_cr("Unhandled type %s", type2name(basic_type));
+    ShouldNotReachHere();
+  }
+
+  const Type *array_type = SharkType::to_arrayType(basic_type);
+  if (value->getType() != array_type)
+    value = builder()->CreateIntCast(value, array_type, basic_type != T_CHAR);
+
+  Value *addr = builder()->CreateArrayAddress(
+    array->jarray_value(), basic_type, index->jint_value(), "addr");
+
+  builder()->CreateStore(value, addr);
+
+  if (basic_type == T_OBJECT) // XXX or T_ARRAY?
+    builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr);
+}
+
+void SharkTopLevelBlock::do_return(BasicType type) {
+  if (target()->intrinsic_id() == vmIntrinsics::_Object_init)
+    call_register_finalizer(local(0)->jobject_value());
+  maybe_add_safepoint();
+  handle_return(type, NULL);
+}
+
+void SharkTopLevelBlock::do_athrow() {
+  SharkValue *exception = pop();
+  check_null(exception);
+  handle_exception(exception->jobject_value(), EX_CHECK_FULL);
+}
+
+void SharkTopLevelBlock::do_goto() {
+  do_branch(ciTypeFlow::GOTO_TARGET);
+}
+
+void SharkTopLevelBlock::do_jsr() {
+  push(SharkValue::address_constant(iter()->next_bci()));
+  do_branch(ciTypeFlow::GOTO_TARGET);
+}
+
+void SharkTopLevelBlock::do_ret() {
+  assert(local(iter()->get_index())->address_value() ==
+         successor(ciTypeFlow::GOTO_TARGET)->start(), "should be");
+  do_branch(ciTypeFlow::GOTO_TARGET);
+}
+
+// All propagation of state from one block to the next (via
+// dest->add_incoming) is handled by these methods:
+//   do_branch
+//   do_if_helper
+//   do_switch
+//   handle_exception
+
+void SharkTopLevelBlock::do_branch(int successor_index) {
+  SharkTopLevelBlock *dest = successor(successor_index);
+  builder()->CreateBr(dest->entry_block());
+  dest->add_incoming(current_state());
+}
+
+void SharkTopLevelBlock::do_if(ICmpInst::Predicate p,
+                               SharkValue*         b,
+                               SharkValue*         a) {
+  Value *llvm_a, *llvm_b;
+  if (a->is_jobject()) {
+    llvm_a = a->intptr_value(builder());
+    llvm_b = b->intptr_value(builder());
+  }
+  else {
+    llvm_a = a->jint_value();
+    llvm_b = b->jint_value();
+  }
+  do_if_helper(p, llvm_b, llvm_a, current_state(), current_state());
+}
+
+void SharkTopLevelBlock::do_if_helper(ICmpInst::Predicate p,
+                                      Value*              b,
+                                      Value*              a,
+                                      SharkState*         if_taken_state,
+                                      SharkState*         not_taken_state) {
+  SharkTopLevelBlock *if_taken  = successor(ciTypeFlow::IF_TAKEN);
+  SharkTopLevelBlock *not_taken = successor(ciTypeFlow::IF_NOT_TAKEN);
+
+  builder()->CreateCondBr(
+    builder()->CreateICmp(p, a, b),
+    if_taken->entry_block(), not_taken->entry_block());
+
+  if_taken->add_incoming(if_taken_state);
+  not_taken->add_incoming(not_taken_state);
+}
+
+void SharkTopLevelBlock::do_switch() {
+  int len = switch_table_length();
+
+  SharkTopLevelBlock *dest_block = successor(ciTypeFlow::SWITCH_DEFAULT);
+  SwitchInst *switchinst = builder()->CreateSwitch(
+    pop()->jint_value(), dest_block->entry_block(), len);
+  dest_block->add_incoming(current_state());
+
+  for (int i = 0; i < len; i++) {
+    int dest_bci = switch_dest(i);
+    if (dest_bci != switch_default_dest()) {
+      dest_block = bci_successor(dest_bci);
+      switchinst->addCase(
+        LLVMValue::jint_constant(switch_key(i)),
+        dest_block->entry_block());
+      dest_block->add_incoming(current_state());
+    }
+  }
+}
+
+ciMethod* SharkTopLevelBlock::improve_virtual_call(ciMethod*   caller,
+                                              ciInstanceKlass* klass,
+                                              ciMethod*        dest_method,
+                                              ciType*          receiver_type) {
+  // If the method is obviously final then we are already done
+  if (dest_method->can_be_statically_bound())
+    return dest_method;
+
+  // Array methods are all inherited from Object and are monomorphic
+  if (receiver_type->is_array_klass() &&
+      dest_method->holder() == java_lang_Object_klass())
+    return dest_method;
+
+#ifdef SHARK_CAN_DEOPTIMIZE_ANYWHERE
+  // This code can replace a virtual call with a direct call if this
+  // class is the only one in the entire set of loaded classes that
+  // implements this method.  This makes the compiled code dependent
+  // on other classes that implement the method not being loaded, a
+  // condition which is enforced by the dependency tracker.  If the
+  // dependency tracker determines a method has become invalid it
+  // will mark it for recompilation, causing running copies to be
+  // deoptimized.  Shark currently can't deoptimize arbitrarily like
+  // that, so this optimization cannot be used.
+  // http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=481
+
+  // All other interesting cases are instance classes
+  if (!receiver_type->is_instance_klass())
+    return NULL;
+
+  // Attempt to improve the receiver
+  ciInstanceKlass* actual_receiver = klass;
+  ciInstanceKlass *improved_receiver = receiver_type->as_instance_klass();
+  if (improved_receiver->is_loaded() &&
+      improved_receiver->is_initialized() &&
+      !improved_receiver->is_interface() &&
+      improved_receiver->is_subtype_of(actual_receiver)) {
+    actual_receiver = improved_receiver;
+  }
+
+  // Attempt to find a monomorphic target for this call using
+  // class heirachy analysis.
+  ciInstanceKlass *calling_klass = caller->holder();
+  ciMethod* monomorphic_target =
+    dest_method->find_monomorphic_target(calling_klass, klass, actual_receiver);
+  if (monomorphic_target != NULL) {
+    assert(!monomorphic_target->is_abstract(), "shouldn't be");
+
+    // Opto has a bunch of type checking here that I don't
+    // understand.  It's to inhibit casting in one direction,
+    // possibly because objects in Opto can have inexact
+    // types, but I can't even tell which direction it
+    // doesn't like.  For now I'm going to block *any* cast.
+    if (monomorphic_target != dest_method) {
+      if (SharkPerformanceWarnings) {
+        warning("found monomorphic target, but inhibited cast:");
+        tty->print("  dest_method = ");
+        dest_method->print_short_name(tty);
+        tty->cr();
+        tty->print("  monomorphic_target = ");
+        monomorphic_target->print_short_name(tty);
+        tty->cr();
+      }
+      monomorphic_target = NULL;
+    }
+  }
+
+  // Replace the virtual call with a direct one.  This makes
+  // us dependent on that target method not getting overridden
+  // by dynamic class loading.
+  if (monomorphic_target != NULL) {
+    dependencies()->assert_unique_concrete_method(
+      actual_receiver, monomorphic_target);
+    return monomorphic_target;
+  }
+
+  // Because Opto distinguishes exact types from inexact ones
+  // it can perform a further optimization to replace calls
+  // with non-monomorphic targets if the receiver has an exact
+  // type.  We don't mark types this way, so we can't do this.
+
+#endif // SHARK_CAN_DEOPTIMIZE_ANYWHERE
+
+  return NULL;
+}
+
+Value *SharkTopLevelBlock::get_direct_callee(ciMethod* method) {
+  return builder()->CreateBitCast(
+    builder()->CreateInlineOop(method),
+    SharkType::methodOop_type(),
+    "callee");
+}
+
+Value *SharkTopLevelBlock::get_virtual_callee(SharkValue* receiver,
+                                              int vtable_index) {
+  Value *klass = builder()->CreateValueOfStructEntry(
+    receiver->jobject_value(),
+    in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "klass");
+
+  return builder()->CreateLoad(
+    builder()->CreateArrayAddress(
+      klass,
+      SharkType::methodOop_type(),
+      vtableEntry::size() * wordSize,
+      in_ByteSize(instanceKlass::vtable_start_offset() * wordSize),
+      LLVMValue::intptr_constant(vtable_index)),
+    "callee");
+}
+
+Value* SharkTopLevelBlock::get_interface_callee(SharkValue *receiver,
+                                                ciMethod*   method) {
+  BasicBlock *loop       = function()->CreateBlock("loop");
+  BasicBlock *got_null   = function()->CreateBlock("got_null");
+  BasicBlock *not_null   = function()->CreateBlock("not_null");
+  BasicBlock *next       = function()->CreateBlock("next");
+  BasicBlock *got_entry  = function()->CreateBlock("got_entry");
+
+  // Locate the receiver's itable
+  Value *object_klass = builder()->CreateValueOfStructEntry(
+    receiver->jobject_value(), in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "object_klass");
+
+  Value *vtable_start = builder()->CreateAdd(
+    builder()->CreatePtrToInt(object_klass, SharkType::intptr_type()),
+    LLVMValue::intptr_constant(
+      instanceKlass::vtable_start_offset() * HeapWordSize),
+    "vtable_start");
+
+  Value *vtable_length = builder()->CreateValueOfStructEntry(
+    object_klass,
+    in_ByteSize(instanceKlass::vtable_length_offset() * HeapWordSize),
+    SharkType::jint_type(),
+    "vtable_length");
+  vtable_length =
+    builder()->CreateIntCast(vtable_length, SharkType::intptr_type(), false);
+
+  bool needs_aligning = HeapWordsPerLong > 1;
+  Value *itable_start = builder()->CreateAdd(
+    vtable_start,
+    builder()->CreateShl(
+      vtable_length,
+      LLVMValue::intptr_constant(exact_log2(vtableEntry::size() * wordSize))),
+    needs_aligning ? "" : "itable_start");
+  if (needs_aligning) {
+    itable_start = builder()->CreateAnd(
+      builder()->CreateAdd(
+        itable_start, LLVMValue::intptr_constant(BytesPerLong - 1)),
+      LLVMValue::intptr_constant(~(BytesPerLong - 1)),
+      "itable_start");
+  }
+
+  // Locate this interface's entry in the table
+  Value *iklass = builder()->CreateInlineOop(method->holder());
+  BasicBlock *loop_entry = builder()->GetInsertBlock();
+  builder()->CreateBr(loop);
+  builder()->SetInsertPoint(loop);
+  PHINode *itable_entry_addr = builder()->CreatePHI(
+    SharkType::intptr_type(), "itable_entry_addr");
+  itable_entry_addr->addIncoming(itable_start, loop_entry);
+
+  Value *itable_entry = builder()->CreateIntToPtr(
+    itable_entry_addr, SharkType::itableOffsetEntry_type(), "itable_entry");
+
+  Value *itable_iklass = builder()->CreateValueOfStructEntry(
+    itable_entry,
+    in_ByteSize(itableOffsetEntry::interface_offset_in_bytes()),
+    SharkType::oop_type(),
+    "itable_iklass");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(itable_iklass, LLVMValue::null()),
+    got_null, not_null);
+
+  // A null entry means that the class doesn't implement the
+  // interface, and wasn't the same as the class checked when
+  // the interface was resolved.
+  builder()->SetInsertPoint(got_null);
+  builder()->CreateUnimplemented(__FILE__, __LINE__);
+  builder()->CreateUnreachable();
+
+  builder()->SetInsertPoint(not_null);
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(itable_iklass, iklass),
+    got_entry, next);
+
+  builder()->SetInsertPoint(next);
+  Value *next_entry = builder()->CreateAdd(
+    itable_entry_addr,
+    LLVMValue::intptr_constant(itableOffsetEntry::size() * wordSize));
+  builder()->CreateBr(loop);
+  itable_entry_addr->addIncoming(next_entry, next);
+
+  // Locate the method pointer
+  builder()->SetInsertPoint(got_entry);
+  Value *offset = builder()->CreateValueOfStructEntry(
+    itable_entry,
+    in_ByteSize(itableOffsetEntry::offset_offset_in_bytes()),
+    SharkType::jint_type(),
+    "offset");
+  offset =
+    builder()->CreateIntCast(offset, SharkType::intptr_type(), false);
+
+  return builder()->CreateLoad(
+    builder()->CreateIntToPtr(
+      builder()->CreateAdd(
+        builder()->CreateAdd(
+          builder()->CreateAdd(
+            builder()->CreatePtrToInt(
+              object_klass, SharkType::intptr_type()),
+            offset),
+          LLVMValue::intptr_constant(
+            method->itable_index() * itableMethodEntry::size() * wordSize)),
+        LLVMValue::intptr_constant(
+          itableMethodEntry::method_offset_in_bytes())),
+      PointerType::getUnqual(SharkType::methodOop_type())),
+    "callee");
+}
+
+void SharkTopLevelBlock::do_call() {
+  // Set frequently used booleans
+  bool is_static = bc() == Bytecodes::_invokestatic;
+  bool is_virtual = bc() == Bytecodes::_invokevirtual;
+  bool is_interface = bc() == Bytecodes::_invokeinterface;
+
+  // Find the method being called
+  bool will_link;
+  ciMethod *dest_method = iter()->get_method(will_link);
+  assert(will_link, "typeflow responsibility");
+  assert(dest_method->is_static() == is_static, "must match bc");
+
+  // Find the class of the method being called.  Note
+  // that the superclass check in the second assertion
+  // is to cope with a hole in the spec that allows for
+  // invokeinterface instructions where the resolved
+  // method is a virtual method in java.lang.Object.
+  // javac doesn't generate code like that, but there's
+  // no reason a compliant Java compiler might not.
+  ciInstanceKlass *holder_klass  = dest_method->holder();
+  assert(holder_klass->is_loaded(), "scan_for_traps responsibility");
+  assert(holder_klass->is_interface() ||
+         holder_klass->super() == NULL ||
+         !is_interface, "must match bc");
+  ciKlass *holder = iter()->get_declared_method_holder();
+  ciInstanceKlass *klass =
+    ciEnv::get_instance_klass_for_declared_method_holder(holder);
+
+  // Find the receiver in the stack.  We do this before
+  // trying to inline because the inliner can only use
+  // zero-checked values, not being able to perform the
+  // check itself.
+  SharkValue *receiver = NULL;
+  if (!is_static) {
+    receiver = xstack(dest_method->arg_size() - 1);
+    check_null(receiver);
+  }
+
+  // Try to improve non-direct calls
+  bool call_is_virtual = is_virtual || is_interface;
+  ciMethod *call_method = dest_method;
+  if (call_is_virtual) {
+    ciMethod *optimized_method = improve_virtual_call(
+      target(), klass, dest_method, receiver->type());
+    if (optimized_method) {
+      call_method = optimized_method;
+      call_is_virtual = false;
+    }
+  }
+
+  // Try to inline the call
+  if (!call_is_virtual) {
+    if (SharkInliner::attempt_inline(call_method, current_state()))
+      return;
+  }
+
+  // Find the method we are calling
+  Value *callee;
+  if (call_is_virtual) {
+    if (is_virtual) {
+      assert(klass->is_linked(), "scan_for_traps responsibility");
+      int vtable_index = call_method->resolve_vtable_index(
+        target()->holder(), klass);
+      assert(vtable_index >= 0, "should be");
+      callee = get_virtual_callee(receiver, vtable_index);
+    }
+    else {
+      assert(is_interface, "should be");
+      callee = get_interface_callee(receiver, call_method);
+    }
+  }
+  else {
+    callee = get_direct_callee(call_method);
+  }
+
+  // Load the SharkEntry from the callee
+  Value *base_pc = builder()->CreateValueOfStructEntry(
+    callee, methodOopDesc::from_interpreted_offset(),
+    SharkType::intptr_type(),
+    "base_pc");
+
+  // Load the entry point from the SharkEntry
+  Value *entry_point = builder()->CreateLoad(
+    builder()->CreateIntToPtr(
+      builder()->CreateAdd(
+        base_pc,
+        LLVMValue::intptr_constant(in_bytes(ZeroEntry::entry_point_offset()))),
+      PointerType::getUnqual(
+        PointerType::getUnqual(SharkType::entry_point_type()))),
+    "entry_point");
+
+  // Make the call
+  decache_for_Java_call(call_method);
+  Value *deoptimized_frames = builder()->CreateCall3(
+    entry_point, callee, base_pc, thread());
+
+  // If the callee got deoptimized then reexecute in the interpreter
+  BasicBlock *reexecute      = function()->CreateBlock("reexecute");
+  BasicBlock *call_completed = function()->CreateBlock("call_completed");
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(deoptimized_frames, LLVMValue::jint_constant(0)),
+    reexecute, call_completed);
+
+  builder()->SetInsertPoint(reexecute);
+  builder()->CreateCall2(
+    builder()->deoptimized_entry_point(),
+    builder()->CreateSub(deoptimized_frames, LLVMValue::jint_constant(1)),
+    thread());
+  builder()->CreateBr(call_completed);
+
+  // Cache after the call
+  builder()->SetInsertPoint(call_completed);
+  cache_after_Java_call(call_method);
+
+  // Check for pending exceptions
+  check_pending_exception(EX_CHECK_FULL);
+
+  // Mark that a safepoint check has occurred
+  current_state()->set_has_safepointed(true);
+}
+
+bool SharkTopLevelBlock::static_subtype_check(ciKlass* check_klass,
+                                              ciKlass* object_klass) {
+  // If the class we're checking against is java.lang.Object
+  // then this is a no brainer.  Apparently this can happen
+  // in reflective code...
+  if (check_klass == java_lang_Object_klass())
+    return true;
+
+  // Perform a subtype check.  NB in opto's code for this
+  // (GraphKit::static_subtype_check) it says that static
+  // interface types cannot be trusted, and if opto can't
+  // trust them then I assume we can't either.
+  if (object_klass->is_loaded() && !object_klass->is_interface()) {
+    if (object_klass == check_klass)
+      return true;
+
+    if (check_klass->is_loaded() && object_klass->is_subtype_of(check_klass))
+      return true;
+  }
+
+  return false;
+}
+
+void SharkTopLevelBlock::do_instance_check() {
+  // Get the class we're checking against
+  bool will_link;
+  ciKlass *check_klass = iter()->get_klass(will_link);
+
+  // Get the class of the object we're checking
+  ciKlass *object_klass = xstack(0)->type()->as_klass();
+
+  // Can we optimize this check away?
+  if (static_subtype_check(check_klass, object_klass)) {
+    if (bc() == Bytecodes::_instanceof) {
+      pop();
+      push(SharkValue::jint_constant(1));
+    }
+    return;
+  }
+
+  // Need to check this one at runtime
+  if (will_link)
+    do_full_instance_check(check_klass);
+  else
+    do_trapping_instance_check(check_klass);
+}
+
+bool SharkTopLevelBlock::maybe_do_instanceof_if() {
+  // Get the class we're checking against
+  bool will_link;
+  ciKlass *check_klass = iter()->get_klass(will_link);
+
+  // If the class is unloaded then the instanceof
+  // cannot possibly succeed.
+  if (!will_link)
+    return false;
+
+  // Keep a copy of the object we're checking
+  SharkValue *old_object = xstack(0);
+
+  // Get the class of the object we're checking
+  ciKlass *object_klass = old_object->type()->as_klass();
+
+  // If the instanceof can be optimized away at compile time
+  // then any subsequent checkcasts will be too so we handle
+  // it normally.
+  if (static_subtype_check(check_klass, object_klass))
+    return false;
+
+  // Perform the instance check
+  do_full_instance_check(check_klass);
+  Value *result = pop()->jint_value();
+
+  // Create the casted object
+  SharkValue *new_object = SharkValue::create_generic(
+    check_klass, old_object->jobject_value(), old_object->zero_checked());
+
+  // Create two copies of the current state, one with the
+  // original object and one with all instances of the
+  // original object replaced with the new, casted object.
+  SharkState *new_state = current_state();
+  SharkState *old_state = new_state->copy();
+  new_state->replace_all(old_object, new_object);
+
+  // Perform the check-and-branch
+  switch (iter()->next_bc()) {
+  case Bytecodes::_ifeq:
+    // branch if not an instance
+    do_if_helper(
+      ICmpInst::ICMP_EQ,
+      LLVMValue::jint_constant(0), result,
+      old_state, new_state);
+    break;
+
+  case Bytecodes::_ifne:
+    // branch if an instance
+    do_if_helper(
+      ICmpInst::ICMP_NE,
+      LLVMValue::jint_constant(0), result,
+      new_state, old_state);
+    break;
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  return true;
+}
+
+void SharkTopLevelBlock::do_full_instance_check(ciKlass* klass) {
+  BasicBlock *not_null      = function()->CreateBlock("not_null");
+  BasicBlock *subtype_check = function()->CreateBlock("subtype_check");
+  BasicBlock *is_instance   = function()->CreateBlock("is_instance");
+  BasicBlock *not_instance  = function()->CreateBlock("not_instance");
+  BasicBlock *merge1        = function()->CreateBlock("merge1");
+  BasicBlock *merge2        = function()->CreateBlock("merge2");
+
+  enum InstanceCheckStates {
+    IC_IS_NULL,
+    IC_IS_INSTANCE,
+    IC_NOT_INSTANCE,
+  };
+
+  // Pop the object off the stack
+  Value *object = pop()->jobject_value();
+
+  // Null objects aren't instances of anything
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(object, LLVMValue::null()),
+    merge2, not_null);
+  BasicBlock *null_block = builder()->GetInsertBlock();
+
+  // Get the class we're checking against
+  builder()->SetInsertPoint(not_null);
+  Value *check_klass = builder()->CreateInlineOop(klass);
+
+  // Get the class of the object being tested
+  Value *object_klass = builder()->CreateValueOfStructEntry(
+    object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
+    SharkType::oop_type(),
+    "object_klass");
+
+  // Perform the check
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(check_klass, object_klass),
+    is_instance, subtype_check);
+
+  builder()->SetInsertPoint(subtype_check);
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(
+      builder()->CreateCall2(
+        builder()->is_subtype_of(), check_klass, object_klass),
+      LLVMValue::jbyte_constant(0)),
+    is_instance, not_instance);
+
+  builder()->SetInsertPoint(is_instance);
+  builder()->CreateBr(merge1);
+
+  builder()->SetInsertPoint(not_instance);
+  builder()->CreateBr(merge1);
+
+  // First merge
+  builder()->SetInsertPoint(merge1);
+  PHINode *nonnull_result = builder()->CreatePHI(
+    SharkType::jint_type(), "nonnull_result");
+  nonnull_result->addIncoming(
+    LLVMValue::jint_constant(IC_IS_INSTANCE), is_instance);
+  nonnull_result->addIncoming(
+    LLVMValue::jint_constant(IC_NOT_INSTANCE), not_instance);
+  BasicBlock *nonnull_block = builder()->GetInsertBlock();
+  builder()->CreateBr(merge2);
+
+  // Second merge
+  builder()->SetInsertPoint(merge2);
+  PHINode *result = builder()->CreatePHI(
+    SharkType::jint_type(), "result");
+  result->addIncoming(LLVMValue::jint_constant(IC_IS_NULL), null_block);
+  result->addIncoming(nonnull_result, nonnull_block);
+
+  // Handle the result
+  if (bc() == Bytecodes::_checkcast) {
+    BasicBlock *failure = function()->CreateBlock("failure");
+    BasicBlock *success = function()->CreateBlock("success");
+
+    builder()->CreateCondBr(
+      builder()->CreateICmpNE(
+        result, LLVMValue::jint_constant(IC_NOT_INSTANCE)),
+      success, failure);
+
+    builder()->SetInsertPoint(failure);
+    SharkState *saved_state = current_state()->copy();
+
+    call_vm(
+      builder()->throw_ClassCastException(),
+      builder()->CreateIntToPtr(
+        LLVMValue::intptr_constant((intptr_t) __FILE__),
+        PointerType::getUnqual(SharkType::jbyte_type())),
+      LLVMValue::jint_constant(__LINE__),
+      EX_CHECK_NONE);
+
+    Value *pending_exception = get_pending_exception();
+    clear_pending_exception();
+    handle_exception(pending_exception, EX_CHECK_FULL);
+
+    set_current_state(saved_state);
+    builder()->SetInsertPoint(success);
+    push(SharkValue::create_generic(klass, object, false));
+  }
+  else {
+    push(
+      SharkValue::create_jint(
+        builder()->CreateIntCast(
+          builder()->CreateICmpEQ(
+            result, LLVMValue::jint_constant(IC_IS_INSTANCE)),
+          SharkType::jint_type(), false), false));
+  }
+}
+
+void SharkTopLevelBlock::do_trapping_instance_check(ciKlass* klass) {
+  BasicBlock *not_null = function()->CreateBlock("not_null");
+  BasicBlock *is_null  = function()->CreateBlock("null");
+
+  // Leave the object on the stack so it's there if we trap
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(xstack(0)->jobject_value(), LLVMValue::null()),
+    is_null, not_null);
+  SharkState *saved_state = current_state()->copy();
+
+  // If it's not null then we need to trap
+  builder()->SetInsertPoint(not_null);
+  set_current_state(saved_state->copy());
+  do_trap(
+    Deoptimization::make_trap_request(
+      Deoptimization::Reason_uninitialized,
+      Deoptimization::Action_reinterpret));
+
+  // If it's null then we're ok
+  builder()->SetInsertPoint(is_null);
+  set_current_state(saved_state);
+  if (bc() == Bytecodes::_checkcast) {
+    push(SharkValue::create_generic(klass, pop()->jobject_value(), false));
+  }
+  else {
+    pop();
+    push(SharkValue::jint_constant(0));
+  }
+}
+
+void SharkTopLevelBlock::do_new() {
+  bool will_link;
+  ciInstanceKlass* klass = iter()->get_klass(will_link)->as_instance_klass();
+  assert(will_link, "typeflow responsibility");
+
+  BasicBlock *got_tlab            = NULL;
+  BasicBlock *heap_alloc          = NULL;
+  BasicBlock *retry               = NULL;
+  BasicBlock *got_heap            = NULL;
+  BasicBlock *initialize          = NULL;
+  BasicBlock *got_fast            = NULL;
+  BasicBlock *slow_alloc_and_init = NULL;
+  BasicBlock *got_slow            = NULL;
+  BasicBlock *push_object         = NULL;
+
+  SharkState *fast_state = NULL;
+
+  Value *tlab_object = NULL;
+  Value *heap_object = NULL;
+  Value *fast_object = NULL;
+  Value *slow_object = NULL;
+  Value *object      = NULL;
+
+  // The fast path
+  if (!Klass::layout_helper_needs_slow_path(klass->layout_helper())) {
+    if (UseTLAB) {
+      got_tlab          = function()->CreateBlock("got_tlab");
+      heap_alloc        = function()->CreateBlock("heap_alloc");
+    }
+    retry               = function()->CreateBlock("retry");
+    got_heap            = function()->CreateBlock("got_heap");
+    initialize          = function()->CreateBlock("initialize");
+    slow_alloc_and_init = function()->CreateBlock("slow_alloc_and_init");
+    push_object         = function()->CreateBlock("push_object");
+
+    size_t size_in_bytes = klass->size_helper() << LogHeapWordSize;
+
+    // Thread local allocation
+    if (UseTLAB) {
+      Value *top_addr = builder()->CreateAddressOfStructEntry(
+        thread(), Thread::tlab_top_offset(),
+        PointerType::getUnqual(SharkType::intptr_type()),
+        "top_addr");
+
+      Value *end = builder()->CreateValueOfStructEntry(
+        thread(), Thread::tlab_end_offset(),
+        SharkType::intptr_type(),
+        "end");
+
+      Value *old_top = builder()->CreateLoad(top_addr, "old_top");
+      Value *new_top = builder()->CreateAdd(
+        old_top, LLVMValue::intptr_constant(size_in_bytes));
+
+      builder()->CreateCondBr(
+        builder()->CreateICmpULE(new_top, end),
+        got_tlab, heap_alloc);
+
+      builder()->SetInsertPoint(got_tlab);
+      tlab_object = builder()->CreateIntToPtr(
+        old_top, SharkType::oop_type(), "tlab_object");
+
+      builder()->CreateStore(new_top, top_addr);
+      builder()->CreateBr(initialize);
+
+      builder()->SetInsertPoint(heap_alloc);
+    }
+
+    // Heap allocation
+    Value *top_addr = builder()->CreateIntToPtr(
+        LLVMValue::intptr_constant((intptr_t) Universe::heap()->top_addr()),
+      PointerType::getUnqual(SharkType::intptr_type()),
+      "top_addr");
+
+    Value *end = builder()->CreateLoad(
+      builder()->CreateIntToPtr(
+        LLVMValue::intptr_constant((intptr_t) Universe::heap()->end_addr()),
+        PointerType::getUnqual(SharkType::intptr_type())),
+      "end");
+
+    builder()->CreateBr(retry);
+    builder()->SetInsertPoint(retry);
+
+    Value *old_top = builder()->CreateLoad(top_addr, "top");
+    Value *new_top = builder()->CreateAdd(
+      old_top, LLVMValue::intptr_constant(size_in_bytes));
+
+    builder()->CreateCondBr(
+      builder()->CreateICmpULE(new_top, end),
+      got_heap, slow_alloc_and_init);
+
+    builder()->SetInsertPoint(got_heap);
+    heap_object = builder()->CreateIntToPtr(
+      old_top, SharkType::oop_type(), "heap_object");
+
+    Value *check = builder()->CreateCmpxchgPtr(new_top, top_addr, old_top);
+    builder()->CreateCondBr(
+      builder()->CreateICmpEQ(old_top, check),
+      initialize, retry);
+
+    // Initialize the object
+    builder()->SetInsertPoint(initialize);
+    if (tlab_object) {
+      PHINode *phi = builder()->CreatePHI(
+        SharkType::oop_type(), "fast_object");
+      phi->addIncoming(tlab_object, got_tlab);
+      phi->addIncoming(heap_object, got_heap);
+      fast_object = phi;
+    }
+    else {
+      fast_object = heap_object;
+    }
+
+    builder()->CreateMemset(
+      builder()->CreateBitCast(
+        fast_object, PointerType::getUnqual(SharkType::jbyte_type())),
+      LLVMValue::jbyte_constant(0),
+      LLVMValue::jint_constant(size_in_bytes),
+      LLVMValue::jint_constant(HeapWordSize));
+
+    Value *mark_addr = builder()->CreateAddressOfStructEntry(
+      fast_object, in_ByteSize(oopDesc::mark_offset_in_bytes()),
+      PointerType::getUnqual(SharkType::intptr_type()),
+      "mark_addr");
+
+    Value *klass_addr = builder()->CreateAddressOfStructEntry(
+      fast_object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
+      PointerType::getUnqual(SharkType::oop_type()),
+      "klass_addr");
+
+    // Set the mark
+    intptr_t mark;
+    if (UseBiasedLocking) {
+      Unimplemented();
+    }
+    else {
+      mark = (intptr_t) markOopDesc::prototype();
+    }
+    builder()->CreateStore(LLVMValue::intptr_constant(mark), mark_addr);
+
+    // Set the class
+    Value *rtklass = builder()->CreateInlineOop(klass);
+    builder()->CreateStore(rtklass, klass_addr);
+    got_fast = builder()->GetInsertBlock();
+
+    builder()->CreateBr(push_object);
+    builder()->SetInsertPoint(slow_alloc_and_init);
+    fast_state = current_state()->copy();
+  }
+
+  // The slow path
+  call_vm(
+    builder()->new_instance(),
+    LLVMValue::jint_constant(iter()->get_klass_index()),
+    EX_CHECK_FULL);
+  slow_object = get_vm_result();
+  got_slow = builder()->GetInsertBlock();
+
+  // Push the object
+  if (push_object) {
+    builder()->CreateBr(push_object);
+    builder()->SetInsertPoint(push_object);
+  }
+  if (fast_object) {
+    PHINode *phi = builder()->CreatePHI(SharkType::oop_type(), "object");
+    phi->addIncoming(fast_object, got_fast);
+    phi->addIncoming(slow_object, got_slow);
+    object = phi;
+    current_state()->merge(fast_state, got_fast, got_slow);
+  }
+  else {
+    object = slow_object;
+  }
+
+  push(SharkValue::create_jobject(object, true));
+}
+
+void SharkTopLevelBlock::do_newarray() {
+  BasicType type = (BasicType) iter()->get_index();
+
+  call_vm(
+    builder()->newarray(),
+    LLVMValue::jint_constant(type),
+    pop()->jint_value(),
+    EX_CHECK_FULL);
+
+  ciArrayKlass *array_klass = ciArrayKlass::make(ciType::make(type));
+  push(SharkValue::create_generic(array_klass, get_vm_result(), true));
+}
+
+void SharkTopLevelBlock::do_anewarray() {
+  bool will_link;
+  ciKlass *klass = iter()->get_klass(will_link);
+  assert(will_link, "typeflow responsibility");
+
+  ciObjArrayKlass *array_klass = ciObjArrayKlass::make(klass);
+  if (!array_klass->is_loaded()) {
+    Unimplemented();
+  }
+
+  call_vm(
+    builder()->anewarray(),
+    LLVMValue::jint_constant(iter()->get_klass_index()),
+    pop()->jint_value(),
+    EX_CHECK_FULL);
+
+  push(SharkValue::create_generic(array_klass, get_vm_result(), true));
+}
+
+void SharkTopLevelBlock::do_multianewarray() {
+  bool will_link;
+  ciArrayKlass *array_klass = iter()->get_klass(will_link)->as_array_klass();
+  assert(will_link, "typeflow responsibility");
+
+  // The dimensions are stack values, so we use their slots for the
+  // dimensions array.  Note that we are storing them in the reverse
+  // of normal stack order.
+  int ndims = iter()->get_dimensions();
+
+  Value *dimensions = stack()->slot_addr(
+    stack()->stack_slots_offset() + max_stack() - xstack_depth(),
+    ArrayType::get(SharkType::jint_type(), ndims),
+    "dimensions");
+
+  for (int i = 0; i < ndims; i++) {
+    builder()->CreateStore(
+      xstack(ndims - 1 - i)->jint_value(),
+      builder()->CreateStructGEP(dimensions, i));
+  }
+
+  call_vm(
+    builder()->multianewarray(),
+    LLVMValue::jint_constant(iter()->get_klass_index()),
+    LLVMValue::jint_constant(ndims),
+    builder()->CreateStructGEP(dimensions, 0),
+    EX_CHECK_FULL);
+
+  // Now we can pop the dimensions off the stack
+  for (int i = 0; i < ndims; i++)
+    pop();
+
+  push(SharkValue::create_generic(array_klass, get_vm_result(), true));
+}
+
+void SharkTopLevelBlock::acquire_method_lock() {
+  Value *lockee;
+  if (target()->is_static())
+    lockee = builder()->CreateInlineOop(target()->holder()->java_mirror());
+  else
+    lockee = local(0)->jobject_value();
+
+  iter()->force_bci(start()); // for the decache in acquire_lock
+  acquire_lock(lockee, EX_CHECK_NO_CATCH);
+}
+
+void SharkTopLevelBlock::do_monitorenter() {
+  SharkValue *lockee = pop();
+  check_null(lockee);
+  acquire_lock(lockee->jobject_value(), EX_CHECK_FULL);
+}
+
+void SharkTopLevelBlock::do_monitorexit() {
+  pop(); // don't need this (monitors are block structured)
+  release_lock(EX_CHECK_NO_CATCH);
+}
+
+void SharkTopLevelBlock::acquire_lock(Value *lockee, int exception_action) {
+  BasicBlock *try_recursive = function()->CreateBlock("try_recursive");
+  BasicBlock *got_recursive = function()->CreateBlock("got_recursive");
+  BasicBlock *not_recursive = function()->CreateBlock("not_recursive");
+  BasicBlock *acquired_fast = function()->CreateBlock("acquired_fast");
+  BasicBlock *lock_acquired = function()->CreateBlock("lock_acquired");
+
+  int monitor = num_monitors();
+  Value *monitor_addr        = stack()->monitor_addr(monitor);
+  Value *monitor_object_addr = stack()->monitor_object_addr(monitor);
+  Value *monitor_header_addr = stack()->monitor_header_addr(monitor);
+
+  // Store the object and mark the slot as live
+  builder()->CreateStore(lockee, monitor_object_addr);
+  set_num_monitors(monitor + 1);
+
+  // Try a simple lock
+  Value *mark_addr = builder()->CreateAddressOfStructEntry(
+    lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()),
+    PointerType::getUnqual(SharkType::intptr_type()),
+    "mark_addr");
+
+  Value *mark = builder()->CreateLoad(mark_addr, "mark");
+  Value *disp = builder()->CreateOr(
+    mark, LLVMValue::intptr_constant(markOopDesc::unlocked_value), "disp");
+  builder()->CreateStore(disp, monitor_header_addr);
+
+  Value *lock = builder()->CreatePtrToInt(
+    monitor_header_addr, SharkType::intptr_type());
+  Value *check = builder()->CreateCmpxchgPtr(lock, mark_addr, disp);
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(disp, check),
+    acquired_fast, try_recursive);
+
+  // Locking failed, but maybe this thread already owns it
+  builder()->SetInsertPoint(try_recursive);
+  Value *addr = builder()->CreateAnd(
+    disp,
+    LLVMValue::intptr_constant(~markOopDesc::lock_mask_in_place));
+
+  // NB we use the entire stack, but JavaThread::is_lock_owned()
+  // uses a more limited range.  I don't think it hurts though...
+  Value *stack_limit = builder()->CreateValueOfStructEntry(
+    thread(), Thread::stack_base_offset(),
+    SharkType::intptr_type(),
+    "stack_limit");
+
+  assert(sizeof(size_t) == sizeof(intptr_t), "should be");
+  Value *stack_size = builder()->CreateValueOfStructEntry(
+    thread(), Thread::stack_size_offset(),
+    SharkType::intptr_type(),
+    "stack_size");
+
+  Value *stack_start =
+    builder()->CreateSub(stack_limit, stack_size, "stack_start");
+
+  builder()->CreateCondBr(
+    builder()->CreateAnd(
+      builder()->CreateICmpUGE(addr, stack_start),
+      builder()->CreateICmpULT(addr, stack_limit)),
+    got_recursive, not_recursive);
+
+  builder()->SetInsertPoint(got_recursive);
+  builder()->CreateStore(LLVMValue::intptr_constant(0), monitor_header_addr);
+  builder()->CreateBr(acquired_fast);
+
+  // Create an edge for the state merge
+  builder()->SetInsertPoint(acquired_fast);
+  SharkState *fast_state = current_state()->copy();
+  builder()->CreateBr(lock_acquired);
+
+  // It's not a recursive case so we need to drop into the runtime
+  builder()->SetInsertPoint(not_recursive);
+  call_vm(
+    builder()->monitorenter(), monitor_addr,
+    exception_action | EAM_MONITOR_FUDGE);
+  BasicBlock *acquired_slow = builder()->GetInsertBlock();
+  builder()->CreateBr(lock_acquired);
+
+  // All done
+  builder()->SetInsertPoint(lock_acquired);
+  current_state()->merge(fast_state, acquired_fast, acquired_slow);
+}
+
+void SharkTopLevelBlock::release_lock(int exception_action) {
+  BasicBlock *not_recursive = function()->CreateBlock("not_recursive");
+  BasicBlock *released_fast = function()->CreateBlock("released_fast");
+  BasicBlock *slow_path     = function()->CreateBlock("slow_path");
+  BasicBlock *lock_released = function()->CreateBlock("lock_released");
+
+  int monitor = num_monitors() - 1;
+  Value *monitor_addr        = stack()->monitor_addr(monitor);
+  Value *monitor_object_addr = stack()->monitor_object_addr(monitor);
+  Value *monitor_header_addr = stack()->monitor_header_addr(monitor);
+
+  // If it is recursive then we're already done
+  Value *disp = builder()->CreateLoad(monitor_header_addr);
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(disp, LLVMValue::intptr_constant(0)),
+    released_fast, not_recursive);
+
+  // Try a simple unlock
+  builder()->SetInsertPoint(not_recursive);
+
+  Value *lock = builder()->CreatePtrToInt(
+    monitor_header_addr, SharkType::intptr_type());
+
+  Value *lockee = builder()->CreateLoad(monitor_object_addr);
+
+  Value *mark_addr = builder()->CreateAddressOfStructEntry(
+    lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()),
+    PointerType::getUnqual(SharkType::intptr_type()),
+    "mark_addr");
+
+  Value *check = builder()->CreateCmpxchgPtr(disp, mark_addr, lock);
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(lock, check),
+    released_fast, slow_path);
+
+  // Create an edge for the state merge
+  builder()->SetInsertPoint(released_fast);
+  SharkState *fast_state = current_state()->copy();
+  builder()->CreateBr(lock_released);
+
+  // Need to drop into the runtime to release this one
+  builder()->SetInsertPoint(slow_path);
+  call_vm(builder()->monitorexit(), monitor_addr, exception_action);
+  BasicBlock *released_slow = builder()->GetInsertBlock();
+  builder()->CreateBr(lock_released);
+
+  // All done
+  builder()->SetInsertPoint(lock_released);
+  current_state()->merge(fast_state, released_fast, released_slow);
+
+  // The object slot is now dead
+  set_num_monitors(monitor);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,430 @@
+/*
+ * 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 SharkTopLevelBlock : public SharkBlock {
+ public:
+  SharkTopLevelBlock(SharkFunction* function, ciTypeFlow::Block* ciblock)
+    : SharkBlock(function),
+      _function(function),
+      _ciblock(ciblock),
+      _entered(false),
+      _has_trap(false),
+      _needs_phis(false),
+      _entry_state(NULL),
+      _entry_block(NULL) {}
+
+ private:
+  SharkFunction*     _function;
+  ciTypeFlow::Block* _ciblock;
+
+ public:
+  SharkFunction* function() const {
+    return _function;
+  }
+  ciTypeFlow::Block* ciblock() const {
+    return _ciblock;
+  }
+
+  // Function properties
+ public:
+  SharkStack* stack() const {
+    return function()->stack();
+  }
+
+  // Typeflow properties
+ public:
+  int index() const {
+    return ciblock()->pre_order();
+  }
+  bool is_backedge_copy() const {
+    return ciblock()->is_backedge_copy();
+  }
+  int stack_depth_at_entry() const {
+    return ciblock()->stack_size();
+  }
+  ciType* local_type_at_entry(int index) const {
+    return ciblock()->local_type_at(index);
+  }
+  ciType* stack_type_at_entry(int slot) const {
+    return ciblock()->stack_type_at(slot);
+  }
+  int start() const {
+    return ciblock()->start();
+  }
+  int limit() const {
+    return ciblock()->limit();
+  }
+  bool falls_through() const {
+    return ciblock()->control() == ciBlock::fall_through_bci;
+  }
+  int num_successors() const {
+    return ciblock()->successors()->length();
+  }
+  SharkTopLevelBlock* successor(int index) const {
+    return function()->block(ciblock()->successors()->at(index)->pre_order());
+  }
+  SharkTopLevelBlock* bci_successor(int bci) const;
+
+  // Exceptions
+ private:
+  GrowableArray<ciExceptionHandler*>* _exc_handlers;
+  GrowableArray<SharkTopLevelBlock*>* _exceptions;
+
+ private:
+  void compute_exceptions();
+
+ private:
+  int num_exceptions() const {
+    return _exc_handlers->length();
+  }
+  ciExceptionHandler* exc_handler(int index) const {
+    return _exc_handlers->at(index);
+  }
+  SharkTopLevelBlock* exception(int index) const {
+    return _exceptions->at(index);
+  }
+
+  // Traps
+ private:
+  bool _has_trap;
+  int  _trap_request;
+  int  _trap_bci;
+
+  void set_trap(int trap_request, int trap_bci) {
+    assert(!has_trap(), "shouldn't have");
+    _has_trap     = true;
+    _trap_request = trap_request;
+    _trap_bci     = trap_bci;
+  }
+
+ private:
+  bool has_trap() {
+    return _has_trap;
+  }
+  int trap_request() {
+    assert(has_trap(), "should have");
+    return _trap_request;
+  }
+  int trap_bci() {
+    assert(has_trap(), "should have");
+    return _trap_bci;
+  }
+
+ private:
+  void scan_for_traps();
+
+ private:
+  bool static_field_ok_in_clinit(ciField* field);
+
+  // Entry state
+ private:
+  bool _entered;
+  bool _needs_phis;
+
+ public:
+  bool entered() const {
+    return _entered;
+  }
+  bool needs_phis() const {
+    return _needs_phis;
+  }
+
+ private:
+  void enter(SharkTopLevelBlock* predecessor, bool is_exception);
+
+ public:
+  void enter() {
+    enter(NULL, false);
+  }
+
+ private:
+  SharkState* _entry_state;
+
+ private:
+  SharkState* entry_state();
+
+ private:
+  llvm::BasicBlock* _entry_block;
+
+ public:
+  llvm::BasicBlock* entry_block() const {
+    return _entry_block;
+  }
+
+ public:
+  void initialize();
+
+ public:
+  void add_incoming(SharkState* incoming_state);
+
+  // Method
+ public:
+  llvm::Value* method() {
+    return current_state()->method();
+  }
+
+  // Temporary oop storage
+ public:
+  void set_oop_tmp(llvm::Value* value) {
+    assert(value, "value must be non-NULL (will be reset by get_oop_tmp)");
+    assert(!current_state()->oop_tmp(), "oop_tmp gets and sets must match");
+    current_state()->set_oop_tmp(value);
+  }
+  llvm::Value* get_oop_tmp() {
+    llvm::Value* value = current_state()->oop_tmp();
+    assert(value, "oop_tmp gets and sets must match");
+    current_state()->set_oop_tmp(NULL);
+    return value;
+  }
+
+  // Cache and decache
+ private:
+  void decache_for_Java_call(ciMethod* callee);
+  void cache_after_Java_call(ciMethod* callee);
+  void decache_for_VM_call();
+  void cache_after_VM_call();
+  void decache_for_trap();
+
+  // Monitors
+ private:
+  int num_monitors() {
+    return current_state()->num_monitors();
+  }
+  int set_num_monitors(int num_monitors) {
+    current_state()->set_num_monitors(num_monitors);
+  }
+
+  // Code generation
+ public:
+  void emit_IR();
+
+  // Branch helpers
+ private:
+  void do_branch(int successor_index);
+
+  // Zero checks
+ private:
+  void do_zero_check(SharkValue* value);
+  void zero_check_value(SharkValue* value, llvm::BasicBlock* continue_block);
+
+ public:
+  void do_deferred_zero_check(SharkValue*       value,
+                              int               bci,
+                              SharkState*       saved_state,
+                              llvm::BasicBlock* continue_block);
+  // Exceptions
+ private:
+  llvm::Value* pending_exception_address() const {
+    return builder()->CreateAddressOfStructEntry(
+      thread(), Thread::pending_exception_offset(),
+      llvm::PointerType::getUnqual(SharkType::oop_type()),
+      "pending_exception_addr");
+  }
+  llvm::LoadInst* get_pending_exception() const {
+    return builder()->CreateLoad(
+      pending_exception_address(), "pending_exception");
+  }
+  void clear_pending_exception() const {
+    builder()->CreateStore(LLVMValue::null(), pending_exception_address());
+  }
+ public:
+  enum ExceptionActionMask {
+    // The actual bitmasks that things test against
+    EAM_CHECK         = 1, // whether to check for pending exceptions
+    EAM_HANDLE        = 2, // whether to attempt to handle pending exceptions
+    EAM_MONITOR_FUDGE = 4, // whether the monitor count needs adjusting
+
+    // More convenient values for passing
+    EX_CHECK_NONE     = 0,
+    EX_CHECK_NO_CATCH = EAM_CHECK,
+    EX_CHECK_FULL     = EAM_CHECK | EAM_HANDLE
+  };
+  void check_pending_exception(int action);
+  void handle_exception(llvm::Value* exception, int action);
+  void marshal_exception_fast(int num_options);
+  void marshal_exception_slow(int num_options);
+  llvm::BasicBlock* handler_for_exception(int index);
+
+  // VM calls
+ private:
+  llvm::CallInst* call_vm(llvm::Value*  callee,
+                          llvm::Value** args_start,
+                          llvm::Value** args_end,
+                          int           exception_action) {
+    decache_for_VM_call();
+    stack()->CreateSetLastJavaFrame();
+    llvm::CallInst *res = builder()->CreateCall(callee, args_start, args_end);
+    stack()->CreateResetLastJavaFrame();
+    cache_after_VM_call();
+    if (exception_action & EAM_CHECK) {
+      check_pending_exception(exception_action);
+      current_state()->set_has_safepointed(true);
+    }
+    return res;
+  }
+
+ public:
+  llvm::CallInst* call_vm(llvm::Value* callee,
+                          int          exception_action) {
+    llvm::Value *args[] = {thread()};
+    return call_vm(callee, args, args + 1, exception_action);
+  }
+  llvm::CallInst* call_vm(llvm::Value* callee,
+                          llvm::Value* arg1,
+                          int          exception_action) {
+    llvm::Value *args[] = {thread(), arg1};
+    return call_vm(callee, args, args + 2, exception_action);
+  }
+  llvm::CallInst* call_vm(llvm::Value* callee,
+                          llvm::Value* arg1,
+                          llvm::Value* arg2,
+                          int          exception_action) {
+    llvm::Value *args[] = {thread(), arg1, arg2};
+    return call_vm(callee, args, args + 3, exception_action);
+  }
+  llvm::CallInst* call_vm(llvm::Value* callee,
+                          llvm::Value* arg1,
+                          llvm::Value* arg2,
+                          llvm::Value* arg3,
+                          int          exception_action) {
+    llvm::Value *args[] = {thread(), arg1, arg2, arg3};
+    return call_vm(callee, args, args + 4, exception_action);
+  }
+
+  // VM call oop return handling
+ private:
+  llvm::LoadInst* get_vm_result() const {
+    llvm::Value *addr = builder()->CreateAddressOfStructEntry(
+      thread(), JavaThread::vm_result_offset(),
+      llvm::PointerType::getUnqual(SharkType::oop_type()),
+      "vm_result_addr");
+    llvm::LoadInst *result = builder()->CreateLoad(addr, "vm_result");
+    builder()->CreateStore(LLVMValue::null(), addr);
+    return result;
+  }
+
+  // Synchronization
+ private:
+  void acquire_lock(llvm::Value* lockee, int exception_action);
+  void release_lock(int exception_action);
+
+ public:
+  void acquire_method_lock();
+
+  // Bounds checks
+ private:
+  void check_bounds(SharkValue* array, SharkValue* index);
+
+  // Safepoints
+ private:
+  void maybe_add_safepoint();
+  void maybe_add_backedge_safepoint();
+
+  // Loop safepoint removal
+ private:
+  bool _can_reach_visited;
+
+  bool can_reach(SharkTopLevelBlock* other);
+  bool can_reach_helper(SharkTopLevelBlock* other);
+
+  // Traps
+ private:
+  llvm::BasicBlock* make_trap(int trap_bci, int trap_request);
+  void do_trap(int trap_request);
+
+  // Returns
+ private:
+  void call_register_finalizer(llvm::Value* receiver);
+  void handle_return(BasicType type, llvm::Value* exception);
+
+  // arraylength
+ private:
+  void do_arraylength();
+
+  // *aload and *astore
+ private:
+  void do_aload(BasicType basic_type);
+  void do_astore(BasicType basic_type);
+
+  // *return and athrow
+ private:
+  void do_return(BasicType type);
+  void do_athrow();
+
+  // goto*
+ private:
+  void do_goto();
+
+  // jsr* and ret
+ private:
+  void do_jsr();
+  void do_ret();
+
+  // if*
+ private:
+  void do_if_helper(llvm::ICmpInst::Predicate p,
+                    llvm::Value*              b,
+                    llvm::Value*              a,
+                    SharkState*               if_taken_state,
+                    SharkState*               not_taken_state);
+  void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a);
+
+  // tableswitch and lookupswitch
+ private:
+  void do_switch();
+
+  // invoke*
+ private:
+  ciMethod* improve_virtual_call(ciMethod*        caller,
+                                 ciInstanceKlass* klass,
+                                 ciMethod*        dest_method,
+                                 ciType*          receiver_type);
+  llvm::Value* get_direct_callee(ciMethod* method);
+  llvm::Value* get_virtual_callee(SharkValue* receiver, int vtable_index);
+  llvm::Value* get_interface_callee(SharkValue* receiver, ciMethod* method);
+
+  void do_call();
+
+  // checkcast and instanceof
+ private:
+  bool static_subtype_check(ciKlass* check_klass, ciKlass* object_klass);
+  void do_full_instance_check(ciKlass* klass);
+  void do_trapping_instance_check(ciKlass* klass);
+
+  void do_instance_check();
+  bool maybe_do_instanceof_if();
+
+  // new and *newarray
+ private:
+  void do_new();
+  void do_newarray();
+  void do_anewarray();
+  void do_multianewarray();
+
+  // monitorenter and monitorexit
+ private:
+  void do_monitorenter();
+  void do_monitorexit();
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkType.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,112 @@
+/*
+ * 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 SharkType : public AllStatic {
+ private:
+  static SharkContext& context() {
+    return SharkContext::current();
+  }
+
+  // Basic types
+ public:
+  static const llvm::Type* void_type() {
+    return context().void_type();
+  }
+  static const llvm::IntegerType* bit_type() {
+    return context().bit_type();
+  }
+  static const llvm::IntegerType* jbyte_type() {
+    return context().jbyte_type();
+  }
+  static const llvm::IntegerType* jshort_type() {
+    return context().jshort_type();
+  }
+  static const llvm::IntegerType* jint_type() {
+    return context().jint_type();
+  }
+  static const llvm::IntegerType* jlong_type() {
+    return context().jlong_type();
+  }
+  static const llvm::Type* jfloat_type() {
+    return context().jfloat_type();
+  }
+  static const llvm::Type* jdouble_type() {
+    return context().jdouble_type();
+  }
+  static const llvm::IntegerType* intptr_type() {
+    return context().intptr_type();
+  }
+
+  // Compound types
+ public:
+  static const llvm::PointerType* itableOffsetEntry_type() {
+    return context().itableOffsetEntry_type();
+  }
+  static const llvm::PointerType* jniEnv_type() {
+    return context().jniEnv_type();
+  }
+  static const llvm::PointerType* jniHandleBlock_type() {
+    return context().jniHandleBlock_type();
+  }
+  static const llvm::PointerType* klass_type() {
+    return context().klass_type();
+  }
+  static const llvm::PointerType* methodOop_type() {
+    return context().methodOop_type();
+  }
+  static const llvm::ArrayType* monitor_type() {
+    return context().monitor_type();
+  }
+  static const llvm::PointerType* oop_type() {
+    return context().oop_type();
+  }
+  static const llvm::PointerType* thread_type() {
+    return context().thread_type();
+  }
+  static const llvm::PointerType* zeroStack_type() {
+    return context().zeroStack_type();
+  }
+  static const llvm::FunctionType* entry_point_type() {
+    return context().entry_point_type();
+  }
+  static const llvm::FunctionType* osr_entry_point_type() {
+    return context().osr_entry_point_type();
+  }
+
+  // Mappings
+ public:
+  static const llvm::Type* to_stackType(BasicType type) {
+    return context().to_stackType(type);
+  }
+  static const llvm::Type* to_stackType(ciType* type) {
+    return to_stackType(type->basic_type());
+  }
+  static const llvm::Type* to_arrayType(BasicType type) {
+    return context().to_arrayType(type);
+  }
+  static const llvm::Type* to_arrayType(ciType* type) {
+    return to_arrayType(type->basic_type());
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkValue.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,260 @@
+/*
+ * 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/_sharkValue.cpp.incl"
+
+using namespace llvm;
+
+// Cloning
+
+SharkValue* SharkNormalValue::clone() const {
+  return SharkValue::create_generic(type(), generic_value(), zero_checked());
+}
+SharkValue* SharkPHIValue::clone() const {
+  return SharkValue::create_phi(type(), (PHINode *) generic_value(), this);
+}
+SharkValue* SharkAddressValue::clone() const {
+  return SharkValue::address_constant(address_value());
+}
+
+// Casting
+
+bool SharkValue::is_phi() const {
+  return false;
+}
+bool SharkPHIValue::is_phi() const {
+  return true;
+}
+SharkPHIValue* SharkValue::as_phi() {
+  ShouldNotCallThis();
+}
+SharkPHIValue* SharkPHIValue::as_phi() {
+  return this;
+}
+
+// Comparison
+
+bool SharkNormalValue::equal_to(SharkValue *other) const {
+  return (this->type()          == other->type() &&
+          this->generic_value() == other->generic_value() &&
+          this->zero_checked()  == other->zero_checked());
+}
+bool SharkAddressValue::equal_to(SharkValue *other) const {
+  return (this->address_value() == other->address_value());
+}
+
+// Type access
+
+ciType* SharkValue::type() const {
+  ShouldNotCallThis();
+}
+ciType* SharkNormalValue::type() const {
+  return _type;
+}
+
+BasicType SharkNormalValue::basic_type() const {
+  return type()->basic_type();
+}
+BasicType SharkAddressValue::basic_type() const {
+  return T_ADDRESS;
+}
+
+int SharkNormalValue::size() const {
+  return type()->size();
+}
+int SharkAddressValue::size() const {
+  return 1;
+}
+
+bool SharkValue::is_jint() const {
+  return false;
+}
+bool SharkValue::is_jlong() const {
+  return false;
+}
+bool SharkValue::is_jfloat() const {
+  return false;
+}
+bool SharkValue::is_jdouble() const {
+  return false;
+}
+bool SharkValue::is_jobject() const {
+  return false;
+}
+bool SharkValue::is_jarray() const {
+  return false;
+}
+bool SharkValue::is_address() const {
+  return false;
+}
+
+bool SharkNormalValue::is_jint() const {
+  return llvm_value()->getType() == SharkType::jint_type();
+}
+bool SharkNormalValue::is_jlong() const {
+  return llvm_value()->getType() == SharkType::jlong_type();
+}
+bool SharkNormalValue::is_jfloat() const {
+  return llvm_value()->getType() == SharkType::jfloat_type();
+}
+bool SharkNormalValue::is_jdouble() const {
+  return llvm_value()->getType() == SharkType::jdouble_type();
+}
+bool SharkNormalValue::is_jobject() const {
+  return llvm_value()->getType() == SharkType::oop_type();
+}
+bool SharkNormalValue::is_jarray() const {
+  return basic_type() == T_ARRAY;
+}
+bool SharkAddressValue::is_address() const {
+  return true;
+}
+
+// Typed conversions from SharkValues
+
+Value* SharkValue::jint_value() const {
+  ShouldNotCallThis();
+}
+Value* SharkValue::jlong_value() const {
+  ShouldNotCallThis();
+}
+Value* SharkValue::jfloat_value() const {
+  ShouldNotCallThis();
+}
+Value* SharkValue::jdouble_value() const {
+  ShouldNotCallThis();
+}
+Value* SharkValue::jobject_value() const {
+  ShouldNotCallThis();
+}
+Value* SharkValue::jarray_value() const {
+  ShouldNotCallThis();
+}
+int SharkValue::address_value() const {
+  ShouldNotCallThis();
+}
+
+Value* SharkNormalValue::jint_value() const {
+  assert(is_jint(), "should be");
+  return llvm_value();
+}
+Value* SharkNormalValue::jlong_value() const {
+  assert(is_jlong(), "should be");
+  return llvm_value();
+}
+Value* SharkNormalValue::jfloat_value() const {
+  assert(is_jfloat(), "should be");
+  return llvm_value();
+}
+Value* SharkNormalValue::jdouble_value() const {
+  assert(is_jdouble(), "should be");
+  return llvm_value();
+}
+Value* SharkNormalValue::jobject_value() const {
+  assert(is_jobject(), "should be");
+  return llvm_value();
+}
+Value* SharkNormalValue::jarray_value() const {
+  // XXX assert(is_jarray(), "should be");
+  // XXX http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=324
+  assert(is_jobject(), "should be");
+  return llvm_value();
+}
+int SharkAddressValue::address_value() const {
+  return _bci;
+}
+
+// Type-losing conversions -- use with care!
+
+Value* SharkNormalValue::generic_value() const {
+  return llvm_value();
+}
+Value* SharkAddressValue::generic_value() const {
+  return LLVMValue::intptr_constant(address_value());
+}
+
+Value* SharkValue::intptr_value(SharkBuilder* builder) const {
+  ShouldNotCallThis();
+}
+Value* SharkNormalValue::intptr_value(SharkBuilder* builder) const {
+  return builder->CreatePtrToInt(jobject_value(), SharkType::intptr_type());
+}
+
+// Phi-style stuff for SharkPHIState::add_incoming
+
+void SharkValue::addIncoming(SharkValue *value, BasicBlock* block) {
+  ShouldNotCallThis();
+}
+void SharkPHIValue::addIncoming(SharkValue *value, BasicBlock* block) {
+  assert(!is_clone(), "shouldn't be");
+  ((llvm::PHINode *) generic_value())->addIncoming(
+      value->generic_value(), block);
+  if (!value->zero_checked())
+    _all_incomers_zero_checked = false;
+}
+void SharkAddressValue::addIncoming(SharkValue *value, BasicBlock* block) {
+  assert(this->equal_to(value), "should be");
+}
+
+// Phi-style stuff for SharkState::merge
+
+SharkValue* SharkNormalValue::merge(SharkBuilder* builder,
+                                    SharkValue*   other,
+                                    BasicBlock*   other_block,
+                                    BasicBlock*   this_block,
+                                    const char*   name) {
+  assert(type() == other->type(), "should be");
+  assert(zero_checked() == other->zero_checked(), "should be");
+
+  PHINode *phi = builder->CreatePHI(SharkType::to_stackType(type()), name);
+  phi->addIncoming(this->generic_value(), this_block);
+  phi->addIncoming(other->generic_value(), other_block);
+  return SharkValue::create_generic(type(), phi, zero_checked());
+}
+SharkValue* SharkAddressValue::merge(SharkBuilder* builder,
+                                     SharkValue*   other,
+                                     BasicBlock*   other_block,
+                                     BasicBlock*   this_block,
+                                     const char*   name) {
+  assert(this->equal_to(other), "should be");
+  return this;
+}
+
+// Repeated null and divide-by-zero check removal
+
+bool SharkValue::zero_checked() const {
+  ShouldNotCallThis();
+}
+void SharkValue::set_zero_checked(bool zero_checked) {
+  ShouldNotCallThis();
+}
+
+bool SharkNormalValue::zero_checked() const {
+  return _zero_checked;
+}
+void SharkNormalValue::set_zero_checked(bool zero_checked) {
+  _zero_checked = zero_checked;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/sharkValue.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,332 @@
+/*
+ * 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.
+ *
+ */
+
+// Items on the stack and in local variables are tracked using
+// SharkValue objects.
+//
+// All SharkValues are one of two core types, SharkNormalValue
+// and SharkAddressValue, but no code outside this file should
+// ever refer to those directly.  The split is because of the
+// way JSRs are handled: the typeflow pass expands them into
+// multiple copies, so the return addresses pushed by jsr and
+// popped by ret only exist at compile time.  Having separate
+// classes for these allows us to check that our jsr handling
+// is correct, via assertions.
+//
+// There is one more type, SharkPHIValue, which is a subclass
+// of SharkNormalValue with a couple of extra methods.  Use of
+// SharkPHIValue outside of this file is acceptable, so long
+// as it is obtained via SharkValue::as_phi().
+
+class SharkBuilder;
+class SharkPHIValue;
+
+class SharkValue : public ResourceObj {
+ protected:
+  SharkValue() {}
+
+  // Cloning
+ public:
+  virtual SharkValue* clone() const = 0;
+
+  // Casting
+ public:
+  virtual bool           is_phi() const;
+  virtual SharkPHIValue* as_phi();
+
+  // Comparison
+ public:
+  virtual bool equal_to(SharkValue* other) const = 0;
+
+  // Type access
+ public:
+  virtual BasicType basic_type() const = 0;
+  virtual ciType*   type()       const;
+
+  virtual bool is_jint()    const;
+  virtual bool is_jlong()   const;
+  virtual bool is_jfloat()  const;
+  virtual bool is_jdouble() const;
+  virtual bool is_jobject() const;
+  virtual bool is_jarray()  const;
+  virtual bool is_address() const;
+
+  virtual int size() const = 0;
+
+  bool is_one_word() const {
+    return size() == 1;
+  }
+  bool is_two_word() const {
+    return size() == 2;
+  }
+
+  // Typed conversion from SharkValues
+ public:
+  virtual llvm::Value* jint_value()    const;
+  virtual llvm::Value* jlong_value()   const;
+  virtual llvm::Value* jfloat_value()  const;
+  virtual llvm::Value* jdouble_value() const;
+  virtual llvm::Value* jobject_value() const;
+  virtual llvm::Value* jarray_value()  const;
+  virtual int          address_value() const;
+
+  // Typed conversion to SharkValues
+ public:
+  static SharkValue* create_jint(llvm::Value* value, bool zero_checked) {
+    assert(value->getType() == SharkType::jint_type(), "should be");
+    return create_generic(ciType::make(T_INT), value, zero_checked);
+  }
+  static SharkValue* create_jlong(llvm::Value* value, bool zero_checked) {
+    assert(value->getType() == SharkType::jlong_type(), "should be");
+    return create_generic(ciType::make(T_LONG), value, zero_checked);
+  }
+  static SharkValue* create_jfloat(llvm::Value* value) {
+    assert(value->getType() == SharkType::jfloat_type(), "should be");
+    return create_generic(ciType::make(T_FLOAT), value, false);
+  }
+  static SharkValue* create_jdouble(llvm::Value* value) {
+    assert(value->getType() == SharkType::jdouble_type(), "should be");
+    return create_generic(ciType::make(T_DOUBLE), value, false);
+  }
+  static SharkValue* create_jobject(llvm::Value* value, bool zero_checked) {
+    assert(value->getType() == SharkType::oop_type(), "should be");
+    return create_generic(ciType::make(T_OBJECT), value, zero_checked);
+  }
+
+  // Typed conversion from constants of various types
+ public:
+  static SharkValue* jint_constant(jint value) {
+    return create_jint(LLVMValue::jint_constant(value), value != 0);
+  }
+  static SharkValue* jlong_constant(jlong value) {
+    return create_jlong(LLVMValue::jlong_constant(value), value != 0);
+  }
+  static SharkValue* jfloat_constant(jfloat value) {
+    return create_jfloat(LLVMValue::jfloat_constant(value));
+  }
+  static SharkValue* jdouble_constant(jdouble value) {
+    return create_jdouble(LLVMValue::jdouble_constant(value));
+  }
+  static SharkValue* null() {
+    return create_jobject(LLVMValue::null(), false);
+  }
+  static inline SharkValue* address_constant(int bci);
+
+  // Type-losing conversions -- use with care!
+ public:
+  virtual llvm::Value* generic_value() const = 0;
+  virtual llvm::Value* intptr_value(SharkBuilder* builder) const;
+
+  static inline SharkValue* create_generic(ciType*      type,
+                                           llvm::Value* value,
+                                           bool         zero_checked);
+  static inline SharkValue* create_phi(ciType*              type,
+                                       llvm::PHINode*       phi,
+                                       const SharkPHIValue* parent = NULL);
+
+  // Phi-style stuff
+ public:
+  virtual void addIncoming(SharkValue* value, llvm::BasicBlock* block);
+  virtual SharkValue* merge(SharkBuilder*     builder,
+                            SharkValue*       other,
+                            llvm::BasicBlock* other_block,
+                            llvm::BasicBlock* this_block,
+                            const char*       name) = 0;
+
+  // Repeated null and divide-by-zero check removal
+ public:
+  virtual bool zero_checked() const;
+  virtual void set_zero_checked(bool zero_checked);
+};
+
+class SharkNormalValue : public SharkValue {
+  friend class SharkValue;
+
+ protected:
+  SharkNormalValue(ciType* type, llvm::Value* value, bool zero_checked)
+    : _type(type), _llvm_value(value), _zero_checked(zero_checked) {}
+
+ private:
+  ciType*      _type;
+  llvm::Value* _llvm_value;
+  bool         _zero_checked;
+
+ private:
+  llvm::Value* llvm_value() const {
+    return _llvm_value;
+  }
+
+  // Cloning
+ public:
+  SharkValue* clone() const;
+
+  // Comparison
+ public:
+  bool equal_to(SharkValue* other) const;
+
+  // Type access
+ public:
+  ciType*   type()       const;
+  BasicType basic_type() const;
+  int       size()       const;
+
+ public:
+  bool is_jint()    const;
+  bool is_jlong()   const;
+  bool is_jfloat()  const;
+  bool is_jdouble() const;
+  bool is_jobject() const;
+  bool is_jarray()  const;
+
+  // Typed conversions to LLVM values
+ public:
+  llvm::Value* jint_value()    const;
+  llvm::Value* jlong_value()   const;
+  llvm::Value* jfloat_value()  const;
+  llvm::Value* jdouble_value() const;
+  llvm::Value* jobject_value() const;
+  llvm::Value* jarray_value()  const;
+
+  // Type-losing conversions, use with care
+ public:
+  llvm::Value* generic_value() const;
+  llvm::Value* intptr_value(SharkBuilder* builder) const;
+
+  // Phi-style stuff
+ public:
+  SharkValue* merge(SharkBuilder*     builder,
+                    SharkValue*       other,
+                    llvm::BasicBlock* other_block,
+                    llvm::BasicBlock* this_block,
+                    const char*       name);
+
+  // Repeated null and divide-by-zero check removal
+ public:
+  bool zero_checked() const;
+  void set_zero_checked(bool zero_checked);
+};
+
+class SharkPHIValue : public SharkNormalValue {
+  friend class SharkValue;
+
+ protected:
+  SharkPHIValue(ciType* type, llvm::PHINode* phi, const SharkPHIValue *parent)
+    : SharkNormalValue(type, phi, parent && parent->zero_checked()),
+      _parent(parent),
+      _all_incomers_zero_checked(true) {}
+
+ private:
+  const SharkPHIValue* _parent;
+  bool                 _all_incomers_zero_checked;
+
+ private:
+  const SharkPHIValue* parent() const {
+    return _parent;
+  }
+  bool is_clone() const {
+    return parent() != NULL;
+  }
+
+ public:
+  bool all_incomers_zero_checked() const {
+    if (is_clone())
+      return parent()->all_incomers_zero_checked();
+
+    return _all_incomers_zero_checked;
+  }
+
+  // Cloning
+ public:
+  SharkValue* clone() const;
+
+  // Casting
+ public:
+  bool           is_phi() const;
+  SharkPHIValue* as_phi();
+
+  // Phi-style stuff
+ public:
+  void addIncoming(SharkValue *value, llvm::BasicBlock* block);
+};
+
+class SharkAddressValue : public SharkValue {
+  friend class SharkValue;
+
+ protected:
+  SharkAddressValue(int bci)
+    : _bci(bci) {}
+
+ private:
+  int _bci;
+
+  // Cloning
+ public:
+  SharkValue* clone() const;
+
+  // Comparison
+ public:
+  bool equal_to(SharkValue* other) const;
+
+  // Type access
+ public:
+  BasicType basic_type() const;
+  int       size()       const;
+  bool      is_address() const;
+
+  // Typed conversion from SharkValues
+ public:
+  int address_value() const;
+
+  // Type-losing conversion -- use with care!
+ public:
+  llvm::Value* generic_value() const;
+
+  // Phi-style stuff
+ public:
+  void addIncoming(SharkValue *value, llvm::BasicBlock* block);
+  SharkValue* merge(SharkBuilder*     builder,
+                    SharkValue*       other,
+                    llvm::BasicBlock* other_block,
+                    llvm::BasicBlock* this_block,
+                    const char*       name);
+};
+
+// SharkValue methods that can't be declared above
+
+inline SharkValue* SharkValue::create_generic(ciType*      type,
+                                              llvm::Value* value,
+                                              bool         zero_checked) {
+  return new SharkNormalValue(type, value, zero_checked);
+}
+
+inline SharkValue* SharkValue::create_phi(ciType*              type,
+                                          llvm::PHINode*       phi,
+                                          const SharkPHIValue* parent) {
+  return new SharkPHIValue(type, phi, parent);
+}
+
+inline SharkValue* SharkValue::address_constant(int bci) {
+  return new SharkAddressValue(bci);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/shark_globals.cpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008 Red Hat, Inc.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "incls/_precompiled.incl"
+#include "incls/_shark_globals.cpp.incl"
+
+SHARK_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/vm/shark/shark_globals.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ *
+ */
+
+#define SHARK_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \
+                                                                              \
+  product(intx, MaxNodeLimit, 65000,                                          \
+          "Maximum number of nodes")                                          \
+                                                                              \
+  /* inlining */                                                              \
+  product(intx, SharkMaxInlineSize, 32,                                       \
+          "Maximum bytecode size of methods to inline when using Shark")      \
+                                                                              \
+  /* compiler debugging */                                                    \
+  develop(ccstr, SharkPrintTypeflowOf, NULL,                                  \
+          "Print the typeflow of the specified method")                       \
+                                                                              \
+  diagnostic(ccstr, SharkPrintBitcodeOf, NULL,                                \
+          "Print the LLVM bitcode of the specified method")                   \
+                                                                              \
+  diagnostic(ccstr, SharkPrintAsmOf, NULL,                                    \
+          "Print the asm of the specified method")                            \
+                                                                              \
+  develop(bool, SharkTraceBytecodes, false,                                   \
+          "Trace bytecode compilation")                                       \
+                                                                              \
+  diagnostic(bool, SharkTraceInstalls, false,                                 \
+          "Trace method installation")                                        \
+                                                                              \
+  diagnostic(bool, SharkPerformanceWarnings, false,                           \
+          "Warn about things that could be made faster")                      \
+
+SHARK_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
--- a/hotspot/src/share/vm/utilities/macros.hpp	Wed Aug 11 01:17:27 2010 -0700
+++ b/hotspot/src/share/vm/utilities/macros.hpp	Wed Aug 11 05:51:21 2010 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, 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
@@ -151,9 +151,11 @@
 #if defined(IA32) || defined(AMD64)
 #define X86
 #define X86_ONLY(code) code
+#define NOT_X86(code)
 #else
 #undef X86
 #define X86_ONLY(code)
+#define NOT_X86(code) code
 #endif
 
 #ifdef IA32