changeset 1026:4f4d268762d7

2008-08-20 Gary Benson <gbenson@redhat.com> * patches/icedtea-shark.patch: Updated to latest Shark. * ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp: Likewise. * ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp: Likewise. * ports/hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp: Likewise. * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp: Likewise. * ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp: Likewise. * ports/hotspot/src/cpu/zero/vm/interpreter_zero.cpp: Likewise. * ports/hotspot/src/cpu/zero/vm/interpreter_zero.hpp: Likewise. * ports/hotspot/src/share/vm/includeDB_shark: 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/sharkConstantPool.cpp: 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/sharkMonitor.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkRuntime.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/cpu/zero/vm/entry_zero.hpp: New file. * ports/hotspot/src/share/vm/shark/sharkEntry.cpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkEntry.hpp: Likewise. * ports/hotspot/src/share/vm/shark/sharkMethod.hpp: Removed.
author Gary Benson <gbenson@redhat.com>
date Wed, 20 Aug 2008 04:24:45 -0400
parents 67600de741be
children 1842897fe307
files ChangeLog patches/icedtea-shark.patch ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp ports/hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp ports/hotspot/src/cpu/zero/vm/entry_zero.hpp ports/hotspot/src/cpu/zero/vm/interpreter_zero.cpp ports/hotspot/src/cpu/zero/vm/interpreter_zero.hpp ports/hotspot/src/share/vm/includeDB_shark 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/sharkEntry.cpp ports/hotspot/src/share/vm/shark/sharkEntry.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.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
diffstat 31 files changed, 1477 insertions(+), 569 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Aug 20 04:12:41 2008 -0400
+++ b/ChangeLog	Wed Aug 20 04:24:45 2008 -0400
@@ -1,3 +1,37 @@
+2008-08-20  Gary Benson  <gbenson@redhat.com>
+
+	* patches/icedtea-shark.patch: Updated to latest Shark.
+	* ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp: 
+	Likewise.
+	* ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/interpreter_zero.cpp: Likewise.
+	* ports/hotspot/src/cpu/zero/vm/interpreter_zero.hpp: Likewise.
+	* ports/hotspot/src/share/vm/includeDB_shark: 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/sharkConstantPool.cpp: 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/sharkMonitor.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkRuntime.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkRuntime.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/cpu/zero/vm/entry_zero.hpp: New file.
+	* ports/hotspot/src/share/vm/shark/sharkEntry.cpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkEntry.hpp: Likewise.
+	* ports/hotspot/src/share/vm/shark/sharkMethod.hpp: Removed.
+
 2008-08-20  Gary Benson  <gbenson@redhat.com>
 
 	* ports/hotspot/src/cpu/zero/vm/bytecodeInterpreter_zero.inline.hpp
--- a/patches/icedtea-shark.patch	Wed Aug 20 04:12:41 2008 -0400
+++ b/patches/icedtea-shark.patch	Wed Aug 20 04:24:45 2008 -0400
@@ -181,7 +181,7 @@
  
    OrderAccess::storestore();
 +#ifdef SHARK
-+  mh->_from_interpreted_entry = SharkMethod::mark(code->instructions_begin());
++  mh->_from_interpreted_entry = code->instructions_begin();
 +#else
    mh->_from_compiled_entry = code->verified_entry_point();
    OrderAccess::storestore();
--- a/ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/assembler_zero.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -28,11 +28,7 @@
 
 int AbstractAssembler::code_fill_byte()
 {
-#ifdef SHARK
   return 0;
-#else
-  Unimplemented();
-#endif // SHARK
 }
 
 void Assembler::pd_patch_instruction(address branch, address target)
@@ -47,27 +43,26 @@
 }
 #endif // PRODUCT
 
+void MacroAssembler::align(int modulus)
+{
+  while (offset() % modulus != 0)
+    emit_byte(AbstractAssembler::code_fill_byte());
+}
+
 void MacroAssembler::bang_stack_with_offset(int offset)
 {
   Unimplemented();
 }
 
-void MacroAssembler::align(int modulus)
+void MacroAssembler::advance(int bytes)
 {
-  // Loads of places assert that code is generated,
-  // and I'm guessing plenty of places assume that
-  // *something* was generated.  This is a sneaky
-  // place to emit such a something.
-  emit_byte(0x23);
-
-  // Probably ought to align it too, while we're here.
-  while (offset() % modulus != 0)
-    emit_byte(0x23);
+  _code_pos += bytes;
+  sync();
 }
 
 static void _UnimplementedStub()
 {
-  report_unimplemented("fake-generated-code", 23);
+  report_unimplemented(__FILE__, __LINE__);
 }
 
 address UnimplementedStub()
--- a/ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/assembler_zero.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -23,28 +23,21 @@
  *
  */
 
-// The definitions needed for zero assembly code generation.
-
-// The zero Assembler: Pure assembler doing NO optimizations on
-// the instruction level; i.e., what you write is what you get.
-// The Assembler is generating code into a CodeBuffer.
+// In normal, CPU-specific ports of HotSpot these two classes are used
+// for generating assembly language.  We don't do any of this in zero,
+// of course, but we do sneak entry points around in CodeBuffers so we
+// generate those here.
 
 class Assembler : public AbstractAssembler {
  public:
   Assembler(CodeBuffer* code) : AbstractAssembler(code) {}
 
-  // Function to fix up forward branches
   void pd_patch_instruction(address branch, address target);
 #ifndef PRODUCT
   static void pd_print_patched_instruction(address branch);
 #endif // PRODUCT
 };
 
-// MacroAssembler extends Assembler by frequently used macros.
-//
-// Instructions for which a 'better' code sequence exists depending
-// on arguments should also go in here.
-
 class MacroAssembler : public Assembler {
  public:
   MacroAssembler(CodeBuffer* code) : Assembler(code) {}
@@ -52,17 +45,8 @@
   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
+  void advance(int bytes);
 };
 
 #ifdef ASSERT
@@ -79,4 +63,5 @@
 // Nothing to do with the assembler (or lack of),
 // just a real convenient place to include these.
 #include <ffi.h>
+#include <entry_zero.hpp>
 #include <stack_zero.hpp>
--- a/ports/hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreterGenerator_zero.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2003-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.
+ *
+ */
+
+ protected:
+  MacroAssembler* assembler() const
+  {
+    return _masm;
+  }
+
+ protected:
+  address generate_entry(ZeroEntry::method_entry_t entry_point)
+  {
+    ZeroEntry *entry = (ZeroEntry *) assembler()->pc();
+    assembler()->advance(sizeof(ZeroEntry));
+    entry->set_entry_point(entry_point);
+    return (address) entry;
+  }
--- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -37,7 +37,7 @@
   thread->reset_last_Java_frame();              \
   fixup_after_potential_safepoint()
 
-void CppInterpreter::normal_entry(methodOop method, TRAPS)
+void CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS)
 {
   JavaThread *thread = (JavaThread *) THREAD;
   ZeroStack *stack = thread->zero_stack();
@@ -146,7 +146,7 @@
     stack->push(result[-i]);
 }
 
-void CppInterpreter::native_entry(methodOop method, TRAPS)
+void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS)
 {
   JavaThread *thread = (JavaThread *) THREAD;
   ZeroStack *stack = thread->zero_stack();
@@ -374,7 +374,7 @@
   }
 }
 
-void CppInterpreter::accessor_entry(methodOop method, TRAPS)
+void CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS)
 {
   JavaThread *thread = (JavaThread *) THREAD;
   ZeroStack *stack = thread->zero_stack();
@@ -382,7 +382,7 @@
 
   // Drop into the slow path if we need a safepoint check
   if (SafepointSynchronize::do_call_back()) {
-    normal_entry(method, THREAD);
+    normal_entry(method, 0, THREAD);
     return;
   }
 
@@ -390,7 +390,7 @@
   // if we have a NullPointerException
   oop object = LOCALS_OBJECT(0);
   if (object == NULL) {
-    normal_entry(method, THREAD);
+    normal_entry(method, 0, THREAD);
     return;
   }
 
@@ -413,7 +413,7 @@
   constantPoolCacheOop cache = method->constants()->cache();
   ConstantPoolCacheEntry* entry = cache->entry_at(index);
   if (!entry->is_resolved(Bytecodes::_getfield)) {
-    normal_entry(method, THREAD);
+    normal_entry(method, 0, THREAD);
     return;
   }
 
@@ -505,14 +505,14 @@
   }
 }
 
-void CppInterpreter::empty_entry(methodOop method, TRAPS)
+void CppInterpreter::empty_entry(methodOop method, intptr_t UNUSED, TRAPS)
 {
   JavaThread *thread = (JavaThread *) THREAD;
   ZeroStack *stack = thread->zero_stack();
 
   // Drop into the slow path if we need a safepoint check
   if (SafepointSynchronize::do_call_back()) {
-    normal_entry(method, THREAD);
+    normal_entry(method, 0, THREAD);
     return;
   }
 
@@ -609,7 +609,7 @@
   if (!UseFastEmptyMethods)
     return NULL;
 
-  return (address) CppInterpreter::empty_entry;
+  return generate_entry(CppInterpreter::empty_entry);
 }
 
 address InterpreterGenerator::generate_accessor_entry()
@@ -617,19 +617,21 @@
   if (!UseFastAccessorMethods)
     return NULL;
 
-  return (address) CppInterpreter::accessor_entry;
+  return generate_entry(CppInterpreter::accessor_entry);
 }
 
 address InterpreterGenerator::generate_native_entry(bool synchronized)
 {
   assert (synchronized == false, "should be");
-  return (address) CppInterpreter::native_entry;
+
+  return generate_entry(CppInterpreter::native_entry);
 }
 
 address InterpreterGenerator::generate_normal_entry(bool synchronized)
 {
   assert (synchronized == false, "should be");
-  return (address) CppInterpreter::normal_entry;
+
+  return generate_entry(CppInterpreter::normal_entry);
 }
 
 address AbstractInterpreterGenerator::generate_method_entry(
@@ -679,10 +681,6 @@
   if (entry_point == NULL)
     entry_point = ((InterpreterGenerator*)this)->generate_normal_entry(false);
 
-#ifdef SHARK
-  assert(!SharkMethod::is_shark_method(entry_point), "shouldn't be");
-#endif // SHARK
-  
   return entry_point;
 }
 
@@ -732,21 +730,25 @@
 
 address CppInterpreterGenerator::generate_result_handler_for(
     BasicType type) {
+  assembler()->advance(1);
   return ShouldNotReachHereStub();
 }
 
 address CppInterpreterGenerator::generate_tosca_to_stack_converter(
     BasicType type) {
+  assembler()->advance(1);
   return ShouldNotReachHereStub();
 }
 
 address CppInterpreterGenerator::generate_stack_to_stack_converter(
     BasicType type) {
+  assembler()->advance(1);
   return ShouldNotReachHereStub();
 }
 
 address CppInterpreterGenerator::generate_stack_to_native_abi_converter(
     BasicType type) {
+  assembler()->advance(1);
   return ShouldNotReachHereStub();
 }
 
