changeset 1008:e8c5220a41f5

2008-08-12 Gary Benson <gbenson@redhat.com> * patches/icedtea-shark.patch: Updated to latest Shark. * ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp: Likewise. * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp: Likewise. * ports/hotspot/src/cpu/zero/vm/frame_zero.cpp: Likewise. * ports/hotspot/src/cpu/zero/vm/frame_zero.hpp: Likewise. * ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp: Likewise. * ports/hotspot/src/cpu/zero/vm/interpreter_zero.hpp: Likewise. * ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp: Likewise. * ports/hotspot/src/cpu/zero/vm/stackPrinter_zero.hpp: Likewise. * ports/hotspot/src/cpu/zero/vm/stack_zero.hpp: Likewise. * ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp: Likewise. * ports/hotspot/src/share/vm/includeDB_shark: Likewise. * ports/hotspot/src/share/vm/shark/llvmHeaders.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkBlock.cpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkBlock.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkCompiler.cpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkCompiler.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkFunction.cpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkFunction.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkState.cpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkState.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkType.cpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkType.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkValue.hpp: Likewise. * ports/hotspot/src/share/vm/shark/shark_globals.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp: New file. * ports/hotspot/src/share/vm/shark/sharkConstantPool.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkMethod.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkMonitor.cpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkMonitor.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkRuntime.hpp: Likewise.
author Gary Benson <gbenson@redhat.com>
date Tue, 12 Aug 2008 05:35:18 -0400
parents 7cd4d87f69f2
children 3b7c41ea8ccb
files ChangeLog patches/icedtea-shark.patch ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp ports/hotspot/src/cpu/zero/vm/frame_zero.cpp ports/hotspot/src/cpu/zero/vm/frame_zero.hpp ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp ports/hotspot/src/cpu/zero/vm/interpreter_zero.hpp ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp ports/hotspot/src/cpu/zero/vm/stackPrinter_zero.hpp ports/hotspot/src/cpu/zero/vm/stack_zero.hpp ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp ports/hotspot/src/share/vm/includeDB_shark ports/hotspot/src/share/vm/shark/llvmHeaders.hpp ports/hotspot/src/share/vm/shark/sharkBlock.cpp ports/hotspot/src/share/vm/shark/sharkBlock.hpp ports/hotspot/src/share/vm/shark/sharkBuilder.cpp ports/hotspot/src/share/vm/shark/sharkBuilder.hpp ports/hotspot/src/share/vm/shark/sharkCompiler.cpp ports/hotspot/src/share/vm/shark/sharkCompiler.hpp ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp ports/hotspot/src/share/vm/shark/sharkConstantPool.hpp ports/hotspot/src/share/vm/shark/sharkFunction.cpp ports/hotspot/src/share/vm/shark/sharkFunction.hpp ports/hotspot/src/share/vm/shark/sharkMethod.hpp ports/hotspot/src/share/vm/shark/sharkMonitor.cpp ports/hotspot/src/share/vm/shark/sharkMonitor.hpp ports/hotspot/src/share/vm/shark/sharkRuntime.cpp ports/hotspot/src/share/vm/shark/sharkRuntime.hpp ports/hotspot/src/share/vm/shark/sharkState.cpp ports/hotspot/src/share/vm/shark/sharkState.hpp ports/hotspot/src/share/vm/shark/sharkType.cpp ports/hotspot/src/share/vm/shark/sharkType.hpp ports/hotspot/src/share/vm/shark/sharkValue.hpp ports/hotspot/src/share/vm/shark/shark_globals.hpp
diffstat 35 files changed, 2634 insertions(+), 561 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Aug 12 09:37:13 2008 +0200
+++ b/ChangeLog	Tue Aug 12 05:35:18 2008 -0400
@@ -1,3 +1,40 @@
+2008-08-12  Gary Benson  <gbenson@redhat.com>
+
+	* patches/icedtea-shark.patch: Updated to latest Shark.
+	* ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/frame_zero.cpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/frame_zero.hpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/interpreter_zero.hpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/stackPrinter_zero.hpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/stack_zero.hpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp: Likewise.
+	* ports/hotspot/src/share/vm/includeDB_shark: Likewise.
+	* ports/hotspot/src/share/vm/shark/llvmHeaders.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkBlock.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkBlock.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkBuilder.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkCompiler.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkCompiler.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkFunction.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkFunction.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkState.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkState.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkType.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkType.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkValue.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/shark_globals.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp: New file.
+	* ports/hotspot/src/share/vm/shark/sharkConstantPool.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkMethod.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkMonitor.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkMonitor.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkRuntime.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkRuntime.hpp: Likewise.
+
 2008-08-12  Christian Thalinger  <twisti@complang.tuwien.ac.at>
 
 	* Makefile.am (ICEDTEA_PATCHES): Fixed typo.
--- a/patches/icedtea-shark.patch	Tue Aug 12 09:37:13 2008 +0200
+++ b/patches/icedtea-shark.patch	Tue Aug 12 05:35:18 2008 -0400
@@ -176,13 +176,16 @@
 diff -ru openjdk/hotspot/src/share/vm/oops/methodOop.cpp openjdk/hotspot/src/share/vm/oops/methodOop.cpp
 --- openjdk/hotspot/src/share/vm/oops/methodOop.cpp	2008-06-20 10:22:11.000000000 +0100
 +++ openjdk/hotspot/src/share/vm/oops/methodOop.cpp	2008-04-15 10:52:44.000000000 +0100
-@@ -733,7 +733,11 @@
+@@ -730,10 +730,14 @@ void methodOopDesc::set_code(methodHandl
+   }
+ 
+   OrderAccess::storestore();
++#ifdef SHARK
++  mh->_from_interpreted_entry = SharkMethod::mark(code->instructions_begin());
++#else
    mh->_from_compiled_entry = code->verified_entry_point();
    OrderAccess::storestore();
    // Instantly compiled code can execute.
-+#ifdef SHARK
-+  mh->_from_interpreted_entry = *(address *) code->instructions_begin();
-+#else
    mh->_from_interpreted_entry = mh->get_i2c_entry();
 +#endif // SHARK
  
@@ -281,3 +284,22 @@
  #endif // TIERED
  
  #ifndef HOTSPOT_VM_DISTRO
+diff -r ef3bb05d21d5 openjdk/hotspot/src/share/vm/code/nmethod.cpp
+--- openjdk/hotspot/src/share/vm/code/nmethod.cpp	Fri Aug 08 11:17:59 2008 +0100
++++ openjdk/hotspot/src/share/vm/code/nmethod.cpp	Fri Aug 08 11:35:04 2008 +0100
+@@ -1453,6 +1453,7 @@ void nmethod::oops_do(OopClosure* f) {
+ // Method that knows how to preserve outgoing arguments at call. This method must be
+ // called with a frame corresponding to a Java invoke
+ void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) {
++#ifndef SHARK
+   if (!method()->is_native()) {
+     SimpleScopeDesc ssd(this, fr.pc());
+     Bytecode_invoke* call = Bytecode_invoke_at(ssd.method(), ssd.bci());
+@@ -1460,6 +1461,7 @@ void nmethod::preserve_callee_argument_o
+     symbolOop signature = call->signature();
+     fr.oops_compiled_arguments_do(signature, is_static, reg_map, f);
+   }
++#endif // !SHARK
+ }
+ 
+ 
--- a/ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -51,6 +51,18 @@
 
   void align(int modulus);
   void bang_stack_with_offset(int offset);
+
+#ifdef SHARK
+ public:
+  void emit_zero_byte()
+  {
+    emit_byte(0);
+  }
+  void emit_intptr(intptr_t x)
+  {
+    emit_address((address) x);
+  }
+#endif // SHARK
 };
 
 #ifdef ASSERT
--- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -85,8 +85,7 @@
       stack->set_sp(istate->stack() + 1);
     
       // Make the call
-      address entry_point = istate->callee_entry_point();
-      ((Interpreter::method_entry_t) entry_point) (method, THREAD);
+      Interpreter::invoke_method(method, istate->callee_entry_point(), THREAD);
       fixup_after_potential_safepoint();
 
       // Convert the result
@@ -623,11 +622,13 @@
 
 address InterpreterGenerator::generate_native_entry(bool synchronized)
 {
+  assert (synchronized == false, "should be");
   return (address) CppInterpreter::native_entry;
 }
 
 address InterpreterGenerator::generate_normal_entry(bool synchronized)
 {
+  assert (synchronized == false, "should be");
   return (address) CppInterpreter::normal_entry;
 }
 
@@ -635,14 +636,10 @@
     AbstractInterpreter::MethodKind kind) {
 
   address entry_point = NULL;
-  bool synchronized = false;
 
   switch (kind) {
   case Interpreter::zerolocals:
-    break;
-
   case Interpreter::zerolocals_synchronized:
-    synchronized = true;
     break;
 
   case Interpreter::native:
@@ -679,10 +676,14 @@
     ShouldNotReachHere();
   }
 
-  if (entry_point)
-    return entry_point;
+  if (entry_point == NULL)
+    entry_point = ((InterpreterGenerator*)this)->generate_normal_entry(false);
 
-  return ((InterpreterGenerator*)this)->generate_normal_entry(false);
+#ifdef SHARK
+  assert(!SharkMethod::is_shark_method(entry_point), "shouldn't be");
+#endif // SHARK
+  
+  return entry_point;
 }
 
 InterpreterGenerator::InterpreterGenerator(StubQueue* code)
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.cpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -26,8 +26,6 @@
 #include "incls/_precompiled.incl"
 #include "incls/_frame_zero.cpp.incl"
 
-intptr_t frame::shark_dummy_bcx = 0;
-
 #ifdef ASSERT
 void RegisterMap::check_location_valid()
 {
@@ -37,8 +35,7 @@
 
 bool frame::is_interpreted_frame() const
 {
-  return zeroframe()->is_interpreter_frame() ||
-         zeroframe()->is_shark_frame();
+  return zeroframe()->is_interpreter_frame();
 }
 
 frame frame::sender_for_entry_frame(RegisterMap *map) const
@@ -57,6 +54,11 @@
   return frame(sender_sp());
 }
 
+frame frame::sender_for_compiled_frame(RegisterMap *map) const
+{
+  return frame(sender_sp());
+}
+
 frame frame::sender(RegisterMap* map) const
 {
   // Default is not to follow arguments; the various
@@ -69,6 +71,11 @@
   if (is_interpreted_frame())
     return sender_for_interpreter_frame(map);
 
+  assert(_cb == CodeCache::find_blob(pc()),"Must be the same");
+  if (_cb != NULL) {
+    return sender_for_compiled_frame(map);
+  }
+
   Unimplemented();
 }
 
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -37,7 +37,6 @@
  public:
   // Constructors
   frame(intptr_t* sp);
-  frame(intptr_t* sp, address pc);
 
   // accessors for the instance variables
   intptr_t* fp() const
@@ -70,6 +69,3 @@
     assert(zeroframe()->is_shark_frame(), "must be");
     return (SharkFrame *) zeroframe();
   }
-
- private:
-  static intptr_t shark_dummy_bcx;
--- a/ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/cpu/zero/vm/frame_zero.inline.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -40,11 +40,25 @@
 inline frame::frame(intptr_t* sp)
 {
   _sp = sp;
-  if (zeroframe()->is_entry_frame())
+  switch (zeroframe()->type()) {
+  case ZeroFrame::ENTRY_FRAME:
     _pc = StubRoutines::call_stub_return_pc();
-  else
+    _cb = NULL;
+    break;
+
+  case ZeroFrame::INTERPRETER_FRAME:
     _pc = NULL;
-  _cb = NULL;
+    _cb = NULL;
+    break;
+
+  case ZeroFrame::SHARK_FRAME:
+    _pc = zero_sharkframe()->pc();
+    _cb = CodeCache::find_blob(pc());
+    break;
+
+  default:
+    ShouldNotReachHere();
+  }
   _deopt_state = not_deoptimized;
 }
 
@@ -73,10 +87,7 @@
 
 inline intptr_t* frame::interpreter_frame_bcx_addr() const
 {
-  if (zeroframe()->is_shark_frame())
-    return &shark_dummy_bcx;
-  else
-    return (intptr_t*) &(get_interpreterState()->_bcp);
+  return (intptr_t*) &(get_interpreterState()->_bcp);
 }
 
 inline constantPoolCacheOop* frame::interpreter_frame_cache_addr() const
@@ -86,10 +97,7 @@
 
 inline methodOop* frame::interpreter_frame_method_addr() const
 {
-  if (zeroframe()->is_shark_frame())
-    return zero_sharkframe()->method_addr();
-  else
-    return &(get_interpreterState()->_method);
+  return &(get_interpreterState()->_method);
 }
 
 inline intptr_t* frame::interpreter_frame_mdx_addr() const
@@ -154,5 +162,5 @@
 
 inline intptr_t* frame::unextended_sp() const
 {
-  Unimplemented();
+  return zero_sharkframe()->unextended_sp();
 }
--- a/ports/hotspot/src/cpu/zero/vm/interpreter_zero.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/cpu/zero/vm/interpreter_zero.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -26,6 +26,17 @@
  public:
   typedef void (*method_entry_t)(methodOop method, TRAPS);
 
+  static void invoke_method(methodOop method, address entry_point, TRAPS)
+  {
+#ifdef SHARK
+    if (SharkMethod::is_shark_method(entry_point)) {
+      SharkMethod::get(entry_point)->invoke(method, THREAD);
+      return;
+    }
+#endif // SHARK
+    ((method_entry_t) entry_point) (method, THREAD);
+  }
+
  public:
   static int expr_index_at(int i)
   {
--- a/ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/cpu/zero/vm/sharkFrame_zero.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -28,9 +28,12 @@
 // | stack slot n-1     |       low addresses
 // |  ...               |
 // | stack slot 0       |
-// | monitor 0 (maybe)  |
+// | monitor m-1        |
 // |  ...               |
+// | monitor 0          |
 // | method             |
+// | unextended_sp      |
+// | pc                 |
 // | frame_type         |
 // | next_frame         |      high addresses
 // +--------------------+  ------------------
@@ -48,17 +51,25 @@
 
  protected:
   enum Layout {
-    method_off = jf_header_words,
+    pc_off = jf_header_words,
+    unextended_sp_off,
+    method_off,
     header_words
   };
 
  public:
-  methodOop* method_addr() const
+  address pc() const
   {
-    return (methodOop *) addr_of_word(method_off);
+    return (address) value_of_word(pc_off);
   }
+
+  intptr_t* unextended_sp() const
+  {
+    return (intptr_t *) value_of_word(unextended_sp_off);
+  }
+
   methodOop method() const
   {
-    return *method_addr();
+    return (methodOop) value_of_word(method_off);
   }
 };
