< prev index next > src/hotspot/share/runtime/signature.cpp
Print this page
#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"
// 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)
// 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)
}
_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;
}
_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++) {
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;
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;
}
}
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));
}
}
}
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));
}
}
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 >