< prev index next >

src/hotspot/share/runtime/signature.cpp

Print this page

        

*** 29,48 **** #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" #include "oops/typeArrayKlass.hpp" #include "runtime/signature.hpp" // Implementation of SignatureIterator // Signature syntax: // // Signature = "(" {Parameter} ")" ReturnType. // Parameter = FieldType. // ReturnType = FieldType | "V". ! // FieldType = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "[" FieldType. // ClassName = string. SignatureIterator::SignatureIterator(Symbol* signature) { _signature = signature; --- 29,49 ---- #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" #include "oops/oop.inline.hpp" #include "oops/symbol.hpp" #include "oops/typeArrayKlass.hpp" + #include "oops/valueKlass.hpp" #include "runtime/signature.hpp" // Implementation of SignatureIterator // 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. SignatureIterator::SignatureIterator(Symbol* signature) { _signature = signature;
*** 87,103 **** do_object(begin, _index); } if (_parameter_index < 0 ) _return_type = T_OBJECT; size = T_OBJECT_size; break; case '[': { int begin = ++_index; Symbol* sig = _signature; while (sig->char_at(_index) == '[') { _index++; } ! if (sig->char_at(_index) == 'L') { while (sig->char_at(_index++) != ';') ; } else { _index++; } do_array(begin, _index); --- 88,113 ---- do_object(begin, _index); } if (_parameter_index < 0 ) _return_type = T_OBJECT; size = T_OBJECT_size; break; + case 'Q': + { int begin = ++_index; + Symbol* sig = _signature; + while (sig->char_at(_index++) != ';') ; + do_valuetype(begin, _index); + } + if (_parameter_index < 0 ) _return_type = T_VALUETYPE; + size = T_VALUETYPE_size; + break; case '[': { int begin = ++_index; Symbol* sig = _signature; while (sig->char_at(_index) == '[') { _index++; } ! if (sig->char_at(_index) == 'L' || sig->char_at(_index) == 'Q') { while (sig->char_at(_index++) != ';') ; } else { _index++; } do_array(begin, _index);
*** 230,239 **** --- 240,250 ---- case 'V': { _index++; } break; + case 'Q': case 'L': { while (sig->char_at(_index++) != ';') ; } break;
*** 241,251 **** { int begin = ++_index; while (sig->char_at(_index) == '[') { _index++; } ! if (sig->char_at(_index) == 'L') { while (sig->char_at(_index++) != ';') ; } else { _index++; } } --- 252,262 ---- { int begin = ++_index; while (sig->char_at(_index) == '[') { _index++; } ! if (sig->char_at(_index) == 'L' || sig->char_at(_index) == 'Q' ) { while (sig->char_at(_index++) != ';') ; } else { _index++; } }
*** 305,314 **** --- 316,331 ---- _type = T_OBJECT; Symbol* sig = _signature; while (sig->char_at(_end++) != ';'); break; } + case 'Q': { + _type = T_VALUETYPE; + Symbol* sig = _signature; + while (sig->char_at(_end++) != ';'); + break; + } case '[': { _type = T_ARRAY; Symbol* sig = _signature; char c = sig->char_at(_end); while ('0' <= c && c <= '9') c = sig->char_at(_end++);
*** 339,349 **** } bool SignatureStream::is_object() const { return _type == T_OBJECT ! || _type == T_ARRAY; } bool SignatureStream::is_array() const { return _type == T_ARRAY; } --- 356,367 ---- } bool SignatureStream::is_object() const { return _type == T_OBJECT ! || _type == T_ARRAY ! || _type == T_VALUETYPE; } bool SignatureStream::is_array() const { return _type == T_ARRAY; }
*** 351,364 **** Symbol* SignatureStream::as_symbol(TRAPS) { // Create a symbol from for string _begin _end int begin = _begin; int end = _end; ! if ( _signature->char_at(_begin) == 'L' ! && _signature->char_at(_end-1) == ';') { begin++; end--; } // Save names for cleaning up reference count at the end of // SignatureStream scope. Symbol* name = SymbolTable::new_symbol(_signature, begin, end, CHECK_NULL); --- 369,384 ---- Symbol* SignatureStream::as_symbol(TRAPS) { // Create a symbol from for string _begin _end int begin = _begin; int end = _end; ! if (_type == T_OBJECT || _type == T_VALUETYPE) { begin++; end--; + if (begin == end) { + return vmSymbols::java_lang_Object(); + } } // Save names for cleaning up reference count at the end of // SignatureStream scope. Symbol* name = SymbolTable::new_symbol(_signature, begin, end, CHECK_NULL);
*** 382,405 **** FailureMode failure_mode, TRAPS) { if (!is_object()) return Universe::java_mirror(type()); Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); if (klass == NULL) return NULL; ! return klass->java_mirror(); } Symbol* SignatureStream::as_symbol_or_null() { // Create a symbol from for string _begin _end ResourceMark rm; int begin = _begin; int end = _end; ! if ( _signature->char_at(_begin) == 'L' ! && _signature->char_at(_end-1) == ';') { begin++; end--; } char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); for (int index = begin; index < end; index++) { buffer[index - begin] = _signature->char_at(index); --- 402,427 ---- FailureMode failure_mode, TRAPS) { if (!is_object()) return Universe::java_mirror(type()); Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); if (klass == NULL) return NULL; ! return _type == T_VALUETYPE ? ValueKlass::cast(InstanceKlass::cast(klass))->value_mirror() : klass->java_mirror(); } Symbol* SignatureStream::as_symbol_or_null() { // Create a symbol from for string _begin _end ResourceMark rm; int begin = _begin; int end = _end; ! if (_type == T_OBJECT || _type == T_VALUETYPE) { begin++; end--; + if (begin == end) { + return vmSymbols::java_lang_Object(); + } } char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); for (int index = begin; index < end; index++) { buffer[index - begin] = _signature->char_at(index);
*** 473,482 **** --- 495,505 ---- } switch (type[index]) { case 'B': case 'C': case 'D': case 'F': case 'I': case 'J': case 'S': case 'Z': case 'V': return index + 1; + case 'Q': // fall through case 'L': for (index = index + 1; index < limit; ++index) { char c = type[index]; if (c == ';') { return index + 1;
*** 497,501 **** --- 520,608 ---- return true; default: return false; } } + + // Adds an argument to the signature + void SigEntry::add_entry(GrowableArray<SigEntry>* sig, BasicType bt, int offset) { + sig->append(SigEntry(bt, offset)); + if (bt == T_LONG || bt == T_DOUBLE) { + sig->append(SigEntry(T_VOID, offset)); // Longs and doubles take two stack slots + } + } + + // Inserts a reserved argument at position 'i' + void SigEntry::insert_reserved_entry(GrowableArray<SigEntry>* sig, int i, BasicType bt) { + if (bt == T_OBJECT || bt == T_ARRAY || bt == T_VALUETYPE) { + // Treat this as INT to not confuse the GC + bt = T_INT; + } else if (bt == T_LONG || bt == T_DOUBLE) { + // Longs and doubles take two stack slots + sig->insert_before(i, SigEntry(T_VOID, SigEntry::ReservedOffset)); + } + sig->insert_before(i, SigEntry(bt, SigEntry::ReservedOffset)); + } + + // Returns true if the argument at index 'i' is a reserved argument + bool SigEntry::is_reserved_entry(const GrowableArray<SigEntry>* sig, int i) { + return sig->at(i)._offset == SigEntry::ReservedOffset; + } + + // Returns true if the argument at index 'i' is not a value type delimiter + bool SigEntry::skip_value_delimiters(const GrowableArray<SigEntry>* sig, int i) { + return (sig->at(i)._bt != T_VALUETYPE && + (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_VALUETYPE || 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++] = ')'; + sig_str[idx++] = '\0'; + return SymbolTable::new_symbol(sig_str, Thread::current()); + } + + // Increment signature iterator (skips value type delimiters and T_VOID) and check if next entry is reserved + bool SigEntry::next_is_reserved(ExtendedSignature& sig, BasicType& bt, bool can_be_void) { + assert(can_be_void || bt != T_VOID, "should never see void"); + if (sig.at_end() || (can_be_void && type2size[bt] == 2 && (*sig)._offset != SigEntry::ReservedOffset)) { + // Don't increment at the end or at a T_LONG/T_DOUBLE which will be followed by a (skipped) T_VOID + return false; + } + assert(bt == T_VOID || type2wfield[bt] == type2wfield[(*sig)._bt], "inconsistent signature"); + ++sig; + if (!sig.at_end() && (*sig)._offset == SigEntry::ReservedOffset) { + bt = (*sig)._bt; + return true; + } + return false; + }
< prev index next >