Native method wrapper generation

Gary Benson gbenson at redhat.com
Wed Nov 11 08:38:39 PST 2009


Hi all,

This commit adds native wrapper generation to Shark.  It also removes
support for LLVM < 2.6, because the new code requires it.  I'll write
this up in more detail tomorrow with some benchmarks.

Cheers,
Gary

-- 
http://gbenson.net/
-------------- next part --------------
diff -r b3d03017bdef ChangeLog
--- a/ChangeLog	Wed Nov 11 10:50:38 2009 -0500
+++ b/ChangeLog	Wed Nov 11 16:21:16 2009 +0000
@@ -1,3 +1,186 @@
+2009-11-11  Gary Benson  <gbenson at redhat.com>
+
+	* ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
+	(CppInterpreter::native_entry): Add invocation counting for
+	non-synchronized native methods.
+
+	* ports/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp
+	(SharedRuntime::generate_native_wrapper): Implemented.
+
+	* ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp
+	(SharkFrame): Made friendly with SharkStack.  Snubbed
+	SharkFunction.
+
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.hpp
+	(SharkBuilder::SharkBuilder): Removed module argument.
+	(SharkBuilder::_module): Removed.
+	(SharkBuilder::module): Likewise.
+	(SharkBuilder::check_special_condition_for_native_trans): New method.
+	(SharkBuilder::CreateInlineOop): New method with jobject argument.
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.cpp
+	(SharkBuilder::SharkBuilder): Removed module argument, and changed
+	to use Shark context instead of global context.
+	(SharkBuilder::make_type): Updated for new SharkType.
+	(SharkBuilder::make_function): Use SharkContext for resolution.
+	(SharkBuilder::check_special_condition_for_native_trans): New method.
+	(SharkBuilder::CreateDump): Removed support for LLVM < 2.6.
+	(SharkBuilder::CreateBlock): Likewise.
+	(SharkBuilder::CreateInlineOop): Changed object argument type.
+
+	* ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp
+	(SharkDecacher::oopmap_slot_munge): Defer to SharkStack method.
+	(SharkDecacher::slot2reg): Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp
+	(SharkDecacher::start_frame): Use new SharkStack code.
+	(SharkDecacher::start_stack): Likewise.
+	(SharkDecacher::process_pc_slot): Likewise.
+	(SharkOSREntryCacher::process_monitor): Likewise.
+	(SharkDecacher::write_value_to_frame): Likewise.
+	(SharkCacher::read_value_from_frame): Likewise.
+
+	* ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp
+	(SharkCodeBuffer::SharkCodeBuffer): Wrap a MacroAssembler
+	instead of creating one along with a CodeBuffer.
+	(SharkCodeBuffer::_cb): Removed.
+	(SharkCodeBuffer::_cb): Likewise.
+	(SharkCodeBuffer::inline_oop): Changed object argument type.
+
+	* ports/hotspot/src/share/vm/shark/sharkCompiler.hpp
+	(SharkCompiler::supports_native): Return true instead of false.
+	(SharkCompiler::generate_native_wrapper): New method.
+	(SharkCompiler::_module): Removed.
+	(SharkCompiler::module): Likewise.
+	(SharkCompiler::_normal_context): New field.
+	(SharkCompiler::_native_context): Likewise.
+	(SharkCompiler::_execution_engine_lock): Likewise.
+	(SharkCompiler::context): New method.
+	(SharkCompiler::execution_engine_lock): Likewise.
+	(SharkCompiler::memory_manager): Added assertion.
+	(SharkCompiler::execution_engine): Likewise.
+	(SharkCompiler::compiler): New method.
+	(SharkCompiler::generate_native_code): Likewise.
+	(SharkCompiler::free_queued_methods): Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkCompiler.cpp
+	(SharkCompiler::SharkCompiler): Create the lock and the two
+	contexts.  Removed support for LLVM < 2.6.
+	(SharkCompiler::compile_method): Create the HotSpot code buffer
+	and macro assembler, and defer native code generation to new
+	method SharkCompiler::generate_native_code().
+	(SharkCompiler::generate_native_wrapper): New method.
+	(SharkCompiler::generate_native_code): Likewise.
+	(SharkCompiler::free_compiled_method): New implementation.
+	(SharkCompiler::free_queued_methods): New method.
+
+	* ports/hotspot/src/share/vm/shark/sharkEntry.hpp
+	(SharkEntry::_context): New field.
+	(SharkEntry::context): New method.
+	(SharkEntry::set_context): Likewise.
+
+	* ports/hotspot/src/share/vm/shark/sharkFunction.hpp
+	(SharkFunction::build): Removed compiler argument.
+	(SharkFunction::SharkFunction): Likewise.
+	(SharkFunction::_stack): New field.
+	(SharkFunction::stack): New method.
+	(SharkFunction::CreateBlock): Removed support for LLVM < 2.6.
+	(SharkFunction::_zero_stack_base): Removed.
+	(SharkFunction::_zero_stack_pointer_addr): Likewise.
+	(SharkFunction::_zero_frame_pointer_addr): Likewise.
+	(SharkFunction::zero_stack_base): Likewise.
+	(SharkFunction::zero_stack_pointer_addr): Likewise.
+	(SharkFunction::zero_frame_pointer_addr): Likewise.
+	(SharkFunction::CreateInitZeroStack): Likewise.
+	(SharkFunction::CreateLoadZeroStackPointer): Likewise.
+	(SharkFunction::CreateStoreZeroStackPointer): Likewise.
+	(SharkFunction::CreateLoadZeroFramePointer): Likewise.
+	(SharkFunction::CreateStoreZeroFramePointer): Likewise.
+	(SharkFunction::CreateStackOverflowCheck): Likewise.
+	(SharkFunction::CreatePushFrame): Likewise.
+	(SharkFunction::CreatePopFrame): Likewise.
+	(SharkFunction::_frame): Likewise.
+	(SharkFunction::CreateAddressOfFrameEntry): Likewise.
+	(SharkFunction::CreateBuildFrame): Likewise.
+	(SharkFunction::_extended_frame_size): Likewise.
+	(SharkFunction::_stack_slots_offset): Likewise.
+	(SharkFunction::_monitors_slots_offset): Likewise.
+	(SharkFunction::_oop_tmp_slot_offset): Likewise.
+	(SharkFunction::_method_slot_offset): Likewise.
+	(SharkFunction::_pc_slot_offset): Likewise.
+	(SharkFunction::_locals_slots_offset): Likewise.
+	(SharkFunction::extended_frame_size): Likewise.
+	(SharkFunction::oopmap_frame_size): Likewise.
+	(SharkFunction::stack_slots_offset): Likewise.
+	(SharkFunction::monitors_slots_offset): Likewise.
+	(SharkFunction::oop_tmp_slot_offset): Likewise.
+	(SharkFunction::method_slot_offset): Likewise.
+	(SharkFunction::pc_slot_offset): Likewise.
+	(SharkFunction::locals_slots_offset): Likewise.
+	(SharkFunction::monitor_offset): Likewise.
+	(SharkFunction::monitor_object_offset): Likewise.
+	(SharkFunction::monitor_header_offset): Likewise.
+	(SharkFunction::monitor_addr): Likewise.
+	(SharkFunction::monitor_object_addr): Likewise.
+	(SharkFunction::monitor_header_addr): Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkFunction.cpp
+	(SharkFunction::initialize): Defer stack frame creation to new
+	SharkStack code.
+	(SharkFunction::CreateInitZeroStack): Removed.
+	(SharkFunction::CreateStackOverflowCheck): Likewise.
+	(SharkFunction::CreatePushFrame): Likewise.
+	(SharkFunction::CreatePopFrame): Likewise.
+	(SharkFunction::CreateBuildFrame): Likewise.
+	(SharkFunction::CreateAddressOfFrameEntry): Likewise.
+
+	* ports/hotspot/src/share/vm/shark/sharkInvariants.hpp
+	(SharkCompileInvariants::SharkCompileInvariants): Removed
+	compiler argument. 
+	(SharkTargetInvariants::SharkTargetInvariants): Likewise.
+	(SharkCompileInvariants::_compiler): Removed.
+	(SharkCompileInvariants::env): Added assertion.
+
+	* ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp
+	(SharkStateScanner::SharkStateScanner): Updated.
+	(SharkStateScanner::_function): Removed.
+	(SharkStateScanner::function): Likewise.
+	(SharkStateScanner::_stack): New field.
+	(SharkStateScanner::stack): New method.
+	* ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp
+	(SharkStateScanner::scan): Use new SharkStack code.
+
+	* ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp
+	(SharkTopLevelBlock::stack): New method.
+	(SharkTopLevelBlock::set_last_Java_frame): Removed.
+	(SharkTopLevelBlock::reset_last_Java_frame): Likewise.
+	(SharkTopLevelBlock::call_vm): Use new SharkStack code.
+	* ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
+	(SharkTopLevelBlock::handle_return): Likewise.
+	(SharkTopLevelBlock::do_multianewarray): Likewise.
+	(SharkTopLevelBlock::acquire_lock): Likewise.
+	(SharkTopLevelBlock::release_lock): Likewise.
+
+	* ports/hotspot/src/share/vm/shark/sharkType.hpp:
+	Defer everything to new SharkContext code.
+	* ports/hotspot/src/share/vm/shark/sharkType.cpp: Removed.
+	
+	* ports/hotspot/src/share/vm/shark/llvmHeaders.hpp:
+	Removed support for LLVM < 2.6.
+	* ports/hotspot/src/share/vm/shark/llvmValue.hpp
+	(LLVMValue::jfloat_constant): Likewise.
+	(LLVMValue::jdouble_constant): Likewise.
+	(LLVMValue::bit_constant): Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkBlock.cpp
+	(SharkBlock::parse_bytecode): Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkMemoryManager.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkMemoryManager.cpp: Likewise.
+
+	* ports/hotspot/src/share/vm/shark/sharkContext.hpp: New file.
+	* ports/hotspot/src/share/vm/shark/sharkContext.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkNativeWrapper.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkStack.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkStack.cpp: Likewise.
+
+	* ports/hotspot/src/share/vm/includeDB_shark: Updated.
+
 2009-11-11  Gary Benson  <gbenson at redhat.com>
 
 	PR icedtea/324:
