< prev index next >

src/hotspot/share/runtime/signature.cpp

Print this page
*** 32,10 ***
--- 32,11 ---
  #include "oops/instanceKlass.hpp"
  #include "oops/klass.inline.hpp"
  #include "oops/oop.inline.hpp"
  #include "oops/symbol.hpp"
  #include "oops/typeArrayKlass.hpp"
+ #include "oops/inlineKlass.inline.hpp"
  #include "runtime/fieldDescriptor.inline.hpp"
  #include "runtime/handles.inline.hpp"
  #include "runtime/safepointVerifiers.hpp"
  #include "runtime/signature.hpp"
  

*** 44,11 ***
  // Signature syntax:
  //
  // Signature  = "(" {Parameter} ")" ReturnType.
  // Parameter  = FieldType.
  // ReturnType = FieldType | "V".
! // FieldType  = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "[" FieldType.
  // ClassName  = string.
  
  // The ClassName string can be any JVM-style UTF8 string except:
  //  - an empty string (the empty string is never a name of any kind)
  //  - a string which begins or ends with slash '/' (the package separator)
--- 45,11 ---
  // Signature syntax:
  //
  // Signature  = "(" {Parameter} ")" ReturnType.
  // Parameter  = FieldType.
  // ReturnType = FieldType | "V".
! // FieldType  = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "Q" ValueClassName ";" | "[" FieldType.
  // ClassName  = string.
  
  // The ClassName string can be any JVM-style UTF8 string except:
  //  - an empty string (the empty string is never a name of any kind)
  //  - a string which begins or ends with slash '/' (the package separator)

*** 223,10 ***
--- 224,11 ---
    int end = _end;
    int limit = _limit;
    const u1* tem;
    switch (type) {
    case T_OBJECT:
+   case T_INLINE_TYPE:
      tem = (const u1*) memchr(&base[end], JVM_SIGNATURE_ENDCLASS, limit - end);
      return (tem == NULL ? limit : tem + 1 - base);
  
    case T_ARRAY:
      while ((end < limit) && ((char)base[end] == JVM_SIGNATURE_ARRAY)) { end++; }

*** 302,10 ***
--- 304,11 ---
    case JVM_SIGNATURE_SHORT:
    case JVM_SIGNATURE_BOOLEAN:
      // If it is an array, the type is the last character
      return (i + 1 == len);
    case JVM_SIGNATURE_CLASS:
+   case JVM_SIGNATURE_INLINE_TYPE:
      // If it is an object, the last character must be a ';'
      return sig->char_at(len - 1) == JVM_SIGNATURE_ENDCLASS;
    }
    return false;
  }

*** 383,10 ***
--- 386,19 ---
    }
    _previous_name = name;
    return name;
  }
  
+ InlineKlass* SignatureStream::as_inline_klass(InstanceKlass* holder) {
+   JavaThread* THREAD = JavaThread::current();
+   Handle class_loader(THREAD, holder->class_loader());
+   Handle protection_domain(THREAD, holder->protection_domain());
+   Klass* k = as_klass(class_loader, protection_domain, SignatureStream::ReturnNull, THREAD);
+   assert(k != NULL && !HAS_PENDING_EXCEPTION, "unresolved inline klass");
+   return InlineKlass::cast(k);
+ }
+ 
  Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain,
                                   FailureMode failure_mode, TRAPS) {
    if (!is_reference()) {
      return NULL;
    }

*** 422,11 ***
    }
    Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL);
    if (klass == NULL) {
      return NULL;
    }
!   return klass->java_mirror();
  }
  
  void SignatureStream::skip_to_return_type() {
    while (!at_return_type()) {
      next();
--- 434,12 ---
    }
    Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL);
    if (klass == NULL) {
      return NULL;
    }
!   return has_Q_descriptor() ? InlineKlass::cast(klass)->val_mirror()
+                             : klass->java_mirror();
  }
  
  void SignatureStream::skip_to_return_type() {
    while (!at_return_type()) {
      next();

*** 479,11 ***
    }
    return klass;
  }
  
  #ifdef ASSERT
- 
  extern bool signature_constants_sane(); // called from basic_types_init()
  
  bool signature_constants_sane() {
    // for the lookup table, test every 8-bit code point, and then some:
    for (int i = -256; i <= 256; i++) {
--- 492,10 ---

*** 498,11 ***
      assert(btc == btcode, "misconfigured table: %d => %d not %d", i, btc, btcode);
    }
    return true;
  }
  