--- a/ports/hotspot/src/cpu/zero/vm/stackPrinter_zero.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/cpu/zero/vm/stackPrinter_zero.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -101,6 +101,7 @@
       if (frame->is_interpreter_frame()) {
         interpreterState istate =
           ((InterpreterFrame *) frame)->interpreter_state();
+        intptr_t *monitor_base = (intptr_t *) istate->monitor_base();
         if (addr >= (intptr_t *) istate) {
           field = istate->name_of_field_at_address((address) addr);
           if (field) {
@@ -118,6 +119,24 @@
             field = "(vtable for istate)";
           }
         }
+        else if (addr >= istate->stack_base() && addr < monitor_base) {
+          int monitor_size = frame::interpreter_frame_monitor_size();
+          int last_index =
+            (monitor_base - istate->stack_base()) / monitor_size - 1;
+          int index =
+            last_index - (addr - istate->stack_base()) / monitor_size;
+          intptr_t monitor = (intptr_t) (istate->monitor_base() - 1 - index);
+          intptr_t offset = (intptr_t) addr - monitor;
+          
+          if (offset == BasicObjectLock::obj_offset_in_bytes()) {
+            snprintf(_buf, _buflen, "monitor[%d]->_obj", index);
+            field = _buf;
+          }
+          else if (offset ==  BasicObjectLock::lock_offset_in_bytes()) {
+            snprintf(_buf, _buflen, "monitor[%d]->_lock", index);
+            field = _buf;
+          }
+        }
         else if (addr < istate->stack_base()) {
           if (istate->method()->is_native()) {
             address hA = istate->method()->signature_handler();
@@ -164,7 +183,13 @@
         }
       }
       if (frame->is_shark_frame()) {
-        if (word == SharkFrame::method_off) {
+        if (word == SharkFrame::pc_off) {
+          field = "pc";
+        }
+        else if (word == SharkFrame::unextended_sp_off) {
+          field = "unextended_sp";
+        }
+        else if (word == SharkFrame::method_off) {
           field = "method";
           methodOop method = ((SharkFrame *) frame)->method();
           if (method->is_oop())
--- a/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/cpu/zero/vm/stack_zero.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -98,10 +98,12 @@
   {
     return byte_offset_of(ZeroStack, _base);
   }
+
   static ByteSize top_offset()
   {
     return byte_offset_of(ZeroStack, _top);
   }
+
   static ByteSize sp_offset()
   {
     return byte_offset_of(ZeroStack, _sp);
@@ -118,6 +120,7 @@
 // |  ...               |
 
 class ZeroFrame {
+  friend class frame;
   friend class ZeroStackPrinter;
 
  protected:
--- a/ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/cpu/zero/vm/stubGenerator_zero.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -66,7 +66,7 @@
       EntryFrame::build(stack, parameters, parameter_words, call_wrapper));
 
     // Make the call
-    ((Interpreter::method_entry_t) entry_point) (method, THREAD);
+    Interpreter::invoke_method(method, entry_point, THREAD);
 
     // Store result depending on type
     if (!HAS_PENDING_EXCEPTION) {
--- a/ports/hotspot/src/share/vm/includeDB_shark	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/includeDB_shark	Tue Aug 12 05:35:18 2008 -0400
@@ -56,6 +56,10 @@
 
 globals.cpp                             shark_globals.hpp
 
+interpreter.hpp                         sharkMethod.hpp
+
+methodOop.cpp                           sharkMethod.hpp
+
 shark_globals.cpp                       shark_globals.hpp
 
 shark_globals.hpp                       shark_globals_<arch>.hpp
@@ -72,6 +76,8 @@
 sharkBlock.cpp                          shark_globals.hpp
 sharkBlock.cpp                          sharkBlock.hpp
 sharkBlock.cpp                          sharkBuilder.hpp
+sharkBlock.cpp                          sharkConstantPool.hpp
+sharkBlock.cpp                          sharkRuntime.hpp
 sharkBlock.cpp                          sharkState.inline.hpp
 sharkBlock.cpp                          sharkValue.hpp
 
@@ -81,8 +87,9 @@
 sharkBlock.hpp                          ciType.hpp
 sharkBlock.hpp                          ciTypeFlow.hpp
 sharkBlock.hpp                          llvmHeaders.hpp
+sharkBlock.hpp                          sharkBuilder.hpp
 sharkBlock.hpp                          sharkFunction.hpp
-sharkBlock.hpp                          sharkBuilder.hpp
+sharkBlock.hpp                          sharkMonitor.hpp
 sharkBlock.hpp                          sharkState.hpp
 sharkBlock.hpp                          sharkValue.hpp
 
@@ -94,8 +101,9 @@
 sharkBuilder.cpp                        resourceArea.hpp
 sharkBuilder.cpp                        llvmHeaders.hpp
 sharkBuilder.cpp                        sharkBuilder.hpp
+sharkBuilder.cpp                        sharkRuntime.hpp
+sharkBuilder.cpp                        synchronizer.hpp
 sharkBuilder.cpp                        thread.hpp
-sharkBuilder.cpp                        synchronizer.hpp
 
 sharkBuilder.hpp                        barrierSet.hpp
 sharkBuilder.hpp                        cardTableModRefBS.hpp
@@ -119,6 +127,7 @@
 sharkCompiler.cpp                       shark_globals.hpp
 sharkCompiler.cpp                       sharkCompiler.hpp
 sharkCompiler.cpp                       sharkFunction.hpp
+sharkCompiler.cpp                       sharkRuntime.hpp
 
 sharkCompiler.hpp                       abstractCompiler.hpp
 sharkCompiler.hpp                       ciEnv.hpp
@@ -126,6 +135,24 @@
 sharkCompiler.hpp                       llvmHeaders.hpp
 sharkCompiler.hpp                       sharkBuilder.hpp
 
+sharkConstantPool.cpp                   allocation.hpp
+sharkConstantPool.cpp                   constantPoolOop.hpp
+sharkConstantPool.cpp                   cpCacheOop.hpp
+sharkConstantPool.cpp                   debug.hpp
+sharkConstantPool.cpp                   llvmHeaders.hpp
+sharkConstantPool.cpp                   methodOop.hpp
+sharkConstantPool.cpp                   sharkBuilder.hpp
+sharkConstantPool.cpp                   sharkConstantPool.hpp
+sharkConstantPool.cpp                   sharkRuntime.hpp
+sharkConstantPool.cpp                   sharkState.inline.hpp
+sharkConstantPool.cpp                   sharkType.hpp
+sharkConstantPool.cpp                   sharkValue.hpp
+
+sharkConstantPool.hpp                   allocation.hpp
+sharkConstantPool.hpp                   llvmHeaders.hpp
+sharkConstantPool.hpp                   sharkBlock.hpp
+sharkConstantPool.hpp                   sharkBuilder.hpp
+
 sharkFunction.cpp                       allocation.hpp
 sharkFunction.cpp                       ciTypeFlow.hpp
 sharkFunction.cpp                       debug.hpp
@@ -133,6 +160,7 @@
 sharkFunction.cpp                       sharkBlock.hpp
 sharkFunction.cpp                       sharkBuilder.hpp
 sharkFunction.cpp                       sharkFunction.hpp
+sharkFunction.cpp                       sharkMonitor.hpp
 sharkFunction.cpp                       sharkState.inline.hpp
 
 sharkFunction.hpp                       allocation.hpp
@@ -142,8 +170,32 @@
 sharkFunction.hpp                       llvmHeaders.hpp
 sharkFunction.hpp                       sharkBuilder.hpp
 
+sharkMethod.hpp                         llvmHeaders.hpp
+
+sharkMonitor.cpp                        sharkMonitor.hpp
+sharkMonitor.cpp                        llvmHeaders.hpp
+
+sharkMonitor.hpp                        allocation.hpp
+sharkMonitor.hpp                        llvmHeaders.hpp
+sharkMonitor.hpp                        sharkBuilder.hpp
+sharkMonitor.hpp                        sharkFunction.hpp
+
+sharkRuntime.cpp                        llvmHeaders.hpp
+sharkRuntime.cpp                        klassOop.hpp
+sharkRuntime.cpp                        sharkBuilder.hpp
+sharkRuntime.cpp                        sharkRuntime.hpp
+sharkRuntime.cpp                        sharkType.hpp
+sharkRuntime.cpp                        thread.hpp
+
+sharkRuntime.hpp                        allocation.hpp
+sharkRuntime.hpp                        llvmHeaders.hpp
+sharkRuntime.hpp                        klassOop.hpp
+sharkRuntime.hpp                        sharkBuilder.hpp
+sharkRuntime.hpp                        thread.hpp
+
 sharkState.cpp                          allocation.hpp
 sharkState.cpp                          ciType.hpp
+sharkState.cpp                          ciTypeFlow.hpp
 sharkState.cpp                          sharkBlock.hpp
 sharkState.cpp                          sharkBuilder.hpp
 sharkState.cpp                          sharkState.inline.hpp
@@ -152,6 +204,7 @@
 
 sharkState.hpp                          allocation.hpp
 sharkState.hpp                          sharkValue.hpp
+sharkState.hpp                          vmreg.hpp
 
 sharkState.inline.hpp                   sharkBlock.hpp
 sharkState.inline.hpp                   sharkState.hpp
@@ -160,6 +213,7 @@
 sharkType.cpp                           globalDefinitions.hpp
 sharkType.cpp                           llvmHeaders.hpp
 sharkType.cpp                           oop.hpp
+sharkType.cpp                           sharkMethod.hpp
 sharkType.cpp                           sharkType.hpp
 
 sharkType.hpp                           allocation.hpp
--- a/ports/hotspot/src/share/vm/shark/llvmHeaders.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/llvmHeaders.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -23,10 +23,8 @@
  *
  */
 
-#ifdef ASSERT
-  #ifdef assert
-    #undef assert
-  #endif
+#ifdef assert
+  #undef assert
 #endif
 
 #include <llvm/Argument.h>
@@ -39,16 +37,18 @@
 #include <llvm/Support/IRBuilder.h>
 #include <llvm/Type.h>
 
+#ifdef assert
+  #undef assert
+#endif
+
+// from hotspot/src/share/vm/utilities/debug.hpp
 #ifdef ASSERT
-  #ifdef assert
-    #undef assert
-  #endif
-
-  // copied verbatim from hotspot/src/share/vm/utilities/debug.hpp
-  #define assert(p,msg)                                          \
+  #define assert(p, msg)                                          \
     if (!(p)) {                                                  \
       report_assertion_failure(__FILE__, __LINE__,               \
                               "assert(" XSTR(p) ",\"" msg "\")");\
       BREAKPOINT;                                                \
     }
+#else
+  #define assert(p, msg)
 #endif
--- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -37,11 +37,6 @@
            ciblock()->start(),
            ciblock()->is_private_copy() ? "_private_copy" : "");
   _entry_block = function()->CreateBlock(name);
-
-  // Cached values
-  _constant_pool_check       = NULL;
-  _constant_pool_tags_check  = NULL;
-  _constant_pool_cache_check = NULL;
 }
 
 void SharkBlock::parse()
@@ -59,6 +54,8 @@
   }
 
   if (ciblock()->has_trap()) {
+    current_state()->decache();
+    builder()->CreateDump(LLVMValue::jint_constant(start()));
     builder()->CreateUnimplemented(__FILE__, __LINE__);
     builder()->CreateUnreachable();
     return;
@@ -217,6 +214,10 @@
       push(a);
       break;
 
+    case Bytecodes::_arraylength:
+      do_arraylength();
+      break;
+
     case Bytecodes::_baload:
       do_aload(T_BYTE);
       break;
@@ -379,11 +380,6 @@
       do_return(T_OBJECT);
       break;
 
-    case Bytecodes::_athrow:
-      builder()->CreateUnimplemented(__FILE__, __LINE__);
-      builder()->CreateUnreachable();
-      break;
-
     case Bytecodes::_goto:
     case Bytecodes::_goto_w:
       builder()->CreateBr(successor(ciTypeFlow::GOTO_TARGET)->entry_block());
@@ -454,9 +450,26 @@
       do_instance_check();
       break;
 
+    case Bytecodes::_new:
+      do_new();
+      break;
+
+    case Bytecodes::_monitorenter:
+      do_monitorenter();
+      break;
+    case Bytecodes::_monitorexit:
+      do_monitorexit();
+      break;
+
     default:
-      tty->print_cr("Unhandled bytecode %s", Bytecodes::name(bc()));
-      ShouldNotReachHere();
+      {
+        const char *code = Bytecodes::name(bc());
+        int buflen = 19 + strlen(code) + 1;
+        char *buf = (char *) function()->env()->arena()->Amalloc(buflen);
+        snprintf(buf, buflen, "Unhandled bytecode %s", code);
+        function()->record_method_not_compilable(buf);
+        return;
+      }
     }
   }
 
@@ -479,106 +492,6 @@
   ShouldNotReachHere();
 }
 
-Value *SharkBlock::constant_pool()
-{
-  Value *m = method();
-  if (m != _constant_pool_check) {
-    _constant_pool_value = builder()->CreateValueOfStructEntry(
-      m, methodOopDesc::constants_offset(),
-      SharkType::oop_type(), "constants");
-    _constant_pool_check = m;
-  }
-  return _constant_pool_value;
-}
-
-Value *SharkBlock::constant_pool_tags()
-{
-  Value *cp = constant_pool();
-  if (cp != _constant_pool_tags_check) {
-    _constant_pool_tags_value = builder()->CreateValueOfStructEntry(
-      cp, in_ByteSize(constantPoolOopDesc::tags_offset_in_bytes()),
-      SharkType::oop_type(), "tags");
-    _constant_pool_tags_check = cp;
-  }
-  return _constant_pool_tags_value;
-}
-
-Value *SharkBlock::constant_pool_cache()
-{
-  Value *cp = constant_pool();
-  if (cp != _constant_pool_cache_check) {
-    _constant_pool_cache_value = builder()->CreateValueOfStructEntry(
-      cp, in_ByteSize(constantPoolOopDesc::cache_offset_in_bytes()),
-      SharkType::oop_type(), "cache");
-    _constant_pool_cache_check = cp;
-  }
-  return _constant_pool_cache_value;
-}
-
-Value *SharkBlock::constant_pool_tag_at(int which)
-{
-  return builder()->CreateArrayLoad(
-    constant_pool_tags(), T_BYTE, LLVMValue::jint_constant(which));
-}
-
-Value *SharkBlock::constant_pool_object_at(int which)
-{
-  return builder()->CreateArrayLoad(
-    constant_pool(),
-    T_OBJECT, in_ByteSize(sizeof(constantPoolOopDesc)),
-    LLVMValue::jint_constant(which));
-}
-
-Value *SharkBlock::constant_pool_cache_entry_at(int which)
-{
-  Value *entry = builder()->CreateIntToPtr(
-    builder()->CreateAdd(
-      builder()->CreatePtrToInt(
-        constant_pool_cache(), SharkType::intptr_type()),
-      LLVMValue::intptr_constant(
-        in_bytes(constantPoolCacheOopDesc::base_offset()) +
-        which * sizeof(ConstantPoolCacheEntry))),
-    SharkType::cpCacheEntry_type());
-
-#ifdef ASSERT
-  // Check the entry is resolved
-  int shift;
-  switch (ConstantPoolCacheEntry::bytecode_number(bc())) {
-  case 1:
-    shift = 16;
-    break;
-  case 2:
-    shift = 24;
-    break;
-  default:
-    ShouldNotReachHere();
-  }
-
-  Value *opcode = builder()->CreateAnd(
-    builder()->CreateLShr(
-      builder()->CreateValueOfStructEntry(
-        entry, ConstantPoolCacheEntry::indices_offset(),
-        SharkType::intptr_type()),
-      LLVMValue::jint_constant(shift)),
-    LLVMValue::intptr_constant(0xff));
-
-  BasicBlock *not_resolved = function()->CreateBlock("not_resolved");
-  BasicBlock *resolved     = function()->CreateBlock("resolved");
-
-  builder()->CreateCondBr(
-    builder()->CreateICmpEQ(opcode, LLVMValue::intptr_constant(bc())),
-    resolved, not_resolved);
-
-  builder()->SetInsertPoint(not_resolved);  
-  builder()->CreateShouldNotReachHere(__FILE__, __LINE__);
-  builder()->CreateUnreachable();
-
-  builder()->SetInsertPoint(resolved);
-#endif // ASSERT
-
-  return entry;
-}
-
 void SharkBlock::check_null(SharkValue *object)
 {
   if (object->null_checked())
@@ -605,10 +518,7 @@
   BasicBlock *out_of_bounds = function()->CreateBlock("out_of_bounds");
   BasicBlock *in_bounds     = function()->CreateBlock("in_bounds");
 
-  Value *length = builder()->CreateValueOfStructEntry(
-    array->jarray_value(), in_ByteSize(arrayOopDesc::length_offset_in_bytes()),
-    SharkType::jint_type(), "length");
-
+  Value *length = builder()->CreateArrayLength(array->jarray_value());
   builder()->CreateCondBr(
     builder()->CreateICmpSLT(index->jint_value(), length),
     in_bounds, out_of_bounds);
@@ -672,15 +582,95 @@
   builder()->SetInsertPoint(safepointed);
 }
 
+CallInst* SharkBlock::call_vm_base(Constant* callee,
+                                   Value**   args_start,
+                                   Value**   args_end)
+{
+  // Decache the state
+  current_state()->decache();
+
+  // Set up the Java frame anchor  
+  function()->set_last_Java_frame();
+
+  // Make the call
+  CallInst *result = builder()->CreateCall(callee, args_start, args_end);
+
+  // Clear the frame anchor
+  function()->reset_last_Java_frame();
+
+  // Recache the state
+  current_state()->cache();
+
+  // Check for pending exceptions  
+  check_pending_exception();
+
+  return result;
+}
+
 void SharkBlock::do_ldc()
 {
   SharkValue *value = SharkValue::from_ciConstant(iter()->get_constant());
   if (value == NULL) {
-    Unimplemented() // XXX it's an oop :(
+    SharkConstantPool constants(this);
+
+    BasicBlock *string     = function()->CreateBlock("string");
+    BasicBlock *klass      = function()->CreateBlock("klass");
+    BasicBlock *unresolved = function()->CreateBlock("unresolved");
+    BasicBlock *unknown    = function()->CreateBlock("unknown");
+    BasicBlock *done       = function()->CreateBlock("done");
+    
+    SwitchInst *switchinst = builder()->CreateSwitch(
+      constants.tag_at(iter()->get_constant_index()),
+      unknown, 5);
+
+    switchinst->addCase(
+      LLVMValue::jbyte_constant(JVM_CONSTANT_String), string);
+    switchinst->addCase(
+      LLVMValue::jbyte_constant(JVM_CONSTANT_Class), klass);
+    switchinst->addCase(
+      LLVMValue::jbyte_constant(JVM_CONSTANT_UnresolvedString), unresolved);
+    switchinst->addCase(
+      LLVMValue::jbyte_constant(JVM_CONSTANT_UnresolvedClass), unresolved);
+    switchinst->addCase(
+      LLVMValue::jbyte_constant(JVM_CONSTANT_UnresolvedClassInError),
+      unresolved);
+
+    builder()->SetInsertPoint(string);
+    Value *string_value = constants.object_at(iter()->get_constant_index());
+    builder()->CreateBr(done);
+
+    builder()->SetInsertPoint(klass);
+    builder()->CreateUnimplemented(__FILE__, __LINE__);
+    Value *klass_value = LLVMValue::null();
+    builder()->CreateBr(done);
+
+    builder()->SetInsertPoint(unresolved);
+    builder()->CreateUnimplemented(__FILE__, __LINE__);
+    Value *unresolved_value = LLVMValue::null();
+    builder()->CreateBr(done);
+
+    builder()->SetInsertPoint(unknown);
+    builder()->CreateShouldNotReachHere(__FILE__, __LINE__);
+    builder()->CreateUnreachable();
+
+    builder()->SetInsertPoint(done);
+    PHINode *phi = builder()->CreatePHI(SharkType::jobject_type(), "constant");
+    phi->addIncoming(string_value, string);
+    phi->addIncoming(klass_value, klass);
+    phi->addIncoming(unresolved_value, unresolved);
+    value = SharkValue::create_jobject(phi);
   }
   push(value);
 }
 
+void SharkBlock::do_arraylength()
+{
+  SharkValue *array = pop();
+  check_null(array);
+  Value *length = builder()->CreateArrayLength(array->jarray_value());
+  push(SharkValue::create_jint(length));
+}
+
 void SharkBlock::do_aload(BasicType basic_type)
 {
   SharkValue *index = pop();
@@ -701,6 +691,7 @@
     value = builder()->CreateIntCast(value, stack_type, basic_type != T_CHAR);
 
   switch (basic_type) {
+  case T_BOOLEAN:
   case T_BYTE:
   case T_CHAR:
   case T_SHORT:
@@ -708,6 +699,10 @@
     push(SharkValue::create_jint(value));
     break;
 
+  case T_OBJECT:
+    push(SharkValue::create_jobject(value));
+    break;
+
   default:
     tty->print_cr("Unhandled type %s", type2name(basic_type));
     ShouldNotReachHere();
@@ -736,6 +731,14 @@
     value = svalue->jint_value();
     break;
 
+  case T_LONG:
+    value = svalue->jlong_value();
+    break;
+
+  case T_OBJECT:
+    value = svalue->jobject_value();
+    break;
+
   default:
     tty->print_cr("Unhandled type %s", type2name(basic_type));
     ShouldNotReachHere();
@@ -777,31 +780,48 @@
   }
   if (!is_get || value == NULL) {
     if (!is_field) {
-      Value *cache = constant_pool_cache_entry_at(iter()->get_field_index());
+      SharkConstantPool constants(this);
+      Value *cache = constants.cache_entry_at(iter()->get_field_index());
   
       object = builder()->CreateValueOfStructEntry(
        cache, ConstantPoolCacheEntry::f1_offset(),
        SharkType::jobject_type(),
        "object");
     }
+
+    BasicType   basic_type = field->type()->basic_type();
+    const Type *stack_type = SharkType::to_stackType(basic_type);
+    const Type *field_type = SharkType::to_arrayType(basic_type);
+    
     Value *addr = builder()->CreateAddressOfStructEntry(
       object, in_ByteSize(field->offset_in_bytes()),
-      PointerType::getUnqual(SharkType::to_stackType(field->type())),
+      PointerType::getUnqual(field_type),
       "field");
   
     // Do the access
     if (is_get) {
-      value = SharkValue::create_generic(
-        field->type(), builder()->CreateLoad(addr, "value"));
+      Value *field_value = builder()->CreateLoad(addr);
+
+      if (field_type != stack_type)
+      field_value = builder()->CreateIntCast(
+        field_value, stack_type, basic_type != T_CHAR);
+
+      value = SharkValue::create_generic(field->type(), field_value);
     }
     else {
-      builder()->CreateStore(value->generic_value(), addr);
+      Value *field_value = value->generic_value();
+
+      if (field_type != stack_type)
+        field_value = builder()->CreateIntCast(
+          field_value, field_type, basic_type != T_CHAR);
+
+      builder()->CreateStore(field_value, addr);
       
       if (!field->type()->is_primitive_type())
-        Unimplemented(); // XXX builder()->CreateUpdateBarrierSet(
-                         //       oopDesc::bs(), addr, value);
+        builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr);
+
       if (field->is_volatile())
-        Unimplemented(); // XXX __sync_synchronize
+        builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD);
     }
   }
 
