1 /* 2 * Copyright (c) 1999, 2023, 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 "ci/ciMethodType.hpp" 27 #include "ci/ciSignature.hpp" 28 #include "ci/ciStreams.hpp" 29 #include "ci/ciUtilities.inline.hpp" 30 #include "memory/allocation.inline.hpp" 31 #include "memory/resourceArea.hpp" 32 #include "oops/oop.inline.hpp" 33 #include "runtime/signature.hpp" 34 35 // ciSignature 36 // 37 // This class represents the signature of a method. 38 39 // ------------------------------------------------------------------ 40 // ciSignature::ciSignature 41 ciSignature::ciSignature(ciKlass* accessing_klass, const constantPoolHandle& cpool, ciSymbol* symbol) 42 : _symbol(symbol), _accessing_klass(accessing_klass), _types(CURRENT_ENV->arena(), 8, 0, nullptr) { 43 ASSERT_IN_VM; 44 EXCEPTION_CONTEXT; 45 assert(accessing_klass != nullptr, "need origin of access"); 46 47 ciEnv* env = CURRENT_ENV; 48 49 int size = 0; 50 ResourceMark rm(THREAD); 51 for (SignatureStream ss(symbol->get_symbol()); !ss.is_done(); ss.next()) { 52 // Process one element of the signature 53 ciType* type = nullptr; 54 if (ss.is_reference()) { 55 ciSymbol* klass_name = env->get_symbol(ss.as_symbol()); 56 type = env->get_klass_by_name_impl(_accessing_klass, cpool, klass_name, false); 57 } else { 58 type = ciType::make(ss.type()); 59 } 60 if (ss.at_return_type()) { 61 // don't include return type in size calculation 62 _return_type = type; 63 } else { 64 _types.append(type); 65 size += type->size(); 66 } 67 } 68 _size = size; 69 } 70 71 // ------------------------------------------------------------------ 72 // ciSignature::equals 73 // 74 // Compare this signature to another one. Signatures with different 75 // accessing classes but with signature-types resolved to the same 76 // types are defined to be equal. 77 bool ciSignature::equals(ciSignature* that) { 78 // Compare signature 79 if (!this->as_symbol()->equals(that->as_symbol())) { 80 return false; 81 } 82 // Compare all types of the arguments 83 if (_types.length() != that->_types.length()) { 84 return false; 85 } 86 for (int i = 0; i < _types.length(); i++) { 87 if (this->type_at(i) != that->type_at(i)) { 88 return false; 89 } 90 } 91 // Compare the return type 92 if (this->return_type() != that->return_type()) { 93 return false; 94 } 95 return true; 96 } 97 98 // ------------------------------------------------------------------ 99 // ciSignature::has_unloaded_classes 100 // 101 // Reports if there are any unloaded classes present in the signature. 102 // Each ciSignature when instantiated is resolved against some accessing class 103 // and the resolved classes aren't required to be local, but can be revealed 104 // through loader constraints. 105 bool ciSignature::has_unloaded_classes() { 106 for (ciSignatureStream str(this); !str.is_done(); str.next()) { 107 if (!str.type()->is_loaded()) { 108 return true; 109 } 110 } 111 return false; 112 } 113 114 // ------------------------------------------------------------------ 115 // ciSignature::print_signature 116 void ciSignature::print_signature() { 117 _symbol->print_symbol(); 118 } 119 120 // ------------------------------------------------------------------ 121 // ciSignature::print 122 void ciSignature::print() { 123 tty->print("<ciSignature symbol="); 124 print_signature(); 125 tty->print(" accessing_klass="); 126 _accessing_klass->print(); 127 tty->print(" address=" INTPTR_FORMAT ">", p2i((address)this)); 128 }