diff -r b3d03017bdef ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -204,6 +204,20 @@
     goto unwind_and_return;
   }
 
+  // Update the invocation counter
+  if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) {
+    thread->set_do_not_unlock();
+    InvocationCounter *counter = method->invocation_counter();
+    counter->increment();
+    if (counter->reached_InvocationLimit()) {
+      CALL_VM_NOCHECK(
+        InterpreterRuntime::frequency_counter_overflow(thread, NULL));
+      if (HAS_PENDING_EXCEPTION)
+        goto unwind_and_return;
+    }
+    thread->clr_do_not_unlock();
+  }
+
   // Lock if necessary
   BasicObjectLock *monitor;
   monitor = NULL;
diff -r b3d03017bdef ports/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp
--- a/ports/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/cpu/zero/vm/sharedRuntime_zero.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -61,7 +61,14 @@
                                                 BasicType *in_sig_bt,
                                                 VMRegPair *in_regs,
                                                 BasicType ret_type) {
+#ifdef SHARK
+  return SharkCompiler::compiler()->generate_native_wrapper(masm,
+                                                            method,
+                                                            in_sig_bt,
+                                                            ret_type);
+#else
   ShouldNotCallThis();
+#endif // SHARK
 }
 
 int Deoptimization::last_frame_adjust(int callee_parameters,
diff -r b3d03017bdef ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp
--- a/ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -1,6 +1,6 @@
 /*
  * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
- * Copyright 2008 Red Hat, Inc.
+ * 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
@@ -41,7 +41,7 @@
 // |  ...               |
 
 class SharkFrame : public ZeroFrame {
-  friend class SharkFunction;
+  friend class SharkStack;
 
  private:
   SharkFrame() : ZeroFrame() {
diff -r b3d03017bdef ports/hotspot/src/share/vm/includeDB_shark
--- a/ports/hotspot/src/share/vm/includeDB_shark	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/includeDB_shark	Wed Nov 11 16:21:16 2009 +0000
@@ -48,6 +48,8 @@
 ciTypeFlow.hpp                          ciKlass.hpp
 ciTypeFlow.hpp                          ciMethodBlocks.hpp
 
+cppInterpreter_<arch>.cpp               shark_globals.hpp
+
 compileBroker.cpp                       sharkCompiler.hpp
 
 globals.hpp                             shark_globals_<arch>.hpp
@@ -55,10 +57,14 @@
 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
@@ -95,7 +101,7 @@
 sharkBuilder.cpp                        resourceArea.hpp
 sharkBuilder.cpp                        llvmHeaders.hpp
 sharkBuilder.cpp                        sharkBuilder.hpp
-sharkBuilder.cpp                        sharkCompiler.hpp
+sharkBuilder.cpp                        sharkContext.hpp
 sharkBuilder.cpp                        sharkRuntime.hpp
 sharkBuilder.cpp                        synchronizer.hpp
 sharkBuilder.cpp                        thread.hpp
@@ -108,7 +114,6 @@
 sharkBuilder.hpp                        llvmValue.hpp
 sharkBuilder.hpp                        sizes.hpp
 sharkBuilder.hpp                        sharkCodeBuffer.hpp
-sharkBuilder.hpp                        sharkCompiler.hpp
 sharkBuilder.hpp                        sharkType.hpp
 sharkBuilder.hpp                        sharkValue.hpp
 sharkBuilder.hpp                        sharkEntry.hpp
@@ -145,16 +150,29 @@
 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
@@ -186,7 +204,9 @@
 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
@@ -229,8 +249,6 @@
 sharkInvariants.hpp                     dependencies.hpp
 sharkInvariants.hpp                     llvmHeaders.hpp
 sharkInvariants.hpp                     sharkBuilder.hpp
-sharkInvariants.hpp                     sharkCompiler.hpp
-sharkInvariants.hpp                     sharkMemoryManager.hpp
 
 sharkMemoryManager.hpp                  llvmHeaders.hpp
 sharkMemoryManager.hpp                  sharkEntry.hpp
@@ -239,6 +257,17 @@
 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
@@ -248,9 +277,20 @@
 
 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
@@ -279,6 +319,8 @@
 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
@@ -307,17 +349,11 @@
 sharkTopLevelBlock.hpp                  sharkState.hpp
 sharkTopLevelBlock.hpp                  sharkValue.hpp
 
-sharkType.cpp                           arrayOop.hpp
-sharkType.cpp                           globalDefinitions.hpp
-sharkType.cpp                           llvmHeaders.hpp
-sharkType.cpp                           oop.hpp
-sharkType.cpp                           sharkEntry.hpp
-sharkType.cpp                           sharkType.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
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/llvmHeaders.hpp
--- a/ports/hotspot/src/share/vm/shark/llvmHeaders.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/llvmHeaders.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -32,16 +32,12 @@
 #include <llvm/DerivedTypes.h>
 #include <llvm/ExecutionEngine/ExecutionEngine.h>
 #include <llvm/Instructions.h>
-#if SHARK_LLVM_VERSION >= 26
 #include <llvm/LLVMContext.h>
-#endif
 #include <llvm/Module.h>
 #include <llvm/ModuleProvider.h>
 #include <llvm/Support/IRBuilder.h>
-#if SHARK_LLVM_VERSION >= 26
 #include <llvm/System/Threading.h>
 #include <llvm/Target/TargetSelect.h>
-#endif
 #include <llvm/Type.h>
 #include <llvm/ExecutionEngine/JITMemoryManager.h>
 #if SHARK_LLVM_VERSION < 27
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/llvmValue.hpp
--- a/ports/hotspot/src/share/vm/shark/llvmValue.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/llvmValue.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -39,19 +39,11 @@
   }
   static llvm::ConstantFP* jfloat_constant(jfloat value)
   {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::ConstantFP::get(llvm::getGlobalContext(), llvm::APFloat(value));
-#else
-    return llvm::ConstantFP::get(SharkType::jfloat_type(), value);
-#endif
+    return llvm::ConstantFP::get(SharkContext::current(), llvm::APFloat(value));
   }
   static llvm::ConstantFP* jdouble_constant(jdouble value)
   {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::ConstantFP::get(llvm::getGlobalContext(), llvm::APFloat(value));
-#else
-    return llvm::ConstantFP::get(SharkType::jdouble_type(), value);
-#endif
+    return llvm::ConstantFP::get(SharkContext::current(), llvm::APFloat(value));
   }
   static llvm::ConstantPointerNull* null()
   {
@@ -61,11 +53,7 @@
  public:
   static llvm::ConstantInt* bit_constant(int value)
   {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::ConstantInt::get(llvm::Type::getInt1Ty(llvm::getGlobalContext()), value, false);
-#else
-    return llvm::ConstantInt::get(llvm::Type::Int1Ty, value, false);
-#endif
+    return llvm::ConstantInt::get(SharkType::bit_type(), value, false);
   }
   static llvm::ConstantInt* intptr_constant(intptr_t value)
   {
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkBlock.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -532,31 +532,19 @@
       b = pop();
       a = pop();
       push(SharkValue::create_jfloat(
-#if SHARK_LLVM_VERSION >= 26
         builder()->CreateFAdd(a->jfloat_value(), b->jfloat_value())));
-#else
-        builder()->CreateAdd(a->jfloat_value(), b->jfloat_value())));
-#endif
       break;
     case Bytecodes::_fsub:
       b = pop();
       a = pop();
       push(SharkValue::create_jfloat(
-#if SHARK_LLVM_VERSION >= 26
         builder()->CreateFSub(a->jfloat_value(), b->jfloat_value())));
-#else
-        builder()->CreateSub(a->jfloat_value(), b->jfloat_value())));
-#endif
       break;
     case Bytecodes::_fmul:
       b = pop();
       a = pop();
       push(SharkValue::create_jfloat(
-#if SHARK_LLVM_VERSION >= 26
         builder()->CreateFMul(a->jfloat_value(), b->jfloat_value())));
-#else
-        builder()->CreateMul(a->jfloat_value(), b->jfloat_value())));
-#endif
       break;
     case Bytecodes::_fdiv:
       b = pop();
@@ -573,42 +561,26 @@
     case Bytecodes::_fneg:
       a = pop();      
       push(SharkValue::create_jfloat(
-#if SHARK_LLVM_VERSION >= 26
         builder()->CreateFNeg(a->jfloat_value())));
-#else
-        builder()->CreateNeg(a->jfloat_value())));
-#endif
       break;
 
     case Bytecodes::_dadd:
       b = pop();
       a = pop();
       push(SharkValue::create_jdouble(
-#if SHARK_LLVM_VERSION >= 26
         builder()->CreateFAdd(a->jdouble_value(), b->jdouble_value())));
-#else
-        builder()->CreateAdd(a->jdouble_value(), b->jdouble_value())));
-#endif
       break;
     case Bytecodes::_dsub:
       b = pop();
       a = pop();
       push(SharkValue::create_jdouble(
-#if SHARK_LLVM_VERSION >= 26
         builder()->CreateFSub(a->jdouble_value(), b->jdouble_value())));
-#else
-        builder()->CreateSub(a->jdouble_value(), b->jdouble_value())));
-#endif
       break;
     case Bytecodes::_dmul:
       b = pop();
       a = pop();
       push(SharkValue::create_jdouble(
-#if SHARK_LLVM_VERSION >= 26
         builder()->CreateFMul(a->jdouble_value(), b->jdouble_value())));
-#else
-        builder()->CreateMul(a->jdouble_value(), b->jdouble_value())));
-#endif
       break;
     case Bytecodes::_ddiv:
       b = pop();
@@ -625,11 +597,7 @@
     case Bytecodes::_dneg:
       a = pop();      
       push(SharkValue::create_jdouble(
-#if SHARK_LLVM_VERSION >= 26
         builder()->CreateFNeg(a->jdouble_value())));
-#else
-        builder()->CreateNeg(a->jdouble_value())));
-#endif
       break;
 
     case Bytecodes::_iinc:
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkBuilder.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -28,16 +28,8 @@
 
 using namespace llvm;
 
-SharkBuilder::SharkBuilder(Module* module, SharkCodeBuffer* code_buffer)
-#if SHARK_LLVM_VERSION >= 26
-  // LLVM 2.6 requires a LLVMContext during IRBuilder construction.
-  // getGlobalConext() returns one that can be used as long as the shark
-  // compiler are single-threaded.
-  : IRBuilder<>(getGlobalContext()),
-#else
-  : IRBuilder<>(),
-#endif // SHARK_LLVM_VERSION >= 26
-    _module(module),
+SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer)
+  : IRBuilder<>(SharkContext::current()),
     _code_buffer(code_buffer)
 {
 }
@@ -155,17 +147,9 @@
     // Miscellaneous
   case 'v':
     assert(void_ok, "should be");
-#if SHARK_LLVM_VERSION >= 26
-    return Type::getVoidTy(getGlobalContext());
-#else
-    return Type::VoidTy;
-#endif
+    return SharkType::void_type();
   case '1':
-#if SHARK_LLVM_VERSION >= 26
-    return Type::getInt1Ty(getGlobalContext());
-#else
-    return Type::Int1Ty;
-#endif
+    return SharkType::bit_type();
 
   default:
     ShouldNotReachHere();
@@ -196,7 +180,7 @@
                                    const char* params,
                                    const char* ret)
 {
-  return module()->getOrInsertFunction(name, make_ftype(params, ret));
+  return SharkContext::current().get_external(name, make_ftype(params, ret));
 }
 
 // Create an object representing an external function by inlining a
@@ -372,6 +356,15 @@
   return make_function((address) SharkRuntime::uncommon_trap, "Ti", "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
@@ -520,11 +513,7 @@
   const char *name;
   if (value->hasName())
     // XXX this leaks, but it's only debug code
-#if SHARK_LLVM_VERSION >= 26
     name = strdup(value->getName().str().c_str());
-#else
-    name = strdup(value->getName().c_str());
-#endif
   else
     name = "unnamed_value";
 
@@ -572,7 +561,7 @@
     LLVMValue::intptr_constant(offset));
 }
 
-Value* SharkBuilder::CreateInlineOop(ciObject* object, const char* name)
+Value* SharkBuilder::CreateInlineOop(jobject object, const char* name)
 {
   return CreateLoad(
     CreateIntToPtr(
@@ -607,9 +596,6 @@
 
 BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const
 {
-#if SHARK_LLVM_VERSION >= 26
-  return BasicBlock::Create(getGlobalContext(), name, GetInsertBlock()->getParent(), ip);
-#else
-  return BasicBlock::Create(name, GetInsertBlock()->getParent(), ip);
-#endif
+  return BasicBlock::Create(
+    SharkContext::current(), name, GetInsertBlock()->getParent(), ip);
 }  
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkBuilder.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -27,18 +27,12 @@
   friend class SharkCompileInvariants;
 
  public:
-  SharkBuilder(llvm::Module* module, SharkCodeBuffer* code_buffer);
+  SharkBuilder(SharkCodeBuffer* code_buffer);
 
-  // The LLVM module and Shark code buffer we are building into.
+  // The code buffer we are building into.
  private:
-  llvm::Module*    _module;
   SharkCodeBuffer* _code_buffer;
 
- private:
-  llvm::Module* module() const
-  {
-    return _module;
-  }
  protected:
   SharkCodeBuffer* code_buffer() const
   {
@@ -138,7 +132,14 @@
  public:
   llvm::Value* uncommon_trap();
 
-  // Intrinsics and external functions, part 4: Low-level non-VM calls.
+  // 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.
@@ -184,7 +185,11 @@
   // Helpers for accessing the code buffer.
  public:
   llvm::Value* code_buffer_address(int offset);
-  llvm::Value* CreateInlineOop(ciObject* object, const char* name = "");
+  llvm::Value* CreateInlineOop(jobject object, const char* name = "");
+  llvm::Value* CreateInlineOop(ciObject* object, const char* name = "")
+  {
+    return CreateInlineOop(object->encoding(), name);
+  }
 
   // Helpers for creating basic blocks.
   // NB don't use unless SharkFunction::CreateBlock is unavailable.
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -33,7 +33,7 @@
   // Start recording the debug information
   _pc_offset = code_buffer()->create_unique_offset();
   _oopmap = new OopMap(
-    oopmap_slot_munge(function()->oopmap_frame_size()),
+    oopmap_slot_munge(stack()->oopmap_frame_size()),
     oopmap_slot_munge(arg_size()));
   debug_info()->add_safepoint(pc_offset(), oopmap());
 }
@@ -44,10 +44,10 @@
   _exparray = new GrowableArray<ScopeValue*>(stack_depth);
 
   // Set the stack pointer
-  function()->CreateStoreZeroStackPointer(
+  stack()->CreateStoreStackPointer(
     builder()->CreatePtrToInt(
-      function()->CreateAddressOfFrameEntry(
-        function()->stack_slots_offset() + max_stack() - stack_depth),
+      stack()->slot_addr(
+        stack()->stack_slots_offset() + max_stack() - stack_depth),
       SharkType::intptr_type()));
 }
 
@@ -120,7 +120,7 @@
   // Record the PC
   builder()->CreateStore(
     builder()->code_buffer_address(pc_offset()),
-    function()->CreateAddressOfFrameEntry(offset));
+    stack()->slot_addr(offset));
 }
   
 void SharkDecacher::start_locals()
@@ -194,13 +194,11 @@
   builder()->CreateStore(
     builder()->CreateLoad(
       CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())),
-    function()->CreateAddressOfFrameEntry(
-      box_offset, SharkType::intptr_type()));
+    stack()->slot_addr(box_offset, SharkType::intptr_type()));
   builder()->CreateStore(
     builder()->CreateLoad(
       CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())),
-    function()->CreateAddressOfFrameEntry(
-      obj_offset, SharkType::oop_type()));
+    stack()->slot_addr(obj_offset, SharkType::oop_type()));
 }
 
 void SharkCacher::process_oop_tmp_slot(Value** value, int offset)
@@ -270,12 +268,10 @@
                                          Value*      value,
                                          int         offset)
 {
-  builder()->CreateStore(
-    value, function()->CreateAddressOfFrameEntry(offset, type));
+  builder()->CreateStore(value, stack()->slot_addr(offset, type));
 }
 
 Value* SharkCacher::read_value_from_frame(const Type* type, int offset)
 {
-  return builder()->CreateLoad(
-    function()->CreateAddressOfFrameEntry(offset, type));
+  return builder()->CreateLoad(stack()->slot_addr(offset, type));
 }
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkCacheDecache.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -116,13 +116,13 @@
 
   // oopmap and debuginfo helpers
  private:
-  static int oopmap_slot_munge(int x)
+  static int oopmap_slot_munge(int offset)
   {
-    return x << (LogBytesPerWord - LogBytesPerInt);
+    return SharkStack::oopmap_slot_munge(offset);
   }
   static VMReg slot2reg(int offset)
   {
-    return VMRegImpl::stack2reg(oopmap_slot_munge(offset));
+    return SharkStack::slot2reg(offset);
   }
   static Location slot2loc(int offset, Location::Type type)
   {
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkCodeBuffer.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -25,25 +25,13 @@
 
 class SharkCodeBuffer : public StackObj {
  public:
-  SharkCodeBuffer(OopRecorder* oop_recorder)
-    : _cb("Shark", 256 * K, 64 * K),
-      _masm(new MacroAssembler(&_cb)),
-      _base_pc(NULL)
-  {
-    cb()->initialize_oop_recorder(oop_recorder);
-  }
+  SharkCodeBuffer(MacroAssembler* masm)
+    : _masm(masm), _base_pc(NULL) {}
 
  private:
-  CodeBuffer      _cb;
   MacroAssembler* _masm;
   llvm::Value*    _base_pc;
 
- public:
-  CodeBuffer* cb()
-  {
-    return &_cb;
-  }
-
  private:
   MacroAssembler* masm() const
   {
@@ -84,11 +72,11 @@
 
   // Inline an oop into the buffer and return its offset.
  public:
-  int inline_oop(ciObject* object) const
+  int inline_oop(jobject object) const
   {
     masm()->align(BytesPerWord);
     int offset = masm()->offset();
-    masm()->store_oop(object->encoding());
+    masm()->store_oop(object);
     return offset;
   }
 };
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkCompiler.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -33,52 +33,32 @@
 SharkCompiler::SharkCompiler()
   : AbstractCompiler()
 {
-#if SHARK_LLVM_VERSION >= 26
-  // Make LLVM safe for multithreading.  We only make LLVM calls from
-  // the compiler thread, but if LLVM leaves stubs to be rewritten on
-  // execution then it's possible for Java threads to be making LLVM
-  // calls at the same time we are.
+  // 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()) 
-    warning("llvm_start_multithreaded() failed");
-#endif
+    fatal("llvm_start_multithreaded() failed");
 
-  // Create a module to build our functions into
-#if SHARK_LLVM_VERSION >= 26
-  // LLVM 2.6 and later requires passing a LLVMContext during module
-  // creation. The LLVM API getGlobalContext() returns a LLVMContext that
-  // can be used safely as long as the shark compiler stays single threaded
-  // and only uses one module.
-  _module = new Module("shark", getGlobalContext());
-#else
-  _module = new Module("shark");
-#endif
+  // Initialize the native target
+  InitializeNativeTarget();
 
-#if SHARK_LLVM_VERSION >= 26
-  // If we have a native target, initialize it to ensure it is linked in and
-  // usable by the JIT.
-  InitializeNativeTarget();
-#endif
-  
+  // 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();
+
   // Create the JIT
-  ModuleProvider *module_provider = new ExistingModuleProvider(module());
-  _memory_manager = new SharkMemoryManager();
   _execution_engine = ExecutionEngine::createJIT(
-#if SHARK_LLVM_VERSION >= 26
-   /*
-    * LLVM 26 introduced a more fine-grained control to set the optimization
-    * level when creating the LLVM JIT.
-    * The optimization level are now specified with a enum instead of a bool.
-    * CodeGenOpt::None = bool true; a fast JIT with reduced optimization.
-    * CodeGenOpt::Default = bool false; a non-fast JIT with optimization.
-    * CodeGenOpt::Aggressive = a new non-fast JIT with best optimization.
-    */
-    module_provider, NULL, memory_manager(), CodeGenOpt::Default);
-#else
-    module_provider, NULL, memory_manager(), false);
-#endif
+    _normal_context->module_provider(),
+    NULL, memory_manager(), CodeGenOpt::Default);
+  execution_engine()->addModuleProvider(
+    _native_context->module_provider());
 