--- a/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/cppInterpreter_zero.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -25,13 +25,12 @@
 
 
  protected:
-  // Size of interpreter code.  We don't have generated code so
-  // this should be zero, but that hits all kinds of assertions
+  // Size of interpreter code
   const static int InterpreterCodeSize = 6 * K;
 
  private:
   // Method entries
-  static void normal_entry(methodOop method, TRAPS);
-  static void native_entry(methodOop method, TRAPS);
-  static void accessor_entry(methodOop method, TRAPS);
-  static void empty_entry(methodOop method, TRAPS);
+  static void normal_entry(methodOop method, intptr_t UNUSED, TRAPS);
+  static void native_entry(methodOop method, intptr_t UNUSED, TRAPS);
+  static void accessor_entry(methodOop method, intptr_t UNUSED, TRAPS);
+  static void empty_entry(methodOop method, intptr_t UNUSED, TRAPS);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/cpu/zero/vm/entry_zero.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2003-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 ZeroEntry {
+ public:
+  ZeroEntry()
+  {
+    ShouldNotCallThis();
+  }
+
+ public:
+  typedef void (*method_entry_t)(methodOop method, intptr_t base_pc, TRAPS);
+
+ private:
+  method_entry_t _entry_point;
+
+ public:
+  method_entry_t entry_point() const
+  {
+    return _entry_point;
+  }
+  void set_entry_point(method_entry_t entry_point)
+  {
+    _entry_point = entry_point;
+  }
+
+ public:
+  void invoke(methodOop method, TRAPS) const
+  {
+    entry_point()(method, (intptr_t) this, THREAD);
+  }
+
+ public:
+  static ByteSize entry_point_offset()
+  {
+    return byte_offset_of(ZeroEntry, _entry_point);
+  }
+};
--- a/ports/hotspot/src/cpu/zero/vm/interpreter_zero.cpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/interpreter_zero.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -28,6 +28,7 @@
 
 address AbstractInterpreterGenerator::generate_slow_signature_handler()
 {
+  _masm->advance(1);
   return (address) InterpreterRuntime::slow_signature_handler;
 }
 
--- a/ports/hotspot/src/cpu/zero/vm/interpreter_zero.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/cpu/zero/vm/interpreter_zero.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -24,17 +24,9 @@
  */
 
  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);
+    ((ZeroEntry *) entry_point)->invoke(method, THREAD);
   }
 
  public:
--- a/ports/hotspot/src/share/vm/includeDB_shark	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/includeDB_shark	Wed Aug 20 04:24:45 2008 -0400
@@ -56,9 +56,7 @@
 
 globals.cpp                             shark_globals.hpp
 
-interpreter.hpp                         sharkMethod.hpp
-
-methodOop.cpp                           sharkMethod.hpp
+methodOop.cpp                           sharkEntry.hpp
 
 shark_globals.cpp                       shark_globals.hpp
 
@@ -126,6 +124,7 @@
 sharkCompiler.cpp                       oopRecorder.hpp
 sharkCompiler.cpp                       shark_globals.hpp
 sharkCompiler.cpp                       sharkCompiler.hpp
+sharkCompiler.cpp                       sharkEntry.hpp
 sharkCompiler.cpp                       sharkFunction.hpp
 sharkCompiler.cpp                       sharkRuntime.hpp
 
@@ -153,12 +152,18 @@
 sharkConstantPool.hpp                   sharkBlock.hpp
 sharkConstantPool.hpp                   sharkBuilder.hpp
 
+sharkEntry.cpp                          sharkEntry.hpp
+
+sharkEntry.hpp                          llvmHeaders.hpp
+
 sharkFunction.cpp                       allocation.hpp
 sharkFunction.cpp                       ciTypeFlow.hpp
 sharkFunction.cpp                       debug.hpp
 sharkFunction.cpp                       llvmHeaders.hpp
+sharkFunction.cpp                       shark_globals.hpp
 sharkFunction.cpp                       sharkBlock.hpp
 sharkFunction.cpp                       sharkBuilder.hpp
+sharkFunction.cpp                       sharkEntry.hpp
 sharkFunction.cpp                       sharkFunction.hpp
 sharkFunction.cpp                       sharkMonitor.hpp
 sharkFunction.cpp                       sharkState.inline.hpp
@@ -170,8 +175,6 @@
 sharkFunction.hpp                       llvmHeaders.hpp
 sharkFunction.hpp                       sharkBuilder.hpp
 
-sharkMethod.hpp                         llvmHeaders.hpp
-
 sharkMonitor.cpp                        sharkMonitor.hpp
 sharkMonitor.cpp                        llvmHeaders.hpp
 
@@ -213,7 +216,7 @@
 sharkType.cpp                           globalDefinitions.hpp
 sharkType.cpp                           llvmHeaders.hpp
 sharkType.cpp                           oop.hpp
-sharkType.cpp                           sharkMethod.hpp
+sharkType.cpp                           sharkEntry.hpp
 sharkType.cpp                           sharkType.hpp
 
 sharkType.hpp                           allocation.hpp
--- a/ports/hotspot/src/share/vm/shark/sharkBlock.cpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkBlock.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -71,6 +71,10 @@
     if(UseLoopSafepoints) {
       int len;
 
+      // XXX if a lcmp is followed by an if_?? then C2 maybe-inserts
+      // the safepoint before the lcmp rather than before the if.
+      // Maybe we should do this too.  See parse2.cpp for details.
+
       switch (bc()) {
       case Bytecodes::_goto:
       case Bytecodes::_goto_w:
@@ -112,6 +116,10 @@
     case Bytecodes::_nop:
       break;
 
+    case Bytecodes::_aconst_null:
+      push(SharkValue::null());
+      break;
+
     case Bytecodes::_iconst_m1:
       push(SharkValue::jint_constant(-1));
       break;
@@ -134,6 +142,30 @@
       push(SharkValue::jint_constant(5));
       break;
 
+    case Bytecodes::_lconst_0:
+      push(SharkValue::jlong_constant(0));
+      break;
+    case Bytecodes::_lconst_1:
+      push(SharkValue::jlong_constant(1));
+      break;
+
+    case Bytecodes::_fconst_0:
+      push(SharkValue::jfloat_constant(0));
+      break;
+    case Bytecodes::_fconst_1:
+      push(SharkValue::jfloat_constant(1));
+      break;
+    case Bytecodes::_fconst_2:
+      push(SharkValue::jfloat_constant(2));
+      break;
+
+    case Bytecodes::_dconst_0:
+      push(SharkValue::jdouble_constant(0));
+      break;
+    case Bytecodes::_dconst_1:
+      push(SharkValue::jdouble_constant(1));
+      break;
+
     case Bytecodes::_bipush:
       push(SharkValue::jint_constant(iter()->get_byte()));
       break;
@@ -141,10 +173,6 @@
       push(SharkValue::jint_constant(iter()->get_short()));
       break;
 
-    case Bytecodes::_aconst_null:
-      push(SharkValue::null());
-      break;
-
     case Bytecodes::_ldc:
     case Bytecodes::_ldc_w:
     case Bytecodes::_ldc2_w:
@@ -152,72 +180,41 @@
       break;
 
     case Bytecodes::_iload_0:
+    case Bytecodes::_lload_0:
     case Bytecodes::_fload_0:
+    case Bytecodes::_dload_0:
     case Bytecodes::_aload_0:
       push(local(0));
       break;
     case Bytecodes::_iload_1:
+    case Bytecodes::_lload_1:
     case Bytecodes::_fload_1:
+    case Bytecodes::_dload_1:
     case Bytecodes::_aload_1:
       push(local(1));
       break;
     case Bytecodes::_iload_2:
+    case Bytecodes::_lload_2:
     case Bytecodes::_fload_2:
+    case Bytecodes::_dload_2:
     case Bytecodes::_aload_2:
       push(local(2));
       break;
     case Bytecodes::_iload_3:
+    case Bytecodes::_lload_3:
     case Bytecodes::_fload_3:
+    case Bytecodes::_dload_3:
     case Bytecodes::_aload_3:
       push(local(3));
       break;
     case Bytecodes::_iload:
+    case Bytecodes::_lload:
     case Bytecodes::_fload:
+    case Bytecodes::_dload:
     case Bytecodes::_aload:
       push(local(iter()->get_index()));
       break;
 
-    case Bytecodes::_istore_0:
-    case Bytecodes::_fstore_0:
-    case Bytecodes::_astore_0:
-      set_local(0, pop());
-      break;
-    case Bytecodes::_istore_1:
-    case Bytecodes::_fstore_1:
-    case Bytecodes::_astore_1:
-      set_local(1, pop());
-      break;
-    case Bytecodes::_istore_2:
-    case Bytecodes::_fstore_2:
-    case Bytecodes::_astore_2:
-      set_local(2, pop());
-      break;
-    case Bytecodes::_istore_3:
-    case Bytecodes::_fstore_3:
-    case Bytecodes::_astore_3:
-      set_local(3, pop());
-      break;
-    case Bytecodes::_istore:
-    case Bytecodes::_fstore:
-    case Bytecodes::_astore:
-      set_local(iter()->get_index(), pop());
-      break;
-
-    case Bytecodes::_pop:
-      assert(stack(0)->is_one_word(), "should be");
-      pop();
-      break;
-    case Bytecodes::_dup:
-      assert(stack(0)->is_one_word(), "should be");
-      a = pop();
-      push(a);
-      push(a);
-      break;
-
-    case Bytecodes::_arraylength:
-      do_arraylength();
-      break;
-
     case Bytecodes::_baload:
       do_aload(T_BYTE);
       break;
@@ -243,6 +240,42 @@
       do_aload(T_OBJECT);
       break;
 
+    case Bytecodes::_istore_0:
+    case Bytecodes::_lstore_0:
+    case Bytecodes::_fstore_0:
+    case Bytecodes::_dstore_0:
+    case Bytecodes::_astore_0:
+      set_local(0, pop());
+      break;
+    case Bytecodes::_istore_1:
+    case Bytecodes::_lstore_1:
+    case Bytecodes::_fstore_1:
+    case Bytecodes::_dstore_1:
+    case Bytecodes::_astore_1:
+      set_local(1, pop());
+      break;
+    case Bytecodes::_istore_2:
+    case Bytecodes::_lstore_2:
+    case Bytecodes::_fstore_2:
+    case Bytecodes::_dstore_2:
+    case Bytecodes::_astore_2:
+      set_local(2, pop());
+      break;
+    case Bytecodes::_istore_3:
+    case Bytecodes::_lstore_3:
+    case Bytecodes::_fstore_3:
+    case Bytecodes::_dstore_3:
+    case Bytecodes::_astore_3:
+      set_local(3, pop());
+      break;
+    case Bytecodes::_istore:
+    case Bytecodes::_lstore:
+    case Bytecodes::_fstore:
+    case Bytecodes::_dstore:
+    case Bytecodes::_astore:
+      set_local(iter()->get_index(), pop());
+      break;
+
     case Bytecodes::_bastore:
       do_astore(T_BYTE);
       break;
@@ -268,6 +301,137 @@
       do_astore(T_OBJECT);
       break;
 
+    case Bytecodes::_pop:
+      pop_and_assert_one_word();
+      break;
+    case Bytecodes::_pop2:
+      if (stack(0)->is_two_word()) {
+        pop_and_assert_two_word();
+      }
+      else {
+        pop_and_assert_one_word();
+        pop_and_assert_one_word();
+      }
+      break;
+    case Bytecodes::_swap: 
+      a = pop_and_assert_one_word();
+      b = pop_and_assert_one_word();
+      push(a);
+      push(b);
+      break;  
+    case Bytecodes::_dup:
+      a = pop_and_assert_one_word();
+      push(a);
+      push(a);
+      break;
+    case Bytecodes::_dup_x1: 
+      a = pop_and_assert_one_word();
+      b = pop_and_assert_one_word();
+      push(a);
+      push(b);
+      push(a);
+      break;
+    case Bytecodes::_dup_x2: 
+      if (stack(1)->is_two_word()) {
+        a = pop_and_assert_one_word();
+        b = pop_and_assert_two_word();
+        push(a);
+        push(b);
+        push(a);
+      }
+      else {
+        a = pop_and_assert_one_word();
+        b = pop_and_assert_one_word();
+        c = pop_and_assert_one_word();
+        push(a);
+        push(c);
+        push(b);
+        push(a);
+      }
+      break;
+    case Bytecodes::_dup2: 
+      if (stack(0)->is_two_word()) {
+        a = pop_and_assert_two_word();
+        push(a);
+        push(a);
+      }
+      else {
+        a = pop_and_assert_one_word();
+        b = pop_and_assert_one_word();
+        push(b);
+        push(a);
+        push(b);
+        push(a);
+      }
+      break;
+    case Bytecodes::_dup2_x1:
+      if (stack(0)->is_two_word()) {
+        a = pop_and_assert_two_word();
+        b = pop_and_assert_one_word();
+        push(a);
+        push(b);
+        push(a);
+      }
+      else {
+        a = pop_and_assert_one_word();
+        b = pop_and_assert_one_word();
+        c = pop_and_assert_one_word();
+        push(b);
+        push(a);
+        push(c);
+        push(b);
+        push(a);
+      }
+      break;
+    case Bytecodes::_dup2_x2:
+      if (stack(0)->is_one_word()) {
+        if (stack(2)->is_one_word()) {
+          a = pop_and_assert_one_word();
+          b = pop_and_assert_one_word();
+          c = pop_and_assert_one_word();
+          d = pop_and_assert_one_word();
+          push(b);
+          push(a);
+          push(d);
+          push(c);
+          push(b);
+          push(a);
+        }
+        else {
+          a = pop_and_assert_one_word();
+          b = pop_and_assert_one_word();
+          c = pop_and_assert_two_word();
+          push(b);
+          push(a);
+          push(c);
+          push(b);
+          push(a);
+        }
+      }
+      else {
+        if (stack(1)->is_one_word()) {
+          a = pop_and_assert_two_word();
+          b = pop_and_assert_one_word();
+          c = pop_and_assert_one_word();
+          push(a);
+          push(c);
+          push(b);
+          push(a);
+        }
+        else {
+          a = pop_and_assert_two_word();
+          b = pop_and_assert_two_word();
+          push(a);
+          push(b);
+          push(a);
+        }
+      }
+      break;
+
+    case Bytecodes::_arraylength:
+      do_arraylength();
+      break;
+
     case Bytecodes::_getfield:
       do_getfield();
       break;
@@ -281,28 +445,52 @@
       do_putstatic();
       break;
 
+    case Bytecodes::_iadd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateAdd(a->jint_value(), b->jint_value())));
+      break;
+    case Bytecodes::_isub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateSub(a->jint_value(), b->jint_value())));
+      break;
     case Bytecodes::_imul:
       b = pop();
       a = pop();
       push(SharkValue::create_jint(
         builder()->CreateMul(a->jint_value(), b->jint_value())));
       break;