@@ -814,13 +834,30 @@
 {
   add_safepoint();
 
+  if (target()->is_synchronized())
+    monitor(0)->release();
+
   Value *result_addr = function()->CreatePopFrame(type2size[basic_type]);
   if (basic_type != T_VOID) {
     SharkValue *result = pop();
 
-    assert(result->basic_type() == basic_type ||
-           result->basic_type() == T_ARRAY && basic_type == T_OBJECT,
-           "type mismatch");
+#ifdef ASSERT
+    switch (result->basic_type()) {
+    case T_BOOLEAN:
+    case T_BYTE:
+    case T_CHAR:
+    case T_SHORT:
+      assert(basic_type == T_INT, "type mismatch");
+      break;
+
+    case T_ARRAY:
+      assert(basic_type == T_OBJECT, "type mismatch");
+      break;
+
+    default:
+      assert(result->basic_type() == basic_type, "type mismatch");
+    }
+#endif // ASSERT
 
     builder()->CreateStore(
       result->generic_value(),
@@ -828,7 +865,6 @@
         result_addr,
         PointerType::getUnqual(SharkType::to_stackType(basic_type))));
   }
-  assert(stack_depth() == 0, "should be");
 
   builder()->CreateRetVoid();
 }
@@ -878,46 +914,283 @@
   // Find the receiver in the stack
   SharkValue *receiver = NULL;
   if (bc() != Bytecodes::_invokestatic) {
-    receiver = stack(method->arg_size() - 1);
+    int shark_slot = 0, java_slot = 0;
+    while (java_slot < method->arg_size() - 1)
+      java_slot += stack(shark_slot++)->type()->size();
+    receiver = stack(shark_slot);
     check_null(receiver);
   }
 
   // Find the method we are calling
   Value *callee = NULL;
-  if (bc() == Bytecodes::_invokeinterface) {
-    Unimplemented();
+  SharkConstantPool constants(this);
+  Value *cache = constants.cache_entry_at(iter()->get_method_index());
+
+  if (bc() == Bytecodes::_invokevirtual) {
+    BasicBlock *final     = function()->CreateBlock("final");
+    BasicBlock *not_final = function()->CreateBlock("not_final");
+    BasicBlock *invoke    = function()->CreateBlock("invoke");
+
+    Value *flags = builder()->CreateValueOfStructEntry(
+      cache, ConstantPoolCacheEntry::flags_offset(),
+      SharkType::intptr_type(),
+      "flags");
+
+    const int mask = 1 << ConstantPoolCacheEntry::vfinalMethod;
+    builder()->CreateCondBr(
+      builder()->CreateICmpNE(
+        builder()->CreateAnd(flags, LLVMValue::intptr_constant(mask)),
+        LLVMValue::intptr_constant(0)),
+      final, not_final);
+
+    // For final methods f2 is the actual address of the method
+    builder()->SetInsertPoint(final);
+    Value *final_callee = builder()->CreateValueOfStructEntry(
+      cache, ConstantPoolCacheEntry::f2_offset(),
+      SharkType::methodOop_type(),
+      "final_callee");
+    builder()->CreateBr(invoke);
+
+    // For non-final methods f2 is the index into the vtable
+    builder()->SetInsertPoint(not_final);
+    Value *klass = builder()->CreateValueOfStructEntry(
+      receiver->jobject_value(),
+      in_ByteSize(oopDesc::klass_offset_in_bytes()),
+      SharkType::jobject_type(),
+      "klass");
+
+    Value *index = builder()->CreateValueOfStructEntry(
+      cache, ConstantPoolCacheEntry::f2_offset(),
+      SharkType::intptr_type(),
+      "index");
+
+    Value *nonfinal_callee = builder()->CreateArrayLoad(
+      klass,
+      SharkType::methodOop_type(),
+      vtableEntry::size() * wordSize,
+      in_ByteSize(instanceKlass::vtable_start_offset() * wordSize),
+      index,
+      "nonfinal_callee");
+    builder()->CreateBr(invoke);
+
+    builder()->SetInsertPoint(invoke);
+    callee = builder()->CreatePHI(SharkType::methodOop_type(), "callee");
+    ((PHINode *) callee)->addIncoming(final_callee, final);
+    ((PHINode *) callee)->addIncoming(nonfinal_callee, not_final);
+  }
+  else if (bc() == Bytecodes::_invokeinterface) {
+    BasicBlock *hacky     = function()->CreateBlock("hacky");
+    BasicBlock *normal    = function()->CreateBlock("normal");
+    BasicBlock *loop      = function()->CreateBlock("loop");
+    BasicBlock *got_null  = function()->CreateBlock("got_null");
+    BasicBlock *not_null  = function()->CreateBlock("not_null");
+    BasicBlock *next      = function()->CreateBlock("next");
+    BasicBlock *got_entry = function()->CreateBlock("got_entry");
+    BasicBlock *invoke    = function()->CreateBlock("invoke");
+
+    Value *flags = builder()->CreateValueOfStructEntry(
+      cache, ConstantPoolCacheEntry::flags_offset(),
+      SharkType::intptr_type(),
+      "flags");
+
+    const int mask = 1 << ConstantPoolCacheEntry::methodInterface;
+    builder()->CreateCondBr(
+      builder()->CreateICmpNE(
+        builder()->CreateAnd(flags, LLVMValue::intptr_constant(mask)),
+        LLVMValue::intptr_constant(0)),
+      hacky, normal);
+
+    // Workaround for the case where we encounter an invokeinterface,
+    // but should really have an invokevirtual since the resolved
+    // method is a virtual method in java.lang.Object. This is a
+    // corner case in the spec but is presumably legal, and while
+    // javac does not generate this code there's no reason it could
+    // not be produced by a compliant java compiler.  See
+    // cpCacheOop.cpp for more details.
+    builder()->SetInsertPoint(hacky);
+    builder()->CreateUnimplemented(__FILE__, __LINE__);
+    Value *hacky_callee =
+      ConstantPointerNull::get(SharkType::methodOop_type());
+    builder()->CreateBr(invoke);
+
+    // Locate the receiver's itable
+    builder()->SetInsertPoint(normal);
+    Value *object_klass = builder()->CreateValueOfStructEntry(
+      receiver->jobject_value(), in_ByteSize(oopDesc::klass_offset_in_bytes()),
+      SharkType::jobject_type(),
+      "object_klass");
+
+    Value *vtable_start = builder()->CreateAdd(
+      builder()->CreatePtrToInt(object_klass, SharkType::intptr_type()),
+      LLVMValue::intptr_constant(
+        instanceKlass::vtable_start_offset() * HeapWordSize),
+      "vtable_start");
+
+    Value *vtable_length = builder()->CreateValueOfStructEntry(
+      object_klass,
+      in_ByteSize(instanceKlass::vtable_length_offset() * HeapWordSize),
+      SharkType::jint_type(),
+      "vtable_length");
+
+    bool needs_aligning = HeapWordsPerLong > 1;
+    const char *itable_start_name = "itable_start";
+    Value *itable_start = builder()->CreateAdd(
+      vtable_start,
+      builder()->CreateShl(
+        vtable_length,
+        LLVMValue::jint_constant(exact_log2(vtableEntry::size() * wordSize))),
+      needs_aligning ? "" : itable_start_name);
+    if (needs_aligning)
+      itable_start = builder()->CreateAlign(
+        itable_start, BytesPerLong, itable_start_name);
+
+    // Locate this interface's entry in the table
+    Value *iklass = builder()->CreateValueOfStructEntry(
+      cache, ConstantPoolCacheEntry::f1_offset(),
+      SharkType::jobject_type(),
+      "iklass");
+
+    builder()->CreateBr(loop);
+    builder()->SetInsertPoint(loop);
+    PHINode *itable_entry_addr = builder()->CreatePHI(
+      SharkType::intptr_type(), "itable_entry_addr");
+    itable_entry_addr->addIncoming(itable_start, normal);
+
+    Value *itable_entry = builder()->CreateIntToPtr(
+      itable_entry_addr, SharkType::itableOffsetEntry_type(), "itable_entry");
+
+    Value *itable_iklass = builder()->CreateValueOfStructEntry(
+      itable_entry,
+      in_ByteSize(itableOffsetEntry::interface_offset_in_bytes()),
+      SharkType::jobject_type(),
+      "itable_iklass");
+
+    builder()->CreateCondBr(
+      builder()->CreateICmpEQ(itable_iklass, LLVMValue::null()),
+      got_null, not_null);
+
+    // A null entry means that the class doesn't implement the
+    // interface, and wasn't the same as the class checked when
+    // the interface was resolved.
+    builder()->SetInsertPoint(got_null);
+    builder()->CreateUnimplemented(__FILE__, __LINE__);
+    builder()->CreateUnreachable();
+                            
+    builder()->SetInsertPoint(not_null);
+    builder()->CreateCondBr(
+      builder()->CreateICmpEQ(itable_iklass, iklass),
+      got_entry, next);
+
+    builder()->SetInsertPoint(next);
+    Value *next_entry = builder()->CreateAdd(
+      itable_entry_addr,
+      LLVMValue::intptr_constant(itableOffsetEntry::size() * wordSize));
+    builder()->CreateBr(loop);
+    itable_entry_addr->addIncoming(next_entry, next);
+
+    // Locate the method pointer
+    builder()->SetInsertPoint(got_entry);
+    Value *offset = builder()->CreateValueOfStructEntry(
+      itable_entry,
+      in_ByteSize(itableOffsetEntry::offset_offset_in_bytes()),
+      SharkType::jint_type(),
+      "offset");
+
+    Value *index = builder()->CreateValueOfStructEntry(
+      cache, ConstantPoolCacheEntry::f2_offset(),
+      SharkType::intptr_type(),
+      "index");
+
+    Value *normal_callee = builder()->CreateLoad(
+      builder()->CreateIntToPtr(
+        builder()->CreateAdd(
+          builder()->CreateAdd(
+            builder()->CreateAdd(
+              builder()->CreatePtrToInt(
+                object_klass, SharkType::intptr_type()),
+              offset),
+            builder()->CreateShl(
+              index,
+              LLVMValue::jint_constant(
+                exact_log2(itableMethodEntry::size() * wordSize)))),
+          LLVMValue::intptr_constant(
+            itableMethodEntry::method_offset_in_bytes())),
+        PointerType::getUnqual(SharkType::methodOop_type())),
+      "normal_callee");
+    builder()->CreateBr(invoke);
+
+    builder()->SetInsertPoint(invoke);
+    callee = builder()->CreatePHI(SharkType::methodOop_type(), "callee");
+    ((PHINode *) callee)->addIncoming(hacky_callee, hacky);
+    ((PHINode *) callee)->addIncoming(normal_callee, got_entry);    
   }
   else {
-    Value *cache = constant_pool_cache_entry_at(iter()->get_method_index());
-
-    if (bc() == Bytecodes::_invokevirtual) {
-      int mask = 1 << ConstantPoolCacheEntry::vfinalMethod;
-      if (method->flags().as_int() & mask == mask) {
-        callee = builder()->CreateValueOfStructEntry(
-          cache, ConstantPoolCacheEntry::f2_offset(),
-          SharkType::methodOop_type(),
-          "callee");
-      }
-      else {
-        Unimplemented();
-      }
-    }
-    else {
-      callee = builder()->CreateValueOfStructEntry(
-        cache, ConstantPoolCacheEntry::f1_offset(),
-        SharkType::methodOop_type(),
-        "callee");
-    }
+    callee = builder()->CreateValueOfStructEntry(
+      cache, ConstantPoolCacheEntry::f1_offset(),
+      SharkType::methodOop_type(),
+      "callee");
   }
 
   Value *entry_point = builder()->CreateValueOfStructEntry(
     callee, methodOopDesc::from_interpreted_offset(), // XXX hacky
-    PointerType::getUnqual(SharkType::method_entry_type()),
+    PointerType::getUnqual(SharkType::interpreter_entry_type()),
     "entry_point");
 
-  // Make the call
+  // Decache for the call
   current_state()->decache(method);
-  builder()->CreateCall2(entry_point, callee, thread());
+
+  // Make the call
+  BasicBlock *interpreter_call = function()->CreateBlock("interpreter_call");
+  BasicBlock *shark_call       = function()->CreateBlock("shark_call");
+  BasicBlock *post_call        = function()->CreateBlock("post_call");
+
+  Value *entry_point_or_sharkmethod = builder()->CreateValueOfStructEntry(
+    callee, methodOopDesc::from_interpreted_offset(),
+    SharkType::intptr_type(),
+    "entry_point_or_sharkmethod");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(
+      builder()->CreateAnd(
+        entry_point_or_sharkmethod,
+        LLVMValue::intptr_constant(SharkMethod::marker())),
+      LLVMValue::intptr_constant(0)),
+    interpreter_call, shark_call);
+
+  // Interpreter calls
+  builder()->SetInsertPoint(interpreter_call);
+
+  Value *interpreter_entry_point = builder()->CreateIntToPtr(
+    entry_point_or_sharkmethod,
+    PointerType::getUnqual(SharkType::interpreter_entry_type()),
+    "interpreter_entry_point");
+
+  builder()->CreateCall2(interpreter_entry_point, callee, thread());
+  builder()->CreateBr(post_call);
+
+  // Shark calls
+  builder()->SetInsertPoint(shark_call);
+
+  Value *base_pc = builder()->CreateAnd(
+    entry_point_or_sharkmethod,
+    LLVMValue::intptr_constant(~SharkMethod::marker()),
+    "base_pc");
+
+  Value *shark_entry_point = builder()->CreateLoad(
+    builder()->CreateIntToPtr(
+      builder()->CreateAdd(
+        base_pc,
+        LLVMValue::intptr_constant(
+          in_bytes(SharkMethod::entry_point_offset()))),
+      PointerType::getUnqual(
+        PointerType::getUnqual(SharkType::shark_entry_type()))),
+    "shark_entry_point");
+
+  builder()->CreateCall3(shark_entry_point, callee, base_pc, thread());
+  builder()->CreateBr(post_call);
+
+  // Recache state
+  builder()->SetInsertPoint(post_call); 
   current_state()->cache(method);
 
   // Check for pending exceptions