-  // Initialize Shark components that need it
-  SharkType::initialize();
+  // All done
   mark_initialized();
 }
 
@@ -90,9 +70,9 @@
 void SharkCompiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci)
 {
   assert(is_initialized(), "should be");
-
   ResourceMark rm;
-  const char *name = methodname(target);
+  const char *name = methodname(
+    target->holder()->name()->as_utf8(), target->name()->as_utf8());
 
   // Do the typeflow analysis
   ciTypeFlow *flow;
@@ -116,62 +96,26 @@
   env->set_dependencies(new Dependencies(env));
 
   // Create the code buffer and builder
-  SharkCodeBuffer cb(env->oop_recorder());
-  SharkBuilder builder(module(), &cb);
+  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(this, env, &builder, flow, name);
-  if (SharkPrintBitcodeOf != NULL) {
-    if (!fnmatch(SharkPrintBitcodeOf, name, 0))
-      function->dump();
+  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);
   }
-  entry->set_function(function);
 
-  // Compile to native code
-#ifndef PRODUCT
-#if SHARK_LLVM_VERSION < 27
-#ifdef X86
-  if (SharkPrintAsmOf != NULL) {
-    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 // X86
-#else
-  if (SharkPrintAsmOf != NULL) {
-    if (!fnmatch(SharkPrintAsmOf, name, 0)) {
-#ifdef X86
-      llvm::SetCurrentDebugType("x86-emitter");
-#else
-      llvm::SetCurrentDebugType("jit");
-#endif // X86
-      llvm::DebugFlag=true;
-    } else {
-      llvm::SetCurrentDebugType(""); 
-      llvm::DebugFlag=false;
-    }
-  }
-#endif
-#endif // !PRODUCT
-  memory_manager()->set_entry_for_function(function, entry);
-  module()->getFunctionList().push_back(function);
-  entry->set_entry_point(
-    (address) execution_engine()->getPointerToFunction(function));
-  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);
-  
   // Install the method into the VM
   CodeOffsets offsets;
   offsets.set_value(CodeOffsets::Deopt, 0);
