1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/runtime/signature.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,472 @@ 1.4 +/* 1.5 + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "classfile/symbolTable.hpp" 1.30 +#include "classfile/systemDictionary.hpp" 1.31 +#include "memory/oopFactory.hpp" 1.32 +#include "oops/instanceKlass.hpp" 1.33 +#include "oops/oop.inline.hpp" 1.34 +#include "oops/symbol.hpp" 1.35 +#include "oops/typeArrayKlass.hpp" 1.36 +#include "runtime/signature.hpp" 1.37 + 1.38 +PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 1.39 + 1.40 +// Implementation of SignatureIterator 1.41 + 1.42 +// Signature syntax: 1.43 +// 1.44 +// Signature = "(" {Parameter} ")" ReturnType. 1.45 +// Parameter = FieldType. 1.46 +// ReturnType = FieldType | "V". 1.47 +// FieldType = "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z" | "L" ClassName ";" | "[" FieldType. 1.48 +// ClassName = string. 1.49 + 1.50 + 1.51 +SignatureIterator::SignatureIterator(Symbol* signature) { 1.52 + _signature = signature; 1.53 + _parameter_index = 0; 1.54 +} 1.55 + 1.56 +void SignatureIterator::expect(char c) { 1.57 + if (_signature->byte_at(_index) != c) fatal(err_msg("expecting %c", c)); 1.58 + _index++; 1.59 +} 1.60 + 1.61 + 1.62 +void SignatureIterator::skip_optional_size() { 1.63 + Symbol* sig = _signature; 1.64 + char c = sig->byte_at(_index); 1.65 + while ('0' <= c && c <= '9') c = sig->byte_at(++_index); 1.66 +} 1.67 + 1.68 + 1.69 +int SignatureIterator::parse_type() { 1.70 + // Note: This function could be simplified by using "return T_XXX_size;" 1.71 + // instead of the assignment and the break statements. However, it 1.72 + // seems that the product build for win32_i486 with MS VC++ 6.0 doesn't 1.73 + // work (stack underflow for some tests) - this seems to be a VC++ 6.0 1.74 + // compiler bug (was problem - gri 4/27/2000). 1.75 + int size = -1; 1.76 + switch(_signature->byte_at(_index)) { 1.77 + case 'B': do_byte (); if (_parameter_index < 0 ) _return_type = T_BYTE; 1.78 + _index++; size = T_BYTE_size ; break; 1.79 + case 'C': do_char (); if (_parameter_index < 0 ) _return_type = T_CHAR; 1.80 + _index++; size = T_CHAR_size ; break; 1.81 + case 'D': do_double(); if (_parameter_index < 0 ) _return_type = T_DOUBLE; 1.82 + _index++; size = T_DOUBLE_size ; break; 1.83 + case 'F': do_float (); if (_parameter_index < 0 ) _return_type = T_FLOAT; 1.84 + _index++; size = T_FLOAT_size ; break; 1.85 + case 'I': do_int (); if (_parameter_index < 0 ) _return_type = T_INT; 1.86 + _index++; size = T_INT_size ; break; 1.87 + case 'J': do_long (); if (_parameter_index < 0 ) _return_type = T_LONG; 1.88 + _index++; size = T_LONG_size ; break; 1.89 + case 'S': do_short (); if (_parameter_index < 0 ) _return_type = T_SHORT; 1.90 + _index++; size = T_SHORT_size ; break; 1.91 + case 'Z': do_bool (); if (_parameter_index < 0 ) _return_type = T_BOOLEAN; 1.92 + _index++; size = T_BOOLEAN_size; break; 1.93 + case 'V': do_void (); if (_parameter_index < 0 ) _return_type = T_VOID; 1.94 + _index++; size = T_VOID_size; ; break; 1.95 + case 'L': 1.96 + { int begin = ++_index; 1.97 + Symbol* sig = _signature; 1.98 + while (sig->byte_at(_index++) != ';') ; 1.99 + do_object(begin, _index); 1.100 + } 1.101 + if (_parameter_index < 0 ) _return_type = T_OBJECT; 1.102 + size = T_OBJECT_size; 1.103 + break; 1.104 + case '[': 1.105 + { int begin = ++_index; 1.106 + skip_optional_size(); 1.107 + Symbol* sig = _signature; 1.108 + while (sig->byte_at(_index) == '[') { 1.109 + _index++; 1.110 + skip_optional_size(); 1.111 + } 1.112 + if (sig->byte_at(_index) == 'L') { 1.113 + while (sig->byte_at(_index++) != ';') ; 1.114 + } else { 1.115 + _index++; 1.116 + } 1.117 + do_array(begin, _index); 1.118 + if (_parameter_index < 0 ) _return_type = T_ARRAY; 1.119 + } 1.120 + size = T_ARRAY_size; 1.121 + break; 1.122 + default: 1.123 + ShouldNotReachHere(); 1.124 + break; 1.125 + } 1.126 + assert(size >= 0, "size must be set"); 1.127 + return size; 1.128 +} 1.129 + 1.130 + 1.131 +void SignatureIterator::check_signature_end() { 1.132 + if (_index < _signature->utf8_length()) { 1.133 + tty->print_cr("too many chars in signature"); 1.134 + _signature->print_value_on(tty); 1.135 + tty->print_cr(" @ %d", _index); 1.136 + } 1.137 +} 1.138 + 1.139 + 1.140 +void SignatureIterator::dispatch_field() { 1.141 + // no '(', just one (field) type 1.142 + _index = 0; 1.143 + _parameter_index = 0; 1.144 + parse_type(); 1.145 + check_signature_end(); 1.146 +} 1.147 + 1.148 + 1.149 +void SignatureIterator::iterate_parameters() { 1.150 + // Parse parameters 1.151 + _index = 0; 1.152 + _parameter_index = 0; 1.153 + expect('('); 1.154 + while (_signature->byte_at(_index) != ')') _parameter_index += parse_type(); 1.155 + expect(')'); 1.156 + _parameter_index = 0; 1.157 +} 1.158 + 1.159 +// Optimized version of iterat_parameters when fingerprint is known 1.160 +void SignatureIterator::iterate_parameters( uint64_t fingerprint ) { 1.161 + uint64_t saved_fingerprint = fingerprint; 1.162 + 1.163 + // Check for too many arguments 1.164 + if ( fingerprint == UCONST64(-1) ) { 1.165 + SignatureIterator::iterate_parameters(); 1.166 + return; 1.167 + } 1.168 + 1.169 + assert(fingerprint, "Fingerprint should not be 0"); 1.170 + 1.171 + _parameter_index = 0; 1.172 + fingerprint = fingerprint >> (static_feature_size + result_feature_size); 1.173 + while ( 1 ) { 1.174 + switch ( fingerprint & parameter_feature_mask ) { 1.175 + case bool_parm: 1.176 + do_bool(); 1.177 + _parameter_index += T_BOOLEAN_size; 1.178 + break; 1.179 + case byte_parm: 1.180 + do_byte(); 1.181 + _parameter_index += T_BYTE_size; 1.182 + break; 1.183 + case char_parm: 1.184 + do_char(); 1.185 + _parameter_index += T_CHAR_size; 1.186 + break; 1.187 + case short_parm: 1.188 + do_short(); 1.189 + _parameter_index += T_SHORT_size; 1.190 + break; 1.191 + case int_parm: 1.192 + do_int(); 1.193 + _parameter_index += T_INT_size; 1.194 + break; 1.195 + case obj_parm: 1.196 + do_object(0, 0); 1.197 + _parameter_index += T_OBJECT_size; 1.198 + break; 1.199 + case long_parm: 1.200 + do_long(); 1.201 + _parameter_index += T_LONG_size; 1.202 + break; 1.203 + case float_parm: 1.204 + do_float(); 1.205 + _parameter_index += T_FLOAT_size; 1.206 + break; 1.207 + case double_parm: 1.208 + do_double(); 1.209 + _parameter_index += T_DOUBLE_size; 1.210 + break; 1.211 + case done_parm: 1.212 + return; 1.213 + break; 1.214 + default: 1.215 + tty->print_cr("*** parameter is %d", fingerprint & parameter_feature_mask); 1.216 + tty->print_cr("*** fingerprint is " PTR64_FORMAT, saved_fingerprint); 1.217 + ShouldNotReachHere(); 1.218 + break; 1.219 + } 1.220 + fingerprint >>= parameter_feature_size; 1.221 + } 1.222 + _parameter_index = 0; 1.223 +} 1.224 + 1.225 + 1.226 +void SignatureIterator::iterate_returntype() { 1.227 + // Ignore parameters 1.228 + _index = 0; 1.229 + expect('('); 1.230 + Symbol* sig = _signature; 1.231 + while (sig->byte_at(_index) != ')') _index++; 1.232 + expect(')'); 1.233 + // Parse return type 1.234 + _parameter_index = -1; 1.235 + parse_type(); 1.236 + check_signature_end(); 1.237 + _parameter_index = 0; 1.238 +} 1.239 + 1.240 + 1.241 +void SignatureIterator::iterate() { 1.242 + // Parse parameters 1.243 + _parameter_index = 0; 1.244 + _index = 0; 1.245 + expect('('); 1.246 + while (_signature->byte_at(_index) != ')') _parameter_index += parse_type(); 1.247 + expect(')'); 1.248 + // Parse return type 1.249 + _parameter_index = -1; 1.250 + parse_type(); 1.251 + check_signature_end(); 1.252 + _parameter_index = 0; 1.253 +} 1.254 + 1.255 + 1.256 +// Implementation of SignatureStream 1.257 +SignatureStream::SignatureStream(Symbol* signature, bool is_method) : 1.258 + _signature(signature), _at_return_type(false) { 1.259 + _begin = _end = (is_method ? 1 : 0); // skip first '(' in method signatures 1.260 + _names = new GrowableArray<Symbol*>(10); 1.261 + next(); 1.262 +} 1.263 + 1.264 +SignatureStream::~SignatureStream() { 1.265 + // decrement refcount for names created during signature parsing 1.266 + for (int i = 0; i < _names->length(); i++) { 1.267 + _names->at(i)->decrement_refcount(); 1.268 + } 1.269 +} 1.270 + 1.271 +bool SignatureStream::is_done() const { 1.272 + return _end > _signature->utf8_length(); 1.273 +} 1.274 + 1.275 + 1.276 +void SignatureStream::next_non_primitive(int t) { 1.277 + switch (t) { 1.278 + case 'L': { 1.279 + _type = T_OBJECT; 1.280 + Symbol* sig = _signature; 1.281 + while (sig->byte_at(_end++) != ';'); 1.282 + break; 1.283 + } 1.284 + case '[': { 1.285 + _type = T_ARRAY; 1.286 + Symbol* sig = _signature; 1.287 + char c = sig->byte_at(_end); 1.288 + while ('0' <= c && c <= '9') c = sig->byte_at(_end++); 1.289 + while (sig->byte_at(_end) == '[') { 1.290 + _end++; 1.291 + c = sig->byte_at(_end); 1.292 + while ('0' <= c && c <= '9') c = sig->byte_at(_end++); 1.293 + } 1.294 + switch(sig->byte_at(_end)) { 1.295 + case 'B': 1.296 + case 'C': 1.297 + case 'D': 1.298 + case 'F': 1.299 + case 'I': 1.300 + case 'J': 1.301 + case 'S': 1.302 + case 'Z':_end++; break; 1.303 + default: { 1.304 + while (sig->byte_at(_end++) != ';'); 1.305 + break; 1.306 + } 1.307 + } 1.308 + break; 1.309 + } 1.310 + case ')': _end++; next(); _at_return_type = true; break; 1.311 + default : ShouldNotReachHere(); 1.312 + } 1.313 +} 1.314 + 1.315 + 1.316 +bool SignatureStream::is_object() const { 1.317 + return _type == T_OBJECT 1.318 + || _type == T_ARRAY; 1.319 +} 1.320 + 1.321 +bool SignatureStream::is_array() const { 1.322 + return _type == T_ARRAY; 1.323 +} 1.324 + 1.325 +Symbol* SignatureStream::as_symbol(TRAPS) { 1.326 + // Create a symbol from for string _begin _end 1.327 + int begin = _begin; 1.328 + int end = _end; 1.329 + 1.330 + if ( _signature->byte_at(_begin) == 'L' 1.331 + && _signature->byte_at(_end-1) == ';') { 1.332 + begin++; 1.333 + end--; 1.334 + } 1.335 + 1.336 + // Save names for cleaning up reference count at the end of 1.337 + // SignatureStream scope. 1.338 + Symbol* name = SymbolTable::new_symbol(_signature, begin, end, CHECK_NULL); 1.339 + _names->push(name); // save new symbol for decrementing later 1.340 + return name; 1.341 +} 1.342 + 1.343 +Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain, 1.344 + FailureMode failure_mode, TRAPS) { 1.345 + if (!is_object()) return NULL; 1.346 + Symbol* name = as_symbol(CHECK_NULL); 1.347 + if (failure_mode == ReturnNull) { 1.348 + return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD); 1.349 + } else { 1.350 + bool throw_error = (failure_mode == NCDFError); 1.351 + return SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, THREAD); 1.352 + } 1.353 +} 1.354 + 1.355 +oop SignatureStream::as_java_mirror(Handle class_loader, Handle protection_domain, 1.356 + FailureMode failure_mode, TRAPS) { 1.357 + if (!is_object()) 1.358 + return Universe::java_mirror(type()); 1.359 + Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); 1.360 + if (klass == NULL) return NULL; 1.361 + return klass->java_mirror(); 1.362 +} 1.363 + 1.364 +Symbol* SignatureStream::as_symbol_or_null() { 1.365 + // Create a symbol from for string _begin _end 1.366 + ResourceMark rm; 1.367 + 1.368 + int begin = _begin; 1.369 + int end = _end; 1.370 + 1.371 + if ( _signature->byte_at(_begin) == 'L' 1.372 + && _signature->byte_at(_end-1) == ';') { 1.373 + begin++; 1.374 + end--; 1.375 + } 1.376 + 1.377 + char* buffer = NEW_RESOURCE_ARRAY(char, end - begin); 1.378 + for (int index = begin; index < end; index++) { 1.379 + buffer[index - begin] = _signature->byte_at(index); 1.380 + } 1.381 + Symbol* result = SymbolTable::probe(buffer, end - begin); 1.382 + return result; 1.383 +} 1.384 + 1.385 +int SignatureStream::reference_parameter_count() { 1.386 + int args_count = 0; 1.387 + for ( ; !at_return_type(); next()) { 1.388 + if (is_object()) { 1.389 + args_count++; 1.390 + } 1.391 + } 1.392 + return args_count; 1.393 +} 1.394 + 1.395 +bool SignatureVerifier::is_valid_signature(Symbol* sig) { 1.396 + const char* signature = (const char*)sig->bytes(); 1.397 + ssize_t len = sig->utf8_length(); 1.398 + if (signature == NULL || signature[0] == '\0' || len < 1) { 1.399 + return false; 1.400 + } else if (signature[0] == '(') { 1.401 + return is_valid_method_signature(sig); 1.402 + } else { 1.403 + return is_valid_type_signature(sig); 1.404 + } 1.405 +} 1.406 + 1.407 +bool SignatureVerifier::is_valid_method_signature(Symbol* sig) { 1.408 + const char* method_sig = (const char*)sig->bytes(); 1.409 + ssize_t len = sig->utf8_length(); 1.410 + ssize_t index = 0; 1.411 + if (method_sig != NULL && len > 1 && method_sig[index] == '(') { 1.412 + ++index; 1.413 + while (index < len && method_sig[index] != ')') { 1.414 + ssize_t res = is_valid_type(&method_sig[index], len - index); 1.415 + if (res == -1) { 1.416 + return false; 1.417 + } else { 1.418 + index += res; 1.419 + } 1.420 + } 1.421 + if (index < len && method_sig[index] == ')') { 1.422 + // check the return type 1.423 + ++index; 1.424 + return (is_valid_type(&method_sig[index], len - index) == (len - index)); 1.425 + } 1.426 + } 1.427 + return false; 1.428 +} 1.429 + 1.430 +bool SignatureVerifier::is_valid_type_signature(Symbol* sig) { 1.431 + const char* type_sig = (const char*)sig->bytes(); 1.432 + ssize_t len = sig->utf8_length(); 1.433 + return (type_sig != NULL && len >= 1 && 1.434 + (is_valid_type(type_sig, len) == len)); 1.435 +} 1.436 + 1.437 +// Checks to see if the type (not to go beyond 'limit') refers to a valid type. 1.438 +// Returns -1 if it is not, or the index of the next character that is not part 1.439 +// of the type. The type encoding may end before 'limit' and that's ok. 1.440 +ssize_t SignatureVerifier::is_valid_type(const char* type, ssize_t limit) { 1.441 + ssize_t index = 0; 1.442 + 1.443 + // Iterate over any number of array dimensions 1.444 + while (index < limit && type[index] == '[') ++index; 1.445 + if (index >= limit) { 1.446 + return -1; 1.447 + } 1.448 + switch (type[index]) { 1.449 + case 'B': case 'C': case 'D': case 'F': case 'I': 1.450 + case 'J': case 'S': case 'Z': case 'V': 1.451 + return index + 1; 1.452 + case 'L': 1.453 + for (index = index + 1; index < limit; ++index) { 1.454 + char c = type[index]; 1.455 + if (c == ';') { 1.456 + return index + 1; 1.457 + } 1.458 + if (invalid_name_char(c)) { 1.459 + return -1; 1.460 + } 1.461 + } 1.462 + // fall through 1.463 + default: ; // fall through 1.464 + } 1.465 + return -1; 1.466 +} 1.467 + 1.468 +bool SignatureVerifier::invalid_name_char(char c) { 1.469 + switch (c) { 1.470 + case '\0': case '.': case ';': case '[': 1.471 + return true; 1.472 + default: 1.473 + return false; 1.474 + } 1.475 +}