changeset 1731:5e454391b4ce

2009-03-09 Gary Benson <gbenson@redhat.com> * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp (SharkTopLevelBlock::_trap_request): New field. (SharkTopLevelBlock::trap_request): New method. (SharkTopLevelBlock::scan_for_traps): Likewise. (SharkTopLevelBlock::has_trap): Rewritten. (SharkTopLevelBlock::trap_index): Removed method. * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp (SharkTopLevelBlock::scan_for_traps): New method. (SharkTopLevelBlock::emit_IR): s/trap_index/trap_request/. (SharkTopLevelBlock::get_virtual_callee): Removed slow case. * ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp (SharkConstantPool::cache_entry_at): Removed slow case. * ports/hotspot/src/share/vm/shark/sharkRuntime.hpp (SharkRuntime::_resolve_get_put): Removed. (SharkRuntime::_resolve_invoke): Likewise. (SharkRuntime::resolve_get_put): Likewise. (SharkRuntime::resolve_invoke): Likewise. (SharkRuntime::resolve_get_put_C): Likewise. (SharkRuntime::resolve_invoke_C): Likewise. (SharkRuntime::uncommon_trap_C): s/index/trap_request/. * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp (SharkRuntime::_resolve_get_put): Removed. (SharkRuntime::_resolve_invoke): Likewise. (SharkRuntime::initialize): Removed initialization for the above. (SharkRuntime::resolve_get_put_C): Removed. (SharkRuntime::resolve_invoke_C): Likewise. (SharkRuntime::uncommon_trap_C): s/index/trap_request/. * ports/hotspot/src/share/vm/shark/sharkBlock.cpp (SharkBlock::do_field_access): Mismatch case now handled by trap. * ports/hotspot/src/share/vm/includeDB_shark: Updated. (transplanted from a28649aea20fad5a814c3cd8d56b8ed704c7203b)
author Gary Benson <gbenson@redhat.com>
date Mon, 09 Mar 2009 10:26:08 -0400
parents 146e5d33e990
children 5caf65dd9bd3
files ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp
diffstat 2 files changed, 116 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Mon Mar 09 10:26:08 2009 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp	Mon Mar 09 10:26:08 2009 -0400
@@ -236,6 +236,99 @@
   return TRAP_NO_TRAPS;
 }
 
+int SharkTopLevelBlock::scan_for_traps()
+{
+  // If typeflow got one then we're already done
+  if (ciblock()->has_trap()) {
+    return Deoptimization::make_trap_request(
+      Deoptimization::Reason_unloaded,
+      Deoptimization::Action_reinterpret,
+      ciblock()->trap_index());
+  }
+
+  // Scan the bytecode
+  iter()->reset_to_bci(start());
+  while (iter()->next_bci() < limit()) {
+    iter()->next();
+
+    ciField *field;
+    ciMethod *method;
+    bool will_link;
+    bool is_field;
+
+    int index = -1;
+
+    switch (bc()) {
+    case Bytecodes::_getfield:
+    case Bytecodes::_getstatic:
+    case Bytecodes::_putfield:
+    case Bytecodes::_putstatic:
+      field = iter()->get_field(will_link);
+      assert(will_link, "typeflow responsibility");
+      is_field = (bc() == Bytecodes::_getfield || bc() == Bytecodes::_putfield);
+
+      // If the bytecode does not match the field then bail out to
+      // the interpreter to throw an IncompatibleClassChangeError
+      if (is_field == field->is_static()) {
+        return Deoptimization::make_trap_request(
+                 Deoptimization::Reason_unhandled,
+                 Deoptimization::Action_none);
+      }
+
+      // If this is a getfield or putfield then there won't be a
+      // pool access and we're done
+      if (is_field)
+        break;
+
+      // There won't be a pool access if this is a getstatic that
+      // resolves to a handled constant either
+      if (bc() == Bytecodes::_getstatic && field->is_constant()) {
+        if (SharkValue::from_ciConstant(field->constant_value()))
+          break;
+      }
+
+      // Continue to the check
+      index = iter()->get_field_index();
+      break;
+
+    case Bytecodes::_invokespecial:
+    case Bytecodes::_invokestatic:
+    case Bytecodes::_invokevirtual:
+    case Bytecodes::_invokeinterface:
+      method = iter()->get_method(will_link);
+      assert(will_link, "typeflow responsibility");
+
+      // If this is a non-final invokevirtual then there won't
+      // be a pool access.  We do need to check that its holder
+      // is linked, however, because its vtable won't have been
+      // set up otherwise.
+      if (bc() == Bytecodes::_invokevirtual && !method->is_final_method()) {
+        if (!method->holder()->is_linked()) {
+          return Deoptimization::make_trap_request(
+            Deoptimization::Reason_uninitialized,
+            Deoptimization::Action_reinterpret);
+        }
+        break;
+      }
+
+      // Continue to the check
+      index = iter()->get_method_index();
+      break;
+    }
+
+    // If we found a constant pool access on this bytecode then check it
+    if (index != -1) {
+      if (!target()->holder()->is_cache_entry_resolved(
+             Bytes::swap_u2(index), bc())) {
+        return Deoptimization::make_trap_request(
+          Deoptimization::Reason_uninitialized,
+          Deoptimization::Action_reinterpret);
+      }
+    }
+  }
+  return TRAP_NO_TRAPS;
+}
+
 SharkState* SharkTopLevelBlock::entry_state()
 {
   if (_entry_state == NULL) {
--- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp	Mon Mar 09 10:26:08 2009 -0400
+++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp	Mon Mar 09 10:26:08 2009 -0400
@@ -130,6 +130,29 @@
  private:
   int scan_for_traps();
 
+  // Traps
+ private:
+  enum {
+    TRAP_UNCHECKED = 232323, // > any constant pool index
+    TRAP_NO_TRAPS
+  };
+  int _trap_request;
+
+ public:
+  int trap_request()
+  {
+    if (_trap_request == TRAP_UNCHECKED)
+      _trap_request = scan_for_traps();
+    return _trap_request;
+  }
+  bool has_trap()
+  {
+    return trap_request() != TRAP_NO_TRAPS;
+  }
+
+ private:
+  int scan_for_traps();
+
   // Entry state
  private:
   bool _entered;