-    case Bytecodes::_iadd:
-      b = pop();
-      a = pop();
-      push(SharkValue::create_jint(
-        builder()->CreateAdd(a->jint_value(), b->jint_value())));
+    case Bytecodes::_idiv:
+      do_idiv();
+      break;
+    case Bytecodes::_irem:
+      do_irem();
       break;
     case Bytecodes::_ineg:
       a = pop();      
       push(SharkValue::create_jint(
         builder()->CreateNeg(a->jint_value())));
       break;
-    case Bytecodes::_isub:
+    case Bytecodes::_ishl:
       b = pop();
       a = pop();
       push(SharkValue::create_jint(
-        builder()->CreateSub(a->jint_value(), b->jint_value())));
+        builder()->CreateShl(a->jint_value(), b->jint_value())));
+      break;
+    case Bytecodes::_ishr:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateAShr(a->jint_value(), b->jint_value())));
+      break;
+    case Bytecodes::_iushr:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jint(
+        builder()->CreateLShr(a->jint_value(), b->jint_value())));
       break;
     case Bytecodes::_iand:
       b = pop();
@@ -322,39 +510,152 @@
       push(SharkValue::create_jint(
         builder()->CreateXor(a->jint_value(), b->jint_value())));
       break;
-    case Bytecodes::_ishl:
+
+    case Bytecodes::_ladd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateAdd(a->jlong_value(), b->jlong_value())));
+      break;
+    case Bytecodes::_lsub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateSub(a->jlong_value(), b->jlong_value())));
+      break;
+    case Bytecodes::_lmul:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateMul(a->jlong_value(), b->jlong_value())));
+      break;
+    case Bytecodes::_ldiv:
+      do_ldiv();
+      break;
+    case Bytecodes::_lrem:
+      do_lrem();
+      break;
+    case Bytecodes::_lneg:
+      a = pop();      
+      push(SharkValue::create_jlong(
+        builder()->CreateNeg(a->jlong_value())));
+      break;
+    case Bytecodes::_lshl:
       b = pop();
       a = pop();
-      push(SharkValue::create_jint(
-        builder()->CreateShl(a->jint_value(), b->jint_value())));
+      push(SharkValue::create_jlong(
+        builder()->CreateShl(
+          a->jlong_value(),
+          builder()->CreateIntCast(
+            b->jint_value(), SharkType::jlong_type(), true))));
       break;
-    case Bytecodes::_ishr:
+    case Bytecodes::_lshr:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateAShr(
+          a->jlong_value(),
+          builder()->CreateIntCast(
+            b->jint_value(), SharkType::jlong_type(), true))));
+      break;
+    case Bytecodes::_lushr:
       b = pop();
       a = pop();
-      push(SharkValue::create_jint(
-        builder()->CreateAShr(a->jint_value(), b->jint_value())));
+      push(SharkValue::create_jlong(
+        builder()->CreateLShr(
+          a->jlong_value(),
+          builder()->CreateIntCast(
+            b->jint_value(), SharkType::jlong_type(), true))));
       break;
-    case Bytecodes::_iushr:
+    case Bytecodes::_land:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateAnd(a->jlong_value(), b->jlong_value())));
+      break;
+    case Bytecodes::_lor:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jlong(
+        builder()->CreateOr(a->jlong_value(), b->jlong_value())));
+      break;
+    case Bytecodes::_lxor:
       b = pop();
       a = pop();
-      push(SharkValue::create_jint(
-        builder()->CreateLShr(a->jint_value(), b->jint_value())));
+      push(SharkValue::create_jlong(
+        builder()->CreateXor(a->jlong_value(), b->jlong_value())));
       break;
 