@@ -926,12 +1199,12 @@
 
 void SharkBlock::do_instance_check()
 {
-  BasicBlock *not_null       = function()->CreateBlock("not_null");
-  BasicBlock *resolve        = function()->CreateBlock("resolve");
-  BasicBlock *resolved       = function()->CreateBlock("resolved");
-  BasicBlock *subclass_check = function()->CreateBlock("subclass_check");
-  BasicBlock *failure        = function()->CreateBlock("failure");
-  BasicBlock *success        = function()->CreateBlock("success");
+  BasicBlock *not_null      = function()->CreateBlock("not_null");
+  BasicBlock *resolve       = function()->CreateBlock("resolve");
+  BasicBlock *resolved      = function()->CreateBlock("resolved");
+  BasicBlock *subtype_check = function()->CreateBlock("subtype_check");
+  BasicBlock *failure       = function()->CreateBlock("failure");
+  BasicBlock *success       = function()->CreateBlock("success");
 
   SharkValue *sharkobject = pop();
   Value *object = sharkobject->jobject_value();
@@ -943,7 +1216,8 @@
   builder()->SetInsertPoint(not_null);
 
   // Get the class we're checking against
-  Value *tag = constant_pool_tag_at(iter()->get_klass_index());
+  SharkConstantPool constants(this);
+  Value *tag = constants.tag_at(iter()->get_klass_index());
   builder()->CreateCondBr(
     builder()->CreateOr(
       builder()->CreateICmpEQ(
@@ -955,26 +1229,29 @@
   // If the class is unresolved we must resolve it
   builder()->SetInsertPoint(resolve);
   builder()->CreateUnimplemented(__FILE__, __LINE__);
-  builder()->CreateBr(resolved);
+  builder()->CreateUnreachable(); // XXX builder()->CreateBr(resolved);
 
   builder()->SetInsertPoint(resolved);
-  Value *klass = constant_pool_object_at(iter()->get_klass_index());
+  Value *check_klass = constants.object_at(iter()->get_klass_index());
 
   // Get the class of the object being tested
-  Value *objKlass = builder()->CreateValueOfStructEntry(
+  Value *object_klass = builder()->CreateValueOfStructEntry(
     object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
     SharkType::jobject_type(),
-    "objKlass");
+    "object_klass");
 
-  // Check if it's the same class
+  // Perform the check
   builder()->CreateCondBr(
-    builder()->CreateICmpEQ(klass, objKlass),
-    success, subclass_check);
-
-  // Check if it's a subclass
-  builder()->SetInsertPoint(subclass_check);
-  builder()->CreateUnimplemented(__FILE__, __LINE__);
-  builder()->CreateUnreachable();
+    builder()->CreateICmpEQ(check_klass, object_klass),
+    success, subtype_check);
+  
+  builder()->SetInsertPoint(subtype_check);
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(
+      builder()->CreateCall2(
+        SharkRuntime::is_subtype_of(), check_klass, object_klass),
+      LLVMValue::jbyte_constant(0)),
+    success, failure);
 
   // Handle the result
   if (bc() == Bytecodes::_checkcast) {
@@ -1006,3 +1283,191 @@
     ShouldNotReachHere();
   }
 }
+
+void SharkBlock::do_new()
+{
+  bool will_link;
+  ciInstanceKlass* klass = iter()->get_klass(will_link)->as_instance_klass();
+  assert(will_link, "typeflow responsibility");
+
+  BasicBlock *got_tlab            = NULL;
+  BasicBlock *heap_alloc          = NULL;
+  BasicBlock *retry               = NULL;
+  BasicBlock *got_heap            = NULL;
+  BasicBlock *initialize          = NULL;
+  BasicBlock *slow_alloc_and_init = NULL;
+  BasicBlock *got_slow            = NULL;
+  BasicBlock *push_object         = NULL;
+
+  SharkState *fast_state = NULL;
+  
+  Value *tlab_object = NULL;
+  Value *heap_object = NULL;
+  Value *fast_object = NULL;
+  Value *slow_object = NULL;
+  Value *object      = NULL;
+
+  // The fast path
+  if (!Klass::layout_helper_needs_slow_path(klass->layout_helper())) {
+    if (UseTLAB) {
+      got_tlab          = function()->CreateBlock("got_tlab");
+      heap_alloc        = function()->CreateBlock("heap_alloc");
+    }
+    retry               = function()->CreateBlock("retry");
+    got_heap            = function()->CreateBlock("got_heap");
+    initialize          = function()->CreateBlock("initialize");
+    slow_alloc_and_init = function()->CreateBlock("slow_alloc_and_init");
+    push_object         = function()->CreateBlock("push_object");
+
+    size_t size_in_bytes = klass->size_helper() << LogHeapWordSize;
+
+    // Thread local allocation
+    if (UseTLAB) {
+      Value *top_addr = builder()->CreateAddressOfStructEntry(
+        thread(), Thread::tlab_top_offset(),
+        PointerType::getUnqual(SharkType::intptr_type()),
+        "top_addr");
+
+      Value *end = builder()->CreateValueOfStructEntry(
+        thread(), Thread::tlab_end_offset(),
+        SharkType::intptr_type(),
+        "end");
+
+      Value *old_top = builder()->CreateLoad(top_addr, "old_top");
+      Value *new_top = builder()->CreateAdd(
+        old_top, LLVMValue::intptr_constant(size_in_bytes));
+
+      builder()->CreateCondBr(
+        builder()->CreateICmpULE(new_top, end),
+        got_tlab, heap_alloc);
+
+      builder()->SetInsertPoint(got_tlab);
+      tlab_object = builder()->CreateIntToPtr(
+        old_top, SharkType::jobject_type(), "tlab_object");
+
+      builder()->CreateStore(new_top, top_addr);
+      builder()->CreateBr(initialize);
+      
+      builder()->SetInsertPoint(heap_alloc);
+    }
+
+    // Heap allocation
+    Value *top_addr = builder()->CreateIntToPtr(
+      LLVMValue::intptr_constant((intptr_t) Universe::heap()->top_addr()),
+      PointerType::getUnqual(SharkType::intptr_type()),
+      "top_addr");
+
+    Value *end = builder()->CreateLoad(
+      builder()->CreateIntToPtr(
+        LLVMValue::intptr_constant((intptr_t) Universe::heap()->end_addr()),
+        PointerType::getUnqual(SharkType::intptr_type())),
+      "end");
+
+    builder()->CreateBr(retry);
+    builder()->SetInsertPoint(retry);
+
+    Value *old_top = builder()->CreateLoad(top_addr, "top");
+    Value *new_top = builder()->CreateAdd(
+      old_top, LLVMValue::intptr_constant(size_in_bytes));
+
+    builder()->CreateCondBr(
+      builder()->CreateICmpULE(new_top, end),
+      got_heap, slow_alloc_and_init);
+
+    builder()->SetInsertPoint(got_heap);
+    heap_object = builder()->CreateIntToPtr(
+      old_top, SharkType::jobject_type(), "heap_object");
+
+    Value *check = builder()->CreateCmpxchgPtr(new_top, top_addr, old_top);
+    builder()->CreateCondBr(
+      builder()->CreateICmpEQ(old_top, check),
+      initialize, retry);
+
+    // Initialize the object
+    builder()->SetInsertPoint(initialize);
+    if (tlab_object) {
+      PHINode *phi = builder()->CreatePHI(
+        SharkType::jobject_type(), "fast_object");
+      phi->addIncoming(tlab_object, got_tlab);
+      phi->addIncoming(heap_object, got_heap);
+      fast_object = phi;
+    }
+    else {
+      fast_object = heap_object;
+    }
+
+    builder()->CreateMemset(
+      builder()->CreateBitCast(
+        fast_object, PointerType::getUnqual(SharkType::jbyte_type())),
+      LLVMValue::jbyte_constant(0),
+      LLVMValue::jint_constant(size_in_bytes),
+      LLVMValue::jint_constant(HeapWordSize));
+
+    Value *mark_addr = builder()->CreateAddressOfStructEntry(
+      fast_object, in_ByteSize(oopDesc::mark_offset_in_bytes()),
+      PointerType::getUnqual(SharkType::intptr_type()),
+      "mark_addr");
+
+    Value *klass_addr = builder()->CreateAddressOfStructEntry(
+      fast_object, in_ByteSize(oopDesc::klass_offset_in_bytes()),
+      PointerType::getUnqual(SharkType::jobject_type()),
+      "klass_addr");
+
+    // Set the mark
+    intptr_t mark;
+    if (UseBiasedLocking) {
+      Unimplemented();
+    }
+    else {
+      mark = (intptr_t) markOopDesc::prototype();
+    }
+    builder()->CreateStore(LLVMValue::intptr_constant(mark), mark_addr);
+
+    // Set the class
+    SharkConstantPool constants(this);
+    Value *rtklass = constants.object_at(iter()->get_klass_index());
+    builder()->CreateStore(rtklass, klass_addr);
+
+    builder()->CreateBr(push_object);
+    builder()->SetInsertPoint(slow_alloc_and_init);
+    fast_state = current_state()->copy();
+  }
+
+  // The slow path
+  SharkConstantPool constants(this);
+  call_vm(
+    SharkRuntime::new_instance(),
+    constants.object_at(iter()->get_klass_index()));
+  slow_object = function()->CreateLoadVMResult();
+  got_slow = builder()->GetInsertBlock();
+
+  // Push the object
+  if (push_object) {
+    builder()->CreateBr(push_object);
+    builder()->SetInsertPoint(push_object);
+  }
+  if (fast_object) {
+    PHINode *phi = builder()->CreatePHI(SharkType::jobject_type(), "object");
+    phi->addIncoming(fast_object, initialize);
+    phi->addIncoming(slow_object, got_slow);
+    object = phi;
+    current_state()->merge(fast_state, initialize, got_slow);
+  }
+  else {
+    object = slow_object;
+  }
+
+  push(SharkValue::create_jobject(object));
+}
+
+void SharkBlock::do_monitorenter()
+{
+  SharkValue *lockee = pop();
+  builder()->CreateUnimplemented(__FILE__, __LINE__);
+}
+
+void SharkBlock::do_monitorexit()
+{
+  SharkValue *lockee = pop();
+  builder()->CreateUnimplemented(__FILE__, __LINE__);
+}
--- a/ports/hotspot/src/share/vm/shark/sharkBlock.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkBlock.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -61,16 +61,18 @@
   {
     return function()->builder();
   }
+  SharkMonitor* monitor(int index) const
+  {
+    return function()->monitor(index);
+  }
+  ciMethod* target() const
+  {
+    return function()->target();
+  }
   llvm::Value* thread() const
   {
     return function()->thread();
   }
-#ifndef PRODUCT
-  bool debug() const
-  {
-    return function()->debug();
-  }
-#endif // PRODUCT
 
   // Typeflow properties
  public:
@@ -98,6 +100,10 @@
   {
     return ciblock()->stack_size();
   }
+  int monitor_count() const
+  {
+    return ciblock()->monitor_count();
+  }
   ciType* local_type_at_entry(int index) const
   {
     return ciblock()->local_type_at(index);
@@ -192,7 +198,7 @@
  private:
   SharkTrackingState* _current_state;
   
- private:
+ public:
   SharkTrackingState* current_state()
   {
     if (_current_state == NULL)
@@ -200,11 +206,12 @@
     return _current_state;
   }
 
- private:
+ public:
   llvm::Value* method()
   {
     return current_state()->method();
   }
+ private:
   SharkValue* local(int index)
   {
     return current_state()->local(index);
@@ -230,27 +237,31 @@
     return current_state()->stack(slot);
   }  
 
+  // VM calls
+ private:
+  llvm::CallInst* call_vm_base(llvm::Constant* callee,
+                               llvm::Value**   args_start,
+                               llvm::Value**   args_end);
+
+ public:
+  llvm::CallInst* call_vm(llvm::Constant* callee, llvm::Value* arg1)
+  {
+    llvm::Value *args[] = {thread(), arg1};
+    return call_vm_base(callee, args, args + 2);
+  }
+  llvm::CallInst* call_vm(llvm::Constant* callee,
+                          llvm::Value*    arg1,
+                          llvm::Value*    arg2,
+                          llvm::Value*    arg3)
+  {
+    llvm::Value *args[] = {thread(), arg1, arg2, arg3};
+    return call_vm_base(callee, args, args + 4);
+  }
+
   // Code generation
  public:
   void parse();
 
-  // Constant pool
- private:
-  llvm::Value* _constant_pool_check;
-  llvm::Value* _constant_pool_value;
-  llvm::Value* _constant_pool_tags_check;
-  llvm::Value* _constant_pool_tags_value;
-  llvm::Value* _constant_pool_cache_check;
-  llvm::Value* _constant_pool_cache_value;
-  
- private:
-  llvm::Value* constant_pool();
-  llvm::Value* constant_pool_tags();
-  llvm::Value* constant_pool_cache();
-  llvm::Value* constant_pool_tag_at(int which);
-  llvm::Value* constant_pool_object_at(int which);
-  llvm::Value* constant_pool_cache_entry_at(int which);
-
   // Error checking
  private:
   void check_null(SharkValue* value);
@@ -265,6 +276,10 @@
  private:
   void do_ldc();
 
+  // _arraylength bytecode
+ private:
+  void do_arraylength();
+
   // _*aload and *astore bytecodes
  private:
   void do_aload(BasicType basic_type);
@@ -309,4 +324,13 @@
   // _checkcast and _instanceof
  private:
   void do_instance_check();
+
+  // _new
+ private:
+  void do_new();
+
+  // _monitorenter and monitorexit
+ private:
+  void do_monitorenter();
+  void do_monitorexit();
 };
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -28,101 +28,76 @@
 
 using namespace llvm;
 
-SharkBuilder::SharkBuilder(Module* module)
+SharkBuilder::SharkBuilder()
     : IRBuilder(),
-      _module(module)
+      _module("shark"),
+      _module_provider(module()),
+      _execution_engine(ExecutionEngine::create(&_module_provider))
 {
   init_external_functions();
 }
 
+Constant* SharkBuilder::make_function(intptr_t            addr,
+                                      const FunctionType* sig,
+                                      const char*         name)
+{
+  Constant *func = make_pointer(addr, sig);
+
+#ifndef PRODUCT
+  ResourceMark rm;
+
+  // Use a trampoline to make dumped code more readable
+  Function *trampoline = (Function *) module()->getOrInsertFunction(name, sig);
+  SetInsertPoint(BasicBlock::Create("", trampoline));
+
+  Value **args = NEW_RESOURCE_ARRAY(Value*, trampoline->arg_size());
+  Function::arg_iterator ai = trampoline->arg_begin();
+  for (unsigned i = 0; i < trampoline->arg_size(); i++)
+    args[i] = ai++;
+
+  Value *result = CreateCall(func, args, args + trampoline->arg_size());
+  if (sig->getReturnType() == Type::VoidTy)
+    CreateRetVoid();
+  else
+    CreateRet(result);
+
+  func = trampoline;
+#endif // !PRODUCT
+
+  return func;
+}
+
 void SharkBuilder::init_external_functions()
 {
   std::vector<const Type*> params;
-  params.push_back(SharkType::intptr_type());
-  params.push_back(SharkType::jint_type());
-  FunctionType *type = FunctionType::get(Type::VoidTy, params, false);
-  Constant *func = make_pointer((intptr_t) report_should_not_reach_here, type);
-#ifndef PRODUCT
-  // Use a trampoline to make dumped code more readable
-  Function *trampoline =
-    (Function *) module()->getOrInsertFunction("should_not_reach_here", type);
-  Function::arg_iterator ai = trampoline->arg_begin();
-  Value *file = ai++;
-  Value *line = ai++;
-  SetInsertPoint(BasicBlock::Create("", trampoline));
-  CreateCall2(func, file, line);
-  CreateRetVoid();
-  func = trampoline;
-#endif // !PRODUCT
-  set_report_should_not_reach_here_fn(func);
-
-  // XXX copy and paste -- refactor this!
-  func = make_pointer((intptr_t) report_unimplemented, type);
-#ifndef PRODUCT
-  // Use a trampoline to make dumped code more readable
-  trampoline =
-    (Function *) module()->getOrInsertFunction("unimplemented", type);
-  ai = trampoline->arg_begin();
-  file = ai++;
-  line = ai++;
-  SetInsertPoint(BasicBlock::Create("", trampoline));
-  CreateCall2(func, file, line);
-  CreateRetVoid();
-  func = trampoline;
-#endif // !PRODUCT
-  set_report_unimplemented_fn(func);
-
-  // XXX copy and paste -- refactor this!
-  params.clear();
-  params.push_back(SharkType::jint_type());
-  params.push_back(SharkType::intptr_type());
-  func = make_pointer((intptr_t) trace_bytecode, type);
-#ifndef PRODUCT
-  // Use a trampoline to make dumped code more readable
-  trampoline =
-    (Function *) module()->getOrInsertFunction("trace_bytecode", type);
-  ai = trampoline->arg_begin();
-  file = ai++;
-  line = ai++;
-  SetInsertPoint(BasicBlock::Create("", trampoline));
-  CreateCall2(func, file, line);
-  CreateRetVoid();
-  func = trampoline;
-#endif // !PRODUCT
-  set_trace_bytecode_fn(func);
-
-  params.clear();
-  params.push_back(SharkType::intptr_type());
+  params.push_back(PointerType::getUnqual(SharkType::jbyte_type()));
   params.push_back(SharkType::jbyte_type());
   params.push_back(SharkType::jint_type());
   params.push_back(SharkType::jint_type());
-  type = FunctionType::get(Type::VoidTy, params, false);
+  FunctionType *type = FunctionType::get(Type::VoidTy, params, false);
   set_llvm_memset_fn(module()->getOrInsertFunction("llvm.memset.i32", type));
 
   params.clear();
+  params.push_back(PointerType::getUnqual(SharkType::intptr_type()));
   params.push_back(SharkType::intptr_type());
   params.push_back(SharkType::intptr_type());
+  type = FunctionType::get(SharkType::intptr_type(), params, false);
+  set_llvm_cmpxchg_ptr_fn(
+    module()->getOrInsertFunction(
+      "llvm.atomic.cmp.swap.i" LP64_ONLY("64") NOT_LP64("32"), type));
+
+  params.clear();
+  for (int i = 0; i < 5; i++)
+    params.push_back(Type::Int1Ty);
   type = FunctionType::get(Type::VoidTy, params, false);
-  func = make_pointer((intptr_t) dump, type);
-#ifndef PRODUCT
-  // Use a trampoline to make dumped code more readable
-  trampoline =
-    (Function *) module()->getOrInsertFunction("print_value", type);
-  ai = trampoline->arg_begin();
-  file = ai++;
-  line = ai++;
-  SetInsertPoint(BasicBlock::Create("", trampoline));
-  CreateCall2(func, file, line);
-  CreateRetVoid();
-  func = trampoline;
-#endif // !PRODUCT
-  set_dump_fn(func);
+  set_llvm_memory_barrier_fn(
+    module()->getOrInsertFunction("llvm.memory.barrier", type));
 }
 
 Function *SharkBuilder::CreateFunction()
 {
   Function *function = Function::Create(
-      SharkType::method_entry_type(),
+      SharkType::shark_entry_type(),
       GlobalVariable::InternalLinkage,
       "func");
   module()->getFunctionList().push_back(function);
@@ -154,20 +129,15 @@
     Unimplemented();
 
   Value *args[] = {name, value};
-  return CreateCall2(dump_fn(), name, value);
+  return CreateCall2(SharkRuntime::dump(), name, value);
 }
 
-void SharkBuilder::dump(const char *name, intptr_t value)
+CallInst* SharkBuilder::CreateCmpxchgPtr(Value* exchange_value,
+                                         Value* dst,
+                                         Value* compare_value)
 {
-  oop valueOop = (oop) value;
-  tty->print("%s = ", name);
-  if (valueOop->is_oop(true))
-    valueOop->print_on(tty);
-  else if (value >= ' ' && value <= '~')
-    tty->print("'%c' (%d)", value, value);
-  else
-    tty->print("%d", value);
-  tty->print_cr("");
+  return CreateCall3(
+    llvm_cmpxchg_ptr_fn(), dst, compare_value, exchange_value);
 }
 
 CallInst* SharkBuilder::CreateMemset(Value* dst,
@@ -181,7 +151,7 @@
 CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line)
 {
   return CreateCall2(
-    report_unimplemented_fn(), 
+    SharkRuntime::unimplemented(),
     LLVMValue::intptr_constant((intptr_t) file),
     LLVMValue::jint_constant(line));
 }
@@ -189,20 +159,18 @@
 CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line)
 {
   return CreateCall2(
-    report_should_not_reach_here_fn(),
+    SharkRuntime::should_not_reach_here(),
     LLVMValue::intptr_constant((intptr_t) file),
     LLVMValue::jint_constant(line));
 }
 
-void SharkBuilder::trace_bytecode(int bci, const char* bc)
+CallInst *SharkBuilder::CreateMemoryBarrier(BarrierFlags flags)
 {
-  tty->print_cr("%3d: %s", bci, bc);  
+  Value *args[] = {
+    ConstantInt::get(Type::Int1Ty, (flags & BARRIER_LOADLOAD) ? 1 : 0),
+    ConstantInt::get(Type::Int1Ty, (flags & BARRIER_LOADSTORE) ? 1 : 0),
+    ConstantInt::get(Type::Int1Ty, (flags & BARRIER_STORELOAD) ? 1 : 0),
+    ConstantInt::get(Type::Int1Ty, (flags & BARRIER_STORESTORE) ? 1 : 0),
+    ConstantInt::get(Type::Int1Ty, 0)};
+  return CreateCall(llvm_memory_barrier_fn(), args, args + 5);
 }