@@ -186,7 +130,7 @@
                        entry_bci,
                        &offsets,
                        0,
-                       cb.cb(),
+                       &hscb,
                        0,
                        &oopmaps,
                        &handler_table,
@@ -195,8 +139,96 @@
                        env->comp_level(),
                        false,
                        false);
+}
 
-  // Print statistics, if requested
+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
+      if (!fnmatch(SharkPrintAsmOf, name, 0)) {
+        llvm::SetCurrentDebugType(X86_ONLY("x86-emitter") NOT_X86("jit"));
+        llvm::DebugFlag = true;
+      }
+      else {
+        llvm::SetCurrentDebugType(""); 
+        llvm::DebugFlag = false;
+      }
+#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)",
@@ -206,21 +238,39 @@
 
 void SharkCompiler::free_compiled_method(address code)
 {
-  Function *function = ((SharkEntry *) code)->function();
-  execution_engine()->freeMachineCodeForFunction(function);
-  function->eraseFromParent();
+  // 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());
 }
 
-const char* SharkCompiler::methodname(const ciMethod* target)
+void SharkCompiler::free_queued_methods()
 {
-  const char *klassname = target->holder()->name()->as_utf8();
-  const char *methodname = target->name()->as_utf8();
+  // The free queue is protected by the execution engine lock
+  assert(execution_engine_lock()->owned_by_self(), "should be");
 
-  char *buf = NEW_RESOURCE_ARRAY(
-    char, strlen(klassname) + 2 + strlen(methodname) + 1);
+  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 = klassname; *c; c++) {
+  for (const char *c = klass; *c; c++) {
     if (*c == '/')
       *(dst++) = '.';
     else
@@ -228,7 +278,7 @@
   }
   *(dst++) = ':';
   *(dst++) = ':';
-  for (const char *c = methodname; *c; c++) {
+  for (const char *c = method; *c; c++) {
     *(dst++) = *c;
   }
   *(dst++) = '\0';
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkCompiler.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -23,6 +23,8 @@
  *
  */
 
+class SharkContext;
+
 class SharkCompiler : public AbstractCompiler {
  public:
   // Creation
@@ -32,7 +34,7 @@
   const char *name()     { return "shark"; }
 
   // Missing feature tests
-  bool supports_native() { return false; }
+  bool supports_native() { return true; }
   bool supports_osr()    { return true; }
 
   // Customization
@@ -42,33 +44,81 @@
   // Initialization
   void initialize();
 
-  // Compilation entry point for methods
+  // Compile a normal (bytecode) method and install it in the VM
   void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
 
-  // Free compiled methods
+  // 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);
 
-  // LLVM interface
+  // 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:
-  llvm::Module*          _module;
+  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;
 
- public:
-  llvm::Module* module() const
+ private:
+  Monitor* execution_engine_lock() const
   {
-    return _module;
+    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;
   }
 
-  // Helper
+  // 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 ciMethod* target);
+  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();
 };
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkContext.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkContext.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -0,0 +1,185 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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(void_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(void_type(), params, false);
+
+  // Create mappings
+  for (int i = 0; i < T_CONFLICT; i++) {
+    switch (i) {
+    case T_BOOLEAN:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jbyte_type();
+      break;
+      
+    case T_BYTE:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jbyte_type();
+      break;
+
+    case T_CHAR:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jshort_type();
+      break;
+
+    case T_SHORT:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jshort_type();
+      break;
+
+    case T_INT:
+      _to_stackType[i] = jint_type();
+      _to_arrayType[i] = jint_type();
+      break;
+
+    case T_LONG:
+      _to_stackType[i] = jlong_type();
+      _to_arrayType[i] = jlong_type();
+      break;
+
+    case T_FLOAT:
+      _to_stackType[i] = jfloat_type();
+      _to_arrayType[i] = jfloat_type();
+      break;
+
+    case T_DOUBLE:
+      _to_stackType[i] = jdouble_type();
+      _to_arrayType[i] = jdouble_type();
+      break;
+
+    case T_OBJECT:
+    case T_ARRAY:
+      _to_stackType[i] = oop_type();
+      _to_arrayType[i] = oop_type();
+      break;
+
+    case T_ADDRESS:
+      _to_stackType[i] = intptr_type();
+      _to_arrayType[i] = NULL;
+      break;
+
+    default:
+      _to_stackType[i] = NULL;
+      _to_arrayType[i] = NULL;
+    }
+  }
+}
+
+class SharkFreeQueueItem : public CHeapObj {
+ public:
+  SharkFreeQueueItem(llvm::Function* function, SharkFreeQueueItem *next)
+    : _function(function), _next(next) {}
+
+ private:
+  llvm::Function*     _function;
+  SharkFreeQueueItem* _next;
+
+ public:
+  llvm::Function* function() const
+  {
+    return _function;
+  }
+  SharkFreeQueueItem* next() const
+  {
+    return _next;
+  }
+};
+
+void SharkContext::push_to_free_queue(Function* function)
+{
+  _free_queue = new SharkFreeQueueItem(function, _free_queue);
+}
+
+Function* SharkContext::pop_from_free_queue()
+{
+  if (_free_queue == NULL)
+    return NULL;
+
+  SharkFreeQueueItem *item = _free_queue;
+  Function *function = item->function();
+  _free_queue = item->next();
+  delete item;
+  return function;
+}
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkContext.hpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkContext.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -0,0 +1,208 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+
+ private:
+  llvm::Module* module() const
+  {
+    return _module;
+  }
+
+  // Get this thread's SharkContext
+ public:
+  static SharkContext& current()
+  {
+    return *SharkCompiler::compiler()->context();
+  }
+
+  // Module accessors
+ public:
+  llvm::ModuleProvider* module_provider() const
+  {
+    return new llvm::ExistingModuleProvider(module());
+  }
+  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();
+};
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkEntry.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkEntry.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkEntry.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -23,9 +23,12 @@
  *
  */
 
+class SharkContext;
+
 class SharkEntry : public ZeroEntry {
  private:
   address         _code_limit;
+  SharkContext*   _context;
   llvm::Function* _function;
 
  public:
@@ -37,6 +40,10 @@
   {
     return _code_limit;
   }
+  SharkContext* context() const
+  {
+    return _context;
+  }
   llvm::Function* function() const
   {
     return _function;
@@ -47,6 +54,10 @@
   {
     _code_limit = code_limit;
   }
+  void set_context(SharkContext* context)
+  {
+    _context = context;
+  }
   void set_function(llvm::Function* function)
   {
     _function = function;
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkFunction.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -77,17 +77,10 @@
       block(i)->initialize();
   }
 
-  // Create the method preamble
+  // Create and push our stack frame
   set_block_insertion_point(&function()->front());
   builder()->SetInsertPoint(CreateBlock());
-  CreateInitZeroStack();
-  CreatePushFrame(CreateBuildFrame());
-  NOT_PRODUCT(builder()->CreateStore(
-    method,
-    CreateAddressOfFrameEntry(
-      method_slot_offset(),
-      SharkType::methodOop_type(),
-      "method_slot")));
+  _stack = SharkStack::CreateBuildAndPushFrame(this, method);
 
   // Create the entry state
   SharkState *entry_state;
@@ -132,150 +125,6 @@
   do_deferred_zero_checks();
 }
 
-void SharkFunction::CreateInitZeroStack()
-{
-  Value *zero_stack = builder()->CreateAddressOfStructEntry(
-    thread(), JavaThread::zero_stack_offset(),
-    SharkType::zeroStack_type(),
-    "zero_stack");
-
-  _zero_stack_base = builder()->CreateValueOfStructEntry(
-    zero_stack, ZeroStack::base_offset(),
-    SharkType::intptr_type(),
-    "zero_stack_base");
-
-  _zero_stack_pointer_addr = builder()->CreateAddressOfStructEntry(
-    zero_stack, ZeroStack::sp_offset(),
-    PointerType::getUnqual(SharkType::intptr_type()),
-    "zero_stack_pointer_addr");
-
-  _zero_frame_pointer_addr = builder()->CreateAddressOfStructEntry(
-    thread(), JavaThread::top_zero_frame_offset(),
-    PointerType::getUnqual(SharkType::intptr_type()),
-    "zero_frame_pointer_addr");
-}
-
-void SharkFunction::CreateStackOverflowCheck(Value *sp)
-{
-  BasicBlock *overflow = CreateBlock("stack_overflow");
-  BasicBlock *no_overflow = CreateBlock("no_overflow");
-  
-  builder()->CreateCondBr(
-    builder()->CreateICmpULT(sp, zero_stack_base()),
-    overflow, no_overflow);
-
-  builder()->SetInsertPoint(overflow);
-  builder()->CreateUnimplemented(__FILE__, __LINE__);
-  builder()->CreateUnreachable();
-
-  builder()->SetInsertPoint(no_overflow);  
-}
-
-void SharkFunction::CreatePushFrame(Value *fp)
-{
-  builder()->CreateStore(CreateLoadZeroFramePointer(), fp);
-  CreateStoreZeroFramePointer(
-    builder()->CreatePtrToInt(fp, SharkType::intptr_type()));
-}
-
-Value* SharkFunction::CreatePopFrame(int result_slots)
-{
-  assert(result_slots >= 0 && result_slots <= 2, "should be");
-
-  int locals_to_pop = max_locals() - result_slots;
-
-  Value *fp = CreateLoadZeroFramePointer();
-  Value *sp = builder()->CreateAdd(
-    fp,
-    LLVMValue::intptr_constant((1 + locals_to_pop) * wordSize));
-
-  CreateStoreZeroStackPointer(sp);
-  CreateStoreZeroFramePointer(
-    builder()->CreateLoad(
-      builder()->CreateIntToPtr(
-        fp, PointerType::getUnqual(SharkType::intptr_type()))));
-
-  return sp;
-}
-
-Value* SharkFunction::CreateBuildFrame()
-{
-  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 *zero_stack_pointer = builder()->CreateSub(
-    CreateLoadZeroStackPointer(),
-    LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize));
-  CreateStackOverflowCheck(zero_stack_pointer);
-  NOT_PRODUCT(CreateStoreZeroStackPointer(zero_stack_pointer));
-
-  // Create the frame
-  _frame = builder()->CreateIntToPtr(
-    zero_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++;
-
-  // Unextended SP
-  builder()->CreateStore(
-    zero_stack_pointer,
-    CreateAddressOfFrameEntry(offset++));
-
-  // PC
-  _pc_slot_offset = offset++;
-
-  // Frame header
-  builder()->CreateStore(
-    LLVMValue::intptr_constant(ZeroFrame::SHARK_FRAME),
-    CreateAddressOfFrameEntry(offset++));
-  Value *fp = CreateAddressOfFrameEntry(offset++);
-
-  // Local variables
-  _locals_slots_offset = offset;  
-  offset += locals_words;
-
-  assert(offset == extended_frame_size(), "should do");
-  return fp;
-}
-
-Value* SharkFunction::CreateAddressOfFrameEntry(int               offset,
-                                                const llvm::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;
-}
-
 class DeferredZeroCheck : public SharkTargetInvariants {
  public:
   DeferredZeroCheck(SharkTopLevelBlock* block, SharkValue* value)
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkFunction.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -27,24 +27,24 @@
 class DeferredZeroCheck;
 
 class SharkFunction : public SharkTargetInvariants {
+ friend class SharkStackWithNormalFrame;
+  
  public:
-  static llvm::Function* build(SharkCompiler* compiler,
-                               ciEnv*         env,
-                               SharkBuilder*  builder,
-                               ciTypeFlow*    flow,
-                               const char*    name)
+  static llvm::Function* build(ciEnv*        env,
+                               SharkBuilder* builder,
+                               ciTypeFlow*   flow,
+                               const char*   name)
   {
-    SharkFunction function(compiler, env, builder, flow, name);
+    SharkFunction function(env, builder, flow, name);
     return function.function();
   }
 
  private:
-  SharkFunction(SharkCompiler* compiler,
-                ciEnv*         env,
-                SharkBuilder*  builder,
-                ciTypeFlow*    flow,
-                const char*    name)
-    : SharkTargetInvariants(compiler, env, builder, flow) { initialize(name); }
+  SharkFunction(ciEnv*        env,
+                SharkBuilder* builder,
+                ciTypeFlow*   flow,
+                const char*   name)
+    : SharkTargetInvariants(env, builder, flow) { initialize(name); }
 
  private:
   void initialize(const char* name);
@@ -53,6 +53,7 @@
   llvm::Function*                   _function;
   SharkTopLevelBlock**              _blocks;
   GrowableArray<DeferredZeroCheck*> _deferred_zero_checks;
+  SharkStack*                       _stack;
 
  public:
   llvm::Function* function() const
@@ -72,6 +73,10 @@
   {
     return &_deferred_zero_checks;
   }
+  SharkStack* stack() const
+  {
+    return _stack;
+  }
 
   // On-stack replacement
  private:
@@ -103,153 +108,8 @@
  public:
   llvm::BasicBlock* CreateBlock(const char* name = "") const
   {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::BasicBlock::Create(llvm::getGlobalContext(), name, function(), block_insertion_point());
-#else
-    return llvm::BasicBlock::Create(name, function(), block_insertion_point());
-#endif
-  }
-
-  // Stack management
- private:
-  llvm::Value* _zero_stack_base;
-  llvm::Value* _zero_stack_pointer_addr;
-  llvm::Value* _zero_frame_pointer_addr;
-
- private:
-  llvm::Value* zero_stack_base() const 
-  {
-    return _zero_stack_base;
-  }
-  llvm::Value* zero_stack_pointer_addr() const 
-  {
-    return _zero_stack_pointer_addr;
-  }
-  llvm::Value* zero_frame_pointer_addr() const 
-  {
-    return _zero_frame_pointer_addr;
-  }
-
- private:
-  void CreateInitZeroStack();
-
- public:
-  llvm::LoadInst* CreateLoadZeroStackPointer(const char *name = "")
-  {
-    return builder()->CreateLoad(zero_stack_pointer_addr(), name);
-  }
-  llvm::StoreInst* CreateStoreZeroStackPointer(llvm::Value* value)
-  {
-    return builder()->CreateStore(value, zero_stack_pointer_addr());
-  }
-  llvm::LoadInst* CreateLoadZeroFramePointer(const char *name = "")
-  {
-    return builder()->CreateLoad(zero_frame_pointer_addr(), name);
-  }
- private:
-  llvm::StoreInst* CreateStoreZeroFramePointer(llvm::Value* value)
-  {
-    return builder()->CreateStore(value, zero_frame_pointer_addr());
-  }
-
- private:
-  void CreateStackOverflowCheck(llvm::Value* sp);
-
- public:
-  void CreatePushFrame(llvm::Value* fp);
-  llvm::Value* CreatePopFrame(int result_slots);
-
-  // Frame management
- private:
-  llvm::Value* _frame;
-
- public:
-  llvm::Value* CreateAddressOfFrameEntry(int               offset,
-                                         const llvm::Type* type = NULL,
-                                         const char*       name = "") const;
- private:
-  llvm::Value* CreateBuildFrame();
-
- private:
-  int _extended_frame_size;
-  int _stack_slots_offset;
-  int _monitors_slots_offset;
-  int _oop_tmp_slot_offset;
-  int _method_slot_offset;
-  int _pc_slot_offset;
-  int _locals_slots_offset;
-
- public:
-  int extended_frame_size() const
-  {
-    return _extended_frame_size;
-  }
-  int oopmap_frame_size() const
-  {
-    return extended_frame_size() - arg_size();
-  }
-  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;
-  }
-
-  // Monitors
- public:
-  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);
-  }
-
- public:
-  llvm::Value* monitor_addr(int index) const
-  {
-    return CreateAddressOfFrameEntry(
-      monitor_offset(index),
-      SharkType::monitor_type(),
-      "monitor");
-  }
-  llvm::Value* monitor_object_addr(int index) const
-  {
-    return CreateAddressOfFrameEntry(
-      monitor_object_offset(index),
-      SharkType::oop_type(),
-      "object_addr");
-  }
-  llvm::Value* monitor_header_addr(int index) const
-  {
-    return CreateAddressOfFrameEntry(
-      monitor_header_offset(index),
-      SharkType::intptr_type(),
-      "displaced_header_addr");
+    return llvm::BasicBlock::Create(
+      SharkContext::current(), name, function(), block_insertion_point());
   }
 
   // Deferred zero checks
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkInvariants.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkInvariants.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkInvariants.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -31,35 +31,20 @@
 
 class SharkCompileInvariants : public ResourceObj {
  protected:
-  SharkCompileInvariants(SharkCompiler* compiler,
-                         ciEnv*         env,
-                         SharkBuilder*  builder)
-    : _compiler(compiler),
-      _env(env),
+  SharkCompileInvariants(ciEnv* env, SharkBuilder* builder)
+    : _env(env),
       _builder(builder),
       _thread(NULL) {}
 
   SharkCompileInvariants(const SharkCompileInvariants* parent)
-    : _compiler(parent->_compiler),
-      _env(parent->_env),
+    : _env(parent->_env),
       _builder(parent->_builder),
       _thread(parent->_thread) {}
 
  private:
-  SharkCompiler* _compiler;
-  ciEnv*         _env;
-  SharkBuilder*  _builder;
-  llvm::Value*   _thread;
-
-  // The SharkCompiler that is compiling this method.  Holds the
-  // classes that form the interface with LLVM (the module, the
-  // memory manager, etc) and provides the compile() method to
-  // convert LLVM functions to native code.
- protected:
-  SharkCompiler* compiler() const
-  {
-    return _compiler;
-  }
+  ciEnv*        _env;
+  SharkBuilder* _builder;
+  llvm::Value*  _thread;
 
   // Top-level broker for HotSpot's Compiler Interface.
   //
@@ -73,6 +58,7 @@
  private:
   ciEnv* env() const
   {
+    assert(_env != NULL, "env not available");
     return _env;
   }
 
@@ -124,11 +110,8 @@
 
 class SharkTargetInvariants : public SharkCompileInvariants {
  protected:
-  SharkTargetInvariants(SharkCompiler* compiler,
-                        ciEnv*         env,
-                        SharkBuilder*  builder,
-                        ciTypeFlow*    flow)
-    : SharkCompileInvariants(compiler, env, builder),
+  SharkTargetInvariants(ciEnv* env, SharkBuilder* builder, ciTypeFlow* flow)
+    : SharkCompileInvariants(env, builder),
       _target(flow->method()),
       _flow(flow),
       _max_monitors(count_monitors()) {}
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkMemoryManager.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkMemoryManager.cpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkMemoryManager.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -103,8 +103,8 @@
 }
 #endif
 
-#if SHARK_LLVM_VERSION >= 26
-uint8_t* SharkMemoryManager::allocateGlobal(uintptr_t Size, unsigned int Alignment)
+uint8_t* SharkMemoryManager::allocateGlobal(uintptr_t Size,
+                                            unsigned int Alignment)
 {
   return mm()->allocateGlobal(Size, Alignment);
 }
@@ -124,12 +124,8 @@
   mm()->setPoisonMemory(poison);
 }
 
-#endif
-
-#if SHARK_LLVM_VERSION >= 25
 unsigned char *SharkMemoryManager::allocateSpace(intptr_t Size,
                                                  unsigned int Alignment)
 {
   return mm()->allocateSpace(Size, Alignment);
 }
-#endif
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkMemoryManager.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkMemoryManager.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkMemoryManager.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -71,12 +71,10 @@
                          unsigned char* TableStart,
                          unsigned char* TableEnd,
                          unsigned char* FrameRegister);