-    case Bytecodes::_i2b:
-      push(SharkValue::create_jint(
-        builder()->CreateAShr(
-          builder()->CreateShl(
-            pop()->jint_value(),
-            LLVMValue::jint_constant(24)),
-          LLVMValue::jint_constant(24))));
+    case Bytecodes::_fadd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateAdd(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fsub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateSub(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fmul:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jfloat(
+        builder()->CreateMul(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fdiv:
+      b = pop();
+      a = pop();      
+      push(SharkValue::create_jfloat(
+        builder()->CreateFDiv(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_frem:
+      b = pop();
+      a = pop();      
+      push(SharkValue::create_jfloat(
+        builder()->CreateFRem(a->jfloat_value(), b->jfloat_value())));
+      break;
+    case Bytecodes::_fneg:
+      a = pop();      
+      push(SharkValue::create_jfloat(
+        builder()->CreateNeg(a->jfloat_value())));
       break;
 
-    case Bytecodes::_i2c:
-      push(SharkValue::create_jint(
-        builder()->CreateAnd(
-            pop()->jint_value(),
-            LLVMValue::jint_constant(0xffff))));
+    case Bytecodes::_dadd:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateAdd(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_dsub:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateSub(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_dmul:
+      b = pop();
+      a = pop();
+      push(SharkValue::create_jdouble(
+        builder()->CreateMul(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_ddiv:
+      b = pop();
+      a = pop();      
+      push(SharkValue::create_jdouble(
+        builder()->CreateFDiv(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_drem:
+      b = pop();
+      a = pop();      
+      push(SharkValue::create_jdouble(
+        builder()->CreateFRem(a->jdouble_value(), b->jdouble_value())));
+      break;
+    case Bytecodes::_dneg:
+      a = pop();      
+      push(SharkValue::create_jdouble(
+        builder()->CreateNeg(a->jdouble_value())));
       break;
 
     case Bytecodes::_iinc:
@@ -366,20 +667,122 @@
             LLVMValue::jint_constant(iter()->get_iinc_con()),
             local(i)->jint_value())));
       break;
-      
+
+    case Bytecodes::_lcmp:
+      do_lcmp();
+      break;
+
+    case Bytecodes::_i2l:
+      push(SharkValue::create_jlong(
+        builder()->CreateIntCast(
+          pop()->jint_value(), SharkType::jlong_type(), true)));
+      break;
+    case Bytecodes::_i2f:
+      push(SharkValue::create_jfloat(
+        builder()->CreateSIToFP(
+          pop()->jint_value(), SharkType::jfloat_type())));
+      break;
+    case Bytecodes::_i2d:
+      push(SharkValue::create_jdouble(
+        builder()->CreateSIToFP(
+          pop()->jint_value(), SharkType::jdouble_type())));
+      break;
+
+    case Bytecodes::_l2i:
+      push(SharkValue::create_jint(
+        builder()->CreateIntCast(
+          pop()->jlong_value(), SharkType::jint_type(), true)));
+      break;
+    case Bytecodes::_l2f:
+      push(SharkValue::create_jfloat(
+        builder()->CreateSIToFP(
+          pop()->jlong_value(), SharkType::jfloat_type())));
+      break;
+    case Bytecodes::_l2d:
+      push(SharkValue::create_jdouble(
+        builder()->CreateSIToFP(
+          pop()->jlong_value(), SharkType::jdouble_type())));
+      break;
+
+    case Bytecodes::_f2i:
+      push(SharkValue::create_jint(
+        builder()->CreateFPToSI(
+          pop()->jfloat_value(), SharkType::jint_type())));
+      break;
+    case Bytecodes::_f2l:
+      push(SharkValue::create_jint(
+        builder()->CreateFPToSI(
+          pop()->jfloat_value(), SharkType::jlong_type())));
+      break;
+    case Bytecodes::_f2d:
+      push(SharkValue::create_jdouble(
+        builder()->CreateFPExt(
+          pop()->jfloat_value(), SharkType::jdouble_type())));
+      break;
+
+    case Bytecodes::_d2i:
+      push(SharkValue::create_jint(
+        builder()->CreateFPToSI(
+          pop()->jdouble_value(), SharkType::jint_type())));
+      break;
+    case Bytecodes::_d2l:
+      push(SharkValue::create_jlong(
+        builder()->CreateFPToSI(
+          pop()->jdouble_value(), SharkType::jlong_type())));
+      break;
+    case Bytecodes::_d2f:
+      push(SharkValue::create_jfloat(
+        builder()->CreateFPTrunc(
+          pop()->jdouble_value(), SharkType::jfloat_type())));
+      break;
+
+    case Bytecodes::_i2b:
+      push(SharkValue::create_jint(
+        builder()->CreateAShr(
+          builder()->CreateShl(
+            pop()->jint_value(),
+            LLVMValue::jint_constant(24)),
+          LLVMValue::jint_constant(24))));
+      break;
+    case Bytecodes::_i2c:
+      push(SharkValue::create_jint(
+        builder()->CreateAnd(
+            pop()->jint_value(),
+            LLVMValue::jint_constant(0xffff))));
+      break;
+    case Bytecodes::_i2s:
+      push(SharkValue::create_jint(
+        builder()->CreateAShr(
+          builder()->CreateShl(
+            pop()->jint_value(),
+            LLVMValue::jint_constant(16)),
+          LLVMValue::jint_constant(16))));
+      break;
+
     case Bytecodes::_return:
       do_return(T_VOID);
       break;
     case Bytecodes::_ireturn:
       do_return(T_INT);
       break;
+    case Bytecodes::_lreturn:
+      do_return(T_LONG);
+      break;
     case Bytecodes::_freturn:
       do_return(T_FLOAT);
       break;
+    case Bytecodes::_dreturn:
+      do_return(T_DOUBLE);
+      break;
     case Bytecodes::_areturn:
       do_return(T_OBJECT);
       break;
 
+    case Bytecodes::_athrow:
+      builder()->CreateUnimplemented(__FILE__, __LINE__);
+      builder()->CreateUnreachable();
+      break;
+
     case Bytecodes::_goto:
     case Bytecodes::_goto_w:
       builder()->CreateBr(successor(ciTypeFlow::GOTO_TARGET)->entry_block());
@@ -453,6 +856,9 @@
     case Bytecodes::_new:
       do_new();
       break;
+    case Bytecodes::_newarray:
+      do_newarray();
+      break;
 
     case Bytecodes::_monitorenter:
       do_monitorenter();
@@ -467,10 +873,12 @@
         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;
+        record_method_not_compilable(buf);
       }
     }
+
+    if (failing())
+      return;
   }
 
   if (falls_through()) {
@@ -492,25 +900,42 @@
   ShouldNotReachHere();
 }
 
-void SharkBlock::check_null(SharkValue *object)
+void SharkBlock::check_zero(SharkValue *value)
 {
-  if (object->null_checked())
+  if (value->zero_checked())
     return;
 
-  BasicBlock *null     = function()->CreateBlock("null");
-  BasicBlock *not_null = function()->CreateBlock("not_null");
+  BasicBlock *zero     = function()->CreateBlock("zero");
+  BasicBlock *not_zero = function()->CreateBlock("not_zero");
 
-  builder()->CreateCondBr(
-    builder()->CreateICmpEQ(object->jobject_value(), LLVMValue::null()),
-    null, not_null);
+  Value *a, *b;
+  switch (value->basic_type()) {
+  case T_INT:
+    a = value->jint_value();
+    b = LLVMValue::jint_constant(0);
+    break;
+  case T_LONG:
+    a = value->jlong_value();
+    b = LLVMValue::jlong_constant(0);
+    break;
+  case T_OBJECT:
+  case T_ARRAY:
+    a = value->jobject_value();
+    b = LLVMValue::LLVMValue::null();
+    break;
+  default:
+    ShouldNotReachHere();
+  }
 
-  builder()->SetInsertPoint(null);
+  builder()->CreateCondBr(builder()->CreateICmpNE(a, b), not_zero, zero);
+
+  builder()->SetInsertPoint(zero);
   builder()->CreateUnimplemented(__FILE__, __LINE__);
   builder()->CreateUnreachable();
 
-  builder()->SetInsertPoint(not_null);
+  builder()->SetInsertPoint(not_zero);
 
-  object->set_null_checked(true);
+  value->set_zero_checked(true);
 }
 
 void SharkBlock::check_bounds(SharkValue* array, SharkValue* index)
@@ -683,8 +1108,9 @@
   check_null(array);
   check_bounds(array, index);
 
-  Value *value = builder()->CreateArrayLoad(
-    array->jarray_value(), basic_type, index->jint_value());
+  Value *value = builder()->CreateLoad(
+    builder()->CreateArrayAddress(
+      array->jarray_value(), basic_type, index->jint_value()));
 
   const Type *stack_type = SharkType::to_stackType(basic_type);
   if (value->getType() != stack_type)
@@ -699,6 +1125,18 @@
     push(SharkValue::create_jint(value));
     break;
 
+  case T_LONG:
+    push(SharkValue::create_jlong(value));
+    break;
+
+  case T_FLOAT:
+    push(SharkValue::create_jfloat(value));
+    break;
+
+  case T_DOUBLE:
+    push(SharkValue::create_jdouble(value));
+    break;
+    
   case T_OBJECT:
     push(SharkValue::create_jobject(value));
     break;
@@ -735,8 +1173,17 @@
     value = svalue->jlong_value();
     break;
 
+  case T_FLOAT:
+    value = svalue->jfloat_value();
+    break;
+
+  case T_DOUBLE:
+    value = svalue->jdouble_value();
+    break;
+
   case T_OBJECT:
     value = svalue->jobject_value();
+    // XXX assignability check
     break;
 
   default:
@@ -748,9 +1195,80 @@
   if (value->getType() != array_type)
     value = builder()->CreateIntCast(value, array_type, basic_type != T_CHAR);
 
-  builder()->CreateArrayStore(
-    array->jarray_value(), basic_type,
-    index->jint_value(), value);
+  Value *addr = builder()->CreateArrayAddress(
+    array->jarray_value(), basic_type, index->jint_value(), "addr");
+
+  builder()->CreateStore(value, addr);
+
+  if (!element_type->is_primitive_type())
+    builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr);
+}
+
+void SharkBlock::do_div_or_rem(bool is_long, bool is_rem)
+{
+  SharkValue *sb = pop();
+  SharkValue *sa = pop();
+
+  check_divide_by_zero(sb);
+
+  Value *a, *b, *p, *q;
+  if (is_long) {
+    a = sa->jlong_value();
+    b = sb->jlong_value();
+    p = LLVMValue::jlong_constant(0x8000000000000000LL);
+    q = LLVMValue::jlong_constant(-1);
+  }
+  else {
+    a = sa->jint_value();
+    b = sb->jint_value();
+    p = LLVMValue::jint_constant(0x80000000);
+    q = LLVMValue::jint_constant(-1);
+  }
+
+  BasicBlock *special_case = function()->CreateBlock("special_case");
+  BasicBlock *general_case = function()->CreateBlock("general_case");
+  BasicBlock *done         = function()->CreateBlock("done");
+
+  builder()->CreateCondBr(
+    builder()->CreateAnd(
+      builder()->CreateICmpEQ(a, p),
+      builder()->CreateICmpEQ(b, q)),
+    special_case, general_case);
+  
+  builder()->SetInsertPoint(special_case);
+  Value *special_result;
+  if (is_rem) {
+    if (is_long)
+      special_result = LLVMValue::jlong_constant(0);
+    else
+      special_result = LLVMValue::jint_constant(0);
+  }
+  else {
+    special_result = a;
+  }
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(general_case);
+  Value *general_result;
+  if (is_rem)
+    general_result = builder()->CreateSRem(a, b);
+  else
+    general_result = builder()->CreateSDiv(a, b);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  PHINode *result;
+  if (is_long)
+    result = builder()->CreatePHI(SharkType::jlong_type(), "result");
+  else
+    result = builder()->CreatePHI(SharkType::jint_type(), "result");
+  result->addIncoming(special_result, special_case);
+  result->addIncoming(general_result, general_case);
+
+  if (is_long)
+    push(SharkValue::create_jlong(result));
+  else
+    push(SharkValue::create_jint(result));
 }
 
 void SharkBlock::do_field_access(bool is_get, bool is_field)
@@ -796,7 +1314,7 @@
     Value *addr = builder()->CreateAddressOfStructEntry(
       object, in_ByteSize(field->offset_in_bytes()),
       PointerType::getUnqual(field_type),
-      "field");
+      "addr");
   
     // Do the access
     if (is_get) {
@@ -820,8 +1338,12 @@
       if (!field->type()->is_primitive_type())
         builder()->CreateUpdateBarrierSet(oopDesc::bs(), addr);
 
-      if (field->is_volatile())
+      if (field->is_volatile()) {
         builder()->CreateMemoryBarrier(SharkBuilder::BARRIER_STORELOAD);
+#ifdef PPC
+        record_method_not_compilable("Missing memory barrier");
+#endif // PPC
+      }
     }
   }
 
@@ -830,12 +1352,43 @@
     push(value);
 }
 
+void SharkBlock::do_lcmp()
+{
+  Value *b = pop()->jlong_value();
+  Value *a = pop()->jlong_value();
+
+  BasicBlock *ne   = function()->CreateBlock("lcmp_ne");
+  BasicBlock *lt   = function()->CreateBlock("lcmp_lt");
+  BasicBlock *gt   = function()->CreateBlock("lcmp_gt");
+  BasicBlock *done = function()->CreateBlock("done");
+
+  BasicBlock *eq = builder()->GetInsertBlock();
+  builder()->CreateCondBr(builder()->CreateICmpEQ(a, b), done, ne);
+
+  builder()->SetInsertPoint(ne);
+  builder()->CreateCondBr(builder()->CreateICmpSLT(a, b), lt, gt);
+
+  builder()->SetInsertPoint(lt);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(gt);
+  builder()->CreateBr(done);
+
+  builder()->SetInsertPoint(done);
+  PHINode *result = builder()->CreatePHI(SharkType::jint_type(), "result");
+  result->addIncoming(LLVMValue::jint_constant(-1), lt);
+  result->addIncoming(LLVMValue::jint_constant(0),  eq);
+  result->addIncoming(LLVMValue::jint_constant(1),  gt);
+
+  push(SharkValue::create_jint(result));
+}
+
 void SharkBlock::do_return(BasicType basic_type)
 {
   add_safepoint();
 
   if (target()->is_synchronized())
-    monitor(0)->release();
+    function()->monitor(0)->release();
 
   Value *result_addr = function()->CreatePopFrame(type2size[basic_type]);
   if (basic_type != T_VOID) {
@@ -964,12 +1517,13 @@
       SharkType::intptr_type(),
       "index");
 
-    Value *nonfinal_callee = builder()->CreateArrayLoad(
-      klass,
-      SharkType::methodOop_type(),
-      vtableEntry::size() * wordSize,
-      in_ByteSize(instanceKlass::vtable_start_offset() * wordSize),
-      index,
+    Value *nonfinal_callee = builder()->CreateLoad(
+      builder()->CreateArrayAddress(
+        klass,
+        SharkType::methodOop_type(),
+        vtableEntry::size() * wordSize,
+        in_ByteSize(instanceKlass::vtable_start_offset() * wordSize),
+        index),
       "nonfinal_callee");
     builder()->CreateBr(invoke);
 
@@ -1131,66 +1685,23 @@
       "callee");
   }
 
-  Value *entry_point = builder()->CreateValueOfStructEntry(
-    callee, methodOopDesc::from_interpreted_offset(), // XXX hacky
-    PointerType::getUnqual(SharkType::interpreter_entry_type()),
-    "entry_point");
-
-  // Decache for the call
-  current_state()->decache(method);
-
-  // 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(
+  Value *base_pc = 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(
+  Value *entry_point = builder()->CreateLoad(
     builder()->CreateIntToPtr(
       builder()->CreateAdd(
         base_pc,
-        LLVMValue::intptr_constant(
-          in_bytes(SharkMethod::entry_point_offset()))),
+        LLVMValue::intptr_constant(in_bytes(ZeroEntry::entry_point_offset()))),
       PointerType::getUnqual(
-        PointerType::getUnqual(SharkType::shark_entry_type()))),
-    "shark_entry_point");
+        PointerType::getUnqual(SharkType::entry_point_type()))),
+    "entry_point");
 
-  builder()->CreateCall3(shark_entry_point, callee, base_pc, thread());
-  builder()->CreateBr(post_call);
-
-  // Recache state
-  builder()->SetInsertPoint(post_call); 
+  // Make the call
+  current_state()->decache(method);
+  builder()->CreateCall3(entry_point, callee, base_pc, thread());
   current_state()->cache(method);
 
   // Check for pending exceptions
@@ -1438,7 +1949,7 @@
   call_vm(
     SharkRuntime::new_instance(),
     constants.object_at(iter()->get_klass_index()));
-  slow_object = function()->CreateLoadVMResult();
+  slow_object = function()->CreateGetVMResult();
   got_slow = builder()->GetInsertBlock();
 
   // Push the object
@@ -1457,17 +1968,115 @@
     object = slow_object;
   }
 
