< prev index next >

src/hotspot/share/runtime/signature.hpp

Print this page
@@ -24,10 +24,11 @@
   */
  
  #ifndef SHARE_RUNTIME_SIGNATURE_HPP
  #define SHARE_RUNTIME_SIGNATURE_HPP
  
+ #include "classfile/symbolTable.hpp"
  #include "memory/allocation.hpp"
  #include "oops/method.hpp"
  
  
  // Static routines and parsing loops for processing field and method

@@ -122,11 +123,11 @@
    }
  
    // Determine if this signature char introduces an
    // envelope, which is a class name plus ';'.
    static bool has_envelope(char signature_char) {
-     return (signature_char == JVM_SIGNATURE_CLASS);
+     return (signature_char == JVM_SIGNATURE_CLASS) || (signature_char == JVM_SIGNATURE_INLINE_TYPE);
    }
  
    // Assuming has_envelope is true, return the symbol
    // inside the envelope, by stripping 'L' and ';'.
    // Caller is responsible for decrementing the newly created

@@ -267,11 +268,12 @@
      case T_SHORT:   type_name("jshort"  ); break;
      case T_INT:     type_name("jint"    ); break;
      case T_LONG:    type_name("jlong"   ); break;
      case T_VOID:    type_name("void"    ); break;
      case T_ARRAY:
-     case T_OBJECT:  type_name("jobject" ); break;
+     case T_OBJECT:
+     case T_INLINE_TYPE:  type_name("jobject" ); break;
      default: ShouldNotReachHere();
      }
    }
  
   public:

@@ -405,10 +407,11 @@
        pass_long();   _jni_offset += jni_offset; _offset += 2;
        break;
      }
      case T_ARRAY:
      case T_OBJECT:
+     case T_INLINE_TYPE:
        pass_object(); _jni_offset++; _offset++;
        break;
      default:
        ShouldNotReachHere();
      }

@@ -518,10 +521,14 @@
      // this should always be true, but let's test it:
      assert(_signature->char_at(_end-1) == JVM_SIGNATURE_ENDCLASS, "signature envelope has no semi-colon at end");
      return true;
    }
  
+   bool has_Q_descriptor() const {
+     return has_envelope() && (_signature->char_at(_begin) == JVM_SIGNATURE_INLINE_TYPE);
+   }
+ 
    // return the symbol for chars in symbol_begin()..symbol_end()
    Symbol* as_symbol() {
      return find_symbol();
    }
  

@@ -560,14 +567,67 @@
      return skip_whole_array_prefix();
    }
  
    // free-standing lookups (bring your own CL/PD pair)
    enum FailureMode { ReturnNull, NCDFError, CachedOrNull };
+ 
    Klass* as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS);
+   InlineKlass* as_inline_klass(InstanceKlass* holder);
    oop as_java_mirror(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS);
  };
  
+ class SigEntryFilter;
+ typedef GrowableArrayFilterIterator<SigEntry, SigEntryFilter> ExtendedSignature;
+ 
+ // Used for adapter generation. One SigEntry is used per element of
+ // the signature of the method. Inline type arguments are treated
+ // specially. See comment for InlineKlass::collect_fields().
+ class SigEntry {
+  public:
+   BasicType _bt;
+   int _offset;
+   Symbol* _symbol;
+ 
+   SigEntry()
+     : _bt(T_ILLEGAL), _offset(-1), _symbol(NULL) {}
+ 
+   SigEntry(BasicType bt, int offset, Symbol* symbol)
+     : _bt(bt), _offset(offset), _symbol(symbol) {}
+ 
+   static int compare(SigEntry* e1, SigEntry* e2) {
+     if (e1->_offset != e2->_offset) {
+       return e1->_offset - e2->_offset;
+     }
+     assert((e1->_bt == T_LONG && (e2->_bt == T_LONG || e2->_bt == T_VOID)) ||
+            (e1->_bt == T_DOUBLE && (e2->_bt == T_DOUBLE || e2->_bt == T_VOID)) ||
+            e1->_bt == T_INLINE_TYPE || e2->_bt == T_INLINE_TYPE || e1->_bt == T_VOID || e2->_bt == T_VOID, "bad bt");
+     if (e1->_bt == e2->_bt) {
+       assert(e1->_bt == T_INLINE_TYPE || e1->_bt == T_VOID, "only ones with duplicate offsets");
+       return 0;
+     }
+     if (e1->_bt == T_VOID ||
+         e2->_bt == T_INLINE_TYPE) {
+       return 1;
+     }
+     if (e1->_bt == T_INLINE_TYPE ||
+         e2->_bt == T_VOID) {
+       return -1;
+     }
+     ShouldNotReachHere();
+     return 0;
+   }
+   static void add_entry(GrowableArray<SigEntry>* sig, BasicType bt, Symbol* symbol, int offset = -1);
+   static bool skip_value_delimiters(const GrowableArray<SigEntry>* sig, int i);
+   static int fill_sig_bt(const GrowableArray<SigEntry>* sig, BasicType* sig_bt);
+   static TempNewSymbol create_symbol(const GrowableArray<SigEntry>* sig);
+ };
+ 
+ class SigEntryFilter {
+ public:
+   bool operator()(const SigEntry& entry) { return entry._bt != T_INLINE_TYPE && entry._bt != T_VOID; }
+ };
+ 
  // Specialized SignatureStream: used for invoking SystemDictionary to either find
  //                              or resolve the underlying type when iterating over a
  //                              Java descriptor (or parts of it).
  class ResolvingSignatureStream : public SignatureStream {
    Klass*       _load_origin;

@@ -635,15 +695,15 @@
        callback->do_type(type);
      }
    }
  }
  
-  #ifdef ASSERT
+ #ifdef ASSERT
   class SignatureVerifier : public StackObj {
    public:
-     static bool is_valid_method_signature(Symbol* sig);
-     static bool is_valid_type_signature(Symbol* sig);
+     static bool is_valid_method_signature(const Symbol* sig);
+     static bool is_valid_type_signature(const Symbol* sig);
    private:
      static ssize_t is_valid_type(const char*, ssize_t);
  };
  #endif
  #endif // SHARE_RUNTIME_SIGNATURE_HPP
< prev index next >