-
-CallInst* SharkBuilder::CreateTraceBytecode(int bci, Bytecodes::Code bc)
-{
-  return CreateCall2(
-    trace_bytecode_fn(),
-    LLVMValue::jint_constant(bci),
-    LLVMValue::intptr_constant((intptr_t) Bytecodes::name(bc)));
-}
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -25,16 +25,21 @@
 
 class SharkBuilder : public llvm::IRBuilder {
  public:
-  SharkBuilder(llvm::Module* module);
+  SharkBuilder();
 
-  // The module we build our functions into
  private:
-  llvm::Module* _module;
+  llvm::Module                 _module;
+  llvm::ExistingModuleProvider _module_provider;
+  llvm::ExecutionEngine*       _execution_engine;
 
- protected:
-  llvm::Module* module() const
+ public:
+  llvm::Module* module()
   {
-    return _module;
+    return &_module;
+  }
+  llvm::ExecutionEngine* execution_engine() const
+  {
+    return _execution_engine;
   }
 
   // Function creation
@@ -62,26 +67,46 @@
       name);
   }
 
+  llvm::LoadInst* CreateArrayLength(llvm::Value* array)
+  {
+    return CreateValueOfStructEntry(
+      array, in_ByteSize(arrayOopDesc::length_offset_in_bytes()),
+      SharkType::jint_type(), "length");
+  }
+
+  llvm::LoadInst* CreateArrayLoad(llvm::Value*      arrayoop,
+                                  const llvm::Type* element_type,
+                                  int               element_bytes,
+                                  ByteSize          base_offset,
+                                  llvm::Value*      index,
+                                  const char*       name = "")
+  {
+    llvm::Value* offset = index;
+
+    if (element_bytes != 1)
+      offset = CreateShl(
+        offset,
+        LLVMValue::jint_constant(exact_log2(element_bytes)));
+    offset = CreateAdd(LLVMValue::jint_constant(in_bytes(base_offset)),offset);
+
+    return CreateLoad(
+      CreateIntToPtr(
+        CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset),
+        llvm::PointerType::getUnqual(element_type)),
+      name);
+  }
+
   llvm::LoadInst* CreateArrayLoad(llvm::Value* arrayoop,
                                   BasicType    basic_type,
                                   ByteSize     base_offset,
                                   llvm::Value* index,
                                   const char*  name = "")
   {
-    llvm::Value* offset = index;
-
-    if (type2aelembytes[basic_type] != 1)
-      offset = CreateShl(
-        offset,
-        LLVMValue::jint_constant(exact_log2(type2aelembytes[basic_type])));
-    offset = CreateAdd(LLVMValue::jint_constant(in_bytes(base_offset)),offset);
-
-    const llvm::Type *array_type = SharkType::to_arrayType(basic_type);
-    return CreateLoad(
-      CreateIntToPtr(
-        CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset),
-        llvm::PointerType::getUnqual(array_type)),
-      name);
+    return CreateArrayLoad(
+      arrayoop,
+      SharkType::to_arrayType(basic_type),
+      type2aelembytes[basic_type],
+      base_offset, index, name);
   }
 
   llvm::StoreInst* CreateArrayStore(llvm::Value* arrayoop,
@@ -128,8 +153,14 @@
       index, value);
   }
 
+  // Helper for making function pointers
+ public:
+  llvm::Constant* make_function(intptr_t                  addr,
+                                const llvm::FunctionType* sig,
+                                const char*               name);
+
   // Helper for making pointers
- private:
+ public:
   llvm::Constant* make_pointer(intptr_t addr, const llvm::Type* type) const
   {
     return llvm::ConstantExpr::getIntToPtr(
@@ -139,59 +170,38 @@
 
   // External functions (and intrinsics)
  private:
-  llvm::Constant* _dump_fn;
+  llvm::Constant* _llvm_cmpxchg_ptr_fn;  
+  llvm::Constant* _llvm_memory_barrier_fn;
   llvm::Constant* _llvm_memset_fn;  
-  llvm::Constant* _report_should_not_reach_here_fn;
-  llvm::Constant* _trace_bytecode_fn;
-  llvm::Constant* _report_unimplemented_fn;
 
-  void set_dump_fn(llvm::Constant* dump_fn)
+  void set_llvm_cmpxchg_ptr_fn(llvm::Constant* llvm_cmpxchg_ptr_fn)
   {
-    _dump_fn = dump_fn;
+    _llvm_cmpxchg_ptr_fn = llvm_cmpxchg_ptr_fn;
+  }
+  void set_llvm_memory_barrier_fn(llvm::Constant* llvm_memory_barrier_fn)
+  {
+    _llvm_memory_barrier_fn = llvm_memory_barrier_fn;
   }
   void set_llvm_memset_fn(llvm::Constant* llvm_memset_fn)
   {
     _llvm_memset_fn = llvm_memset_fn;
   }
-  void set_report_should_not_reach_here_fn(llvm::Constant* report_snrh_fn)
-  {
-    _report_should_not_reach_here_fn = report_snrh_fn;
-  }
-  void set_trace_bytecode_fn(llvm::Constant* trace_bytecode_fn)
-  {
-    _trace_bytecode_fn = trace_bytecode_fn;
-  }
-  void set_report_unimplemented_fn(llvm::Constant* report_unimplemented_fn)
-  {
-    _report_unimplemented_fn = report_unimplemented_fn;
-  }
 
   void init_external_functions();
 
-  static void dump(const char *name, intptr_t value);
-  static void trace_bytecode(int bci, const char* bc);
-
  protected:
-  llvm::Constant* dump_fn() const
+  llvm::Constant* llvm_cmpxchg_ptr_fn() const
   {
-    return _dump_fn;
+    return _llvm_cmpxchg_ptr_fn;
+  }
+  llvm::Constant* llvm_memory_barrier_fn() const
+  {
+    return _llvm_memory_barrier_fn;
   }
   llvm::Constant* llvm_memset_fn() const
   {
     return _llvm_memset_fn;
   }
-  llvm::Constant* report_should_not_reach_here_fn() const
-  {
-    return _report_should_not_reach_here_fn;
-  }
-  llvm::Constant* trace_bytecode_fn() const
-  {
-    return _trace_bytecode_fn;
-  }
-  llvm::Constant* report_unimplemented_fn() const
-  {
-    return _report_unimplemented_fn;
-  }
 
  public:
   llvm::CallInst* CreateDump(llvm::Value* value);
@@ -199,15 +209,15 @@
                                llvm::Value* value,
                                llvm::Value* len,
                                llvm::Value* align);
+  llvm::CallInst* CreateCmpxchgPtr(llvm::Value* exchange_value,
+                                   llvm::Value* dst,
+                                   llvm::Value* compare_value);
   llvm::CallInst* CreateShouldNotReachHere(const char* file, int line);  
-  llvm::CallInst* CreateTraceBytecode(int bci, Bytecodes::Code bc);
   llvm::CallInst* CreateUnimplemented(const char* file, int line);  
 
-  // Memory barriers
+  // HotSpot memory barriers
  public:
-  void CreateUpdateBarrierSet(BarrierSet*  bs,
-                              llvm::Value* field,
-                              llvm::Value* new_value)
+  void CreateUpdateBarrierSet(BarrierSet* bs, llvm::Value* field)
   {
     if (bs->kind() != BarrierSet::CardTableModRef) {
       Unimplemented();
@@ -224,4 +234,27 @@
             LLVMValue::intptr_constant(CardTableModRefBS::card_shift))),
         llvm::PointerType::getUnqual(SharkType::jbyte_type())));
   }
+
+  // Hardware memory barriers
+ public:
+  enum BarrierFlags {
+    BARRIER_LOADLOAD   = 1,
+    BARRIER_LOADSTORE  = 2,
+    BARRIER_STORELOAD  = 4,
+    BARRIER_STORESTORE = 8
+  };
+
+ public:
+  llvm::CallInst* CreateMemoryBarrier(BarrierFlags flags);
+
+  // Alignment
+ public:
+  llvm::Value* CreateAlign(llvm::Value* x, intptr_t s, const char* name = "")
+  {
+    assert(is_power_of_2(s), "should be");
+    return CreateAnd(
+      CreateAdd(x, LLVMValue::intptr_constant(s - 1)),
+      LLVMValue::intptr_constant(~(s - 1)),
+      name);
+  }
 };
--- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -25,22 +25,15 @@
 
 #include "incls/_precompiled.incl"
 #include "incls/_sharkCompiler.cpp.incl"
-#ifndef PRODUCT
-#include <fstream>
-#include <ostream>
-#include <llvm/Bitcode/ReaderWriter.h>
-#endif // !PRODUCT
 
 using namespace llvm;
 
 SharkCompiler::SharkCompiler()
   : AbstractCompiler(),
-    _module(name()),
-    _builder(&_module),
-    _module_provider(&_module),
-    _execution_engine(ExecutionEngine::create(&_module_provider))
+    _builder()
 {
   SharkType::initialize();
+  SharkRuntime::initialize(builder());
   mark_initialized();
 }
 
@@ -54,50 +47,83 @@
   assert(is_initialized(), "should be");
   assert(entry_bci == InvocationEntryBci, "OSR is not supported");
 
+  ResourceMark rm;
+
+  const char *method_klass = NULL;
+  const char *method_name  = NULL;
+  
 #ifndef PRODUCT
+  method_klass = klassname(target);
+  method_name  = methodname(target);
+
+  // Skip methods if requested
   static uintx methods_seen = 0;
   methods_seen++;
-  if (methods_seen < SharkStartAt || methods_seen > SharkStopAfter) {
-    env->record_method_not_compilable("outside SharkStartAt/SharkStopAfter");
+  if (methods_seen < SharkStartAt) {
+    env->record_method_not_compilable("methods_seen < SharkStartAt");
     return;
   }
+  else if (methods_seen > SharkStopAfter) {
+    while (true)
+      sleep(1);
+  }
 #endif // !PRODUCT
 
-  ResourceMark rm;
+  if (SharkOnlyCompile != NULL) {
+    if (!method_matches(SharkOnlyCompile, method_klass, method_name)) {
+      env->record_method_not_compilable("does not match SharkOnlyCompile");
+      return;
+    }
+  }
 
   // Do the typeflow analysis
   ciTypeFlow *flow = target->get_flow_analysis();
   if (env->failing())
     return;
-#ifndef PRODUCT
-  if (methods_seen == SharkPrintTypeflowAfter) {
-    flow->print_on(tty);
+  if (SharkPrintTypeflowOf != NULL) {
+    if (method_matches(SharkPrintTypeflowOf, method_klass, method_name))
+      flow->print_on(tty);
   }
-#endif // PRODUCT
 
-  // Generate the IR
+  // Create the CodeBuffer and OopMapSet
+  BufferBlob *bb = BufferBlob::create(
+    "shark_temp", sizeof(SharkMethod) + target->code_size());
+  CodeBuffer cb(bb->instructions_begin(), bb->instructions_size());
+  OopMapSet oopmaps;
+
+  // Compile the method
   ciBytecodeStream iter(target);
-  SharkFunction function(builder(), flow, &iter);
+  SharkFunction function(builder(), flow, &iter, &cb, &oopmaps);
   if (env->failing())
     return;
-#ifndef PRODUCT
-  if (methods_seen == SharkDumpModuleAfter) {
-    tty->print_cr("%3d   Dumping module to hotspot.bc", methods_seen);
-    std::ostream *out = new std::ofstream(
-      "hotspot.bc", std::ios::out | std::ios::trunc | std::ios::binary);
-    WriteBitcodeToFile(&_module, *out);
-    delete out;
+  if (SharkPrintBitcodeOf != NULL) {
+    if (method_matches(SharkPrintBitcodeOf, method_klass, method_name))
+      function.function()->dump();
   }
-#endif // !PRODUCT
+  if (SharkTraceInstalls) {
+#ifdef PPC
+    uint32_t *start = *(uint32_t **) bb->instructions_begin();
+    uint32_t *limit = start;
+    while (*limit)
+      limit++;
+#else
+    Unimplemented();
+#endif // PPC
 
-  // Compile and install the method
-  install_method(env, target, entry_bci, function.function());
+    tty->print_cr(
+      "Installing method %s::%s at [%p-%p)",
+      method_klass, method_name, start, limit);
+  }
+
+  // Install the method
+  install_method(env, target, entry_bci, &cb, &oopmaps);
 }
 
-void SharkCompiler::install_method(ciEnv*    env,
-                                   ciMethod* target,
-                                   int       entry_bci,
-                                   Function* function)
+void SharkCompiler::install_method(ciEnv*      env,
+                                   ciMethod*   target,
+                                   int         entry_bci,
+                                   CodeBuffer* cb,
+                                   OopMapSet*  oopmaps)
 {
   // Pretty much everything in this method is junk to stop
   // ciEnv::register_method() from failing assertions.
@@ -106,11 +132,9 @@
   env->set_oop_recorder(&oop_recorder);
 
   DebugInformationRecorder debug_info(&oop_recorder);
+  debug_info.set_oopmaps(oopmaps);
   env->set_debug_info(&debug_info);
 
-  OopMapSet oopmaps;
-  debug_info.set_oopmaps(&oopmaps);
-
   Dependencies deps(env);  
   env->set_dependencies(&deps);
 
@@ -120,15 +144,7 @@
   offsets.set_value(CodeOffsets::Verified_Entry,
                     target->is_static() ? 0 : wordSize);
 
-  assert(CodeEntryAlignment > (int)(sizeof(intptr_t) * 2), "buffer too small");
-  unsigned char buf[CodeEntryAlignment * 2];
-  intptr_t *data =
-    (intptr_t *) align_size_up((intptr_t) buf, CodeEntryAlignment);
-  CodeBuffer cb((address) data, CodeEntryAlignment);
-  cb.initialize_oop_recorder(&oop_recorder);
-  *(data++) = (intptr_t) execution_engine()->getPointerToFunction(function);
-  *(data++) = (intptr_t) function;
-  cb.set_code_end((address) data);
+  cb->initialize_oop_recorder(&oop_recorder);
 
   ExceptionHandlerTable handler_table;
   ImplicitExceptionTable inc_table;
@@ -137,9 +153,9 @@
                        entry_bci,
                        &offsets,
                        0,
-                       &cb,
+                       cb,
                        0,
-                       &oopmaps,
+                       oopmaps,
                        &handler_table,
                        &inc_table,
                        this,
@@ -147,3 +163,53 @@
                        false,
                        false);
 }
+
+#ifndef PRODUCT
+const char* SharkCompiler::klassname(const ciMethod* target)
+{
+  const char *name = target->holder()->name()->as_utf8();
+  char *buf = NEW_RESOURCE_ARRAY(char, strlen(name) + 1);
+  strcpy(buf, name);
+  for (char *c = buf; *c; c++) {
+    if (*c == '/')
+      *c = '.';
+  }
+  return buf;
+}
+
+const char* SharkCompiler::methodname(const ciMethod* target)
+{
+  return target->name()->as_utf8();
+}
+
+bool SharkCompiler::method_matches(const char* pattern,
+                                   const char* klassname,
+                                   const char* methodname)
+{
+  if (pattern[0] == '*') {
+    pattern++;
+  }
+  else {
+    int len = strlen(klassname);
+    if (strncmp(pattern, klassname, len))
+      return false;
+    pattern += len;
+  }
+
+  if (pattern[0] != ':' && pattern[1] != ':')
+    return false;
+  pattern += 2;
+
+  if (pattern[0] == '*') {
+    pattern++;
+  }
+  else {
+    int len = strlen(methodname);
+    if (strncmp(pattern, methodname, len))
+      return false;
+    pattern += len;
+  }
+
+  return pattern[0] == '\0';
+}
+#endif // !PRODUCT
--- a/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -47,34 +47,30 @@
   // Compilation entry point for methods
   void compile_method(ciEnv* env, ciMethod* target, int entry_bci);
 
+  // The builder we'll use to compile our functions
  private:
-  // The module into which we'll place our functions
-  llvm::Module _module;
-
-  // The builder we'll use to create our functions
   SharkBuilder _builder;
 
-  // Wrapper to make our module look like a fully-fledged module provider
-  llvm::ExistingModuleProvider _module_provider;
-
-  // The execution engine we'll use to compile our functions
-  llvm::ExecutionEngine* _execution_engine;
-
  protected:
-  // Accessors
   SharkBuilder* builder()
   {
     return &_builder;
   }
-  llvm::ExecutionEngine* execution_engine() const
-  {
-    return _execution_engine;
-  }
 
+  // Method installation helper
  private:
-  // Method installation helper
   void install_method(ciEnv*          env,
                       ciMethod*       target,
                       int             entry_bci,
-                      llvm::Function* function);
+                      CodeBuffer*     cb,
+                      OopMapSet*      oopmaps);
+
+  // Debug helpers
+ private:
+  static const char *klassname (const ciMethod* target) PRODUCT_RETURN0;
+  static const char *methodname(const ciMethod* target) PRODUCT_RETURN0;
+
+  static bool method_matches(const char* pattern,
+                             const char* klassname,
+                             const char* methodname) PRODUCT_RETURN0;
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -0,0 +1,156 @@
+/*
+ * 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/_sharkConstantPool.cpp.incl"
+
+using namespace llvm;
+
+Value *SharkConstantPool::constants()
+{
+  Value *m = method();
+  if (m != _constants_method) {
+    _constants = builder()->CreateValueOfStructEntry(
+      m, methodOopDesc::constants_offset(),
+      SharkType::oop_type(), "constants");
+    _constants_method = m;
+  }
+  return _constants;
+}
+
+Value *SharkConstantPool::tags()
+{
+  Value *cp = constants();
+  if (cp != _tags_constants) {
+    _tags = builder()->CreateValueOfStructEntry(
+      cp, in_ByteSize(constantPoolOopDesc::tags_offset_in_bytes()),
+      SharkType::oop_type(), "tags");
+    _tags_constants = cp;
+  }
+  return _tags;
+}
+
+Value *SharkConstantPool::cache()
+{
+  Value *cp = constants();
+  if (cp != _cache_constants) {
+    _cache = builder()->CreateValueOfStructEntry(
+      cp, in_ByteSize(constantPoolOopDesc::cache_offset_in_bytes()),
+      SharkType::oop_type(), "cache");
+    _cache_constants = cp;
+  }
+  return _cache;
+}
+
+Value *SharkConstantPool::object_at(int which)
+{
+  return builder()->CreateArrayLoad(
+    constants(),
+    T_OBJECT, in_ByteSize(sizeof(constantPoolOopDesc)),
+    LLVMValue::jint_constant(which));
+}
+
+Value *SharkConstantPool::tag_at(int which)
+{
+  return builder()->CreateArrayLoad(
+    tags(), T_BYTE, LLVMValue::jint_constant(which));
+}
+
+Value *SharkConstantPool::cache_entry_at(int which)
+{
+  Value *entry = builder()->CreateIntToPtr(
+    builder()->CreateAdd(
+      builder()->CreatePtrToInt(
+        cache(), SharkType::intptr_type()),
+      LLVMValue::intptr_constant(
+        in_bytes(constantPoolCacheOopDesc::base_offset()) +
+        which * sizeof(ConstantPoolCacheEntry))),
+    SharkType::cpCacheEntry_type());
+
+  // Resolve the entry if necessary
+  int shift;
+  switch (ConstantPoolCacheEntry::bytecode_number(block()->bc())) {
+  case 1:
+    shift = 16;
+    break;
+  case 2:
+    shift = 24;
+    break;
+  default:
+    ShouldNotReachHere();
+  }
+
+  Value *opcode = builder()->CreateAnd(
+    builder()->CreateLShr(
+      builder()->CreateValueOfStructEntry(
+        entry, ConstantPoolCacheEntry::indices_offset(),
+        SharkType::intptr_type()),
+      LLVMValue::jint_constant(shift)),
+    LLVMValue::intptr_constant(0xff));
+
+  BasicBlock *orig_block = builder()->GetInsertBlock();
+  SharkState *orig_state = block()->current_state()->copy();
+
+  BasicBlock *resolve  = block()->function()->CreateBlock("resolve");
+  BasicBlock *resolved = block()->function()->CreateBlock("resolved");
+
+  builder()->CreateCondBr(
+    builder()->CreateICmpNE(opcode, LLVMValue::intptr_constant(block()->bc())),
+    resolve, resolved);
+
+  builder()->SetInsertPoint(resolve);
+  Constant *resolver;
+  switch (block()->bc()) {
+  case Bytecodes::_invokestatic:
+  case Bytecodes::_invokespecial:
+  case Bytecodes::_invokevirtual:
+  case Bytecodes::_invokeinterface:
+    resolver = SharkRuntime::resolve_invoke();
+    break;
+
+  case Bytecodes::_getfield:
+  case Bytecodes::_getstatic:
+  case Bytecodes::_putfield:
+  case Bytecodes::_putstatic:
+    resolver = SharkRuntime::resolve_get_put();
+    break;
+
+  default:
+    ShouldNotReachHere();
+  }
+
+  block()->call_vm(
+    resolver,
+    entry,
+    LLVMValue::jint_constant(block()->bci()),
+    LLVMValue::jint_constant(block()->bc()));
+  BasicBlock *resolve_block = builder()->GetInsertBlock();  
+  builder()->CreateBr(resolved);
+
+  builder()->SetInsertPoint(resolved);
+  block()->current_state()->merge(orig_state, orig_block, resolve_block);
+
+  return entry;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkConstantPool.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ *
+ */
+
+class SharkConstantPool : public StackObj {
+ public:
+  SharkConstantPool(SharkBlock* block)
+    : _block(block),
+      _constants_method(NULL),
+      _tags_constants(NULL),
+      _cache_constants(NULL) {}
+
+ private:
+  SharkBlock* _block;
+
+ private:
+  SharkBlock* block() const
+  {
+    return _block;
+  }
+  SharkBuilder* builder() const
+  {
+    return block()->builder();
+  }
+  llvm::Value* method() const
+  {
+    return block()->method();
+  }
+
+ private:
+  llvm::Value* _constants;        // The constant pool, a constantPoolOop
+  llvm::Value* _constants_method; // The method _constants was loaded from
+
+  llvm::Value* _tags;             // The tags array, a typeArrayOop
+  llvm::Value* _tags_constants;   // The constantPoolOop _tags is in
+
+  llvm::Value* _cache;            // The cache, a constantPoolCacheOop
+  llvm::Value* _cache_constants;  // The constantPoolCacheOop _cache is in
+
+ private:
+  llvm::Value* constants();
+  llvm::Value* tags();
+  llvm::Value* cache();
+
+ public:
+  llvm::Value* object_at(int which);
+  llvm::Value* tag_at(int which);
+  llvm::Value* cache_entry_at(int which);
+};
--- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -30,36 +30,54 @@
 
 void SharkFunction::initialize()
 {
-#ifndef PRODUCT
-  _debug = false;
-#endif // PRODUCT
-
   // Create the function
   _function = builder()->CreateFunction();
   set_block_insertion_point(NULL);
 
+  // Create the assembler
+  _masm = new MacroAssembler(cb());
+
+  // Create the SharkMethod
+  assert(
+    masm()->offset() == in_bytes(SharkMethod::entry_point_offset()), "fix");
+  void **code = (void **) masm()->pc();
+  masm()->emit_intptr(0);
+  assert(
+    masm()->offset() == in_bytes(SharkMethod::llvm_function_offset()), "fix");
+  masm()->emit_intptr((intptr_t) function());
+  assert(masm()->offset() == sizeof(SharkMethod), "fix");
+
   // Initialize the blocks
   _blocks = NEW_RESOURCE_ARRAY(SharkBlock*, flow()->block_count());
-  for (int i = 0; i < block_count(); i++) {
+  for (int i = 0; i < block_count(); i++)
     _blocks[i] = new SharkBlock(this, flow()->pre_order_at(i));
-    if (block(i)->start() == 0) {
-      assert(start_block() == NULL, "multiple start blocks");
-      _start_block = block(i);
-    }
-  }
-  start_block()->add_predecessor(NULL);
+
+  assert(block(0)->start() == 0, "blocks out of order");
+  SharkBlock *start_block = block(0);
+
+  start_block->add_predecessor(NULL);
   for (int i = 0; i < block_count(); i++) {
     for (int j = 0; j < block(i)->num_successors(); j++) {
       block(i)->successor(j)->add_predecessor(block(i));
     }
   }
 
+  // Initialize the monitors
+  _monitor_count = 0;  
+  if (target()->is_synchronized() || target()->uses_monitors()) {
+    for (int i = 0; i < block_count(); i++)
+      _monitor_count = MAX2(_monitor_count, block(i)->monitor_count());
+  }
+  if (monitor_count())
+    _monitors = NEW_RESOURCE_ARRAY(SharkMonitor*, monitor_count());
+  
   // Get our arguments
   Function::arg_iterator ai = function()->arg_begin();
   Argument *method = ai++;
+  method->setName("method");
+  _base_pc = ai++;
+  _base_pc->setName("base_pc");
   _thread = ai++;
-
-  method->setName("method");
   _thread->setName("thread");
 
   // Create the method preamble
@@ -67,10 +85,27 @@
   builder()->SetInsertPoint(CreateBlock());
   CreateInitZeroStack();
   CreatePushFrame(CreateBuildFrame());
+  NOT_PRODUCT(builder()->CreateStore(method, method_slot()));
+
+  // Lock if necessary
+  if (target()->is_synchronized()) {
+    Value *object;
+    if (target()->is_static()) {
+      Unimplemented();
+      object = NULL;
+    }
+    else {
+      object = builder()->CreateLoad(
+        builder()->CreateBitCast(
+          builder()->CreateStructGEP(locals_slots(), max_locals() - 1),
+          PointerType::getUnqual(SharkType::oop_type())));
+    }
+    monitor(0)->acquire(object);
+  }
 
   // Transition into the method proper
-  start_block()->add_incoming(new SharkEntryState(start_block()));
-  builder()->CreateBr(start_block()->entry_block());
+  start_block->add_incoming(new SharkEntryState(method, start_block));
+  builder()->CreateBr(start_block->entry_block());
 
   // Parse the blocks
   for (int i = 0; i < block_count(); i++) {
@@ -80,9 +115,14 @@
       set_block_insertion_point(NULL);
 
     block(i)->parse();
-    if (failing())
+    if (failing()) {
+      delete function();
       return;
+    }
   }
+
+  // Compile to native code
+  *code = builder()->execution_engine()->getPointerToFunction(function());
 }
 
 void SharkFunction::CreateInitZeroStack()