-  push(SharkValue::create_jobject(object));
+  SharkValue *result = SharkValue::create_jobject(object);
+  result->set_zero_checked(true);
+  push(result);
+}
+
+void SharkBlock::do_newarray()
+{
+  BasicType type = (BasicType) iter()->get_index();
+
+  call_vm(
+    SharkRuntime::newarray(),
+    LLVMValue::jint_constant(type),
+    pop()->jint_value());
+
+  SharkValue *result = SharkValue::create_generic(
+    ciArrayKlass::make(ciType::make(type)),
+    function()->CreateGetVMResult());
+  result->set_zero_checked(true);
+  push(result);
 }
 
 void SharkBlock::do_monitorenter()
 {
   SharkValue *lockee = pop();
-  builder()->CreateUnimplemented(__FILE__, __LINE__);
+  check_null(lockee);
+  Value *object = lockee->jobject_value();
+
+  // Find a free monitor, or one already allocated for this object
+  BasicBlock *loop_top    = function()->CreateBlock("loop_top");
+  BasicBlock *loop_iter   = function()->CreateBlock("loop_iter");
+  BasicBlock *loop_check  = function()->CreateBlock("loop_check");
+  BasicBlock *no_monitor  = function()->CreateBlock("no_monitor");
+  BasicBlock *got_monitor = function()->CreateBlock("got_monitor");
+
+  BasicBlock *entry_block = builder()->GetInsertBlock();
+  builder()->CreateBr(loop_check);
+
+  builder()->SetInsertPoint(loop_check);
+  PHINode *index = builder()->CreatePHI(SharkType::jint_type(), "index");
+  index->addIncoming(
+    LLVMValue::jint_constant(function()->monitor_count() - 1), entry_block);
+  builder()->CreateCondBr(
+    builder()->CreateICmpUGE(index, LLVMValue::jint_constant(0)),
+    loop_top, no_monitor);
+
+  builder()->SetInsertPoint(loop_top);
+  SharkMonitor* monitor = function()->monitor(index);
+  Value *smo = monitor->object();
+  builder()->CreateCondBr(
+    builder()->CreateOr(
+      builder()->CreateICmpEQ(smo, LLVMValue::null()),
+      builder()->CreateICmpEQ(smo, object)),
+    got_monitor, loop_iter);
+
+  builder()->SetInsertPoint(loop_iter);
+  index->addIncoming(
+    builder()->CreateSub(index, LLVMValue::jint_constant(1)), loop_iter);
+  builder()->CreateBr(loop_check);
+
+  builder()->SetInsertPoint(no_monitor);
+  builder()->CreateShouldNotReachHere(__FILE__, __LINE__);
+  builder()->CreateUnreachable();
+
+  // Acquire the lock
+  builder()->SetInsertPoint(got_monitor);
+  monitor->acquire(object);
 }
 
 void SharkBlock::do_monitorexit()
 {
   SharkValue *lockee = pop();
-  builder()->CreateUnimplemented(__FILE__, __LINE__);
+  check_null(lockee);
+  Value *object = lockee->jobject_value();
+
+  // Find the monitor associated with this object
+  BasicBlock *loop_top    = function()->CreateBlock("loop_top");
+  BasicBlock *loop_iter   = function()->CreateBlock("loop_iter");
+  BasicBlock *loop_check  = function()->CreateBlock("loop_check");
+  BasicBlock *no_monitor  = function()->CreateBlock("no_monitor");
+  BasicBlock *got_monitor = function()->CreateBlock("got_monitor");
+
+  BasicBlock *entry_block = builder()->GetInsertBlock();
+  builder()->CreateBr(loop_check);
+
+  builder()->SetInsertPoint(loop_check);
+  PHINode *index = builder()->CreatePHI(SharkType::jint_type(), "index");
+  index->addIncoming(
+    LLVMValue::jint_constant(function()->monitor_count() - 1), entry_block);
+  builder()->CreateCondBr(
+    builder()->CreateICmpUGE(index, LLVMValue::jint_constant(0)),
+    loop_top, no_monitor);
+
+  builder()->SetInsertPoint(loop_top);
+  SharkMonitor* monitor = function()->monitor(index);
+  Value *smo = monitor->object();
+  builder()->CreateCondBr(
+    builder()->CreateICmpEQ(smo, object),
+    got_monitor, loop_iter);
+
+  builder()->SetInsertPoint(loop_iter);
+  index->addIncoming(
+    builder()->CreateSub(index, LLVMValue::jint_constant(1)), loop_iter);
+  builder()->CreateBr(loop_check);
+
+  builder()->SetInsertPoint(no_monitor);
+  builder()->CreateShouldNotReachHere(__FILE__, __LINE__);
+  builder()->CreateUnreachable();
+
+  // Release the lock
+  builder()->SetInsertPoint(got_monitor);
+  monitor->release();
 }
--- a/ports/hotspot/src/share/vm/shark/sharkBlock.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkBlock.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -61,9 +61,13 @@
   {
     return function()->builder();
   }
-  SharkMonitor* monitor(int index) const
+  bool failing() const
   {
-    return function()->monitor(index);
+    return function()->failing();
+  }
+  void record_method_not_compilable(const char* reason) const
+  {
+    function()->record_method_not_compilable(reason);
   }
   ciMethod* target() const
   {
@@ -100,10 +104,6 @@
   {
     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);
@@ -237,6 +237,21 @@
     return current_state()->stack(slot);
   }  
 
+  // Handy macros for the various pop, swap and dup bytecodes
+ private:
+  SharkValue* pop_and_assert_one_word()
+  {
+    SharkValue* result = pop();
+    assert(result->is_one_word(), "should be");
+    return result;
+  }
+  SharkValue* pop_and_assert_two_word()
+  {
+    SharkValue* result = pop();
+    assert(result->is_two_word(), "should be");
+    return result;
+  }
+
   // VM calls
  private:
   llvm::CallInst* call_vm_base(llvm::Constant* callee,
@@ -244,13 +259,21 @@
                                llvm::Value**   args_end);
 
  public:
-  llvm::CallInst* call_vm(llvm::Constant* callee, llvm::Value* arg1)
+  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 *args[] = {thread(), arg1, arg2};
+    return call_vm_base(callee, args, args + 3);
+  }
+  llvm::CallInst* call_vm(llvm::Constant* callee,
+                          llvm::Value*    arg1,
                           llvm::Value*    arg2,
                           llvm::Value*    arg3)
   {
@@ -264,7 +287,15 @@
 
   // Error checking
  private:
-  void check_null(SharkValue* value);
+  void check_null(SharkValue* object)
+  {
+    check_zero(object);
+  }
+  void check_divide_by_zero(SharkValue* value)
+  {
+    check_zero(value);
+  }
+  void check_zero(SharkValue* value);
   void check_bounds(SharkValue* array, SharkValue* index);
   void check_pending_exception();
   
@@ -272,20 +303,40 @@
  private:
   void add_safepoint();
 
-  // _ldc* bytecodes
+  // ldc*
  private:
   void do_ldc();
 
-  // _arraylength bytecode
+  // arraylength
  private:
   void do_arraylength();
 
-  // _*aload and *astore bytecodes
+  // *aload and *astore
  private:
   void do_aload(BasicType basic_type);
   void do_astore(BasicType basic_type);
 
-  // _get* and _put* bytecodes
+  // *div and *rem
+ private:
+  void do_idiv()
+  {
+    do_div_or_rem(false, false);
+  }
+  void do_irem()
+  {
+    do_div_or_rem(false, true);
+  }
+  void do_ldiv()
+  {
+    do_div_or_rem(true, false);
+  }
+  void do_lrem()
+  {
+    do_div_or_rem(true, true);
+  }
+  void do_div_or_rem(bool is_long, bool is_rem);
+  
+  // get* and put*
  private:
   void do_getstatic()
   {
@@ -305,31 +356,36 @@
   }
   void do_field_access(bool is_get, bool is_field);
 
-  // _*return bytecodes
+  // lcmp
+ private:
+  void do_lcmp();
+
+  // *return
  private:
   void do_return(BasicType basic_type);
 
-  // _if* bytecodes
+  // if*
  private:
   void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a);
 