-#if SHARK_LLVM_VERSION >= 26
   void* getDlsymTable() const;
   void SetDlsymTable(void *ptr);
   void setPoisonMemory(bool);
   uint8_t* allocateGlobal(uintptr_t, unsigned int);
-#endif
   void setMemoryWritable();
   void setMemoryExecutable();
 #if SHARK_LLVM_VERSION >= 27
@@ -85,9 +83,6 @@
 #else
   void deallocateMemForFunction(const llvm::Function* F);
 #endif
-
-#if SHARK_LLVM_VERSION >= 25
   unsigned char *allocateSpace(intptr_t Size,
 			       unsigned int Alignment);
-#endif
 };
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -0,0 +1,352 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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())),
+      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)
+      { Unimplemented(); }
+    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()->CreateRetVoid();
+
+  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_BYTE:
+      needs_cast = true;
+      break;
+      
+    case T_CHAR:
+    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()->CreateRetVoid();
+}
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkNativeWrapper.hpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkNativeWrapper.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -0,0 +1,204 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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");
+  }
+};
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkStack.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkStack.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -0,0 +1,239 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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));
+  CreateHardStackOverflowCheck(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()));
+
+  // Check we're not about to run out of stack
+  CreateSoftStackOverflowCheck(stack_pointer);
+}
+
+// Check that the stack will not overflow before a stack pointer
+// update.  Overflows here are problematic as we haven't yet
+// created a frame, so it's not clear how to report the error.
+// http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=249
+void SharkStack::CreateHardStackOverflowCheck(Value* sp)
+{
+  BasicBlock *overflow = CreateBlock("stack_overflow");
+  BasicBlock *no_overflow = CreateBlock("no_overflow");
+  
+  builder()->CreateCondBr(
+    builder()->CreateICmpULT(sp, stack_base()),
+    overflow, no_overflow);
+
+  builder()->SetInsertPoint(overflow);
+  builder()->CreateUnimplemented(__FILE__, __LINE__);
+  builder()->CreateUnreachable();
+
+  builder()->SetInsertPoint(no_overflow);  
+}
+
+// Check that a stack overflow is not imminent, throwing a
+// StackOverflowError if it is while we still have the stack
+// in which to do so.
+void SharkStack::CreateSoftStackOverflowCheck(Value* sp)
+{
+  // XXX see CppInterpreter::stack_overflow_imminent
+}
+
+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);
+}
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkStack.hpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkStack.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -0,0 +1,292 @@
+/*
+ * Copyright 1999-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 CreateHardStackOverflowCheck(llvm::Value* sp);
+  void CreateSoftStackOverflowCheck(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;
+  
+  // 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* frame_anchor_addr() const
+  {
+    return builder()->CreateAddressOfStructEntry(
+      thread(),
+      JavaThread::last_Java_sp_offset(),
+      llvm::PointerType::getUnqual(SharkType::intptr_type()),
+      "frame_anchor_addr");
+  }
+
+ public:
+  llvm::StoreInst* CreateSetLastJavaFrame()
+  {
+    return builder()->CreateStore(
+      CreateLoadFramePointer(), frame_anchor_addr());
+  }
+  llvm::StoreInst* CreateResetLastJavaFrame()
+  {
+    return builder()->CreateStore(
+      LLVMValue::intptr_constant(0), frame_anchor_addr());
+  }
+
+  // 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;
+};
+
+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;
+};
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkStateScanner.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -39,7 +39,7 @@
     process_stack_slot(
       i,
       state->stack_addr(i),
-      function()->stack_slots_offset() +
+      stack()->stack_slots_offset() +
         i + max_stack() - state->stack_depth());
   }
   end_stack();
@@ -49,17 +49,17 @@
   for (int i = 0; i < state->num_monitors(); i++) {
     process_monitor(
       i,
-      function()->monitor_offset(i),
-      function()->monitor_object_offset(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(), function()->oop_tmp_slot_offset());
-  process_method_slot(state->method_addr(), function()->method_slot_offset());
-  process_pc_slot(function()->pc_slot_offset());
+    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
@@ -69,7 +69,7 @@
     process_local_slot(
       i,
       state->local_addr(i),
-      function()->locals_slots_offset() + max_locals() - 1 - i);
+      stack()->locals_slots_offset() + max_locals() - 1 - i);
   }
   end_locals();
 
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkStateScanner.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -28,15 +28,15 @@
 class SharkStateScanner : public SharkTargetInvariants {
  protected:
   SharkStateScanner(SharkFunction* function)
-    : SharkTargetInvariants(function), _function(function) {}
+    : SharkTargetInvariants(function), _stack(function->stack()) {}
 
  private:
-  SharkFunction* _function;
+  SharkStack* _stack;
 
  protected:
-  SharkFunction* function() const
+  SharkStack* stack() const
   {
-    return _function;
+    return _stack;
   }
 
   // Scan the frame
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Wed Nov 11 16:21:16 2009 +0000
@@ -638,7 +638,7 @@
     builder()->CreateStore(exception, pending_exception_address());
   }
 
-  Value *result_addr = function()->CreatePopFrame(type2size[type]);
+  Value *result_addr = stack()->CreatePopFrame(type2size[type]);
   if (type != T_VOID) {
     builder()->CreateStore(
       pop_result(type)->generic_value(),
@@ -1648,8 +1648,8 @@
   // of normal stack order.
   int ndims = iter()->get_dimensions();
 
-  Value *dimensions = function()->CreateAddressOfFrameEntry(
-    function()->stack_slots_offset() + max_stack() - xstack_depth(),
+  Value *dimensions = stack()->slot_addr(
+    stack()->stack_slots_offset() + max_stack() - xstack_depth(),
     ArrayType::get(SharkType::jint_type(), ndims),
     "dimensions");
 
@@ -1707,9 +1707,9 @@
   BasicBlock *lock_acquired = function()->CreateBlock("lock_acquired");
 
   int monitor = num_monitors();
-  Value *monitor_addr        = function()->monitor_addr(monitor);
-  Value *monitor_object_addr = function()->monitor_object_addr(monitor);
-  Value *monitor_header_addr = function()->monitor_header_addr(monitor);
+  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);
@@ -1791,9 +1791,9 @@
   BasicBlock *lock_released = function()->CreateBlock("lock_released");
 
   int monitor = num_monitors() - 1;
-  Value *monitor_addr        = function()->monitor_addr(monitor);
-  Value *monitor_object_addr = function()->monitor_object_addr(monitor);
-  Value *monitor_header_addr = function()->monitor_header_addr(monitor);
+  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);
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -49,6 +49,13 @@
     return _ciblock;
   }
 
+  // Function properties
+ public:
+  SharkStack* stack() const
+  {
+    return function()->stack();
+  }
+  
   // Typeflow properties
  public:
   int index() const
@@ -272,26 +279,6 @@
   void check_pending_exception(int action);
   void handle_exception(llvm::Value* exception, int action);
 
-  // Frame anchor
- private:
-  void set_last_Java_frame(llvm::Value* value) const
-  {
-    builder()->CreateStore(
-      value,
-      builder()->CreateAddressOfStructEntry(
-        thread(), JavaThread::last_Java_sp_offset(),
-        llvm::PointerType::getUnqual(SharkType::intptr_type()),
-        "last_Java_sp_addr"));
-  }
-  void set_last_Java_frame() const
-  {
-    set_last_Java_frame(function()->CreateLoadZeroFramePointer());
-  }
-  void reset_last_Java_frame() const
-  {
-    set_last_Java_frame(LLVMValue::intptr_constant(0));
-  }
-
   // VM calls
  private:
   llvm::CallInst* call_vm(llvm::Value*  callee,
@@ -300,9 +287,9 @@
                           int           exception_action)
   {
     decache_for_VM_call();
-    set_last_Java_frame();
+    stack()->CreateSetLastJavaFrame();
     llvm::CallInst *res = builder()->CreateCall(callee, args_start, args_end);
-    reset_last_Java_frame();
+    stack()->CreateResetLastJavaFrame();
     cache_after_VM_call();
     if (exception_action & EAM_CHECK) {
       check_pending_exception(exception_action);
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkType.cpp
--- a/ports/hotspot/src/share/vm/shark/sharkType.cpp	Wed Nov 11 10:50:38 2009 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-/*
- * Copyright 1999-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- */
-
-#include "incls/_precompiled.incl"
-#include "incls/_sharkType.cpp.incl"
-
-using namespace llvm;
-
-const PointerType*  SharkType::_cpCacheEntry_type;
-const FunctionType* SharkType::_entry_point_type;
-const FunctionType* SharkType::_osr_entry_point_type;
-const PointerType*  SharkType::_itableOffsetEntry_type;
-const PointerType*  SharkType::_klass_type;
-const PointerType*  SharkType::_methodOop_type;
-const ArrayType*    SharkType::_monitor_type;
-const PointerType*  SharkType::_oop_type;
-const PointerType*  SharkType::_thread_type;
-const PointerType*  SharkType::_zeroStack_type;
-
-const Type* SharkType::_to_stackType_tab[T_CONFLICT + 1];
-const Type* SharkType::_to_arrayType_tab[T_CONFLICT + 1];
-
-void SharkType::initialize()
-{
-  // VM types
-  _cpCacheEntry_type = PointerType::getUnqual(
-#if SHARK_LLVM_VERSION >= 26
-    ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(ConstantPoolCacheEntry)));
-#else
-    ArrayType::get(Type::Int8Ty, sizeof(ConstantPoolCacheEntry)));
-#endif
-
-  _itableOffsetEntry_type = PointerType::getUnqual(
-#if SHARK_LLVM_VERSION >= 26
-    ArrayType::get(Type::getInt8Ty(getGlobalContext()), itableOffsetEntry::size() * wordSize));
-#else
-    ArrayType::get(Type::Int8Ty, itableOffsetEntry::size() * wordSize));
-#endif
-
-  _klass_type = PointerType::getUnqual(
-#if SHARK_LLVM_VERSION >= 26
-    ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(Klass)));
-#else
-    ArrayType::get(Type::Int8Ty, sizeof(Klass)));
-#endif
-
-  _methodOop_type = PointerType::getUnqual(
-#if SHARK_LLVM_VERSION >= 26
-    ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(methodOopDesc)));
-#else
-    ArrayType::get(Type::Int8Ty, sizeof(methodOopDesc)));
-#endif
-
-  _monitor_type = ArrayType::get(
-#if SHARK_LLVM_VERSION >= 26
-      Type::getInt8Ty(getGlobalContext()),
-#else
-      Type::Int8Ty,
-#endif
-      frame::interpreter_frame_monitor_size() * wordSize);
-
-  _oop_type = PointerType::getUnqual(
-#if SHARK_LLVM_VERSION >= 26
-    ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(oopDesc)));
-#else
-    ArrayType::get(Type::Int8Ty, sizeof(oopDesc)));
-#endif
-
-  _thread_type = PointerType::getUnqual(
-#if SHARK_LLVM_VERSION >= 26
-    ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(JavaThread)));
-#else
-    ArrayType::get(Type::Int8Ty, sizeof(JavaThread)));
-#endif
-
-  _zeroStack_type = PointerType::getUnqual(
-#if SHARK_LLVM_VERSION >= 26
-    ArrayType::get(Type::getInt8Ty(getGlobalContext()), sizeof(ZeroStack)));
-#else
-    ArrayType::get(Type::Int8Ty, sizeof(ZeroStack)));
-#endif
-
-  std::vector<const Type*> params;
-  params.push_back(methodOop_type());
-  params.push_back(intptr_type());
-  params.push_back(thread_type());
-#if SHARK_LLVM_VERSION >= 26
-  _entry_point_type = FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false);
-#else
-  _entry_point_type = FunctionType::get(Type::VoidTy, params, false);
-#endif
-
-  params.clear();
-  params.push_back(methodOop_type());
-  params.push_back(PointerType::getUnqual(jbyte_type()));
-  params.push_back(intptr_type());
-  params.push_back(thread_type());
-#if SHARK_LLVM_VERSION >= 26
-  _osr_entry_point_type = FunctionType::get(Type::getVoidTy(getGlobalContext()), params, false);
-#else
-  _osr_entry_point_type = FunctionType::get(Type::VoidTy, params, false);
-#endif
-
-  // Java types a) on the stack and in fields, and b) in arrays
-  for (int i = 0; i < T_CONFLICT + 1; i++) {
-    switch (i) {
-    case T_BOOLEAN:
-      _to_stackType_tab[i] = jint_type();
-      _to_arrayType_tab[i] = jboolean_type();
-      break;
-      
-    case T_BYTE:
-      _to_stackType_tab[i] = jint_type();
-      _to_arrayType_tab[i] = jbyte_type();
-      break;
-
-    case T_CHAR:
-      _to_stackType_tab[i] = jint_type();
-      _to_arrayType_tab[i] = jchar_type();
-      break;
-
-    case T_SHORT:
-      _to_stackType_tab[i] = jint_type();
-      _to_arrayType_tab[i] = jshort_type();
-      break;
-
-    case T_INT:
-      _to_stackType_tab[i] = jint_type();
-      _to_arrayType_tab[i] = jint_type();
-      break;
-
-    case T_LONG:
-      _to_stackType_tab[i] = jlong_type();
-      _to_arrayType_tab[i] = jlong_type();
-      break;
-
-    case T_FLOAT:
-      _to_stackType_tab[i] = jfloat_type();
-      _to_arrayType_tab[i] = jfloat_type();
-      break;
-
-    case T_DOUBLE:
-      _to_stackType_tab[i] = jdouble_type();
-      _to_arrayType_tab[i] = jdouble_type();
-      break;
-
-    case T_OBJECT:
-    case T_ARRAY:
-      _to_stackType_tab[i] = oop_type();
-      _to_arrayType_tab[i] = oop_type();
-      break;
-
-    case T_ADDRESS:
-      _to_stackType_tab[i] = intptr_type();
-      break;
-    }
-  }
-}
diff -r b3d03017bdef ports/hotspot/src/share/vm/shark/sharkType.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkType.hpp	Wed Nov 11 10:50:38 2009 -0500
+++ b/ports/hotspot/src/share/vm/shark/sharkType.hpp	Wed Nov 11 16:21:16 2009 +0000
@@ -24,178 +24,111 @@
  */
 
 class SharkType : public AllStatic {
+ private:
+  static SharkContext& context()
+  {
+    return SharkContext::current();
+  }
+
+  // Basic types
  public:
-  static void initialize();
-
-  // C 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()
   {
-#if SHARK_LLVM_VERSION >= 26
-    return LP64_ONLY(llvm::Type::getInt64Ty(llvm::getGlobalContext()))
-           NOT_LP64 (llvm::Type::getInt32Ty(llvm::getGlobalContext()));
-#else
-    return LP64_ONLY(llvm::Type::Int64Ty)
-           NOT_LP64 (llvm::Type::Int32Ty);
-#endif
+    return context().intptr_type();
   }
 
-  // VM types
- private:
-  static const llvm::PointerType*  _cpCacheEntry_type;
-  static const llvm::FunctionType* _entry_point_type;
-  static const llvm::FunctionType* _osr_entry_point_type;
-  static const llvm::PointerType*  _itableOffsetEntry_type;
-  static const llvm::PointerType*  _klass_type;
-  static const llvm::PointerType*  _methodOop_type;
-  static const llvm::ArrayType*    _monitor_type;
-  static const llvm::PointerType*  _oop_type;
-  static const llvm::PointerType*  _thread_type;
-  static const llvm::PointerType*  _zeroStack_type;
-  
+  // Compound types
  public:
-  static const llvm::PointerType* cpCacheEntry_type()
+  static const llvm::PointerType* itableOffsetEntry_type()
   {
-    return _cpCacheEntry_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 _entry_point_type;
+    return context().entry_point_type();
   }
   static const llvm::FunctionType* osr_entry_point_type()
   {
-    return _osr_entry_point_type;
-  }
-  static const llvm::PointerType* itableOffsetEntry_type()
-  {
-    return _itableOffsetEntry_type;
-  }
-  static const llvm::PointerType* klass_type()
-  {
-    return _klass_type;
-  }
-  static const llvm::PointerType* methodOop_type()
-  {
-    return _methodOop_type;
-  }
-  static const llvm::ArrayType* monitor_type()
-  {
-    return _monitor_type;
-  }
-  static const llvm::PointerType* oop_type()
-  {
-    return _oop_type;
-  }
-  static const llvm::PointerType* thread_type()
-  {
-    return _thread_type;
-  }
-  static const llvm::PointerType* zeroStack_type()
-  {
-    return _zeroStack_type;
+    return context().osr_entry_point_type();
   }
 
-  // Java types
- public:
-  static const llvm::IntegerType* jboolean_type()
-  {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::Type::getInt8Ty(llvm::getGlobalContext());
-#else
-    return llvm::Type::Int8Ty;
-#endif
-  }
-  static const llvm::IntegerType* jbyte_type()
-  {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::Type::getInt8Ty(llvm::getGlobalContext());
-#else
-    return llvm::Type::Int8Ty;
-#endif
-  }
-  static const llvm::IntegerType* jchar_type()
-  {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::Type::getInt16Ty(llvm::getGlobalContext());
-#else
-    return llvm::Type::Int16Ty;
-#endif
-  }
-  static const llvm::IntegerType* jshort_type()
-  {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::Type::getInt16Ty(llvm::getGlobalContext());
-#else
-    return llvm::Type::Int16Ty;
-#endif
-  }
-  static const llvm::IntegerType* jint_type()
-  {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::Type::getInt32Ty(llvm::getGlobalContext());
-#else
-    return llvm::Type::Int32Ty;
-#endif
-  }
-  static const llvm::IntegerType* jlong_type()
-  {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::Type::getInt64Ty(llvm::getGlobalContext());
-#else
-    return llvm::Type::Int64Ty;
-#endif
-  }
-  static const llvm::Type* jfloat_type()
-  {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::Type::getFloatTy(llvm::getGlobalContext());
-#else
-    return llvm::Type::FloatTy;
-#endif
-  }
-  static const llvm::Type* jdouble_type()
-  {
-#if SHARK_LLVM_VERSION >= 26
-    return llvm::Type::getDoubleTy(llvm::getGlobalContext());
-#else
-    return llvm::Type::DoubleTy;
-#endif
-  }
-
-  // Java types as they appear on the stack and in fields
- private:
-  static const llvm::Type* _to_stackType_tab[T_CONFLICT + 1];
-
+  // Mappings
  public:
   static const llvm::Type* to_stackType(BasicType type)
   {
-#ifdef ASSERT
-    if (type < 0 || type > T_CONFLICT || _to_stackType_tab[type] == NULL) {
-      tty->print_cr("Unhandled type %s", type2name(type));
-      ShouldNotReachHere();
-    }
-#endif // ASSERT
-    return _to_stackType_tab[type];
+    return context().to_stackType(type);
   }
   static const llvm::Type* to_stackType(ciType* type)
   {
     return to_stackType(type->basic_type());
   }
-
-  // Java types as they appear in arrays
- private:
-  static const llvm::Type* _to_arrayType_tab[T_CONFLICT + 1];
-
- public:
   static const llvm::Type* to_arrayType(BasicType type)
   {
-#ifdef ASSERT
-    if (type < 0 || type > T_CONFLICT || _to_arrayType_tab[type] == NULL) {
-      tty->print_cr("Unhandled type %s", type2name(type));
-      ShouldNotReachHere();
-    }
-#endif // ASSERT
-    return _to_arrayType_tab[type];
+    return context().to_arrayType(type);
   }
   static const llvm::Type* to_arrayType(ciType* type)
   {


More information about the distro-pkg-dev mailing list