changeset 8580:9fd1e63eb982

8087133: Improve sharing of native wrappers in SignatureHandlerLibrary Summary: fingerprint normalization for arm32 Reviewed-by: dholmes, coleenp
author bdelsart
date Tue, 23 Jun 2015 17:48:34 +0200
parents ee8ce10986aa
children 357d0ffc7dab
files src/share/vm/interpreter/interpreterRuntime.cpp src/share/vm/interpreter/interpreterRuntime.hpp src/share/vm/runtime/signature.hpp
diffstat 3 files changed, 47 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Jun 23 11:00:32 2015 +0000
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Tue Jun 23 17:48:34 2015 +0200
@@ -26,6 +26,7 @@
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "code/codeCache.hpp"
 #include "compiler/compileBroker.hpp"
 #include "compiler/disassembler.hpp"
 #include "gc/shared/collectedHeap.hpp"
@@ -1129,6 +1130,14 @@
 
 // Implementation of SignatureHandlerLibrary
 
+#ifndef SHARING_FAST_NATIVE_FINGERPRINTS
+// Dummy definition (else normalization method is defined in CPU
+// dependant code)
+uint64_t InterpreterRuntime::normalize_fast_native_fingerprint(uint64_t fingerprint) {
+  return fingerprint;
+}
+#endif
+
 address SignatureHandlerLibrary::set_handler_blob() {
   BufferBlob* handler_blob = BufferBlob::create("native signature handlers", blob_size);
   if (handler_blob == NULL) {
@@ -1184,6 +1193,8 @@
       initialize();
       // lookup method signature's fingerprint
       uint64_t fingerprint = Fingerprinter(method).fingerprint();
+      // allow CPU dependant code to optimize the fingerprints for the fast handler
+      fingerprint = InterpreterRuntime::normalize_fast_native_fingerprint(fingerprint);
       handler_index = _fingerprints->find(fingerprint);
       // create handler if necessary
       if (handler_index < 0) {
@@ -1209,13 +1220,18 @@
                           buffer.insts_size());
             Disassembler::decode(handler, handler + buffer.insts_size());
 #ifndef PRODUCT
-            tty->print_cr(" --- associated result handler ---");
             address rh_begin = Interpreter::result_handler(method()->result_type());
-            address rh_end = rh_begin;
-            while (*(int*)rh_end != 0) {
-              rh_end += sizeof(int);
+            if (CodeCache::contains(rh_begin)) {
+              // else it might be special platform dependent values
+              tty->print_cr(" --- associated result handler ---");
+              address rh_end = rh_begin;
+              while (*(int*)rh_end != 0) {
+                rh_end += sizeof(int);
+              }
+              Disassembler::decode(rh_begin, rh_end);
+            } else {
+              tty->print_cr(" associated result handler: " PTR_FORMAT, p2i(rh_begin));
             }
-            Disassembler::decode(rh_begin, rh_end);
 #endif
           }
           // add handler to library
@@ -1227,13 +1243,13 @@
         }
       }
       // Set handler under SignatureHandlerLibrary_lock
-    if (handler_index < 0) {
-      // use generic signature handler
-      method->set_signature_handler(Interpreter::slow_signature_handler());
-    } else {
-      // set handler
-      method->set_signature_handler(_handlers->at(handler_index));
-    }
+      if (handler_index < 0) {
+        // use generic signature handler
+        method->set_signature_handler(Interpreter::slow_signature_handler());
+      } else {
+        // set handler
+        method->set_signature_handler(_handlers->at(handler_index));
+      }
     } else {
       CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops());
       // use generic signature handler
@@ -1250,9 +1266,11 @@
     // have to protect this read access here with the same mutex as well!
     MutexLocker mu(SignatureHandlerLibrary_lock);
     if (_handlers != NULL) {
-    handler_index = _handlers->find(method->signature_handler());
-    fingerprint_index = _fingerprints->find(Fingerprinter(method).fingerprint());
-  }
+      handler_index = _handlers->find(method->signature_handler());
+      uint64_t fingerprint = Fingerprinter(method).fingerprint();
+      fingerprint = InterpreterRuntime::normalize_fast_native_fingerprint(fingerprint);
+      fingerprint_index = _fingerprints->find(fingerprint);
+    }
   }
   assert(method->signature_handler() == Interpreter::slow_signature_handler() ||
          handler_index == fingerprint_index, "sanity check");
--- a/src/share/vm/interpreter/interpreterRuntime.hpp	Tue Jun 23 11:00:32 2015 +0000
+++ b/src/share/vm/interpreter/interpreterRuntime.hpp	Tue Jun 23 17:48:34 2015 +0200
@@ -183,6 +183,8 @@
 # include "interpreterRT_aarch64.hpp"
 #endif
 
+  // optional normalization of fingerprints to reduce the number of adapters
+  static uint64_t normalize_fast_native_fingerprint(uint64_t fingerprint);
 
   // Interpreter's frequency counter overflow
   static nmethod* frequency_counter_overflow(JavaThread* thread, address branch_bcp);
--- a/src/share/vm/runtime/signature.hpp	Tue Jun 23 11:00:32 2015 +0000
+++ b/src/share/vm/runtime/signature.hpp	Tue Jun 23 17:48:34 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -63,6 +63,8 @@
   // Fingerprinter.
   enum {
     static_feature_size    = 1,
+    is_static_bit          = 1,
+
     result_feature_size    = 4,
     result_feature_mask    = 0xF,
     parameter_feature_size = 4,
@@ -114,6 +116,15 @@
   // Object types (begin indexes the first character of the entry, end indexes the first character after the entry)
   virtual void do_object(int begin, int end) = 0;
   virtual void do_array (int begin, int end) = 0;
+
+  static bool is_static(uint64_t fingerprint) {
+    assert(fingerprint != (uint64_t)CONST64(-1), "invalid fingerprint");
+    return fingerprint & is_static_bit;
+  }
+  static BasicType return_type(uint64_t fingerprint) {
+    assert(fingerprint != (uint64_t)CONST64(-1), "invalid fingerprint");
+    return (BasicType) ((fingerprint >> static_feature_size) & result_feature_mask);
+  }
 };