-  // _*switch bytecodes
+  // *switch
  private:
   void do_tableswitch();
 
-  // _invoke* bytecodes
+  // invoke*
  private:
   void do_call();
 
-  // _checkcast and _instanceof
+  // checkcast and instanceof
  private:
   void do_instance_check();
 
-  // _new
+  // new and newarray
  private:
   void do_new();
+  void do_newarray();
 
-  // _monitorenter and monitorexit
+  // monitorenter and monitorexit
  private:
   void do_monitorenter();
   void do_monitorexit();
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -97,7 +97,7 @@
 Function *SharkBuilder::CreateFunction()
 {
   Function *function = Function::Create(
-      SharkType::shark_entry_type(),
+      SharkType::entry_point_type(),
       GlobalVariable::InternalLinkage,
       "func");
   module()->getFunctionList().push_back(function);
--- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -74,7 +74,7 @@
       SharkType::jint_type(), "length");
   }
 
-  llvm::LoadInst* CreateArrayLoad(llvm::Value*      arrayoop,
+  llvm::Value* CreateArrayAddress(llvm::Value*      arrayoop,
                                   const llvm::Type* element_type,
                                   int               element_bytes,
                                   ByteSize          base_offset,
@@ -82,77 +82,43 @@
                                   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);
+    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)),
+    return CreateIntToPtr(
+      CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset),
+      llvm::PointerType::getUnqual(element_type),
       name);
   }
 
-  llvm::LoadInst* CreateArrayLoad(llvm::Value* arrayoop,
+  llvm::Value* CreateArrayAddress(llvm::Value* arrayoop,
                                   BasicType    basic_type,
                                   ByteSize     base_offset,
                                   llvm::Value* index,
                                   const char*  name = "")
   {
-    return CreateArrayLoad(
+    return CreateArrayAddress(
       arrayoop,
       SharkType::to_arrayType(basic_type),
       type2aelembytes[basic_type],
       base_offset, index, name);
   }
 
-  llvm::StoreInst* CreateArrayStore(llvm::Value* arrayoop,
-                                    BasicType    basic_type,
-                                    ByteSize     base_offset,
-                                    llvm::Value* index,
-                                    llvm::Value* value)
-  {
-    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 CreateStore(
-      value,
-      CreateIntToPtr(
-        CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset),
-        llvm::PointerType::getUnqual(array_type)));
-  }
-
-  llvm::LoadInst* CreateArrayLoad(llvm::Value* arrayoop,
+  llvm::Value* CreateArrayAddress(llvm::Value* arrayoop,
                                   BasicType    basic_type,
                                   llvm::Value* index,
                                   const char*  name = "")
   {
-    return CreateArrayLoad(
+    return CreateArrayAddress(
       arrayoop, basic_type,
       in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)),
       index, name);
   }
 
-  llvm::StoreInst* CreateArrayStore(llvm::Value* arrayoop,
-                                    BasicType    basic_type,
-                                    llvm::Value* index,
-                                    llvm::Value* value)
-  {
-    return CreateArrayStore(
-      arrayoop, basic_type,
-      in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)),
-      index, value);
-  }
-
   // Helper for making function pointers
  public:
   llvm::Constant* make_function(intptr_t                  addr,
--- a/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -48,14 +48,9 @@
   assert(entry_bci == InvocationEntryBci, "OSR is not supported");
 
   ResourceMark rm;
+  const char *name = methodname(target);
 
-  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++;
@@ -70,7 +65,7 @@
 #endif // !PRODUCT
 
   if (SharkOnlyCompile != NULL) {
-    if (!method_matches(SharkOnlyCompile, method_klass, method_name)) {
+    if (strcmp(SharkOnlyCompile, name)) {
       env->record_method_not_compilable("does not match SharkOnlyCompile");
       return;
     }
@@ -81,43 +76,23 @@
   if (env->failing())
     return;
   if (SharkPrintTypeflowOf != NULL) {
-    if (method_matches(SharkPrintTypeflowOf, method_klass, method_name))
+    if (!strcmp(SharkPrintTypeflowOf, name))
       flow->print_on(tty);
   }
 
   // Create the CodeBuffer and OopMapSet
   BufferBlob *bb = BufferBlob::create(
-    "shark_temp", sizeof(SharkMethod) + target->code_size());
+    "shark_temp", sizeof(SharkEntry) + target->code_size());
   CodeBuffer cb(bb->instructions_begin(), bb->instructions_size());
   OopMapSet oopmaps;
 
-  // Compile the method
+  // Compile the method into the CodeBuffer
   ciBytecodeStream iter(target);
-  SharkFunction function(builder(), flow, &iter, &cb, &oopmaps);
+  SharkFunction function(builder(), name, flow, &iter, &cb, &oopmaps);
   if (env->failing())
     return;
-  if (SharkPrintBitcodeOf != NULL) {
-    if (method_matches(SharkPrintBitcodeOf, method_klass, method_name))
-      function.function()->dump();
-  }
-  if (SharkTraceInstalls) {
-    uint32_t *start = NULL;
-    uint32_t *limit = NULL;
-#ifdef PPC
-    start = *(uint32_t **) bb->instructions_begin();
-    limit = start;
-    while (*limit)
-      limit++;
-#else
-    Unimplemented();
-#endif // PPC
 
-    tty->print_cr(
-      "Installing method %s::%s at [%p-%p)",
-      method_klass, method_name, start, limit);
-  }
-
-  // Install the method
+  // Install the method into the VM
   install_method(env, target, entry_bci, &cb, &oopmaps);
 }
 
@@ -166,52 +141,26 @@
                        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();
-}
+  const char *klassname = target->holder()->name()->as_utf8();
+  const char *methodname = 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;
-  }
+  char *buf = NEW_RESOURCE_ARRAY(
+    char, strlen(klassname) + 2 + strlen(methodname) + 1);
 
-  if (pattern[0] != ':' && pattern[1] != ':')
-    return false;
-  pattern += 2;
-
-  if (pattern[0] == '*') {
-    pattern++;
+  char *dst = buf;
+  for (const char *c = klassname; *c; c++) {
+    if (*c == '/')
+      *(dst++) = '.';
+    else
+      *(dst++) = *c;
   }
-  else {
-    int len = strlen(methodname);
-    if (strncmp(pattern, methodname, len))
-      return false;
-    pattern += len;
+  *(dst++) = ':';
+  *(dst++) = ':';
+  for (const char *c = methodname; *c; c++) {
+    *(dst++) = *c;
   }
-
-  return pattern[0] == '\0';
+  *(dst++) = '\0';
+  return buf;
 }
-#endif // !PRODUCT
--- a/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkCompiler.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -57,7 +57,7 @@
     return &_builder;
   }
 
-  // Method installation helper
+  // Helpers
  private:
   void install_method(ciEnv*          env,
                       ciMethod*       target,
@@ -65,12 +65,5 @@
                       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;
+  static const char *methodname(const ciMethod* target);
 };
--- a/ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -66,16 +66,18 @@
 
 Value *SharkConstantPool::object_at(int which)
 {
-  return builder()->CreateArrayLoad(
-    constants(),
-    T_OBJECT, in_ByteSize(sizeof(constantPoolOopDesc)),
-    LLVMValue::jint_constant(which));
+  return builder()->CreateLoad(
+    builder()->CreateArrayAddress(
+      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));
+  return builder()->CreateLoad(
+    builder()->CreateArrayAddress(
+      tags(), T_BYTE, LLVMValue::jint_constant(which)));
 }
 
 Value *SharkConstantPool::cache_entry_at(int which)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkEntry.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -0,0 +1,136 @@
