Bug Summary

File:jdk/src/hotspot/share/runtime/signature.hpp
Warning:line 502, column 31
Undefined or garbage value returned to caller

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name signature.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/libjvm/objs/precompiled -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -D __STDC_CONSTANT_MACROS -D _GNU_SOURCE -D _REENTRANT -D LIBC=gnu -D LINUX -D VM_LITTLE_ENDIAN -D _LP64=1 -D ASSERT -D CHECK_UNHANDLED_OOPS -D TARGET_ARCH_x86 -D INCLUDE_SUFFIX_OS=_linux -D INCLUDE_SUFFIX_CPU=_x86 -D INCLUDE_SUFFIX_COMPILER=_gcc -D TARGET_COMPILER_gcc -D AMD64 -D HOTSPOT_LIB_ARCH="amd64" -D COMPILER1 -D COMPILER2 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -I /home/daniel/Projects/java/jdk/src/hotspot/share/precompiled -I /home/daniel/Projects/java/jdk/src/hotspot/share/include -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix/include -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/support/modules_include/java.base/linux -I /home/daniel/Projects/java/jdk/src/java.base/share/native/libjimage -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc/adfiles -I /home/daniel/Projects/java/jdk/src/hotspot/share -I /home/daniel/Projects/java/jdk/src/hotspot/os/linux -I /home/daniel/Projects/java/jdk/src/hotspot/os/posix -I /home/daniel/Projects/java/jdk/src/hotspot/cpu/x86 -I /home/daniel/Projects/java/jdk/src/hotspot/os_cpu/linux_x86 -I /home/daniel/Projects/java/jdk/build/linux-x86_64-server-fastdebug/hotspot/variant-server/gensrc -D _FORTIFY_SOURCE=2 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/x86_64-linux-gnu/c++/7.5.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-format-zero-length -Wno-unused-parameter -Wno-unused -Wno-parentheses -Wno-comment -Wno-unknown-pragmas -Wno-address -Wno-delete-non-virtual-dtor -Wno-char-subscripts -Wno-array-bounds -Wno-int-in-bool-context -Wno-ignored-qualifiers -Wno-missing-field-initializers -Wno-implicit-fallthrough -Wno-empty-body -Wno-strict-overflow -Wno-sequence-point -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-cast-function-type -Wno-shift-negative-value -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /home/daniel/Projects/java/jdk/make/hotspot -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -stack-protector 1 -fno-rtti -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/daniel/Projects/java/scan/2021-12-21-193737-8510-1 -x c++ /home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp

/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp

1/*
2 * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25#include "precompiled.hpp"
26#include "classfile/symbolTable.hpp"
27#include "classfile/systemDictionary.hpp"
28#include "classfile/vmSymbols.hpp"
29#include "memory/oopFactory.hpp"
30#include "memory/resourceArea.hpp"
31#include "memory/universe.hpp"
32#include "oops/instanceKlass.hpp"
33#include "oops/klass.inline.hpp"
34#include "oops/oop.inline.hpp"
35#include "oops/symbol.hpp"
36#include "oops/typeArrayKlass.hpp"
37#include "runtime/fieldDescriptor.inline.hpp"
38#include "runtime/handles.inline.hpp"
39#include "runtime/safepointVerifiers.hpp"
40#include "runtime/signature.hpp"
41
42// Implementation of SignatureIterator
43
44// Signature syntax:
45//
46// Signature = "(" {Parameter} ")" ReturnType.
47// Parameter = FieldType.
48// ReturnType = FieldType | "V".
49// FieldType = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "[" FieldType.
50// ClassName = string.
51
52// The ClassName string can be any JVM-style UTF8 string except:
53// - an empty string (the empty string is never a name of any kind)
54// - a string which begins or ends with slash '/' (the package separator)
55// - a string which contains adjacent slashes '//' (no empty package names)
56// - a string which contains a semicolon ';' (the end-delimiter)
57// - a string which contains a left bracket '[' (the array marker)
58// - a string which contains a dot '.' (the external package separator)
59//
60// Other "meta-looking" characters, such as '(' and '<' and '+',
61// are perfectly legitimate within a class name, for the JVM.
62// Class names which contain double slashes ('a//b') and non-initial
63// brackets ('a[b]') are reserved for possible enrichment of the
64// type language.
65
66void SignatureIterator::set_fingerprint(fingerprint_t fingerprint) {
67 if (!fp_is_valid(fingerprint)) {
68 _fingerprint = fingerprint;
69 _return_type = T_ILLEGAL;
70 } else if (fingerprint != _fingerprint) {
71 assert(_fingerprint == zero_fingerprint(), "consistent fingerprint values")do { if (!(_fingerprint == zero_fingerprint())) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 71, "assert(" "_fingerprint == zero_fingerprint()" ") failed"
, "consistent fingerprint values"); ::breakpoint(); } } while
(0)
;
72 _fingerprint = fingerprint;
73 _return_type = fp_return_type(fingerprint);
74 }
75}
76
77BasicType SignatureIterator::return_type() {
78 if (_return_type == T_ILLEGAL) {
79 SignatureStream ss(_signature);
80 ss.skip_to_return_type();
81 _return_type = ss.type();
82 assert(_return_type != T_ILLEGAL, "illegal return type")do { if (!(_return_type != T_ILLEGAL)) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 82, "assert(" "_return_type != T_ILLEGAL" ") failed", "illegal return type"
); ::breakpoint(); } } while (0)
;
83 }
84 return _return_type;
85}
86
87bool SignatureIterator::fp_is_valid_type(BasicType type, bool for_return_type) {
88 assert(type != (BasicType)fp_parameters_done, "fingerprint is incorrectly at done")do { if (!(type != (BasicType)fp_parameters_done)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 88, "assert(" "type != (BasicType)fp_parameters_done" ") failed"
, "fingerprint is incorrectly at done"); ::breakpoint(); } } while
(0)
;
89 assert(((int)type & ~fp_parameter_feature_mask) == 0, "fingerprint feature mask yielded non-zero value")do { if (!(((int)type & ~fp_parameter_feature_mask) == 0)
) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 89, "assert(" "((int)type & ~fp_parameter_feature_mask) == 0"
") failed", "fingerprint feature mask yielded non-zero value"
); ::breakpoint(); } } while (0)
;
90 return (is_java_primitive(type) ||
91 is_reference_type(type) ||
92 (for_return_type && type == T_VOID));
93}
94
95ArgumentSizeComputer::ArgumentSizeComputer(Symbol* signature)
96 : SignatureIterator(signature)
97{
98 _size = 0;
99 do_parameters_on(this); // non-virtual template execution
100}
101
102ArgumentCount::ArgumentCount(Symbol* signature)
103 : SignatureIterator(signature)
104{
105 _size = 0;
106 do_parameters_on(this); // non-virtual template execution
107}
108
109ReferenceArgumentCount::ReferenceArgumentCount(Symbol* signature)
110 : SignatureIterator(signature)
111{
112 _refs = 0;
113 do_parameters_on(this); // non-virtual template execution
1
Calling 'SignatureIterator::do_parameters_on'
114}
115
116void Fingerprinter::compute_fingerprint_and_return_type(bool static_flag) {
117 // See if we fingerprinted this method already
118 if (_method != NULL__null) {
119 assert(!static_flag, "must not be passed by caller")do { if (!(!static_flag)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 119, "assert(" "!static_flag" ") failed", "must not be passed by caller"
); ::breakpoint(); } } while (0)
;
120 static_flag = _method->is_static();
121 _fingerprint = _method->constMethod()->fingerprint();
122
123 if (_fingerprint != zero_fingerprint()) {
124 _return_type = _method->result_type();
125 assert(is_java_type(_return_type), "return type must be a java type")do { if (!(is_java_type(_return_type))) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 125, "assert(" "is_java_type(_return_type)" ") failed", "return type must be a java type"
); ::breakpoint(); } } while (0)
;
126 return;
127 }
128
129 if (_method->size_of_parameters() > fp_max_size_of_parameters) {
130 _fingerprint = overflow_fingerprint();
131 _method->constMethod()->set_fingerprint(_fingerprint);
132 // as long as we are here compute the return type:
133 _return_type = ResultTypeFinder(_method->signature()).type();
134 assert(is_java_type(_return_type), "return type must be a java type")do { if (!(is_java_type(_return_type))) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 134, "assert(" "is_java_type(_return_type)" ") failed", "return type must be a java type"
); ::breakpoint(); } } while (0)
;
135 return;
136 }
137 }
138
139 // Note: This will always take the slow path, since _fp==zero_fp.
140 initialize_accumulator();
141 do_parameters_on(this);
142 assert(fp_is_valid_type(_return_type, true), "bad result type")do { if (!(fp_is_valid_type(_return_type, true))) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 142, "assert(" "fp_is_valid_type(_return_type, true)" ") failed"
, "bad result type"); ::breakpoint(); } } while (0)
;
143
144 // Fill in the return type and static bits:
145 _accumulator |= _return_type << fp_static_feature_size;
146 if (static_flag) {
147 _accumulator |= fp_is_static_bit;
148 } else {
149 _param_size += 1; // this is the convention for Method::compute_size_of_parameters
150 }
151
152 // Detect overflow. (We counted _param_size correctly.)
153 if (_method == NULL__null && _param_size > fp_max_size_of_parameters) {
154 // We did a one-pass computation of argument size, return type,
155 // and fingerprint.
156 _fingerprint = overflow_fingerprint();
157 return;
158 }
159
160 assert(_shift_count < BitsPerLong,do { if (!(_shift_count < BitsPerLong)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 163, "assert(" "_shift_count < BitsPerLong" ") failed", "shift count overflow %d (%d vs. %d): %s"
, _shift_count, _param_size, fp_max_size_of_parameters, _signature
->as_C_string()); ::breakpoint(); } } while (0)
161 "shift count overflow %d (%d vs. %d): %s",do { if (!(_shift_count < BitsPerLong)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 163, "assert(" "_shift_count < BitsPerLong" ") failed", "shift count overflow %d (%d vs. %d): %s"
, _shift_count, _param_size, fp_max_size_of_parameters, _signature
->as_C_string()); ::breakpoint(); } } while (0)
162 _shift_count, _param_size, fp_max_size_of_parameters,do { if (!(_shift_count < BitsPerLong)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 163, "assert(" "_shift_count < BitsPerLong" ") failed", "shift count overflow %d (%d vs. %d): %s"
, _shift_count, _param_size, fp_max_size_of_parameters, _signature
->as_C_string()); ::breakpoint(); } } while (0)
163 _signature->as_C_string())do { if (!(_shift_count < BitsPerLong)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 163, "assert(" "_shift_count < BitsPerLong" ") failed", "shift count overflow %d (%d vs. %d): %s"
, _shift_count, _param_size, fp_max_size_of_parameters, _signature
->as_C_string()); ::breakpoint(); } } while (0)
;
164 assert((_accumulator >> _shift_count) == fp_parameters_done, "must be zero")do { if (!((_accumulator >> _shift_count) == fp_parameters_done
)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 164, "assert(" "(_accumulator >> _shift_count) == fp_parameters_done"
") failed", "must be zero"); ::breakpoint(); } } while (0)
;
165
166 // This is the result, along with _return_type:
167 _fingerprint = _accumulator;
168
169 // Cache the result on the method itself:
170 if (_method != NULL__null) {
171 _method->constMethod()->set_fingerprint(_fingerprint);
172 }
173}
174
175// Implementation of SignatureStream
176
177static inline BasicType decode_signature_char(int ch) {
178 switch (ch) {
179#define EACH_SIG(ch, bt, ignore) \
180 case ch: return bt;
181 SIGNATURE_TYPES_DO(EACH_SIG, ignore)EACH_SIG(JVM_SIGNATURE_BOOLEAN, T_BOOLEAN, ignore) EACH_SIG(JVM_SIGNATURE_CHAR
, T_CHAR, ignore) EACH_SIG(JVM_SIGNATURE_FLOAT, T_FLOAT, ignore
) EACH_SIG(JVM_SIGNATURE_DOUBLE, T_DOUBLE, ignore) EACH_SIG(JVM_SIGNATURE_BYTE
, T_BYTE, ignore) EACH_SIG(JVM_SIGNATURE_SHORT, T_SHORT, ignore
) EACH_SIG(JVM_SIGNATURE_INT, T_INT, ignore) EACH_SIG(JVM_SIGNATURE_LONG
, T_LONG, ignore) EACH_SIG(JVM_SIGNATURE_CLASS, T_OBJECT, ignore
) EACH_SIG(JVM_SIGNATURE_ARRAY, T_ARRAY, ignore) EACH_SIG(JVM_SIGNATURE_VOID
, T_VOID, ignore)
182#undef EACH_SIG
183 }
184 return (BasicType)0;
185}
186
187SignatureStream::SignatureStream(const Symbol* signature,
188 bool is_method) {
189 assert(!is_method || signature->starts_with(JVM_SIGNATURE_FUNC),do { if (!(!is_method || signature->starts_with(JVM_SIGNATURE_FUNC
))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 190, "assert(" "!is_method || signature->starts_with(JVM_SIGNATURE_FUNC)"
") failed", "method signature required"); ::breakpoint(); } }
while (0)
4
Taking false branch
5
Loop condition is false. Exiting loop
190 "method signature required")do { if (!(!is_method || signature->starts_with(JVM_SIGNATURE_FUNC
))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 190, "assert(" "!is_method || signature->starts_with(JVM_SIGNATURE_FUNC)"
") failed", "method signature required"); ::breakpoint(); } }
while (0)
;
191 _signature = signature;
192 _limit = signature->utf8_length();
193 int oz = (is_method
5.1
'is_method' is true
5.1
'is_method' is true
? _s_method : _s_field);
6
'?' condition is true
194 _state = oz;
195 _begin = _end = oz; // skip first '(' in method signatures
196 _array_prefix = 0; // just for definiteness
197
198 // assigning java/lang/Object to _previous_name means we can
199 // avoid a number of NULL checks in the parser
200 _previous_name = vmSymbols::java_lang_Object();
201 _names = NULL__null;
202 next();
203}
7
Returning without writing to 'this->_type'
204
205SignatureStream::~SignatureStream() {
206 if (_previous_name == vmSymbols::java_lang_Object()) {
207 // no names were created
208 assert(_names == NULL, "_names unexpectedly created")do { if (!(_names == __null)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 208, "assert(" "_names == __null" ") failed", "_names unexpectedly created"
); ::breakpoint(); } } while (0)
;
209 return;
210 }
211
212 // decrement refcount for names created during signature parsing
213 _previous_name->decrement_refcount();
214 if (_names != NULL__null) {
215 for (int i = 0; i < _names->length(); i++) {
216 _names->at(i)->decrement_refcount();
217 }
218 }
219}
220
221inline int SignatureStream::scan_type(BasicType type) {
222 const u1* base = _signature->bytes();
223 int end = _end;
224 int limit = _limit;
225 const u1* tem;
226 switch (type) {
227 case T_OBJECT:
228 tem = (const u1*) memchr(&base[end], JVM_SIGNATURE_ENDCLASS, limit - end);
229 return (tem == NULL__null ? limit : tem + 1 - base);
230
231 case T_ARRAY:
232 while ((end < limit) && ((char)base[end] == JVM_SIGNATURE_ARRAY)) { end++; }
233 _array_prefix = end - _end; // number of '[' chars just skipped
234 if (Signature::has_envelope(base[end])) {
235 tem = (const u1 *) memchr(&base[end], JVM_SIGNATURE_ENDCLASS, limit - end);
236 return (tem == NULL__null ? limit : tem + 1 - base);
237 }
238 // Skipping over a single character for a primitive type.
239 assert(is_java_primitive(decode_signature_char(base[end])), "only primitives expected")do { if (!(is_java_primitive(decode_signature_char(base[end])
))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 239, "assert(" "is_java_primitive(decode_signature_char(base[end]))"
") failed", "only primitives expected"); ::breakpoint(); } }
while (0)
;
240 return end + 1;
241
242 default:
243 // Skipping over a single character for a primitive type (or void).
244 assert(!is_reference_type(type), "only primitives or void expected")do { if (!(!is_reference_type(type))) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 244, "assert(" "!is_reference_type(type)" ") failed", "only primitives or void expected"
); ::breakpoint(); } } while (0)
;
245 return end + 1;
246 }
247}
248
249void SignatureStream::next() {
250 const Symbol* sig = _signature;
251 int len = _limit;
252 if (_end >= len) { set_done(); return; }
253 _begin = _end;
254 int ch = sig->char_at(_begin);
255 if (ch == JVM_SIGNATURE_ENDFUNC) {
256 assert(_state == _s_method, "must be in method")do { if (!(_state == _s_method)) { (*g_assert_poison) = 'X';;
report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 256, "assert(" "_state == _s_method" ") failed", "must be in method"
); ::breakpoint(); } } while (0)
;
257 _state = _s_method_return;
258 _begin = ++_end;
259 if (_end >= len) { set_done(); return; }
260 ch = sig->char_at(_begin);
261 }
262 BasicType bt = decode_signature_char(ch);
263 assert(ch == type2char(bt), "bad signature char %c/%d", ch, ch)do { if (!(ch == type2char(bt))) { (*g_assert_poison) = 'X';;
report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 263, "assert(" "ch == type2char(bt)" ") failed", "bad signature char %c/%d"
, ch, ch); ::breakpoint(); } } while (0)
;
264 _type = bt;
265 _end = scan_type(bt);
266}
267
268int SignatureStream::skip_whole_array_prefix() {
269 assert(_type == T_ARRAY, "must be")do { if (!(_type == T_ARRAY)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 269, "assert(" "_type == T_ARRAY" ") failed", "must be"); ::
breakpoint(); } } while (0)
;
270
271 // we are stripping all levels of T_ARRAY,
272 // so we must decode the next character
273 int whole_array_prefix = _array_prefix;
274 int new_begin = _begin + whole_array_prefix;
275 _begin = new_begin;
276 int ch = _signature->char_at(new_begin);
277 BasicType bt = decode_signature_char(ch);
278 assert(ch == type2char(bt), "bad signature char %c/%d", ch, ch)do { if (!(ch == type2char(bt))) { (*g_assert_poison) = 'X';;
report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 278, "assert(" "ch == type2char(bt)" ") failed", "bad signature char %c/%d"
, ch, ch); ::breakpoint(); } } while (0)
;
279 _type = bt;
280 assert(bt != T_VOID && bt != T_ARRAY, "bad signature type")do { if (!(bt != T_VOID && bt != T_ARRAY)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 280, "assert(" "bt != T_VOID && bt != T_ARRAY" ") failed"
, "bad signature type"); ::breakpoint(); } } while (0)
;
281 // Don't bother to re-scan, since it won't change the value of _end.
282 return whole_array_prefix;
283}
284
285bool Signature::is_valid_array_signature(const Symbol* sig) {
286 assert(sig->utf8_length() > 1, "this should already have been checked")do { if (!(sig->utf8_length() > 1)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 286, "assert(" "sig->utf8_length() > 1" ") failed", "this should already have been checked"
); ::breakpoint(); } } while (0)
;
287 assert(sig->char_at(0) == JVM_SIGNATURE_ARRAY, "this should already have been checked")do { if (!(sig->char_at(0) == JVM_SIGNATURE_ARRAY)) { (*g_assert_poison
) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 287, "assert(" "sig->char_at(0) == JVM_SIGNATURE_ARRAY" ") failed"
, "this should already have been checked"); ::breakpoint(); }
} while (0)
;
288 // The first character is already checked
289 int i = 1;
290 int len = sig->utf8_length();
291 // First skip all '['s
292 while(i < len - 1 && sig->char_at(i) == JVM_SIGNATURE_ARRAY) i++;
293
294 // Check type
295 switch(sig->char_at(i)) {
296 case JVM_SIGNATURE_BYTE:
297 case JVM_SIGNATURE_CHAR:
298 case JVM_SIGNATURE_DOUBLE:
299 case JVM_SIGNATURE_FLOAT:
300 case JVM_SIGNATURE_INT:
301 case JVM_SIGNATURE_LONG:
302 case JVM_SIGNATURE_SHORT:
303 case JVM_SIGNATURE_BOOLEAN:
304 // If it is an array, the type is the last character
305 return (i + 1 == len);
306 case JVM_SIGNATURE_CLASS:
307 // If it is an object, the last character must be a ';'
308 return sig->char_at(len - 1) == JVM_SIGNATURE_ENDCLASS;
309 }
310 return false;
311}
312
313BasicType Signature::basic_type(int ch) {
314 BasicType btcode = decode_signature_char(ch);
315 if (btcode == 0) return T_ILLEGAL;
316 return btcode;
317}
318
319Symbol* Signature::strip_envelope(const Symbol* signature) {
320 assert(has_envelope(signature), "precondition")do { if (!(has_envelope(signature))) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 320, "assert(" "has_envelope(signature)" ") failed", "precondition"
); ::breakpoint(); } } while (0)
;
321 return SymbolTable::new_symbol((char*) signature->bytes() + 1,
322 signature->utf8_length() - 2);
323}
324
325static const int jl_len = 10, object_len = 6, jl_object_len = jl_len + object_len;
326static const char jl_str[] = "java/lang/";
327
328#ifdef ASSERT1
329static bool signature_symbols_sane() {
330 static bool done;
331 if (done) return true;
332 done = true;
333 // test some tense code that looks for common symbol names:
334 assert(vmSymbols::java_lang_Object()->utf8_length() == jl_object_len &&do { if (!(vmSymbols::java_lang_Object()->utf8_length() ==
jl_object_len && vmSymbols::java_lang_Object()->starts_with
(jl_str, jl_len) && vmSymbols::java_lang_Object()->
ends_with("Object", object_len) && vmSymbols::java_lang_Object
()->is_permanent() && vmSymbols::java_lang_String(
)->utf8_length() == jl_object_len && vmSymbols::java_lang_String
()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String
()->ends_with("String", object_len) && vmSymbols::
java_lang_String()->is_permanent())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 342, "assert(" "vmSymbols::java_lang_Object()->utf8_length() == jl_object_len && vmSymbols::java_lang_Object()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_Object()->ends_with(\"Object\", object_len) && vmSymbols::java_lang_Object()->is_permanent() && vmSymbols::java_lang_String()->utf8_length() == jl_object_len && vmSymbols::java_lang_String()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String()->ends_with(\"String\", object_len) && vmSymbols::java_lang_String()->is_permanent()"
") failed", "sanity"); ::breakpoint(); } } while (0)
335 vmSymbols::java_lang_Object()->starts_with(jl_str, jl_len) &&do { if (!(vmSymbols::java_lang_Object()->utf8_length() ==
jl_object_len && vmSymbols::java_lang_Object()->starts_with
(jl_str, jl_len) && vmSymbols::java_lang_Object()->
ends_with("Object", object_len) && vmSymbols::java_lang_Object
()->is_permanent() && vmSymbols::java_lang_String(
)->utf8_length() == jl_object_len && vmSymbols::java_lang_String
()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String
()->ends_with("String", object_len) && vmSymbols::
java_lang_String()->is_permanent())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 342, "assert(" "vmSymbols::java_lang_Object()->utf8_length() == jl_object_len && vmSymbols::java_lang_Object()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_Object()->ends_with(\"Object\", object_len) && vmSymbols::java_lang_Object()->is_permanent() && vmSymbols::java_lang_String()->utf8_length() == jl_object_len && vmSymbols::java_lang_String()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String()->ends_with(\"String\", object_len) && vmSymbols::java_lang_String()->is_permanent()"
") failed", "sanity"); ::breakpoint(); } } while (0)
336 vmSymbols::java_lang_Object()->ends_with("Object", object_len) &&do { if (!(vmSymbols::java_lang_Object()->utf8_length() ==
jl_object_len && vmSymbols::java_lang_Object()->starts_with
(jl_str, jl_len) && vmSymbols::java_lang_Object()->
ends_with("Object", object_len) && vmSymbols::java_lang_Object
()->is_permanent() && vmSymbols::java_lang_String(
)->utf8_length() == jl_object_len && vmSymbols::java_lang_String
()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String
()->ends_with("String", object_len) && vmSymbols::
java_lang_String()->is_permanent())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 342, "assert(" "vmSymbols::java_lang_Object()->utf8_length() == jl_object_len && vmSymbols::java_lang_Object()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_Object()->ends_with(\"Object\", object_len) && vmSymbols::java_lang_Object()->is_permanent() && vmSymbols::java_lang_String()->utf8_length() == jl_object_len && vmSymbols::java_lang_String()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String()->ends_with(\"String\", object_len) && vmSymbols::java_lang_String()->is_permanent()"
") failed", "sanity"); ::breakpoint(); } } while (0)
337 vmSymbols::java_lang_Object()->is_permanent() &&do { if (!(vmSymbols::java_lang_Object()->utf8_length() ==
jl_object_len && vmSymbols::java_lang_Object()->starts_with
(jl_str, jl_len) && vmSymbols::java_lang_Object()->
ends_with("Object", object_len) && vmSymbols::java_lang_Object
()->is_permanent() && vmSymbols::java_lang_String(
)->utf8_length() == jl_object_len && vmSymbols::java_lang_String
()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String
()->ends_with("String", object_len) && vmSymbols::
java_lang_String()->is_permanent())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 342, "assert(" "vmSymbols::java_lang_Object()->utf8_length() == jl_object_len && vmSymbols::java_lang_Object()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_Object()->ends_with(\"Object\", object_len) && vmSymbols::java_lang_Object()->is_permanent() && vmSymbols::java_lang_String()->utf8_length() == jl_object_len && vmSymbols::java_lang_String()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String()->ends_with(\"String\", object_len) && vmSymbols::java_lang_String()->is_permanent()"
") failed", "sanity"); ::breakpoint(); } } while (0)
338 vmSymbols::java_lang_String()->utf8_length() == jl_object_len &&do { if (!(vmSymbols::java_lang_Object()->utf8_length() ==
jl_object_len && vmSymbols::java_lang_Object()->starts_with
(jl_str, jl_len) && vmSymbols::java_lang_Object()->
ends_with("Object", object_len) && vmSymbols::java_lang_Object
()->is_permanent() && vmSymbols::java_lang_String(
)->utf8_length() == jl_object_len && vmSymbols::java_lang_String
()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String
()->ends_with("String", object_len) && vmSymbols::
java_lang_String()->is_permanent())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 342, "assert(" "vmSymbols::java_lang_Object()->utf8_length() == jl_object_len && vmSymbols::java_lang_Object()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_Object()->ends_with(\"Object\", object_len) && vmSymbols::java_lang_Object()->is_permanent() && vmSymbols::java_lang_String()->utf8_length() == jl_object_len && vmSymbols::java_lang_String()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String()->ends_with(\"String\", object_len) && vmSymbols::java_lang_String()->is_permanent()"
") failed", "sanity"); ::breakpoint(); } } while (0)
339 vmSymbols::java_lang_String()->starts_with(jl_str, jl_len) &&do { if (!(vmSymbols::java_lang_Object()->utf8_length() ==
jl_object_len && vmSymbols::java_lang_Object()->starts_with
(jl_str, jl_len) && vmSymbols::java_lang_Object()->
ends_with("Object", object_len) && vmSymbols::java_lang_Object
()->is_permanent() && vmSymbols::java_lang_String(
)->utf8_length() == jl_object_len && vmSymbols::java_lang_String
()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String
()->ends_with("String", object_len) && vmSymbols::
java_lang_String()->is_permanent())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 342, "assert(" "vmSymbols::java_lang_Object()->utf8_length() == jl_object_len && vmSymbols::java_lang_Object()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_Object()->ends_with(\"Object\", object_len) && vmSymbols::java_lang_Object()->is_permanent() && vmSymbols::java_lang_String()->utf8_length() == jl_object_len && vmSymbols::java_lang_String()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String()->ends_with(\"String\", object_len) && vmSymbols::java_lang_String()->is_permanent()"
") failed", "sanity"); ::breakpoint(); } } while (0)
340 vmSymbols::java_lang_String()->ends_with("String", object_len) &&do { if (!(vmSymbols::java_lang_Object()->utf8_length() ==
jl_object_len && vmSymbols::java_lang_Object()->starts_with
(jl_str, jl_len) && vmSymbols::java_lang_Object()->
ends_with("Object", object_len) && vmSymbols::java_lang_Object
()->is_permanent() && vmSymbols::java_lang_String(
)->utf8_length() == jl_object_len && vmSymbols::java_lang_String
()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String
()->ends_with("String", object_len) && vmSymbols::
java_lang_String()->is_permanent())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 342, "assert(" "vmSymbols::java_lang_Object()->utf8_length() == jl_object_len && vmSymbols::java_lang_Object()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_Object()->ends_with(\"Object\", object_len) && vmSymbols::java_lang_Object()->is_permanent() && vmSymbols::java_lang_String()->utf8_length() == jl_object_len && vmSymbols::java_lang_String()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String()->ends_with(\"String\", object_len) && vmSymbols::java_lang_String()->is_permanent()"
") failed", "sanity"); ::breakpoint(); } } while (0)
341 vmSymbols::java_lang_String()->is_permanent(),do { if (!(vmSymbols::java_lang_Object()->utf8_length() ==
jl_object_len && vmSymbols::java_lang_Object()->starts_with
(jl_str, jl_len) && vmSymbols::java_lang_Object()->
ends_with("Object", object_len) && vmSymbols::java_lang_Object
()->is_permanent() && vmSymbols::java_lang_String(
)->utf8_length() == jl_object_len && vmSymbols::java_lang_String
()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String
()->ends_with("String", object_len) && vmSymbols::
java_lang_String()->is_permanent())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 342, "assert(" "vmSymbols::java_lang_Object()->utf8_length() == jl_object_len && vmSymbols::java_lang_Object()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_Object()->ends_with(\"Object\", object_len) && vmSymbols::java_lang_Object()->is_permanent() && vmSymbols::java_lang_String()->utf8_length() == jl_object_len && vmSymbols::java_lang_String()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String()->ends_with(\"String\", object_len) && vmSymbols::java_lang_String()->is_permanent()"
") failed", "sanity"); ::breakpoint(); } } while (0)
342 "sanity")do { if (!(vmSymbols::java_lang_Object()->utf8_length() ==
jl_object_len && vmSymbols::java_lang_Object()->starts_with
(jl_str, jl_len) && vmSymbols::java_lang_Object()->
ends_with("Object", object_len) && vmSymbols::java_lang_Object
()->is_permanent() && vmSymbols::java_lang_String(
)->utf8_length() == jl_object_len && vmSymbols::java_lang_String
()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String
()->ends_with("String", object_len) && vmSymbols::
java_lang_String()->is_permanent())) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 342, "assert(" "vmSymbols::java_lang_Object()->utf8_length() == jl_object_len && vmSymbols::java_lang_Object()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_Object()->ends_with(\"Object\", object_len) && vmSymbols::java_lang_Object()->is_permanent() && vmSymbols::java_lang_String()->utf8_length() == jl_object_len && vmSymbols::java_lang_String()->starts_with(jl_str, jl_len) && vmSymbols::java_lang_String()->ends_with(\"String\", object_len) && vmSymbols::java_lang_String()->is_permanent()"
") failed", "sanity"); ::breakpoint(); } } while (0)
;
343 return true;
344}
345#endif //ASSERT
346
347// returns a symbol; the caller is responsible for decrementing it
348Symbol* SignatureStream::find_symbol() {
349 // Create a symbol from for string _begin _end
350 int begin = raw_symbol_begin();
351 int end = raw_symbol_end();
352
353 const char* symbol_chars = (const char*)_signature->base() + begin;
354 int len = end - begin;
355
356 // Quick check for common symbols in signatures
357 assert(signature_symbols_sane(), "incorrect signature sanity check")do { if (!(signature_symbols_sane())) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 357, "assert(" "signature_symbols_sane()" ") failed", "incorrect signature sanity check"
); ::breakpoint(); } } while (0)
;
358 if (len == jl_object_len &&
359 memcmp(symbol_chars, jl_str, jl_len) == 0) {
360 if (memcmp("String", symbol_chars + jl_len, object_len) == 0) {
361 return vmSymbols::java_lang_String();
362 } else if (memcmp("Object", symbol_chars + jl_len, object_len) == 0) {
363 return vmSymbols::java_lang_Object();
364 }
365 }
366
367 Symbol* name = _previous_name;
368 if (name->equals(symbol_chars, len)) {
369 return name;
370 }
371
372 // Save names for cleaning up reference count at the end of
373 // SignatureStream scope.
374 name = SymbolTable::new_symbol(symbol_chars, len);
375
376 // Only allocate the GrowableArray for the _names buffer if more than
377 // one name is being processed in the signature.
378 if (!_previous_name->is_permanent()) {
379 if (_names == NULL__null) {
380 _names = new GrowableArray<Symbol*>(10);
381 }
382 _names->push(_previous_name);
383 }
384 _previous_name = name;
385 return name;
386}
387
388Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain,
389 FailureMode failure_mode, TRAPSJavaThread* __the_thread__) {
390 if (!is_reference()) {
391 return NULL__null;
392 }
393 Symbol* name = as_symbol();
394 Klass* k = NULL__null;
395 if (failure_mode == ReturnNull) {
396 // Note: SD::resolve_or_null returns NULL for most failure modes,
397 // but not all. Circularity errors, invalid PDs, etc., throw.
398 k = SystemDictionary::resolve_or_null(name, class_loader, protection_domain, CHECK_NULL__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0
);
399 } else if (failure_mode == CachedOrNull) {
400 NoSafepointVerifier nsv; // no loading, now, we mean it!
401 assert(!HAS_PENDING_EXCEPTION, "")do { if (!(!(((ThreadShadow*)__the_thread__)->has_pending_exception
()))) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 401, "assert(" "!(((ThreadShadow*)__the_thread__)->has_pending_exception())"
") failed", ""); ::breakpoint(); } } while (0)
;
402 k = SystemDictionary::find_instance_klass(name, class_loader, protection_domain);
403 // SD::find does not trigger loading, so there should be no throws
404 // Still, bad things can happen, so we CHECK_NULL and ask callers
405 // to do likewise.
406 return k;
407 } else {
408 // The only remaining failure mode is NCDFError.
409 // The test here allows for an additional mode CNFException
410 // if callers need to request the reflective error instead.
411 bool throw_error = (failure_mode == NCDFError);
412 k = SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, CHECK_NULL__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0
);
413 }
414
415 return k;
416}
417
418oop SignatureStream::as_java_mirror(Handle class_loader, Handle protection_domain,
419 FailureMode failure_mode, TRAPSJavaThread* __the_thread__) {
420 if (!is_reference()) {
421 return Universe::java_mirror(type());
422 }
423 Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL__the_thread__); if ((((ThreadShadow*)__the_thread__)->has_pending_exception
())) return __null; (void)(0
);
424 if (klass == NULL__null) {
425 return NULL__null;
426 }
427 return klass->java_mirror();
428}
429
430void SignatureStream::skip_to_return_type() {
431 while (!at_return_type()) {
432 next();
433 }
434}
435
436ResolvingSignatureStream::ResolvingSignatureStream(Symbol* signature,
437 Handle class_loader,
438 Handle protection_domain,
439 bool is_method)
440 : SignatureStream(signature, is_method),
441 _class_loader(class_loader), _protection_domain(protection_domain)
442{
443 initialize_load_origin(NULL__null);
444}
445
446ResolvingSignatureStream::ResolvingSignatureStream(Symbol* signature, Klass* load_origin, bool is_method)
447 : SignatureStream(signature, is_method)
448{
449 assert(load_origin != NULL, "")do { if (!(load_origin != __null)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 449, "assert(" "load_origin != __null" ") failed", ""); ::breakpoint
(); } } while (0)
;
450 initialize_load_origin(load_origin);
451}
452
453ResolvingSignatureStream::ResolvingSignatureStream(const Method* method)
454 : SignatureStream(method->signature(), true)
455{
456 initialize_load_origin(method->method_holder());
457}
458
459ResolvingSignatureStream::ResolvingSignatureStream(fieldDescriptor& field)
460 : SignatureStream(field.signature(), false)
461{
462 initialize_load_origin(field.field_holder());
463}
464
465void ResolvingSignatureStream::cache_handles() {
466 assert(_load_origin != NULL, "")do { if (!(_load_origin != __null)) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 466, "assert(" "_load_origin != __null" ") failed", ""); ::
breakpoint(); } } while (0)
;
467 JavaThread* current = JavaThread::current();
468 _class_loader = Handle(current, _load_origin->class_loader());
469 _protection_domain = Handle(current, _load_origin->protection_domain());
470}
471
472Klass* ResolvingSignatureStream::as_klass_if_loaded(TRAPSJavaThread* __the_thread__) {
473 Klass* klass = as_klass(CachedOrNull, THREAD__the_thread__);
474 // SD::find does not trigger loading, so there should be no throws
475 // Still, bad things can happen, so we CHECK_NULL and ask callers
476 // to do likewise.
477 if (HAS_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->has_pending_exception())) {
478 CLEAR_PENDING_EXCEPTION(((ThreadShadow*)__the_thread__)->clear_pending_exception(
))
;
479 }
480 return klass;
481}
482
483#ifdef ASSERT1
484
485extern bool signature_constants_sane(); // called from basic_types_init()
486
487bool signature_constants_sane() {
488 // for the lookup table, test every 8-bit code point, and then some:
489 for (int i = -256; i <= 256; i++) {
490 int btcode = 0;
491 switch (i) {
492#define EACH_SIG(ch, bt, ignore) \
493 case ch: { btcode = bt; break; }
494 SIGNATURE_TYPES_DO(EACH_SIG, ignore)EACH_SIG(JVM_SIGNATURE_BOOLEAN, T_BOOLEAN, ignore) EACH_SIG(JVM_SIGNATURE_CHAR
, T_CHAR, ignore) EACH_SIG(JVM_SIGNATURE_FLOAT, T_FLOAT, ignore
) EACH_SIG(JVM_SIGNATURE_DOUBLE, T_DOUBLE, ignore) EACH_SIG(JVM_SIGNATURE_BYTE
, T_BYTE, ignore) EACH_SIG(JVM_SIGNATURE_SHORT, T_SHORT, ignore
) EACH_SIG(JVM_SIGNATURE_INT, T_INT, ignore) EACH_SIG(JVM_SIGNATURE_LONG
, T_LONG, ignore) EACH_SIG(JVM_SIGNATURE_CLASS, T_OBJECT, ignore
) EACH_SIG(JVM_SIGNATURE_ARRAY, T_ARRAY, ignore) EACH_SIG(JVM_SIGNATURE_VOID
, T_VOID, ignore)
495#undef EACH_SIG
496 }
497 int btc = decode_signature_char(i);
498 assert(btc == btcode, "misconfigured table: %d => %d not %d", i, btc, btcode)do { if (!(btc == btcode)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.cpp"
, 498, "assert(" "btc == btcode" ") failed", "misconfigured table: %d => %d not %d"
, i, btc, btcode); ::breakpoint(); } } while (0)
;
499 }
500 return true;
501}
502
503bool SignatureVerifier::is_valid_method_signature(Symbol* sig) {
504 const char* method_sig = (const char*)sig->bytes();
505 ssize_t len = sig->utf8_length();
506 ssize_t index = 0;
507 if (method_sig != NULL__null && len > 1 && method_sig[index] == JVM_SIGNATURE_FUNC) {
508 ++index;
509 while (index < len && method_sig[index] != JVM_SIGNATURE_ENDFUNC) {
510 ssize_t res = is_valid_type(&method_sig[index], len - index);
511 if (res == -1) {
512 return false;
513 } else {
514 index += res;
515 }
516 }
517 if (index < len && method_sig[index] == JVM_SIGNATURE_ENDFUNC) {
518 // check the return type
519 ++index;
520 return (is_valid_type(&method_sig[index], len - index) == (len - index));
521 }
522 }
523 return false;
524}
525
526bool SignatureVerifier::is_valid_type_signature(Symbol* sig) {
527 const char* type_sig = (const char*)sig->bytes();
528 ssize_t len = sig->utf8_length();
529 return (type_sig != NULL__null && len >= 1 &&
530 (is_valid_type(type_sig, len) == len));
531}
532
533// Checks to see if the type (not to go beyond 'limit') refers to a valid type.
534// Returns -1 if it is not, or the index of the next character that is not part
535// of the type. The type encoding may end before 'limit' and that's ok.
536ssize_t SignatureVerifier::is_valid_type(const char* type, ssize_t limit) {
537 ssize_t index = 0;
538
539 // Iterate over any number of array dimensions
540 while (index < limit && type[index] == JVM_SIGNATURE_ARRAY) ++index;
541 if (index >= limit) {
542 return -1;
543 }
544 switch (type[index]) {
545 case JVM_SIGNATURE_BYTE:
546 case JVM_SIGNATURE_CHAR:
547 case JVM_SIGNATURE_FLOAT:
548 case JVM_SIGNATURE_DOUBLE:
549 case JVM_SIGNATURE_INT:
550 case JVM_SIGNATURE_LONG:
551 case JVM_SIGNATURE_SHORT:
552 case JVM_SIGNATURE_BOOLEAN:
553 case JVM_SIGNATURE_VOID:
554 return index + 1;
555 case JVM_SIGNATURE_CLASS:
556 for (index = index + 1; index < limit; ++index) {
557 char c = type[index];
558 switch (c) {
559 case JVM_SIGNATURE_ENDCLASS:
560 return index + 1;
561 case '\0': case JVM_SIGNATURE_DOT: case JVM_SIGNATURE_ARRAY:
562 return -1;
563 default: ; // fall through
564 }
565 }
566 // fall through
567 default: ; // fall through
568 }
569 return -1;
570}
571
572#endif // ASSERT

/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp

1/*
2 * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2021, Azul Systems, Inc. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26#ifndef SHARE_RUNTIME_SIGNATURE_HPP
27#define SHARE_RUNTIME_SIGNATURE_HPP
28
29#include "memory/allocation.hpp"
30#include "oops/method.hpp"
31
32
33// Static routines and parsing loops for processing field and method
34// descriptors. In the HotSpot sources we call them "signatures".
35//
36// A SignatureStream iterates over a Java descriptor (or parts of it).
37// The syntax is documented in the Java Virtual Machine Specification,
38// section 4.3.
39//
40// The syntax may be summarized as follows:
41//
42// MethodType: '(' {FieldType}* ')' (FieldType | 'V')
43// FieldType: PrimitiveType | ObjectType | ArrayType
44// PrimitiveType: 'B' | 'C' | 'D' | 'F' | 'I' | 'J' | 'S' | 'Z'
45// ObjectType: 'L' ClassName ';' | ArrayType
46// ArrayType: '[' FieldType
47// ClassName: {UnqualifiedName '/'}* UnqualifiedName
48// UnqualifiedName: NameChar {NameChar}*
49// NameChar: ANY_CHAR_EXCEPT('/' | '.' | ';' | '[')
50//
51// All of the concrete characters in the above grammar are given
52// standard manifest constant names of the form JVM_SIGNATURE_x.
53// Executable code uses these constant names in preference to raw
54// character constants. Comments and assertion code sometimes use
55// the raw character constants for brevity.
56//
57// The primitive field types (like 'I') correspond 1-1 with type codes
58// (like T_INT) which form part of the specification of the 'newarray'
59// instruction (JVMS 6.5, section on newarray). These type codes are
60// widely used in the HotSpot code. They are joined by ad hoc codes
61// like T_OBJECT and T_ARRAY (defined in HotSpot but not in the JVMS)
62// so that each "basic type" of field descriptor (or void return type)
63// has a corresponding T_x code. Thus, while T_x codes play a very
64// minor role in the JVMS, they play a major role in the HotSpot
65// sources. There are fewer than 16 such "basic types", so they fit
66// nicely into bitfields.
67//
68// The syntax of ClassName overlaps slightly with the descriptor
69// syntaxes. The strings "I" and "(I)V" are both class names
70// *and* descriptors. If a class name contains any character other
71// than "BCDFIJSZ()V" it cannot be confused with a descriptor.
72// Class names inside of descriptors are always contained in an
73// "envelope" syntax which starts with 'L' and ends with ';'.
74//
75// As a confounding factor, array types report their type name strings
76// in descriptor format. These name strings are easy to recognize,
77// since they begin with '['. For this reason some API points on
78// HotSpot look for array descriptors as well as proper class names.
79//
80// For historical reasons some API points that accept class names and
81// array names also look for class names wrapped inside an envelope
82// (like "LFoo;") and unwrap them on the fly (to a name like "Foo").
83
84class Signature : AllStatic {
85 private:
86 static bool is_valid_array_signature(const Symbol* sig);
87
88 public:
89
90 // Returns the basic type of a field signature (or T_VOID for "V").
91 // Assumes the signature is a valid field descriptor.
92 // Do not apply this function to class names or method signatures.
93 static BasicType basic_type(const Symbol* signature) {
94 return basic_type(signature->char_at(0));
95 }
96
97 // Returns T_ILLEGAL for an illegal signature char.
98 static BasicType basic_type(int ch);
99
100 // Assuming it is either a class name or signature,
101 // determine if it in fact cannot be a class name.
102 // This means it either starts with '[' or ends with ';'
103 static bool not_class_name(const Symbol* signature) {
104 return (signature->starts_with(JVM_SIGNATURE_ARRAY) ||
105 signature->ends_with(JVM_SIGNATURE_ENDCLASS));
106 }
107
108 // Assuming it is either a class name or signature,
109 // determine if it in fact is an array descriptor.
110 static bool is_array(const Symbol* signature) {
111 return (signature->utf8_length() > 1 &&
112 signature->char_at(0) == JVM_SIGNATURE_ARRAY &&
113 is_valid_array_signature(signature));
114 }
115
116 // Assuming it is either a class name or signature,
117 // determine if it contains a class name plus ';'.
118 static bool has_envelope(const Symbol* signature) {
119 return ((signature->utf8_length() > 0) &&
120 signature->ends_with(JVM_SIGNATURE_ENDCLASS) &&
121 has_envelope(signature->char_at(0)));
122 }
123
124 // Determine if this signature char introduces an
125 // envelope, which is a class name plus ';'.
126 static bool has_envelope(char signature_char) {
127 return (signature_char == JVM_SIGNATURE_CLASS);
128 }
129
130 // Assuming has_envelope is true, return the symbol
131 // inside the envelope, by stripping 'L' and ';'.
132 // Caller is responsible for decrementing the newly created
133 // Symbol's refcount, use TempNewSymbol.
134 static Symbol* strip_envelope(const Symbol* signature);
135
136 // Assuming it's either a field or method descriptor, determine
137 // whether it is in fact a method descriptor:
138 static bool is_method(const Symbol* signature) {
139 return signature->starts_with(JVM_SIGNATURE_FUNC);
140 }
141
142 // Assuming it's a method signature, determine if it must
143 // return void.
144 static bool is_void_method(const Symbol* signature) {
145 assert(is_method(signature), "signature is not for a method")do { if (!(is_method(signature))) { (*g_assert_poison) = 'X';
; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 145, "assert(" "is_method(signature)" ") failed", "signature is not for a method"
); ::breakpoint(); } } while (0)
;
146 return signature->ends_with(JVM_SIGNATURE_VOID);
147 }
148};
149
150// A SignatureIterator uses a SignatureStream to produce BasicType
151// results, discarding class names. This means it can be accelerated
152// using a fingerprint mechanism, in many cases, without loss of type
153// information. The FingerPrinter class computes and caches this
154// reduced information for faster iteration.
155
156class SignatureIterator: public ResourceObj {
157 public:
158 typedef uint64_t fingerprint_t;
159
160 protected:
161 Symbol* _signature; // the signature to iterate over
162 BasicType _return_type;
163 fingerprint_t _fingerprint;
164
165 public:
166 // Definitions used in generating and iterating the
167 // bit field form of the signature generated by the
168 // Fingerprinter.
169 enum {
170 fp_static_feature_size = 1,
171 fp_is_static_bit = 1,
172
173 fp_result_feature_size = 4,
174 fp_result_feature_mask = right_n_bits(fp_result_feature_size)((((fp_result_feature_size) >= BitsPerWord) ? 0 : (OneBit <<
(fp_result_feature_size))) - 1)
,
175 fp_parameter_feature_size = 4,
176 fp_parameter_feature_mask = right_n_bits(fp_parameter_feature_size)((((fp_parameter_feature_size) >= BitsPerWord) ? 0 : (OneBit
<< (fp_parameter_feature_size))) - 1)
,
177
178 fp_parameters_done = 0, // marker for end of parameters (must be zero)
179
180 // Parameters take up full wordsize, minus the result and static bit fields.
181 // Since fp_parameters_done is zero, termination field arises from shifting
182 // in zero bits, and therefore occupies no extra space.
183 // The sentinel value is all-zero-bits, which is impossible for a true
184 // fingerprint, since at least the result field will be non-zero.
185 fp_max_size_of_parameters = ((BitsPerLong
186 - (fp_result_feature_size + fp_static_feature_size))
187 / fp_parameter_feature_size)
188 };
189
190 static bool fp_is_valid_type(BasicType type, bool for_return_type = false);
191
192 // Sentinel values are zero and not-zero (-1).
193 // No need to protect the sign bit, since every valid return type is non-zero
194 // (even T_VOID), and there are no valid parameter fields which are 0xF (T_VOID).
195 static fingerprint_t zero_fingerprint() { return (fingerprint_t)0; }
196 static fingerprint_t overflow_fingerprint() { return ~(fingerprint_t)0; }
197 static bool fp_is_valid(fingerprint_t fingerprint) {
198 return (fingerprint != zero_fingerprint()) && (fingerprint != overflow_fingerprint());
199 }
200
201 // Constructors
202 SignatureIterator(Symbol* signature, fingerprint_t fingerprint = zero_fingerprint()) {
203 _signature = signature;
204 _return_type = T_ILLEGAL; // sentinel value for uninitialized
205 _fingerprint = zero_fingerprint();
206 if (fingerprint != _fingerprint) {
207 set_fingerprint(fingerprint);
208 }
209 }
210
211 // If the fingerprint is present, we can use an accelerated loop.
212 void set_fingerprint(fingerprint_t fingerprint);
213
214 // Returns the set fingerprint, or zero_fingerprint()
215 // if none has been set already.
216 fingerprint_t fingerprint() const { return _fingerprint; }
217
218 // Iteration
219 // Hey look: There are no virtual methods in this class.
220 // So how is it customized? By calling do_parameters_on
221 // an object which answers to "do_type(BasicType)".
222 // By convention, this object is in the subclass
223 // itself, so the call is "do_parameters_on(this)".
224 // The effect of this is to inline the parsing loop
225 // everywhere "do_parameters_on" is called.
226 // If there is a valid fingerprint in the object,
227 // an improved loop is called which just unpacks the
228 // bitfields from the fingerprint. Otherwise, the
229 // symbol is parsed.
230 template<typename T> inline void do_parameters_on(T* callback); // iterates over parameters only
231 BasicType return_type(); // computes the value on the fly if necessary
232
233 static bool fp_is_static(fingerprint_t fingerprint) {
234 assert(fp_is_valid(fingerprint), "invalid fingerprint")do { if (!(fp_is_valid(fingerprint))) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 234, "assert(" "fp_is_valid(fingerprint)" ") failed", "invalid fingerprint"
); ::breakpoint(); } } while (0)
;
235 return fingerprint & fp_is_static_bit;
236 }
237 static BasicType fp_return_type(fingerprint_t fingerprint) {
238 assert(fp_is_valid(fingerprint), "invalid fingerprint")do { if (!(fp_is_valid(fingerprint))) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 238, "assert(" "fp_is_valid(fingerprint)" ") failed", "invalid fingerprint"
); ::breakpoint(); } } while (0)
;
239 return (BasicType) ((fingerprint >> fp_static_feature_size) & fp_result_feature_mask);
240 }
241 static fingerprint_t fp_start_parameters(fingerprint_t fingerprint) {
242 assert(fp_is_valid(fingerprint), "invalid fingerprint")do { if (!(fp_is_valid(fingerprint))) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 242, "assert(" "fp_is_valid(fingerprint)" ") failed", "invalid fingerprint"
); ::breakpoint(); } } while (0)
;
243 return fingerprint >> (fp_static_feature_size + fp_result_feature_size);
244 }
245 static BasicType fp_next_parameter(fingerprint_t& mask) {
246 int result = (mask & fp_parameter_feature_mask);
247 mask >>= fp_parameter_feature_size;
248 return (BasicType) result;
249 }
250};
251
252
253// Specialized SignatureIterators: Used to compute signature specific values.
254
255class SignatureTypeNames : public SignatureIterator {
256 protected:
257 virtual void type_name(const char* name) = 0;
258
259 friend class SignatureIterator; // so do_parameters_on can call do_type
260 void do_type(BasicType type) {
261 switch (type) {
262 case T_BOOLEAN: type_name("jboolean"); break;
263 case T_CHAR: type_name("jchar" ); break;
264 case T_FLOAT: type_name("jfloat" ); break;
265 case T_DOUBLE: type_name("jdouble" ); break;
266 case T_BYTE: type_name("jbyte" ); break;
267 case T_SHORT: type_name("jshort" ); break;
268 case T_INT: type_name("jint" ); break;
269 case T_LONG: type_name("jlong" ); break;
270 case T_VOID: type_name("void" ); break;
271 case T_ARRAY:
272 case T_OBJECT: type_name("jobject" ); break;
273 default: ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 273); ::breakpoint(); } while (0)
;
274 }
275 }
276
277 public:
278 SignatureTypeNames(Symbol* signature) : SignatureIterator(signature) {}
279};
280
281
282// Specialized SignatureIterator: Used to compute the argument size.
283
284class ArgumentSizeComputer: public SignatureIterator {
285 private:
286 int _size;
287 friend class SignatureIterator; // so do_parameters_on can call do_type
288 void do_type(BasicType type) { _size += parameter_type_word_count(type); }
289 public:
290 ArgumentSizeComputer(Symbol* signature);
291 int size() { return _size; }
292};
293
294
295class ArgumentCount: public SignatureIterator {
296 private:
297 int _size;
298 friend class SignatureIterator; // so do_parameters_on can call do_type
299 void do_type(BasicType type) { _size++; }
300 public:
301 ArgumentCount(Symbol* signature);
302 int size() { return _size; }
303};
304
305
306class ReferenceArgumentCount: public SignatureIterator {
307 private:
308 int _refs;
309 friend class SignatureIterator; // so do_parameters_on can call do_type
310 void do_type(BasicType type) { if (is_reference_type(type)) _refs++; }
311 public:
312 ReferenceArgumentCount(Symbol* signature);
313 int count() { return _refs; }
314};
315
316
317// Specialized SignatureIterator: Used to compute the result type.
318
319class ResultTypeFinder: public SignatureIterator {
320 public:
321 BasicType type() { return return_type(); }
322 ResultTypeFinder(Symbol* signature) : SignatureIterator(signature) { }
323};
324
325
326// Fingerprinter computes a unique ID for a given method. The ID
327// is a bitvector characterizing the methods signature (incl. the receiver).
328class Fingerprinter: public SignatureIterator {
329 private:
330 fingerprint_t _accumulator;
331 int _param_size;
332 int _shift_count;
333 const Method* _method;
334
335 void initialize_accumulator() {
336 _accumulator = 0;
337 _shift_count = fp_result_feature_size + fp_static_feature_size;
338 _param_size = 0;
339 }
340
341 // Out-of-line method does it all in constructor:
342 void compute_fingerprint_and_return_type(bool static_flag = false);
343
344 friend class SignatureIterator; // so do_parameters_on can call do_type
345 void do_type(BasicType type) {
346 assert(fp_is_valid_type(type), "bad parameter type")do { if (!(fp_is_valid_type(type))) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 346, "assert(" "fp_is_valid_type(type)" ") failed", "bad parameter type"
); ::breakpoint(); } } while (0)
;
347 _accumulator |= ((fingerprint_t)type << _shift_count);
348 _shift_count += fp_parameter_feature_size;
349 _param_size += (is_double_word_type(type) ? 2 : 1);
350 }
351
352 public:
353 int size_of_parameters() const { return _param_size; }
354 // fingerprint() and return_type() are in super class
355
356 Fingerprinter(const methodHandle& method)
357 : SignatureIterator(method->signature()),
358 _method(method()) {
359 compute_fingerprint_and_return_type();
360 }
361 Fingerprinter(Symbol* signature, bool is_static)
362 : SignatureIterator(signature),
363 _method(NULL__null) {
364 compute_fingerprint_and_return_type(is_static);
365 }
366};
367
368
369// Specialized SignatureIterator: Used for native call purposes
370
371class NativeSignatureIterator: public SignatureIterator {
372 private:
373 methodHandle _method;
374// We need separate JNI and Java offset values because in 64 bit mode,
375// the argument offsets are not in sync with the Java stack.
376// For example a long takes up 1 "C" stack entry but 2 Java stack entries.
377 int _offset; // The java stack offset
378 int _prepended; // number of prepended JNI parameters (1 JNIEnv, plus 1 mirror if static)
379 int _jni_offset; // the current parameter offset, starting with 0
380
381 friend class SignatureIterator; // so do_parameters_on can call do_type
382 void do_type(BasicType type) {
383 switch (type) {
384 case T_BYTE:
385 case T_BOOLEAN:
386 pass_byte(); _jni_offset++; _offset++;
387 break;
388 case T_CHAR:
389 case T_SHORT:
390 pass_short(); _jni_offset++; _offset++;
391 break;
392 case T_INT:
393 pass_int(); _jni_offset++; _offset++;
394 break;
395 case T_FLOAT:
396 pass_float(); _jni_offset++; _offset++;
397 break;
398 case T_DOUBLE: {
399 int jni_offset = LP64_ONLY(1)1 NOT_LP64(2);
400 pass_double(); _jni_offset += jni_offset; _offset += 2;
401 break;
402 }
403 case T_LONG: {
404 int jni_offset = LP64_ONLY(1)1 NOT_LP64(2);
405 pass_long(); _jni_offset += jni_offset; _offset += 2;
406 break;
407 }
408 case T_ARRAY:
409 case T_OBJECT:
410 pass_object(); _jni_offset++; _offset++;
411 break;
412 default:
413 ShouldNotReachHere()do { (*g_assert_poison) = 'X';; report_should_not_reach_here(
"/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 413); ::breakpoint(); } while (0)
;
414 }
415 }
416
417 public:
418 methodHandle method() const { return _method; }
419 int offset() const { return _offset; }
420 int jni_offset() const { return _jni_offset + _prepended; }
421 bool is_static() const { return method()->is_static(); }
422 virtual void pass_int() = 0;
423 virtual void pass_long() = 0;
424 virtual void pass_object() = 0; // objects, arrays, inlines
425 virtual void pass_float() = 0;
426 virtual void pass_byte() { pass_int(); };
427 virtual void pass_short() { pass_int(); };
428#ifdef _LP641
429 virtual void pass_double() = 0;
430#else
431 virtual void pass_double() { pass_long(); } // may be same as long
432#endif
433
434 NativeSignatureIterator(const methodHandle& method) : SignatureIterator(method->signature()) {
435 _method = method;
436 _offset = 0;
437 _jni_offset = 0;
438
439 const int JNIEnv_words = 1;
440 const int mirror_words = 1;
441 _prepended = !is_static() ? JNIEnv_words : JNIEnv_words + mirror_words;
442 }
443
444 void iterate() { iterate(Fingerprinter(method()).fingerprint()); }
445
446 // iterate() calls the 3 virtual methods according to the following invocation syntax:
447 //
448 // {pass_int | pass_long | pass_object}
449 //
450 // Arguments are handled from left to right (receiver first, if any).
451 // The offset() values refer to the Java stack offsets but are 0 based and increasing.
452 // The java_offset() values count down to 0, and refer to the Java TOS.
453 // The jni_offset() values increase from 1 or 2, and refer to C arguments.
454 // The method's return type is ignored.
455
456 void iterate(fingerprint_t fingerprint) {
457 set_fingerprint(fingerprint);
458 if (!is_static()) {
459 // handle receiver (not handled by iterate because not in signature)
460 pass_object(); _jni_offset++; _offset++;
461 }
462 do_parameters_on(this);
463 }
464};
465
466
467// This is the core parsing logic for iterating over signatures.
468// All of the previous classes use this for doing their work.
469
470class SignatureStream : public StackObj {
471 private:
472 const Symbol* _signature;
473 int _begin;
474 int _end;
475 int _limit;
476 int _array_prefix; // count of '[' before the array element descr
477 BasicType _type;
478 int _state;
479 Symbol* _previous_name; // cache the previously looked up symbol to avoid lookups
480 GrowableArray<Symbol*>* _names; // symbols created while parsing that need to be dereferenced
481
482 Symbol* find_symbol();
483
484 enum { _s_field = 0, _s_method = 1, _s_method_return = 3 };
485 void set_done() {
486 _state |= -2; // preserve s_method bit
487 assert(is_done(), "Unable to set state to done")do { if (!(is_done())) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 487, "assert(" "is_done()" ") failed", "Unable to set state to done"
); ::breakpoint(); } } while (0)
;
488 }
489 int scan_type(BasicType bt);
490
491 public:
492 bool at_return_type() const { return _state == (int)_s_method_return; }
493 bool is_done() const { return _state < 0; }
494 void next();
495
496 SignatureStream(const Symbol* signature, bool is_method = true);
497 ~SignatureStream();
498
499 bool is_reference() const { return is_reference_type(_type); }
500 bool is_array() const { return _type == T_ARRAY; }
501 bool is_primitive() const { return is_java_primitive(_type); }
502 BasicType type() const { return _type; }
11
Undefined or garbage value returned to caller
503
504 const u1* raw_bytes() const { return _signature->bytes() + _begin; }
505 int raw_length() const { return _end - _begin; }
506 int raw_symbol_begin() const { return _begin + (has_envelope() ? 1 : 0); }
507 int raw_symbol_end() const { return _end - (has_envelope() ? 1 : 0); }
508 char raw_char_at(int i) const {
509 assert(i < _limit, "index for raw_char_at is over the limit")do { if (!(i < _limit)) { (*g_assert_poison) = 'X';; report_vm_error
("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 509, "assert(" "i < _limit" ") failed", "index for raw_char_at is over the limit"
); ::breakpoint(); } } while (0)
;
510 return _signature->char_at(i);
511 }
512
513 // True if there is an embedded class name in this type,
514 // followed by ';'.
515 bool has_envelope() const {
516 if (!Signature::has_envelope(_signature->char_at(_begin)))
517 return false;
518 // this should always be true, but let's test it:
519 assert(_signature->char_at(_end-1) == JVM_SIGNATURE_ENDCLASS, "signature envelope has no semi-colon at end")do { if (!(_signature->char_at(_end-1) == JVM_SIGNATURE_ENDCLASS
)) { (*g_assert_poison) = 'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 519, "assert(" "_signature->char_at(_end-1) == JVM_SIGNATURE_ENDCLASS"
") failed", "signature envelope has no semi-colon at end"); ::
breakpoint(); } } while (0)
;
520 return true;
521 }
522
523 // return the symbol for chars in symbol_begin()..symbol_end()
524 Symbol* as_symbol() {
525 return find_symbol();
526 }
527
528 // in case you want only the return type:
529 void skip_to_return_type();
530
531 // number of '[' in array prefix
532 int array_prefix_length() {
533 return _type == T_ARRAY ? _array_prefix : 0;
534 }
535
536 // In case you want only the array base type,
537 // reset the stream after skipping some brackets '['.
538 // (The argument is clipped to array_prefix_length(),
539 // and if it ends up as zero this call is a nop.
540 // The default is value skips all brackets '['.)
541 private:
542 int skip_whole_array_prefix();
543 public:
544 int skip_array_prefix(int max_skip_length) {
545 if (_type != T_ARRAY) {
546 return 0;
547 }
548 if (_array_prefix > max_skip_length) {
549 // strip some but not all levels of T_ARRAY
550 _array_prefix -= max_skip_length;
551 _begin += max_skip_length;
552 return max_skip_length;
553 }
554 return skip_whole_array_prefix();
555 }
556 int skip_array_prefix() {
557 if (_type != T_ARRAY) {
558 return 0;
559 }
560 return skip_whole_array_prefix();
561 }
562
563 // free-standing lookups (bring your own CL/PD pair)
564 enum FailureMode { ReturnNull, NCDFError, CachedOrNull };
565 Klass* as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPSJavaThread* __the_thread__);
566 oop as_java_mirror(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPSJavaThread* __the_thread__);
567};
568
569// Specialized SignatureStream: used for invoking SystemDictionary to either find
570// or resolve the underlying type when iterating over a
571// Java descriptor (or parts of it).
572class ResolvingSignatureStream : public SignatureStream {
573 Klass* _load_origin;
574 bool _handles_cached;
575 Handle _class_loader; // cached when needed
576 Handle _protection_domain; // cached when needed
577
578 void initialize_load_origin(Klass* load_origin) {
579 _load_origin = load_origin;
580 _handles_cached = (load_origin == NULL__null);
581 }
582 void need_handles() {
583 if (!_handles_cached) {
584 cache_handles();
585 _handles_cached = true;
586 }
587 }
588 void cache_handles();
589
590 public:
591 ResolvingSignatureStream(Symbol* signature, Klass* load_origin, bool is_method = true);
592 ResolvingSignatureStream(Symbol* signature, Handle class_loader, Handle protection_domain, bool is_method = true);
593 ResolvingSignatureStream(const Method* method);
594 ResolvingSignatureStream(fieldDescriptor& field);
595
596 Klass* load_origin() { return _load_origin; }
597 Handle class_loader() { need_handles(); return _class_loader; }
598 Handle protection_domain() { need_handles(); return _protection_domain; }
599
600 Klass* as_klass_if_loaded(TRAPSJavaThread* __the_thread__);
601 Klass* as_klass(FailureMode failure_mode, TRAPSJavaThread* __the_thread__) {
602 need_handles();
603 return SignatureStream::as_klass(_class_loader, _protection_domain,
604 failure_mode, THREAD__the_thread__);
605 }
606 oop as_java_mirror(FailureMode failure_mode, TRAPSJavaThread* __the_thread__) {
607 if (is_reference()) {
608 need_handles();
609 }
610 return SignatureStream::as_java_mirror(_class_loader, _protection_domain,
611 failure_mode, THREAD__the_thread__);
612 }
613};
614
615// Here is how all the SignatureIterator classes invoke the
616// SignatureStream engine to do their parsing.
617template<typename T> inline
618void SignatureIterator::do_parameters_on(T* callback) {
619 fingerprint_t unaccumulator = _fingerprint;
620
621 // Check for too many arguments, or missing fingerprint:
622 if (!fp_is_valid(unaccumulator)) {
2
Taking true branch
623 SignatureStream ss(_signature);
3
Calling constructor for 'SignatureStream'
8
Returning from constructor for 'SignatureStream'
624 for (; !ss.at_return_type(); ss.next()) {
9
Loop condition is true. Entering loop body
625 callback->do_type(ss.type());
10
Calling 'SignatureStream::type'
626 }
627 // while we are here, capture the return type
628 _return_type = ss.type();
629 } else {
630 // Optimized version of do_parameters when fingerprint is known
631 assert(_return_type != T_ILLEGAL, "return type already captured from fp")do { if (!(_return_type != T_ILLEGAL)) { (*g_assert_poison) =
'X';; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 631, "assert(" "_return_type != T_ILLEGAL" ") failed", "return type already captured from fp"
); ::breakpoint(); } } while (0)
;
632 unaccumulator = fp_start_parameters(unaccumulator);
633 for (BasicType type; (type = fp_next_parameter(unaccumulator)) != (BasicType)fp_parameters_done; ) {
634 assert(fp_is_valid_type(type), "garbled fingerprint")do { if (!(fp_is_valid_type(type))) { (*g_assert_poison) = 'X'
;; report_vm_error("/home/daniel/Projects/java/jdk/src/hotspot/share/runtime/signature.hpp"
, 634, "assert(" "fp_is_valid_type(type)" ") failed", "garbled fingerprint"
); ::breakpoint(); } } while (0)
;
635 callback->do_type(type);
636 }
637 }
638}
639
640 #ifdef ASSERT1
641 class SignatureVerifier : public StackObj {
642 public:
643 static bool is_valid_method_signature(Symbol* sig);
644 static bool is_valid_type_signature(Symbol* sig);
645 private:
646 static ssize_t is_valid_type(const char*, ssize_t);
647};
648#endif
649#endif // SHARE_RUNTIME_SIGNATURE_HPP