! bool SignatureVerifier::is_valid_method_signature(Symbol* sig) {
    const char* method_sig = (const char*)sig->bytes();
    ssize_t len = sig->utf8_length();
    ssize_t index = 0;
    if (method_sig != NULL && len > 1 && method_sig[index] == JVM_SIGNATURE_FUNC) {
      ++index;
--- 510,11 ---
      assert(btc == btcode, "misconfigured table: %d => %d not %d", i, btc, btcode);
    }
    return true;
  }
  
! bool SignatureVerifier::is_valid_method_signature(const Symbol* sig) {
    const char* method_sig = (const char*)sig->bytes();
    ssize_t len = sig->utf8_length();
    ssize_t index = 0;
    if (method_sig != NULL && len > 1 && method_sig[index] == JVM_SIGNATURE_FUNC) {
      ++index;

*** 521,11 ***
      }
    }
    return false;
  }
  
! bool SignatureVerifier::is_valid_type_signature(Symbol* sig) {
    const char* type_sig = (const char*)sig->bytes();
    ssize_t len = sig->utf8_length();
    return (type_sig != NULL && len >= 1 &&
            (is_valid_type(type_sig, len) == len));
  }
--- 533,11 ---
      }
    }
    return false;
  }
  
! bool SignatureVerifier::is_valid_type_signature(const Symbol* sig) {
    const char* type_sig = (const char*)sig->bytes();
    ssize_t len = sig->utf8_length();
    return (type_sig != NULL && len >= 1 &&
            (is_valid_type(type_sig, len) == len));
  }

*** 550,10 ***
--- 562,11 ---
      case JVM_SIGNATURE_LONG:
      case JVM_SIGNATURE_SHORT:
      case JVM_SIGNATURE_BOOLEAN:
      case JVM_SIGNATURE_VOID:
        return index + 1;
+     case JVM_SIGNATURE_INLINE_TYPE: // fall through
      case JVM_SIGNATURE_CLASS:
        for (index = index + 1; index < limit; ++index) {
          char c = type[index];
          switch (c) {
            case JVM_SIGNATURE_ENDCLASS:

*** 568,5 ***
--- 581,58 ---
    }
    return -1;
  }
  
  #endif // ASSERT
+ 
+ // Adds an argument to the signature
+ void SigEntry::add_entry(GrowableArray<SigEntry>* sig, BasicType bt, Symbol* symbol, int offset) {
+   sig->append(SigEntry(bt, offset, symbol));
+   if (bt == T_LONG || bt == T_DOUBLE) {
+     sig->append(SigEntry(T_VOID, offset, symbol)); // Longs and doubles take two stack slots
+   }
+ }
+ 
+ // Returns true if the argument at index 'i' is not an inline type delimiter
+ bool SigEntry::skip_value_delimiters(const GrowableArray<SigEntry>* sig, int i) {
+   return (sig->at(i)._bt != T_INLINE_TYPE &&
+           (sig->at(i)._bt != T_VOID || sig->at(i-1)._bt == T_LONG || sig->at(i-1)._bt == T_DOUBLE));
+ }
+ 
+ // Fill basic type array from signature array
+ int SigEntry::fill_sig_bt(const GrowableArray<SigEntry>* sig, BasicType* sig_bt) {
+   int count = 0;
+   for (int i = 0; i < sig->length(); i++) {
+     if (skip_value_delimiters(sig, i)) {
+       sig_bt[count++] = sig->at(i)._bt;
+     }
+   }
+   return count;
+ }
+ 
+ // Create a temporary symbol from the signature array
+ TempNewSymbol SigEntry::create_symbol(const GrowableArray<SigEntry>* sig) {
+   ResourceMark rm;
+   int length = sig->length();
+   char* sig_str = NEW_RESOURCE_ARRAY(char, 2*length + 3);
+   int idx = 0;
+   sig_str[idx++] = '(';
+   for (int i = 0; i < length; i++) {
+     BasicType bt = sig->at(i)._bt;
+     if (bt == T_INLINE_TYPE || bt == T_VOID) {
+       // Ignore
+     } else {
+       if (bt == T_ARRAY) {
+         bt = T_OBJECT; // We don't know the element type, treat as Object
+       }
+       sig_str[idx++] = type2char(bt);
+       if (bt == T_OBJECT) {
+         sig_str[idx++] = ';';
+       }
+     }
+   }
+   sig_str[idx++] = ')';
+   // Add a dummy return type. It won't be used but SignatureStream needs it.
+   sig_str[idx++] = 'V';
+   sig_str[idx++] = '\0';
+   return SymbolTable::new_symbol(sig_str);
+ }
< prev index next >