+/*
+ * 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/_sharkEntry.cpp.incl"
+
+#ifndef PRODUCT
+void SharkEntry::print_statistics(const char* name) const
+{
+  address start = code_start();
+  address limit = code_limit();
+
+  ttyLocker ttyl;
+  tty->print(" [%p-%p): %s (%d bytes code", start, limit, name, limit - start);
+  print_pd_statistics(start, limit);
+  tty->print_cr(")");
+}
+
+// Lots of the stuff down here is machine- and LLVM-specific.
+// It's only debug stuff though, and none of it's critical.
+
+address SharkEntry::code_start() const
+{
+  return (address) entry_point();
+}
+
+address SharkEntry::code_limit() const
+{
+#ifdef PPC
+  // LLVM seems to insert three junk instructions and a null after
+  // every function.  Only the first junk instruction seems to be
+  // kept after the next function is generated, however, so this
+  // method will only work before you generate another function.
+  // I wish there was a nicer way to do this, but that's life...
+  uint32_t *limit = (uint32_t *) code_start();
+  while (*limit)
+    limit++;
+  assert(limit[-1] == 0xd143cfec && limit[-2] == 0xd143cfec, "should be");
+  limit -= 3;
+  return (address) limit;
+#else
+  Unimplemented();
+#endif // PPC
+}
+
+void SharkEntry::print_pd_statistics(address start, address limit) const
+{
+#ifdef PPC
+  uint32_t *pc = (uint32_t *) start;
+  uint32_t instr;
+
+  // Walk over the bit that allocates the frame
+  instr = *(pc++);
+  assert (instr == 0x7c0802a6, "expecting 'mflr r0'");
+
+  instr = *(pc++);
+  assert (instr == NOT_LP64(0x90010004) LP64_ONLY(0xf8010004),
+          "expecting st" NOT_LP64("w") LP64_ONLY("d") " r0,4(r1)");
+
+  instr = *(pc++);
+  assert ((instr & 0xffff8001) == NOT_LP64(0x94218000) LP64_ONLY(0xf8218001),
+          "expecting st" NOT_LP64("w") LP64_ONLY("d") "u r1,-X(r1)");
+  int frame_size = -((instr | 0xffff0000) LP64_ONLY(& 0xfffffffc));
+  tty->print(", %d bytes stack", frame_size);
+
+  // Walk over the bit that stores the non-volatile registers
+  int first_reg = -1;
+  int next_slot = frame_size - wordSize;
+  int last_reg = -1;
+  while (pc < (uint32_t *) limit) {
+    instr = *(pc++);
+
+    // The opcode should be stw/std
+    int opcode = instr >> 26;
+    if (opcode != NOT_LP64(36) LP64_ONLY(62))
+      break;
+
+    // The destination should be next_slot(r1)
+    int ra = (instr & 0x001f0000) >> 16;
+    if (ra != 1)
+      break;
+
+    int ds = instr & 0x0000ffff;
+    if (ds != next_slot)
+      break;
+    next_slot -= wordSize;
+
+    // The source should be the next register after last_reg
+    int rs = (instr & 0x03e00000) >> 21;
+    if (first_reg == -1) {
+      assert(rs >= 13, "storing a non-volatile register?");
+      first_reg = last_reg = rs;
+    }
+    else {
+      assert(rs == last_reg + 1, "register stores out of order?");
+      last_reg = rs;
+    }
+  }
+
+  if (first_reg == -1) {
+    tty->print(", 0 registers");
+  }
+  else {
+    int num_registers = last_reg - first_reg + 1;
+    if (num_registers == 1)
+      tty->print(", 1 register");
+    else
+      tty->print(", %d registers", num_registers);
+    if (num_registers >= 19)
+      tty->print("!");
+  }
+#endif // PPC
+}
+#endif // !PRODUCT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ports/hotspot/src/share/vm/shark/sharkEntry.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -0,0 +1,55 @@
+/*
+ * 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 SharkEntry : public ZeroEntry {
+ private:
+  llvm::Function* _llvm_function;
+
+ public:
+  llvm::Function* llvm_function() const
+  {
+    return _llvm_function;
+  }
+  void set_llvm_function(llvm::Function* llvm_function)
+  {
+    _llvm_function = llvm_function;
+  }
+
+ public:
+  static ByteSize llvm_function_offset()
+  {
+    return byte_offset_of(SharkEntry, _llvm_function);
+  }
+
+ public:
+  void print_statistics(const char* name) const PRODUCT_RETURN;
+
+#ifndef PRODUCT
+ private:
+  address code_start() const;
+  address code_limit() const;
+  void print_pd_statistics(address start, address limit) const;
+#endif // !PRODUCT
+};
--- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -30,24 +30,17 @@
 
 void SharkFunction::initialize()
 {
+  // Create the assembler and emit the entry point
+  _assembler = new MacroAssembler(cb());
+  SharkEntry *entry = (SharkEntry *) assembler()->pc();
+  assembler()->advance(sizeof(SharkEntry));
+
   // 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");
+  entry->set_llvm_function(function());
 
   // Initialize the blocks
+  set_block_insertion_point(NULL);
   _blocks = NEW_RESOURCE_ARRAY(SharkBlock*, flow()->block_count());
   for (int i = 0; i < block_count(); i++)
     _blocks[i] = new SharkBlock(this, flow()->pre_order_at(i));
@@ -66,10 +59,9 @@
   _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());
+      _monitor_count = MAX2(
+        _monitor_count, block(i)->ciblock()->monitor_count());
   }
-  if (monitor_count())
-    _monitors = NEW_RESOURCE_ARRAY(SharkMonitor*, monitor_count());
   
   // Get our arguments
   Function::arg_iterator ai = function()->arg_begin();
@@ -91,8 +83,29 @@
   if (target()->is_synchronized()) {
     Value *object;
     if (target()->is_static()) {
-      Unimplemented();
-      object = NULL;
+      Value *constants = builder()->CreateValueOfStructEntry(
+        method,
+        methodOopDesc::constants_offset(),
+        SharkType::oop_type(),
+        "constants");
+
+      Value *pool_holder = builder()->CreateValueOfStructEntry(
+        constants,
+        in_ByteSize(constantPoolOopDesc::pool_holder_offset_in_bytes()),
+        SharkType::oop_type(),
+        "pool_holder");
+
+      Value *klass_part = builder()->CreateAddressOfStructEntry(
+        pool_holder,
+        in_ByteSize(klassOopDesc::klass_part_offset_in_bytes()),
+        SharkType::klass_type(),
+        "klass_part");
+
+      object = builder()->CreateValueOfStructEntry(
+        klass_part,
+        in_ByteSize(Klass::java_mirror_offset_in_bytes()),
+        SharkType::oop_type(),
+        "java_mirror");
     }
     else {
       object = builder()->CreateLoad(
@@ -116,13 +129,25 @@
 
     block(i)->parse();
     if (failing()) {
-      delete function();
+      // XXX should delete function() here, but that breaks
+      // -XX:SharkPrintBitcodeOf.  I guess some of the things
+      // we're sharing via SharkBuilder or SharkRuntime or
+      // SharkType are being freed
       return;
     }
   }
 
+  // Dump the bitcode, if requested
+  if (SharkPrintBitcodeOf != NULL) {
+    if (!strcmp(SharkPrintBitcodeOf, name()))
+      function()->dump();
+  }
+
   // Compile to native code
-  *code = builder()->execution_engine()->getPointerToFunction(function());
+  void *code = builder()->execution_engine()->getPointerToFunction(function());
+  entry->set_entry_point((ZeroEntry::method_entry_t) code);
+  if (SharkTraceInstalls)
+    entry->print_statistics(name());
 }
 
 void SharkFunction::CreateInitZeroStack()
@@ -234,20 +259,13 @@
   if (monitor_count()) {
     _monitors_slots_offset = offset; 
 
-    Value *monitors = builder()->CreateBitCast(
+    _monitors_slots = 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();
     }
@@ -290,3 +308,15 @@
   assert(offset == frame_words + locals_words, "should do");
   return fp;
 }
+
+SharkMonitor* SharkFunction::monitor(Value *index) const
+{
+  Value *indexes[] = {
+    LLVMValue::jint_constant(0),
+    builder()->CreateSub(
+      LLVMValue::jint_constant(monitor_count() - 1), index),
+  };
+  return new SharkMonitor(
+    this,
+    builder()->CreateGEP(monitors_slots(), indexes, indexes + 2));
+}
--- a/ports/hotspot/src/share/vm/shark/sharkFunction.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkFunction.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -29,11 +29,13 @@
 class SharkFunction : public StackObj {
  public:
   SharkFunction(SharkBuilder*     builder,
+                const char*       name,
                 ciTypeFlow*       flow,
                 ciBytecodeStream* iter,
                 CodeBuffer*       cb,
                 OopMapSet*        oopmaps)
     : _builder(builder),
+      _name(name),
       _flow(flow),
       _iter(iter),
       _cb(cb),
@@ -45,11 +47,12 @@
 
  private:
   SharkBuilder*     _builder;
+  const char*       _name;
   ciTypeFlow*       _flow;
   ciBytecodeStream* _iter;
   CodeBuffer*       _cb;
   OopMapSet*        _oopmaps;
-  MacroAssembler*   _masm;
+  MacroAssembler*   _assembler;
   llvm::Function*   _function;
   SharkBlock**      _blocks;
   llvm::Value*      _base_pc;
@@ -61,6 +64,10 @@
   {
     return _builder;
   }
+  const char* name() const
+  {
+    return _name;
+  }
   ciTypeFlow* flow() const
   {
     return _flow;
@@ -77,9 +84,9 @@
   {
     return _oopmaps;
   }
-  MacroAssembler* masm() const
+  MacroAssembler* assembler() const
   {
-    return _masm;
+    return _assembler;
   }
   llvm::Function* function() const
   {
@@ -135,7 +142,7 @@
   }
   void record_method_not_compilable(const char* reason) const
   {
-    return env()->record_method_not_compilable(reason);
+    env()->record_method_not_compilable(reason);
   }
 
   // Block management
@@ -152,7 +159,7 @@
   }
 
  public:
-  llvm::BasicBlock* CreateBlock(const char* name = "")
+  llvm::BasicBlock* CreateBlock(const char* name = "") const
   {
     return llvm::BasicBlock::Create(name, function(), block_insertion_point());
   }
@@ -212,7 +219,7 @@
   llvm::Value*   _pc_slot;
   llvm::Value*   _method_slot;
   llvm::Value*   _locals_slots;
-  SharkMonitor** _monitors;
+  llvm::Value*   _monitors_slots;
   llvm::Value*   _stack_slots;
 
  public:
@@ -228,15 +235,22 @@
   {
     return _locals_slots;
   }  
-  SharkMonitor* monitor(int index) const
+  llvm::Value* monitors_slots() const
   {
-    return _monitors[index];
+    return _monitors_slots;
   }
   llvm::Value* stack_slots() const
   {
     return _stack_slots;
   }
 
+ public:
+  SharkMonitor* monitor(int index) const
+  {
+    return monitor(LLVMValue::jint_constant(index));
+  }
+  SharkMonitor* monitor(llvm::Value* index) const;
+
  private:
   llvm::Value* CreateBuildFrame();
 
@@ -244,8 +258,8 @@
  public:
   int code_offset() const
   {
-    int offset = masm()->offset();
-    masm()->emit_zero_byte(); // keeps PCs unique
+    int offset = assembler()->offset();
+    assembler()->advance(1); // keeps PCs unique
     return offset;
   }
   void add_gc_map(int offset, OopMap* oopmap)
@@ -305,11 +319,14 @@
   }
 
  public:
-  llvm::LoadInst* CreateLoadVMResult() const
+  llvm::LoadInst* CreateGetVMResult() const
   {
-    return builder()->CreateValueOfStructEntry(
+    llvm::Value *addr = builder()->CreateAddressOfStructEntry(
       thread(), JavaThread::vm_result_offset(),
-      SharkType::jobject_type(),
-      "vm_result");
+      llvm::PointerType::getUnqual(SharkType::jobject_type()),
+      "vm_result_addr");
+    llvm::LoadInst *result = builder()->CreateLoad(addr, "vm_result");
+    builder()->CreateStore(LLVMValue::null(), addr);
+    return result;
   }
 };
--- a/ports/hotspot/src/share/vm/shark/sharkMethod.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
- * Copyright 2008 Red Hat, Inc.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- *
- */
-
-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);
-  }
-};
--- a/ports/hotspot/src/share/vm/shark/sharkMonitor.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkMonitor.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -25,7 +25,7 @@
 
 class SharkMonitor : public ResourceObj {
  public:
-  SharkMonitor(SharkFunction* function, llvm::Value* monitor)
+  SharkMonitor(const SharkFunction* function, llvm::Value* monitor)
     : _function(function), _monitor(monitor)
   { initialize(); }
 
@@ -33,13 +33,13 @@
   void initialize();
 
  private:
-  SharkFunction* _function;
-  llvm::Value*   _monitor;
-  llvm::Value*   _object_addr;
-  llvm::Value*   _displaced_header_addr;
+  const SharkFunction* _function;
+  llvm::Value*         _monitor;
+  llvm::Value*         _object_addr;
+  llvm::Value*         _displaced_header_addr;
 
  private:
-  SharkFunction* function() const
+  const SharkFunction* function() const
   {
     return _function;
   }
--- a/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -28,6 +28,7 @@
 
 using namespace llvm;
 
+Constant* SharkRuntime::_newarray;
 Constant* SharkRuntime::_new_instance;
 Constant* SharkRuntime::_resolve_get_put;
 Constant* SharkRuntime::_resolve_invoke;
@@ -42,6 +43,15 @@
   // VM calls
   std::vector<const Type*> params;
   params.push_back(SharkType::thread_type());
+  params.push_back(SharkType::jint_type());
+  params.push_back(SharkType::jint_type());
+  _newarray = builder->make_function(
+    (intptr_t) newarray_C,
+    FunctionType::get(Type::VoidTy, params, false),
+    "SharkRuntime__newarray");
+
+  params.clear();
+  params.push_back(SharkType::thread_type());
   params.push_back(SharkType::jobject_type());
   _new_instance = builder->make_function(
     (intptr_t) new_instance_C,
@@ -93,6 +103,15 @@
     "report_unimplemented");
 }
 
