< 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.
+ // 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)
#endif // defined(PPC64) || defined(S390)
case T_LONG:
case T_OBJECT:
case T_ARRAY:
case T_ADDRESS:
+ case T_PRIMITIVE_OBJECT:
if (_int_args < Argument::n_int_register_parameters_j) {
_int_args++;
} else {
PPC64_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2));
S390_ONLY(_stack_arg_slots = align_up(_stack_arg_slots, 2));
int end = _end;
int limit = _limit;
const u1* tem;
switch (type) {
case T_OBJECT:
+ case T_PRIMITIVE_OBJECT:
tem = (const u1*) memchr(&base[end], JVM_SIGNATURE_ENDCLASS, limit - end);
return (tem == nullptr ? limit : tem + 1 - base);
case T_ARRAY:
while ((end < limit) && ((char)base[end] == JVM_SIGNATURE_ARRAY)) { end++; }
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_PRIMITIVE_OBJECT:
// If it is an object, the last character must be a ';'
return sig->char_at(len - 1) == JVM_SIGNATURE_ENDCLASS;
}
return false;
}
}
_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;
}
}
Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL);
if (klass == nullptr) {
return nullptr;
}
- return klass->java_mirror();
+ return has_Q_descriptor() ? InlineKlass::cast(klass)->val_mirror()
+ : klass->java_mirror();
}
void SignatureStream::skip_to_return_type() {
while (!at_return_type()) {
next();
_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) {
+ 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) {
+ 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));
}
case JVM_SIGNATURE_LONG:
case JVM_SIGNATURE_SHORT:
case JVM_SIGNATURE_BOOLEAN:
case JVM_SIGNATURE_VOID:
return index + 1;
+ case JVM_SIGNATURE_PRIMITIVE_OBJECT: // fall through
case JVM_SIGNATURE_CLASS:
for (index = index + 1; index < limit; ++index) {
char c = type[index];
switch (c) {
case JVM_SIGNATURE_ENDCLASS:
}
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_PRIMITIVE_OBJECT &&
+ (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_PRIMITIVE_OBJECT || 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 >