@@ -157,15 +197,15 @@
 
 Value* SharkFunction::CreateBuildFrame()
 {
-  if (flow()->method()->is_synchronized() || flow()->method()->uses_monitors())
-    Unimplemented();
+  int locals_words  = max_locals();
+  int extra_locals  = locals_words - arg_size();
+  int header_words  = SharkFrame::header_words;
+  int monitor_words = monitor_count()*frame::interpreter_frame_monitor_size();
+  int stack_words   = max_stack();
+  int frame_words   = header_words + monitor_words + stack_words;
 
-  int locals_words = max_locals();
-  int extra_locals = locals_words - arg_size();
-  int header_words = SharkFrame::header_words;
-  int stack_words  = max_stack();
-  int frame_words  = header_words + stack_words;
-  
+  _oopmap_frame_size = frame_words + extra_locals;
+
   // Update the stack pointer
   Value *zero_stack_pointer = builder()->CreateSub(
     CreateLoadZeroStackPointer(),
@@ -182,19 +222,56 @@
   int offset = 0;
 
   // Java stack
+  _stack_slots_offset = offset;
   _stack_slots = builder()->CreateBitCast(
-    builder()->CreateStructGEP(frame, offset),
+    builder()->CreateStructGEP(frame, stack_slots_offset()),
     PointerType::getUnqual(
       ArrayType::get(SharkType::intptr_type(), stack_words)),
     "stack_slots");
   offset += stack_words;
 
+  // Monitors
+  if (monitor_count()) {
+    _monitors_slots_offset = offset; 
+
+    Value *monitors = builder()->CreateBitCast(
+      builder()->CreateStructGEP(frame, monitors_slots_offset()),
+      PointerType::getUnqual(
+        ArrayType::get(SharkType::monitor_type(), monitor_count())),
+      "monitors");
+
+    for (int i = 0; i < monitor_count(); i++) {
+      char name[19];
+      snprintf(name, sizeof(name), "monitor_%d", i);
+
+      _monitors[i] = new SharkMonitor(
+        this,
+        builder()->CreateStructGEP(monitors, monitor_count() - 1 - i, name));
+
+      if (i != 0 || !target()->is_synchronized())
+        monitor(i)->mark_free();
+    }
+  }
+  offset += monitor_words;
+
   // Method pointer
+  _method_slot_offset = offset++;
   _method_slot = builder()->CreateBitCast(
-    builder()->CreateStructGEP(frame, offset++),
+    builder()->CreateStructGEP(frame, method_slot_offset()),
     PointerType::getUnqual(SharkType::methodOop_type()),
     "method_slot");
 
+  // Unextended SP
+  builder()->CreateStore(
+    zero_stack_pointer,
+    builder()->CreateStructGEP(frame, offset++));
+
+  // PC
+  _pc_slot = builder()->CreateBitCast(
+    builder()->CreateStructGEP(frame, offset++),
+    PointerType::getUnqual(SharkType::intptr_type()),
+    "pc_slot");
+
   // Frame header
   builder()->CreateStore(
     LLVMValue::intptr_constant(ZeroFrame::SHARK_FRAME),
@@ -202,8 +279,9 @@
   Value *fp = builder()->CreateStructGEP(frame, offset++, "fp");
 
   // Local variables
+  _locals_slots_offset = offset;  
   _locals_slots = builder()->CreateBitCast(
-    builder()->CreateStructGEP(frame, offset),
+    builder()->CreateStructGEP(frame, locals_slots_offset()),
     PointerType::getUnqual(
       ArrayType::get(SharkType::intptr_type(), locals_words)),
     "locals_slots");
--- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -24,13 +24,20 @@
  */
 
 class SharkBlock;
+class SharkMonitor;
 
 class SharkFunction : public StackObj {
  public:
   SharkFunction(SharkBuilder*     builder,
                 ciTypeFlow*       flow,
-                ciBytecodeStream* iter)
-    : _builder(builder), _flow(flow), _iter(iter), _start_block(NULL)
+                ciBytecodeStream* iter,
+                CodeBuffer*       cb,
+                OopMapSet*        oopmaps)
+    : _builder(builder),
+      _flow(flow),
+      _iter(iter),
+      _cb(cb),
+      _oopmaps(oopmaps)
   { initialize(); }
 
  private:
@@ -40,10 +47,14 @@
   SharkBuilder*     _builder;
   ciTypeFlow*       _flow;
   ciBytecodeStream* _iter;
+  CodeBuffer*       _cb;
+  OopMapSet*        _oopmaps;
+  MacroAssembler*   _masm;
   llvm::Function*   _function;
   SharkBlock**      _blocks;
-  SharkBlock*       _start_block;
+  llvm::Value*      _base_pc;
   llvm::Value*      _thread;
+  int               _monitor_count;
 
  public:  
   SharkBuilder* builder() const
@@ -58,6 +69,18 @@
   {
     return _iter;
   }
+  CodeBuffer* cb() const
+  {
+    return _cb;
+  }
+  OopMapSet* oopmaps() const
+  {
+    return _oopmaps;
+  }
+  MacroAssembler* masm() const
+  {
+    return _masm;
+  }
   llvm::Function* function() const
   {
     return _function;
@@ -66,19 +89,23 @@
   {
     return _blocks[i];
   }
-  SharkBlock* start_block() const
+  llvm::Value* base_pc() const
   {
-    return _start_block;
+    return _base_pc;
   }
   llvm::Value* thread() const
   {
     return _thread;
   }
+  int monitor_count() const
+  {
+    return _monitor_count;
+  }
 
  public:
   int arg_size() const
   {
-    return flow()->method()->arg_size();
+    return target()->arg_size();
   }
   int block_count() const
   {
@@ -92,6 +119,10 @@
   {
     return flow()->max_stack();
   }
+  ciMethod* target() const
+  {
+    return flow()->method();
+  }
 
  public:
   ciEnv* env() const
@@ -158,6 +189,7 @@
   {
     return builder()->CreateStore(value, zero_stack_pointer_addr());
   }
+
  private:
   llvm::LoadInst* CreateLoadZeroFramePointer(const char *name = "")
   {
@@ -168,19 +200,26 @@
     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* _method_slot;
-  llvm::Value* _locals_slots;
-  llvm::Value* _stack_slots;
+  llvm::Value*   _pc_slot;
+  llvm::Value*   _method_slot;
+  llvm::Value*   _locals_slots;
+  SharkMonitor** _monitors;
+  llvm::Value*   _stack_slots;
 
  public:
+  llvm::Value* pc_slot() const
+  {
+    return _pc_slot;
+  }  
   llvm::Value* method_slot() const
   {
     return _method_slot;
@@ -189,6 +228,10 @@
   {
     return _locals_slots;
   }  
+  SharkMonitor* monitor(int index) const
+  {
+    return _monitors[index];
+  }
   llvm::Value* stack_slots() const
   {
     return _stack_slots;
@@ -197,15 +240,76 @@
  private:
   llvm::Value* CreateBuildFrame();
 
-  // Debugging
-#ifndef PRODUCT
+  // OopMap support
+ public:
+  int code_offset() const
+  {
+    int offset = masm()->offset();
+    masm()->emit_zero_byte(); // keeps PCs unique
+    return offset;
+  }
+  void add_gc_map(int offset, OopMap* oopmap)
+  {
+    oopmaps()->add_gc_map(offset, oopmap);
+  }
+
  private:
-  bool _debug;
-  
+  int _oopmap_frame_size;
+  int _stack_slots_offset;
+  int _monitors_slots_offset;
+  int _method_slot_offset;
+  int _locals_slots_offset;
+
  public:
-  bool debug() const
+  int oopmap_frame_size() const
+  {
+    return _oopmap_frame_size;
+  }
+  int stack_slots_offset() const
+  {
+    return _stack_slots_offset;
+  }
+  int monitors_slots_offset() const
+  {
+    return _monitors_slots_offset;
+  }
+  int method_slot_offset() const
+  {
+    return _method_slot_offset;
+  }
+  int locals_slots_offset() const
+  {
+    return _locals_slots_offset;
+  }
+
+  // VM interface
+ private:
+  llvm::StoreInst* CreateStoreLastJavaSP(llvm::Value* value) const
   {
-    return _debug;
+    return builder()->CreateStore(
+      value,
+      builder()->CreateAddressOfStructEntry(
+        thread(), JavaThread::last_Java_sp_offset(),
+        llvm::PointerType::getUnqual(SharkType::intptr_type()),
+        "last_Java_sp_addr"));
+  }
+
+ public:
+  void set_last_Java_frame()
+  {
+    CreateStoreLastJavaSP(CreateLoadZeroFramePointer());
   }
-#endif // PRODUCT
+  void reset_last_Java_frame()
+  {
+    CreateStoreLastJavaSP(LLVMValue::intptr_constant(0));
+  }
+
+ public:
+  llvm::LoadInst* CreateLoadVMResult() const
+  {
+    return builder()->CreateValueOfStructEntry(
+      thread(), JavaThread::vm_result_offset(),
+      SharkType::jobject_type(),
+      "vm_result");
+  }
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkMethod.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ *
+ */
+
+class SharkMethod {
+ public:
+  SharkMethod()
+  {
+    ShouldNotCallThis();
+  }
+
+ public:
+  typedef void (*method_entry_t)(methodOop method, intptr_t base_pc, TRAPS);  
+
+ private:
+  method_entry_t  _entry_point;
+  llvm::Function* _llvm_function;
+
+ public:
+  method_entry_t entry_point() const
+  {
+    return _entry_point;
+  }
+  llvm::Function* llvm_function() const
+  {
+    return _llvm_function;
+  }
+
+  // Identifying and manipulating Shark entry points
+ private:
+  const static intptr_t _marker = 1;
+
+ public:
+  static bool is_shark_method(address entry_point)
+  {
+    return (intptr_t) entry_point & _marker;
+  }
+  static address mark(address entry_point)
+  {
+    assert(!is_shark_method(entry_point), "shouldn't be");
+    return (address) ((intptr_t) entry_point | _marker);
+  }
+  static SharkMethod* get(address entry_point)
+  {
+    assert(is_shark_method(entry_point), "should be");
+    return (SharkMethod *) ((intptr_t) entry_point & ~_marker);
+  }
+
+  // Method invocation
+ public:
+  void invoke(methodOop method, TRAPS)
+  {
+    entry_point()(method, (intptr_t) this, THREAD);
+  }
+
+  // Assembly language support
+ public:
+  static intptr_t marker()
+  {
+    return _marker;
+  }
+  static ByteSize entry_point_offset()
+  {
+    return byte_offset_of(SharkMethod, _entry_point);
+  }
+  static ByteSize llvm_function_offset()
+  {
+    return byte_offset_of(SharkMethod, _llvm_function);
+  }
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkMonitor.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -0,0 +1,154 @@
+/*
+ * 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/_sharkMonitor.cpp.incl"
+
+using namespace llvm;
+
+void SharkMonitor::initialize()
+{
+  _object_addr = builder()->CreateAddressOfStructEntry(
+    monitor(), in_ByteSize(BasicObjectLock::obj_offset_in_bytes()),
+    PointerType::getUnqual(SharkType::oop_type()),
+    "object_addr");
+
+  _displaced_header_addr = builder()->CreateAddressOfStructEntry(
+    monitor(), in_ByteSize(
+      BasicObjectLock::lock_offset_in_bytes() +
+      BasicLock::displaced_header_offset_in_bytes()),
+    PointerType::getUnqual(SharkType::intptr_type()),
+    "displaced_header_addr");
+}
+
+void SharkMonitor::acquire(Value *lockee) const
+{
+  BasicBlock *try_recursive = function()->CreateBlock("try_recursive");
+  BasicBlock *got_recursive = function()->CreateBlock("got_recursive");
+  BasicBlock *not_recursive = function()->CreateBlock("not_recursive");
+  BasicBlock *lock_acquired = function()->CreateBlock("lock_acquired");
+
+  set_object(lockee);
+
+  Value *lock = builder()->CreatePtrToInt(
+    displaced_header_addr(), SharkType::intptr_type());
+
+  Value *mark_addr = builder()->CreateAddressOfStructEntry(
+    lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()),
+    PointerType::getUnqual(SharkType::intptr_type()),
+    "mark_addr");
+
+  Value *mark = builder()->CreateLoad(mark_addr, "mark");
+  Value *disp = builder()->CreateOr(
+    mark, LLVMValue::intptr_constant(markOopDesc::unlocked_value), "disp");
+  set_displaced_header(disp);
+
+  // Try a simple lock
+  Value *check = builder()->CreateCmpxchgPtr(lock, mark_addr, disp);
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(disp, check),
+    lock_acquired, try_recursive);
+
+  // Locking failed, but maybe this thread already owns it
+  builder()->SetInsertPoint(try_recursive);
+  Value *addr = builder()->CreateAnd(
+    disp,
+    LLVMValue::intptr_constant(~markOopDesc::lock_mask_in_place));
+
+  // NB we use the entire stack, but JavaThread::is_lock_owned()
+  // uses a more limited range.  I don't think it hurts though...
+  Value *stack_limit = builder()->CreateValueOfStructEntry(
+    function()->thread(), Thread::stack_base_offset(),
+    SharkType::intptr_type(),
+    "stack_limit");
+
+  assert(sizeof(size_t) == sizeof(intptr_t), "should be");
+  Value *stack_size = builder()->CreateValueOfStructEntry(
+    function()->thread(), Thread::stack_size_offset(),
+    SharkType::intptr_type(),
+    "stack_size");
+
+  Value *stack_start =
+    builder()->CreateSub(stack_limit, stack_size, "stack_start");
+
+  builder()->CreateCondBr(
+    builder()->CreateAnd(
+      builder()->CreateICmpUGE(addr, stack_start),
+      builder()->CreateICmpULT(addr, stack_limit)),
+    got_recursive, not_recursive);
+                         
+  builder()->SetInsertPoint(got_recursive);
+  set_displaced_header(LLVMValue::intptr_constant(0));
+  builder()->CreateBr(lock_acquired);
+
+  // It's not a recursive case so we need to drop into the runtime
+  builder()->SetInsertPoint(not_recursive);
+  builder()->CreateUnimplemented(__FILE__, __LINE__);
+  builder()->CreateUnreachable();
+
+  // All done
+  builder()->SetInsertPoint(lock_acquired);  
+}
+
+void SharkMonitor::release() const
+{
+  BasicBlock *not_recursive = function()->CreateBlock("not_recursive");
+  BasicBlock *call_runtime  = function()->CreateBlock("call_runtime");
+  BasicBlock *lock_released = function()->CreateBlock("lock_released");
+
+  Value *disp = displaced_header();
+  Value *lockee = object();
+  set_object(LLVMValue::null());
+
+  // If it is recursive then we're already done
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(disp, LLVMValue::intptr_constant(0)),
+    lock_released, not_recursive);
+
+  // Try a simple unlock
+  builder()->SetInsertPoint(not_recursive);
+
+  Value *lock = builder()->CreatePtrToInt(
+    displaced_header_addr(), SharkType::intptr_type());
+
+  Value *mark_addr = builder()->CreateAddressOfStructEntry(
+    lockee, in_ByteSize(oopDesc::mark_offset_in_bytes()),
+    PointerType::getUnqual(SharkType::intptr_type()),
+    "mark_addr");
+
+  Value *check = builder()->CreateCmpxchgPtr(disp, mark_addr, lock);
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(lock, check),
+    lock_released, call_runtime);
+
+  // Need to drop into the runtime to release this one
+  builder()->SetInsertPoint(call_runtime);
+  set_object(lockee);
+  builder()->CreateUnimplemented(__FILE__, __LINE__);
+  builder()->CreateUnreachable();
+
+  // All done
+  builder()->SetInsertPoint(lock_released);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkMonitor.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ *
+ */
+
+class SharkMonitor : public ResourceObj {
+ public:
+  SharkMonitor(SharkFunction* function, llvm::Value* monitor)
+    : _function(function), _monitor(monitor)
+  { initialize(); }
+
+ private:
+  void initialize();
+
+ private:
+  SharkFunction* _function;
+  llvm::Value*   _monitor;
+  llvm::Value*   _object_addr;
+  llvm::Value*   _displaced_header_addr;
+
+ private:
+  SharkFunction* function() const
+  {
+    return _function;
+  }
+  llvm::Value* monitor() const
+  {
+    return _monitor;
+  }
+  llvm::Value* object_addr() const
+  {
+    return _object_addr;
+  }
+  llvm::Value* displaced_header_addr() const
+  {
+    return _displaced_header_addr;
+  }
+
+ public:
+  SharkBuilder* builder() const
+  {
+    return function()->builder();
+  }
+
+ public:
+  llvm::Value* object() const
+  {
+    builder()->CreateLoad(object_addr());
+  }
+  void set_object(llvm::Value* object) const
+  {
+    builder()->CreateStore(object, object_addr());
+  }
+  llvm::Value* displaced_header() const
+  {
+    builder()->CreateLoad(displaced_header_addr());
+  }
+  void set_displaced_header(llvm::Value* displaced_header) const
+  {
+    builder()->CreateStore(displaced_header, displaced_header_addr());
+  }
+
+ public:
+  void mark_free() const
+  {
+    set_object(LLVMValue::null());
+  }
+
+ public:
+  void acquire(llvm::Value* lockee) const;
+  void release() const;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -0,0 +1,209 @@
+/*
+ * 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/_sharkRuntime.cpp.incl"
+
+using namespace llvm;
+
+Constant* SharkRuntime::_new_instance;
+Constant* SharkRuntime::_resolve_get_put;
+Constant* SharkRuntime::_resolve_invoke;
+
+Constant* SharkRuntime::_dump;
+Constant* SharkRuntime::_is_subtype_of;
+Constant* SharkRuntime::_should_not_reach_here;
+Constant* SharkRuntime::_unimplemented;
+
+void SharkRuntime::initialize(SharkBuilder* builder)
+{
+  // VM calls
+  std::vector<const Type*> params;
+  params.push_back(SharkType::thread_type());
+  params.push_back(SharkType::jobject_type());
+  _new_instance = builder->make_function(
+    (intptr_t) new_instance_C,
+    FunctionType::get(Type::VoidTy, params, false),
+    "SharkRuntime__new_instance");
+
+  params.clear();
+  params.push_back(SharkType::thread_type());
+  params.push_back(SharkType::cpCacheEntry_type());
+  params.push_back(SharkType::jint_type());
+  params.push_back(SharkType::jint_type());
+  _resolve_get_put = builder->make_function(
+    (intptr_t) resolve_get_put_C,
+    FunctionType::get(Type::VoidTy, params, false),
+    "SharkRuntime__resolve_get_put");
+  _resolve_invoke = builder->make_function(
+    (intptr_t) resolve_invoke_C,
+    FunctionType::get(Type::VoidTy, params, false),
+    "SharkRuntime__resolve_invoke");
+
+  // Non-VM calls
+  params.clear();
+  params.push_back(SharkType::intptr_type());
+  params.push_back(SharkType::intptr_type());
+  _dump = builder->make_function(
+    (intptr_t) dump_C,
+    FunctionType::get(Type::VoidTy, params, false),
+    "SharkRuntime__dump");
+
+  params.clear();
+  params.push_back(SharkType::oop_type());
+  params.push_back(SharkType::oop_type());
+  assert(sizeof(bool) == 1, "fix this");
+  _is_subtype_of = builder->make_function(
+    (intptr_t) is_subtype_of_C,
+    FunctionType::get(Type::Int8Ty, params, false),
+    "SharkRuntime__is_subtype_of");
+
+  params.clear();
+  params.push_back(SharkType::intptr_type());
+  params.push_back(SharkType::jint_type());
+  _should_not_reach_here = builder->make_function(
+    (intptr_t) report_should_not_reach_here,
+    FunctionType::get(Type::VoidTy, params, false),
+    "report_should_not_reach_here");
+  _unimplemented = builder->make_function(
+    (intptr_t) report_unimplemented,
+    FunctionType::get(Type::VoidTy, params, false),
+    "report_unimplemented");
+}
+
+JRT_ENTRY(void, SharkRuntime::new_instance_C(JavaThread* thread,
+                                             klassOop klass))
+{
+  // These checks are cheap to make and support reflective allocation.
+  int lh = Klass::cast(klass)->layout_helper();
+  if (Klass::layout_helper_needs_slow_path(lh)
+      || !instanceKlass::cast(klass)->is_initialized()) {
+    KlassHandle kh(THREAD, klass);
+    kh->check_valid_for_instantiation(false, THREAD);
+    if (!HAS_PENDING_EXCEPTION) {
+      instanceKlass::cast(kh())->initialize(THREAD);
+    }
+    if (!HAS_PENDING_EXCEPTION) {
+      klass = kh();
+    } else {
+      klass = NULL;
+    }
+  }
+
+  if (klass != NULL) {
+    // Scavenge and allocate an instance.
+    oop result = instanceKlass::cast(klass)->allocate_instance(THREAD);
+    thread->set_vm_result(result);
+  }
+}
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::resolve_get_put_C(JavaThread*             thread,
+                                                ConstantPoolCacheEntry* entry,
+                                                int                     bci,
+                                                Bytecodes::Code      bytecode))
+{
+  Unimplemented();
+}
+JRT_END
+
+JRT_ENTRY(void, SharkRuntime::resolve_invoke_C(JavaThread*             thread,
+                                               ConstantPoolCacheEntry* entry,
+                                               int                     bci,
+                                               Bytecodes::Code       bytecode))
+{
+  // Find the receiver
+  Handle receiver(thread, NULL);
+  if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) {
+    ResourceMark rm(thread);
+    methodHandle mh(thread, method(thread));
+    Bytecode_invoke *call = Bytecode_invoke_at(mh, bci);
+    symbolHandle signature(thread, call->signature());
+    ArgumentSizeComputer asc(signature);
+    receiver = Handle(thread, (oop) tos_at(thread, asc.size()));
+    assert(
+      receiver.is_null() ||
+      (Universe::heap()->is_in_reserved(receiver()) &&
+       Universe::heap()->is_in_reserved(receiver->klass())), "sanity check");
+  }
+
+  // Resolve the method
+  CallInfo info;
+  {
+    constantPoolHandle pool(thread, method(thread)->constants());
+    JvmtiHideSingleStepping jhss(thread);
+    LinkResolver::resolve_invoke(
+      info, receiver, pool, two_byte_index(thread, bci), bytecode, CHECK);
+    if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
+      int retry_count = 0;
+      while (info.resolved_method()->is_old()) {
+        // It is very unlikely that method is redefined more than 100
+        // times in the middle of resolve. If it is looping here more
+        // than 100 times means then there could be a bug here.
+        guarantee((retry_count++ < 100),
+                  "Could not resolve to latest version of redefined method");
+        // method is redefined in the middle of resolve so re-try.
+        LinkResolver::resolve_invoke(
+          info, receiver, pool, two_byte_index(thread, bci), bytecode, CHECK);
+      }
+    }
+  }
+
+  // Update the cache entry if necessary
+  if (entry->is_resolved(bytecode))
+    return;
+
+  if (bytecode == Bytecodes::_invokeinterface) {
+    Unimplemented();
+  }
+  else {
+    entry->set_method(
+      bytecode,
+      info.resolved_method(),
+      info.vtable_index());
+  }
+}
+JRT_END
+
+// Non-VM calls
+// Nothing in these must ever GC!
+
+void SharkRuntime::dump_C(const char *name, intptr_t value)
+{
+  oop valueOop = (oop) value;
+  tty->print("%s = ", name);
+  if (valueOop->is_oop(true))
+    valueOop->print_on(tty);
+  else if (value >= ' ' && value <= '~')
+    tty->print("'%c' (%d)", value, value);
+  else
+    tty->print("%p", value);
+  tty->print_cr("");
+}
+
+bool SharkRuntime::is_subtype_of_C(klassOop check_klass, klassOop object_klass)
+{
+  return object_klass->klass_part()->is_subtype_of(check_klass);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ *
+ */
+
+class SharkRuntime : public AllStatic {
+ public:
+  static void initialize(SharkBuilder* builder);
+
+  // VM calls
+ private:
+  static llvm::Constant* _new_instance;
+  static llvm::Constant* _resolve_get_put;
+  static llvm::Constant* _resolve_invoke;
+
+ public:
+  static llvm::Constant* new_instance()
+  {
+    return _new_instance;
+  }
+  static llvm::Constant* resolve_get_put()
+  {
+    return _resolve_get_put;
+  }
+  static llvm::Constant* resolve_invoke()
+  {
+    return _resolve_invoke;
+  }
+
+ private:
+  static void new_instance_C(JavaThread* thread, klassOop klass);
+  static void resolve_get_put_C(JavaThread*             thread,
+                                ConstantPoolCacheEntry* entry,
+                                int                     bci,
+                                Bytecodes::Code         bytecode);
+  static void resolve_invoke_C(JavaThread*             thread,
+                               ConstantPoolCacheEntry* entry,
+                               int                     bci,
+                               Bytecodes::Code         bytecode);
+
+  // Helpers for VM calls
+ private:
+  static const SharkFrame* last_frame(JavaThread *thread)
+  {
+    return thread->last_frame().zero_sharkframe();
+  }
+  static methodOop method(JavaThread *thread)
+  {
+    return last_frame(thread)->method();
+  }
+  static address bcp(JavaThread *thread, int bci)
+  {
+    return method(thread)->code_base() + bci;
+  }
+  static int two_byte_index(JavaThread *thread, int bci)
+  {
+    return Bytes::get_Java_u2(bcp(thread, bci) + 1);
+  }
+  static intptr_t tos_at(JavaThread *thread, int offset)
+  {
+    return *(thread->zero_stack()->sp() + offset);
+  }  
+
+  // Non-VM calls
+ private:
+  static llvm::Constant* _dump;
+  static llvm::Constant* _is_subtype_of;
+  static llvm::Constant* _should_not_reach_here;
+  static llvm::Constant* _unimplemented;
+
+ public:
+  static llvm::Constant* dump()
+  {
+    return _dump;
+  }
+  static llvm::Constant* is_subtype_of()
+  {
+    return _is_subtype_of;
+  }
+  static llvm::Constant* should_not_reach_here()
+  {
+    return _should_not_reach_here;
+  }
+  static llvm::Constant* unimplemented()
+  {
+    return _unimplemented;
+  }
+
+ private:
+  static void dump_C(const char *name, intptr_t value);
+  static bool is_subtype_of_C(klassOop check_klass, klassOop object_klass); 
+};
--- a/ports/hotspot/src/share/vm/shark/sharkState.cpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkState.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -34,18 +34,32 @@
   _stack  = NEW_RESOURCE_ARRAY(SharkValue*, max_stack());
 }
 
-void SharkEntryState::initialize()
+void SharkEntryState::initialize(Value* method)
 {
   char name[18];
 
   // Method
-  _method = function()->function()->arg_begin();
+  _method = method;
 
   // Local variables
   for (int i = 0; i < max_locals(); i++) {
     SharkValue *value = NULL;
     ciType *type = block()->local_type_at_entry(i);
-    if (type->basic_type() != T_CONFLICT) {
+    switch (type->basic_type()) {
+    case ciTypeFlow::StateVector::T_BOTTOM:
+    case ciTypeFlow::StateVector::T_LONG2:
+    case ciTypeFlow::StateVector::T_DOUBLE2:
+      break;
+
+    case ciTypeFlow::StateVector::T_TOP:
+      Unimplemented();
+      break;
+
+    case ciTypeFlow::StateVector::T_NULL:
+      ShouldNotReachHere();
+      break;
+      
+    default:
       if (i < function()->arg_size()) {
         snprintf(name, sizeof(name), "local_%d_", i);
         value = SharkValue::create_generic(
@@ -83,7 +97,22 @@
   for (int i = 0; i < max_locals(); i++) {
     SharkValue *value = NULL;
     ciType *type = block()->local_type_at_entry(i);
-    if (type->basic_type() != T_CONFLICT) {
+    switch (type->basic_type()) {
+    case ciTypeFlow::StateVector::T_BOTTOM:
+    case ciTypeFlow::StateVector::T_LONG2:
+    case ciTypeFlow::StateVector::T_DOUBLE2:
+      break;
+
+    case ciTypeFlow::StateVector::T_TOP:
+      Unimplemented();
+      break;
+
+    case ciTypeFlow::StateVector::T_NULL:
+      // XXX we could do all kinds of clever stuff here
+      type = ciType::make(T_OBJECT); // XXX what about T_ARRAY?
+      // fall through
+
+    default:
       snprintf(name, sizeof(name), "local_%d_", i);
       value = SharkValue::create_generic(
         type, builder()->CreatePHI(SharkType::to_stackType(type), name));
@@ -96,9 +125,20 @@
     SharkValue *value = NULL;
     if (i < block()->stack_depth_at_entry()) {
       ciType *type = block()->stack_type_at_entry(i);
-      snprintf(name, sizeof(name), "stack_%d_", i);
-      value = SharkValue::create_generic(
-        type, builder()->CreatePHI(SharkType::to_stackType(type), name));
+      switch (type->basic_type()) {
+      case ciTypeFlow::StateVector::T_TOP:
+      case ciTypeFlow::StateVector::T_BOTTOM:
+      case ciTypeFlow::StateVector::T_LONG2:
+      case ciTypeFlow::StateVector::T_DOUBLE2:
+      case ciTypeFlow::StateVector::T_NULL:
+        Unimplemented();
+        break;
+
+      default:
+        snprintf(name, sizeof(name), "stack_%d_", i);
+        value = SharkValue::create_generic(
+          type, builder()->CreatePHI(SharkType::to_stackType(type), name));
+      }
     }
     _stack[i] = value;
   }
@@ -150,61 +190,93 @@
 
 void SharkTrackingState::decache(ciMethod *callee)
 {
+  // Create the OopMap
+  OopMap *oopmap = new OopMap(
+    oopmap_slot_munge(function()->oopmap_frame_size()),
+    oopmap_slot_munge(function()->arg_size()));
+
   // Decache expression stack slots as necessary
   int stack_slots = stack_depth_in_slots();
   for (int i = 0, j = 0; i < stack_slots; i++) {
     SharkValue *value;
     bool write;
+    bool record;
+    int dst;
 
     if (callee && i < callee->arg_size()) {
       value = pop();
       write = true;
+      record = false;
     }
     else {
       value = stack(j++);
-      write = value->is_jobject();
+      write = record = value->is_jobject();
     }
 
     if (write) {
+      dst = i + max_stack() - stack_slots;
       builder()->CreateStore(
         value->generic_value(),
         builder()->CreateBitCast(
-          builder()->CreateStructGEP(
-            function()->stack_slots(),
-            i + max_stack() - stack_slots),
+          builder()->CreateStructGEP(function()->stack_slots(), dst),
           PointerType::getUnqual(SharkType::to_stackType(value->type()))));
     }
 
+    if (record)
+      oopmap->set_oop(slot2reg(function()->stack_slots_offset() + dst));
+
     if (value->is_two_word())
       i++;
   }
 
+  // Record any monitors
+  for (int i = 0; i < function()->monitor_count(); i++) {
+    oopmap->set_oop(
+      slot2reg(
+        function()->monitors_slots_offset() +
+        i * frame::interpreter_frame_monitor_size() +
+        (BasicObjectLock::obj_offset_in_bytes() >> LogBytesPerWord)));
+  }
+
   // Decache the method pointer
   builder()->CreateStore(method(), function()->method_slot());
+  oopmap->set_oop(slot2reg(function()->method_slot_offset()));
+
+  // Decache the PC
+  int offset = function()->code_offset();
+  builder()->CreateStore(
+    builder()->CreateAdd(
+      function()->base_pc(), LLVMValue::intptr_constant(offset)),
+    function()->pc_slot());
 
   // Decache local variables as necesary
   for (int i = max_locals() - 1; i >= 0; i--) {
     SharkValue *value = local(i);
     if (value && value->is_jobject()) {
+      int dst = max_locals() - 1 - i;
+      
       builder()->CreateStore(
         value->generic_value(),
         builder()->CreateBitCast(
-          builder()->CreateStructGEP(
-            function()->locals_slots(),
-            max_locals() - 1 - i),
+          builder()->CreateStructGEP(function()->locals_slots(), dst),
           PointerType::getUnqual(
             SharkType::to_stackType(value->type()))));
+
+      oopmap->set_oop(slot2reg(function()->locals_slots_offset() + dst));
     }
   }
 
-  // If we're decaching for a call then trim back the stack
-  if (callee && stack_slots != max_stack()) {
+  // Trim back the stack if necessary
+  if (stack_slots != max_stack()) {
     function()->CreateStoreZeroStackPointer(
       builder()->CreatePtrToInt(
         builder()->CreateStructGEP(
           function()->stack_slots(), max_stack() - stack_slots),
         SharkType::intptr_type()));
   }
+
+  // Install the OopMap
+  function()->add_gc_map(offset, oopmap);
 }
 
 void SharkTrackingState::cache(ciMethod *callee)
@@ -212,7 +284,19 @@
   // If we're caching after a call then push a dummy result to set up the stack
   int result_size = callee ? callee->return_type()->size() : 0;
   if (result_size) {
-    push(SharkValue::create_generic(callee->return_type(), NULL));
+    ciType *result_type;
+    switch (callee->return_type()->basic_type()) {
+    case T_BOOLEAN:
+    case T_BYTE:
+    case T_CHAR:
+    case T_SHORT:
+      result_type = ciType::make(T_INT);
+      break;
+
+    default:
+      result_type = callee->return_type();
+    }
+    push(SharkValue::create_generic(result_type, NULL));
   }
 
   // Cache expression stack slots as necessary
@@ -229,15 +313,14 @@
     }
 
     if (read) {
+      int src = i + max_stack() - stack_slots;
       set_stack(
         j,
         SharkValue::create_generic(
           value->type(),
           builder()->CreateLoad(
             builder()->CreateBitCast(
-              builder()->CreateStructGEP(
-                function()->stack_slots(),
-                i + max_stack() - stack_slots),
+              builder()->CreateStructGEP(function()->stack_slots(), src),
               PointerType::getUnqual(
                 SharkType::to_stackType(value->basic_type()))))));
     }
@@ -253,25 +336,80 @@
   for (int i = max_locals() - 1; i >= 0; i--) {
     SharkValue *value = local(i);
     if (value && value->is_jobject()) {
+      int src = max_locals() - 1 - i;
       set_local(
         i,
         SharkValue::create_generic(
           value->type(),
           builder()->CreateLoad(
             builder()->CreateBitCast(
-              builder()->CreateStructGEP(
-                function()->locals_slots(),
-                max_locals() - 1 - i),
+              builder()->CreateStructGEP(function()->locals_slots(), src),
               PointerType::getUnqual(
                 SharkType::to_stackType(value->type()))))));
     }
   }
 
-  // If we're caching after a call then restore the stack pointer
-  if (callee && stack_slots != max_stack()) {
+  // Restore the stack pointer if necessary
+  if (stack_slots != max_stack()) {
     function()->CreateStoreZeroStackPointer(
       builder()->CreatePtrToInt(
         builder()->CreateStructGEP(function()->stack_slots(), 0),
         SharkType::intptr_type()));
   }
 }
+
+void SharkTrackingState::merge(SharkState* other,
+                               BasicBlock* other_block,
+                               BasicBlock* this_block)
+{
+  PHINode *phi;
+  char name[18];
+
+  // Method
+  Value *this_method = this->method();
+  Value *other_method = other->method();
+  if (this_method != other_method) {
+    phi = builder()->CreatePHI(SharkType::methodOop_type(), "method");
+    phi->addIncoming(this_method, this_block);
+    phi->addIncoming(other_method, other_block);
+    _method = phi;
+  }
+
+  // Local variables
+  assert(this->max_locals() == other->max_locals(), "should be");
+  for (int i = 0; i < max_locals(); i++) {
+    SharkValue *this_value = this->local(i);
+    SharkValue *other_value = other->local(i);
+    if (this_value == other_value)
+      continue;
+    assert(this_value != NULL && other_value != NULL, "shouldn't be");
+
+    ciType *this_type = this_value->type();
+    assert(this_type == other_value->type(), "should be");
+
+    snprintf(name, sizeof(name), "local_%d_", i);
+    phi = builder()->CreatePHI(SharkType::to_stackType(this_type), name);
+    phi->addIncoming(this_value->generic_value(), this_block);
+    phi->addIncoming(other_value->generic_value(), other_block);
+    _locals[i] = SharkValue::create_generic(this_type, phi);
+  }
+
+  // Expression stack
+  assert(this->stack_depth() == other->stack_depth(), "should be");
+  for (int i = 0; i < stack_depth(); i++) {
+    SharkValue *this_value = this->stack(i);
+    SharkValue *other_value = other->stack(i);
+    assert(this_value != NULL && other_value != NULL, "shouldn't be");
+    if (this_value == other_value)
+      continue;
+
+    ciType *this_type = this_value->type();
+    assert(this_type == other_value->type(), "should be");
+
+    snprintf(name, sizeof(name), "stack_%d_", i);
+    phi = builder()->CreatePHI(SharkType::to_stackType(this_type), name);
+    phi->addIncoming(this_value->generic_value(), this_block);
+    phi->addIncoming(other_value->generic_value(), other_block);
+    set_stack(i, SharkValue::create_generic(this_type, phi));
+  }
+}
--- a/ports/hotspot/src/share/vm/shark/sharkState.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkState.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -83,6 +83,11 @@
     assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
     return _sp[-(slot + 1)];
   }
+  void set_stack(int slot, SharkValue* value)
+  {
+    assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
+    _sp[-(slot + 1)] = value;
+  }
   int stack_depth() const
   {
     return _sp - _stack;
@@ -91,11 +96,11 @@
 
 class SharkEntryState : public SharkState {
  public:
-  SharkEntryState(SharkBlock* start_block)
-    : SharkState(start_block) { initialize(); }
+  SharkEntryState(llvm::Value* method, SharkBlock* start_block)
+    : SharkState(start_block) { initialize(method); }
 
  private:
-  void initialize();
+  void initialize(llvm::Value* method);
 };
 
 class SharkPHIState : public SharkState {
@@ -156,4 +161,25 @@
  public:
   void cache(ciMethod *callee = NULL);
   void decache(ciMethod *callee = NULL);
+
+  // Decache helpers
+ private:
+  static int oopmap_slot_munge(int x)
+  {
+    return x << (LogBytesPerWord - LogBytesPerInt);
+  }
+  static VMReg slot2reg(int offset)
+  {
+    return VMRegImpl::stack2reg(oopmap_slot_munge(offset));
+  }
+
+  // Copy and merge
+ public:
+  SharkTrackingState* copy() const
+  {
+    return new SharkTrackingState(this);
+  }
+  void merge(SharkState*       other,
+             llvm::BasicBlock* other_block,
+             llvm::BasicBlock* this_block);
 };
--- a/ports/hotspot/src/share/vm/shark/sharkType.cpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkType.cpp	Tue Aug 12 05:35:18 2008 -0400
@@ -29,9 +29,13 @@
 using namespace llvm;
 
 const PointerType*  SharkType::_cpCacheEntry_type;
-const FunctionType* SharkType::_method_entry_type;
+const FunctionType* SharkType::_interpreter_entry_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 FunctionType* SharkType::_shark_entry_type;
 const PointerType*  SharkType::_thread_type;
 const PointerType*  SharkType::_zeroStack_type;
 
@@ -44,9 +48,19 @@
   _cpCacheEntry_type = PointerType::getUnqual(
     ArrayType::get(Type::Int8Ty, sizeof(ConstantPoolCacheEntry)));
   
+  _itableOffsetEntry_type = PointerType::getUnqual(
+    ArrayType::get(Type::Int8Ty, itableOffsetEntry::size() * wordSize));
+  
+  _klass_type = PointerType::getUnqual(
+    ArrayType::get(Type::Int8Ty, sizeof(Klass)));
+  
   _methodOop_type = PointerType::getUnqual(
     ArrayType::get(Type::Int8Ty, sizeof(methodOopDesc)));
   
+  _monitor_type = ArrayType::get(
+      Type::Int8Ty,
+      frame::interpreter_frame_monitor_size() * wordSize);
+  
   _oop_type = PointerType::getUnqual(
     ArrayType::get(Type::Int8Ty, sizeof(oopDesc)));
 
@@ -59,14 +73,20 @@
   std::vector<const Type*> params;
   params.push_back(methodOop_type());
   params.push_back(thread_type());
-  _method_entry_type = FunctionType::get(Type::VoidTy, params, false);
+  _interpreter_entry_type = FunctionType::get(Type::VoidTy, params, false);
+
+  params.clear();
+  params.push_back(methodOop_type());
+  params.push_back(intptr_type());
+  params.push_back(thread_type());
+  _shark_entry_type = FunctionType::get(Type::VoidTy, params, false);
 
   // 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();
+      _to_arrayType_tab[i] = jboolean_type();
       break;
       
     case T_BYTE:
@@ -79,16 +99,31 @@
       _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] = jobject_type();
--- a/ports/hotspot/src/share/vm/shark/sharkType.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkType.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -38,9 +38,13 @@
   // VM types
  private:
   static const llvm::PointerType*  _cpCacheEntry_type;
-  static const llvm::FunctionType* _method_entry_type;
+  static const llvm::FunctionType* _interpreter_entry_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::FunctionType* _shark_entry_type;
   static const llvm::PointerType*  _thread_type;
   static const llvm::PointerType*  _zeroStack_type;
   
@@ -49,18 +53,34 @@
   {
     return _cpCacheEntry_type;
   }
-  static const llvm::FunctionType* method_entry_type()
+  static const llvm::FunctionType* interpreter_entry_type()
+  {
+    return _interpreter_entry_type;
+  }
+  static const llvm::PointerType* itableOffsetEntry_type()
   {
-    return _method_entry_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::FunctionType* shark_entry_type()
+  {
+    return _shark_entry_type;
+  }
   static const llvm::PointerType* thread_type()
   {
     return _thread_type;
@@ -72,6 +92,10 @@
 
   // Java types
  public:
+  static const llvm::IntegerType* jboolean_type()
+  {
+    return llvm::Type::Int8Ty;
+  }
   static const llvm::IntegerType* jbyte_type()
   {
     return llvm::Type::Int8Ty;
--- a/ports/hotspot/src/share/vm/shark/sharkValue.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/sharkValue.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -33,6 +33,10 @@
   {
     return llvm::ConstantInt::get(SharkType::jint_type(), value, true);
   }
+  static llvm::ConstantInt* jlong_constant(jlong value)
+  {
+    return llvm::ConstantInt::get(SharkType::jlong_type(), value, true);
+  }
   static llvm::ConstantPointerNull* null()
   {
     return llvm::ConstantPointerNull::get(SharkType::jobject_type());
@@ -85,6 +89,10 @@
   {
     return llvm_value()->getType() == SharkType::jint_type();
   }
+  bool is_jlong() const
+  {
+    return llvm_value()->getType() == SharkType::jlong_type();
+  }
   bool is_jobject() const
   {
     return llvm_value()->getType() == SharkType::jobject_type();
@@ -99,13 +107,28 @@
   static SharkValue* create_jint(llvm::Value* value)
   {
     assert(value->getType() == SharkType::jint_type(), "should be");
-    return new SharkValue(ciType::make(T_INT), value);
+    return create_generic(ciType::make(T_INT), value);
   }
   llvm::Value* jint_value() const
   {
     assert(is_jint(), "should be");
     return llvm_value();
   }
+  static SharkValue* create_jlong(llvm::Value* value)
+  {
+    assert(value->getType() == SharkType::jlong_type(), "should be");
+    return create_generic(ciType::make(T_LONG), value);
+  }
+  llvm::Value* jlong_value() const
+  {
+    assert(is_jlong(), "should be");
+    return llvm_value();
+  }
+  static SharkValue* create_jobject(llvm::Value* value)
+  {
+    assert(value->getType() == SharkType::jobject_type(), "should be");
+    return create_generic(ciType::make(T_OBJECT), value);
+  }
   llvm::Value* jobject_value() const
   {
     assert(is_jobject(), "should be");
@@ -123,10 +146,22 @@
     switch (value.basic_type()) {
     case T_BOOLEAN:
       return SharkValue::jint_constant(value.as_boolean());
-      
+
+    case T_BYTE:
+      return SharkValue::jint_constant(value.as_byte());
+
+    case T_CHAR:
+      return SharkValue::jint_constant(value.as_char());
+
+    case T_SHORT:
+      return SharkValue::jint_constant(value.as_short());
+
     case T_INT:
       return SharkValue::jint_constant(value.as_int());
 
+    case T_LONG:
+      return SharkValue::jlong_constant(value.as_long());
+      
     case T_OBJECT:
     case T_ARRAY:
       return NULL;
@@ -159,6 +194,10 @@
   {
     return create_jint(LLVMValue::jint_constant(value));
   }
+  static SharkValue* jlong_constant(jlong value)
+  {
+    return create_jlong(LLVMValue::jlong_constant(value));
+  }
   static SharkValue* null()
   {
     return create_generic(ciType::make(T_OBJECT), LLVMValue::null());
--- a/ports/hotspot/src/share/vm/shark/shark_globals.hpp	Tue Aug 12 09:37:13 2008 +0200
+++ b/ports/hotspot/src/share/vm/shark/shark_globals.hpp	Tue Aug 12 05:35:18 2008 -0400
@@ -33,19 +33,25 @@
           "Maximum number of nodes")                                          \
                                                                               \
   /* compiler debugging */                                                    \
-  notproduct(uintx, SharkStartAt, 0,                                          \
-             "First method to consider when using Shark")                     \
+  develop(uintx, SharkStartAt, 0,                                             \
+          "First method to consider when using Shark")                        \
                                                                               \
-  notproduct(uintx, SharkStopAfter, max_uintx,                                \
-             "Last method to consider when using Shark")                      \
+  develop(uintx, SharkStopAfter, max_uintx,                                   \
+          "Last method to consider when using Shark")                         \
+                                                                              \
+  develop(ccstr, SharkOnlyCompile, NULL,                                      \
+          "Only compile the specified method")                                \
                                                                               \
-  notproduct(uintx, SharkDumpModuleAfter, max_uintx,                          \
-             "Dump the LLVM bitcode after compiling this number of methods")  \
+  develop(ccstr, SharkPrintTypeflowOf, NULL,                                  \
+          "Print the typeflow of the specified method")                       \
+                                                                              \
+  develop(ccstr, SharkPrintBitcodeOf, NULL,                                   \
+          "Print the LLVM bitcode of the specified method")                   \
                                                                               \
-  notproduct(uintx, SharkPrintTypeflowAfter, max_uintx,                       \
-             "Print the typeflow after compiling this number of methods")     \
+  develop(bool, SharkTraceBytecodes, false,                                   \
+          "Trace bytecode compilation")                                       \
                                                                               \
-  notproduct(bool, SharkTraceBytecodes, false,                                \
-             "Trace bytecode compilation")                                    \
+  develop(bool, SharkTraceInstalls, false,                                    \
+          "Trace method installation")                                        \
 
 SHARK_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)