+JRT_ENTRY(void, SharkRuntime::newarray_C(JavaThread* thread,
+                                         BasicType type,
+                                         int size))
+{
+  oop obj = oopFactory::new_typeArray(type, size, CHECK);
+  thread->set_vm_result(obj);
+}
+JRT_END
+
 JRT_ENTRY(void, SharkRuntime::new_instance_C(JavaThread* thread,
                                              klassOop klass))
 {
--- a/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -29,11 +29,16 @@
 
   // VM calls
  private:
+  static llvm::Constant* _newarray;
   static llvm::Constant* _new_instance;
   static llvm::Constant* _resolve_get_put;
   static llvm::Constant* _resolve_invoke;
 
  public:
+  static llvm::Constant* newarray()
+  {
+    return _newarray;
+  }
   static llvm::Constant* new_instance()
   {
     return _new_instance;
@@ -48,6 +53,7 @@
   }
 
  private:
+  static void newarray_C(JavaThread* thread, BasicType type, int size);
   static void new_instance_C(JavaThread* thread, klassOop klass);
   static void resolve_get_put_C(JavaThread*             thread,
                                 ConstantPoolCacheEntry* entry,
--- a/ports/hotspot/src/share/vm/shark/sharkState.cpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkState.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -67,7 +67,8 @@
           builder()->CreateLoad(
             builder()->CreateBitCast(
               builder()->CreateStructGEP(
-                function()->locals_slots(), max_locals() - 1 - i),
+                function()->locals_slots(),
+                max_locals() - type->size() - i),
               PointerType::getUnqual(SharkType::to_stackType(type))),
             name));
       }
@@ -121,28 +122,31 @@
   }
 
   // Expression stack
+  _sp = _stack;
   for (int i = 0; i < max_stack(); i++) {
-    SharkValue *value = NULL;
     if (i < block()->stack_depth_at_entry()) {
       ciType *type = block()->stack_type_at_entry(i);
       switch (type->basic_type()) {
       case ciTypeFlow::StateVector::T_TOP:
       case ciTypeFlow::StateVector::T_BOTTOM:
+      case ciTypeFlow::StateVector::T_NULL:
+        Unimplemented();
+        break;
+
       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(
+        *(_sp++) = SharkValue::create_generic(
           type, builder()->CreatePHI(SharkType::to_stackType(type), name));
       }
     }
-    _stack[i] = value;
   }
-  _sp = _stack + block()->stack_depth_at_entry();
+#ifdef ASSERT
+  _stack_depth_at_entry = stack_depth();
+#endif // ASSERT
 
   builder()->SetInsertPoint(saved_insert_point);
 }
@@ -163,9 +167,8 @@
   }
 
   // Expression stack
-  assert(block()->stack_depth_at_entry() == incoming_state->stack_depth(),
-         "should be");
-  for (int i = 0; i < block()->stack_depth_at_entry(); i++) {
+  assert(_stack_depth_at_entry == incoming_state->stack_depth(), "should be");
+  for (int i = 0; i < incoming_state->stack_depth(); i++) {
     ((PHINode *) stack(i)->generic_value())->addIncoming(
       incoming_state->stack(i)->generic_value(),
       predecessor);
--- a/ports/hotspot/src/share/vm/shark/sharkState.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkState.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -111,6 +111,11 @@
  private:
   void initialize();
 
+#ifdef ASSERT
+ private:
+  int _stack_depth_at_entry;
+#endif // ASSERT
+
  public:
   void add_incoming(SharkState* incoming_state);
 };
--- a/ports/hotspot/src/share/vm/shark/sharkType.cpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkType.cpp	Wed Aug 20 04:24:45 2008 -0400
@@ -29,13 +29,12 @@
 using namespace llvm;
 
 const PointerType*  SharkType::_cpCacheEntry_type;
-const FunctionType* SharkType::_interpreter_entry_type;
+const FunctionType* SharkType::_entry_point_type;
 const PointerType*  SharkType::_itableOffsetEntry_type;
 const PointerType*  SharkType::_klass_type;
 const PointerType*  SharkType::_methodOop_type;
 const ArrayType*    SharkType::_monitor_type;
 const PointerType*  SharkType::_oop_type;
-const FunctionType* SharkType::_shark_entry_type;
 const PointerType*  SharkType::_thread_type;
 const PointerType*  SharkType::_zeroStack_type;
 
@@ -72,14 +71,9 @@
 
   std::vector<const Type*> params;
   params.push_back(methodOop_type());
-  params.push_back(thread_type());
-  _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);
+  _entry_point_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++) {
--- a/ports/hotspot/src/share/vm/shark/sharkType.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkType.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -38,13 +38,12 @@
   // VM types
  private:
   static const llvm::PointerType*  _cpCacheEntry_type;
-  static const llvm::FunctionType* _interpreter_entry_type;
+  static const llvm::FunctionType* _entry_point_type;
   static const llvm::PointerType*  _itableOffsetEntry_type;
   static const llvm::PointerType*  _klass_type;
   static const llvm::PointerType*  _methodOop_type;
   static const llvm::ArrayType*    _monitor_type;
   static const llvm::PointerType*  _oop_type;
-  static const llvm::FunctionType* _shark_entry_type;
   static const llvm::PointerType*  _thread_type;
   static const llvm::PointerType*  _zeroStack_type;
   
@@ -53,9 +52,9 @@
   {
     return _cpCacheEntry_type;
   }
-  static const llvm::FunctionType* interpreter_entry_type()
+  static const llvm::FunctionType* entry_point_type()
   {
-    return _interpreter_entry_type;
+    return _entry_point_type;
   }
   static const llvm::PointerType* itableOffsetEntry_type()
   {
@@ -77,10 +76,6 @@
   {
     return _oop_type;
   }
-  static const llvm::FunctionType* shark_entry_type()
-  {
-    return _shark_entry_type;
-  }
   static const llvm::PointerType* thread_type()
   {
     return _thread_type;
--- a/ports/hotspot/src/share/vm/shark/sharkValue.hpp	Wed Aug 20 04:12:41 2008 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkValue.hpp	Wed Aug 20 04:24:45 2008 -0400
@@ -37,6 +37,14 @@
   {
     return llvm::ConstantInt::get(SharkType::jlong_type(), value, true);
   }
+  static llvm::ConstantFP* jfloat_constant(jfloat value)
+  {
+    return llvm::ConstantFP::get(SharkType::jfloat_type(), value);
+  }
+  static llvm::ConstantFP* jdouble_constant(jdouble value)
+  {
+    return llvm::ConstantFP::get(SharkType::jdouble_type(), value);
+  }
   static llvm::ConstantPointerNull* null()
   {
     return llvm::ConstantPointerNull::get(SharkType::jobject_type());
@@ -52,12 +60,12 @@
 class SharkValue : public ResourceObj {
  protected:
   SharkValue(ciType* type, llvm::Value* value)
-    : _type(type), _llvm_value(value), _null_checked(false) {}
+    : _type(type), _llvm_value(value), _zero_checked(false) {}
 
  private:
   ciType*      _type;
   llvm::Value* _llvm_value;
-  bool         _null_checked;
+  bool         _zero_checked;
 
  public:
   ciType* type() const
@@ -93,6 +101,14 @@
   {
     return llvm_value()->getType() == SharkType::jlong_type();
   }
+  bool is_jfloat() const
+  {
+    return llvm_value()->getType() == SharkType::jfloat_type();
+  }
+  bool is_jdouble() const
+  {
+    return llvm_value()->getType() == SharkType::jdouble_type();
+  }
   bool is_jobject() const
   {
     return llvm_value()->getType() == SharkType::jobject_type();
@@ -102,32 +118,27 @@
     return basic_type() == T_ARRAY;
   }
 
-  // Typed conversion between Shark and LLVM values
+  // Typed conversions to LLVM values
  public:
-  static SharkValue* create_jint(llvm::Value* value)
-  {
-    assert(value->getType() == SharkType::jint_type(), "should be");
-    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)
+  llvm::Value* jfloat_value() const
   {
-    assert(value->getType() == SharkType::jobject_type(), "should be");
-    return create_generic(ciType::make(T_OBJECT), value);
+    assert(is_jfloat(), "should be");
+    return llvm_value();
+  }
+  llvm::Value* jdouble_value() const
+  {
+    assert(is_jdouble(), "should be");
+    return llvm_value();
   }
   llvm::Value* jobject_value() const
   {
@@ -140,6 +151,35 @@
     return llvm_value();
   }
 
+  // Typed conversion from LLVM values
+ public:
+  static SharkValue* create_jint(llvm::Value* value)
+  {
+    assert(value->getType() == SharkType::jint_type(), "should be");
+    return create_generic(ciType::make(T_INT), value);
+  }
+  static SharkValue* create_jlong(llvm::Value* value)
+  {
+    assert(value->getType() == SharkType::jlong_type(), "should be");
+    return create_generic(ciType::make(T_LONG), value);
+  }
+  static SharkValue* create_jfloat(llvm::Value* value)
+  {
+    assert(value->getType() == SharkType::jfloat_type(), "should be");
+    return create_generic(ciType::make(T_FLOAT), value);
+  }
+  static SharkValue* create_jdouble(llvm::Value* value)
+  {
+    assert(value->getType() == SharkType::jdouble_type(), "should be");
+    return create_generic(ciType::make(T_DOUBLE), value);
+  }
+  static SharkValue* create_jobject(llvm::Value* value)
+  {
+    assert(value->getType() == SharkType::jobject_type(), "should be");
+    return create_generic(ciType::make(T_OBJECT), value);
+  }
+
+  // Typed conversion from HotSpot ciConstants
  public:
   static SharkValue* from_ciConstant(ciConstant value)
   {
@@ -162,6 +202,12 @@
     case T_LONG:
       return SharkValue::jlong_constant(value.as_long());
       
+    case T_FLOAT:
+      return SharkValue::jfloat_constant(value.as_float());
+      
+    case T_DOUBLE:
+      return SharkValue::jdouble_constant(value.as_double());
+      
     case T_OBJECT:
     case T_ARRAY:
       return NULL;
@@ -198,19 +244,27 @@
   {
     return create_jlong(LLVMValue::jlong_constant(value));
   }
+  static SharkValue* jfloat_constant(jfloat value)
+  {
+    return create_jfloat(LLVMValue::jfloat_constant(value));
+  }
+  static SharkValue* jdouble_constant(jdouble value)
+  {
+    return create_jdouble(LLVMValue::jdouble_constant(value));
+  }
   static SharkValue* null()
   {
     return create_generic(ciType::make(T_OBJECT), LLVMValue::null());
   }
 
-  // Repeated null-check removal
+  // Repeated null and divide-by-zero check removal
  public:
-  bool null_checked() const
+  bool zero_checked() const
   {
-    return _null_checked;
+    return _zero_checked;
   }
-  void set_null_checked(bool null_checked)
+  void set_zero_checked(bool zero_checked)
   {
-    _null_checked = null_checked;
+    _zero_checked = zero_checked;
   }
 };