< prev index next >

src/hotspot/share/runtime/signature.cpp

Print this page
*** 33,12 ***
--- 33,14 ---
  #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/interfaceSupport.inline.hpp"
  #include "runtime/safepointVerifiers.hpp"
  #include "runtime/sharedRuntime.hpp"
  #include "runtime/signature.hpp"
  #include "runtime/sharedRuntime.hpp"
  

*** 47,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)
--- 49,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)

*** 499,10 ***
--- 501,25 ---
    }
    _previous_name = name;
    return name;
  }
  
+ InlineKlass* SignatureStream::as_inline_klass(InstanceKlass* holder) {
+   ThreadInVMfromUnknown tiv;
+   JavaThread* THREAD = JavaThread::current();
+   HandleMark hm(THREAD);
+   Handle class_loader(THREAD, holder->class_loader());
+   Handle protection_domain(THREAD, holder->protection_domain());
+   Klass* k = as_klass(class_loader, protection_domain, SignatureStream::CachedOrNull, THREAD);
+   assert(!HAS_PENDING_EXCEPTION, "Should never throw");
+   if (k != nullptr && k->is_inline_klass()) {
+     return InlineKlass::cast(k);
+   } else {
+     return nullptr;
+   }
+ }
+ 
  Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain,
                                   FailureMode failure_mode, TRAPS) {
    if (!is_reference()) {
      return nullptr;
    }

*** 578,11 ***
    _class_loader = Handle(current, _load_origin->class_loader());
    _protection_domain = Handle(current, _load_origin->protection_domain());
  }
  
  #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++) {
--- 595,10 ---

*** 597,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 != nullptr && len > 1 && method_sig[index] == JVM_SIGNATURE_FUNC) {
      ++index;
--- 613,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 != nullptr && len > 1 && method_sig[index] == JVM_SIGNATURE_FUNC) {
      ++index;

*** 620,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 != nullptr && len >= 1 &&
            (is_valid_type(type_sig, len) == len));
  }
--- 636,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 != nullptr && len >= 1 &&
            (is_valid_type(type_sig, len) == len));
  }

*** 667,5 ***
--- 683,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_METADATA &&
+           (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_METADATA || 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 >