ciSignature.cpp revision 10762:ea81fe138932
11558Srgrimes/*
21558Srgrimes * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
31558Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
41558Srgrimes *
51558Srgrimes * This code is free software; you can redistribute it and/or modify it
61558Srgrimes * under the terms of the GNU General Public License version 2 only, as
71558Srgrimes * published by the Free Software Foundation.
81558Srgrimes *
91558Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT
101558Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
111558Srgrimes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
121558Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
131558Srgrimes * accompanied this code).
141558Srgrimes *
151558Srgrimes * You should have received a copy of the GNU General Public License version
161558Srgrimes * 2 along with this work; if not, write to the Free Software Foundation,
171558Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
181558Srgrimes *
191558Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
201558Srgrimes * or visit www.oracle.com if you need additional information or have any
211558Srgrimes * questions.
221558Srgrimes *
231558Srgrimes */
241558Srgrimes
251558Srgrimes#include "precompiled.hpp"
261558Srgrimes#include "ci/ciMethodType.hpp"
271558Srgrimes#include "ci/ciSignature.hpp"
281558Srgrimes#include "ci/ciUtilities.hpp"
291558Srgrimes#include "memory/allocation.inline.hpp"
301558Srgrimes#include "memory/resourceArea.hpp"
311558Srgrimes#include "oops/oop.inline.hpp"
321558Srgrimes#include "runtime/signature.hpp"
331558Srgrimes
341558Srgrimes// ciSignature
351558Srgrimes//
361558Srgrimes// This class represents the signature of a method.
371558Srgrimes
381558Srgrimes// ------------------------------------------------------------------
391558Srgrimes// ciSignature::ciSignature
401558SrgrimesciSignature::ciSignature(ciKlass* accessing_klass, const constantPoolHandle& cpool, ciSymbol* symbol) {
411558Srgrimes  ASSERT_IN_VM;
421558Srgrimes  EXCEPTION_CONTEXT;
431558Srgrimes  _accessing_klass = accessing_klass;
441558Srgrimes  _symbol = symbol;
451558Srgrimes
461558Srgrimes  ciEnv* env = CURRENT_ENV;
471558Srgrimes  Arena* arena = env->arena();
481558Srgrimes  _types = new (arena) GrowableArray<ciType*>(arena, 8, 0, NULL);
491558Srgrimes
501558Srgrimes  int size = 0;
511558Srgrimes  int count = 0;
521558Srgrimes  ResourceMark rm(THREAD);
531558Srgrimes  Symbol* sh = symbol->get_symbol();
541558Srgrimes  SignatureStream ss(sh);
551558Srgrimes  for (; ; ss.next()) {
561558Srgrimes    // Process one element of the signature
571558Srgrimes    ciType* type;
581558Srgrimes    if (!ss.is_object()) {
591558Srgrimes      type = ciType::make(ss.type());
601558Srgrimes    } else {
611558Srgrimes      Symbol* name = ss.as_symbol(THREAD);
621558Srgrimes      if (HAS_PENDING_EXCEPTION) {
631558Srgrimes        type = ss.is_array() ? (ciType*)ciEnv::unloaded_ciobjarrayklass()
641558Srgrimes          : (ciType*)ciEnv::unloaded_ciinstance_klass();
651558Srgrimes        env->record_out_of_memory_failure();
661558Srgrimes        CLEAR_PENDING_EXCEPTION;
671558Srgrimes      } else {
681558Srgrimes        ciSymbol* klass_name = env->get_symbol(name);
691558Srgrimes        type = env->get_klass_by_name_impl(_accessing_klass, cpool, klass_name, false);
701558Srgrimes      }
711558Srgrimes    }
721558Srgrimes    _types->append(type);
731558Srgrimes    if (ss.at_return_type()) {
741558Srgrimes      // Done processing the return type; do not add it into the count.
751558Srgrimes      break;
761558Srgrimes    }
771558Srgrimes    size += type->size();
781558Srgrimes    count++;
791558Srgrimes  }
801558Srgrimes  _size = size;
811558Srgrimes  _count = count;
821558Srgrimes}
831558Srgrimes
841558Srgrimes// ------------------------------------------------------------------
851558Srgrimes// ciSignature::ciSignature
861558SrgrimesciSignature::ciSignature(ciKlass* accessing_klass, ciSymbol* symbol, ciMethodType* method_type) :
871558Srgrimes  _symbol(symbol),
881558Srgrimes  _accessing_klass(accessing_klass),
891558Srgrimes  _size( method_type->ptype_slot_count()),
901558Srgrimes  _count(method_type->ptype_count())
911558Srgrimes{
921558Srgrimes  ASSERT_IN_VM;
931558Srgrimes  EXCEPTION_CONTEXT;
941558Srgrimes  Arena* arena = CURRENT_ENV->arena();
951558Srgrimes  _types = new (arena) GrowableArray<ciType*>(arena, _count + 1, 0, NULL);
961558Srgrimes  for (int i = 0; i < _count; i++) {
971558Srgrimes    _types->append(method_type->ptype_at(i));
981558Srgrimes  }
991558Srgrimes  _types->append(method_type->rtype());
1001558Srgrimes}
1011558Srgrimes
1021558Srgrimes// ------------------------------------------------------------------
1031558Srgrimes// ciSignature::return_type
1041558Srgrimes//
1051558Srgrimes// What is the return type of this signature?
1061558SrgrimesciType* ciSignature::return_type() const {
1071558Srgrimes  return _types->at(_count);
1081558Srgrimes}
1091558Srgrimes
1101558Srgrimes// ------------------------------------------------------------------
1111558Srgrimes// ciSignature::type_at
1121558Srgrimes//
1131558Srgrimes// What is the type of the index'th element of this
1141558Srgrimes// signature?
1151558SrgrimesciType* ciSignature::type_at(int index) const {
1161558Srgrimes  assert(index < _count, "out of bounds");
1171558Srgrimes  // The first _klasses element holds the return klass.
1181558Srgrimes  return _types->at(index);
1191558Srgrimes}
1201558Srgrimes
1211558Srgrimes// ------------------------------------------------------------------
1221558Srgrimes// ciSignature::equals
1231558Srgrimes//
1241558Srgrimes// Compare this signature to another one.  Signatures with different
1251558Srgrimes// accessing classes but with signature-types resolved to the same
1261558Srgrimes// types are defined to be equal.
1271558Srgrimesbool ciSignature::equals(ciSignature* that) {
1281558Srgrimes  // Compare signature
1291558Srgrimes  if (!this->as_symbol()->equals(that->as_symbol()))  return false;
1301558Srgrimes  // Compare all types of the arguments
1311558Srgrimes  for (int i = 0; i < _count; i++) {
1321558Srgrimes    if (this->type_at(i) != that->type_at(i))         return false;
1331558Srgrimes  }
1341558Srgrimes  // Compare the return type
1351558Srgrimes  if (this->return_type() != that->return_type())     return false;
1361558Srgrimes  return true;
1371558Srgrimes}
1381558Srgrimes
1391558Srgrimes// ------------------------------------------------------------------
1401558Srgrimes// ciSignature::print_signature
1411558Srgrimesvoid ciSignature::print_signature() {
1421558Srgrimes  _symbol->print_symbol();
1431558Srgrimes}
1441558Srgrimes
1451558Srgrimes// ------------------------------------------------------------------
1461558Srgrimes// ciSignature::print
1471558Srgrimesvoid ciSignature::print() {
1481558Srgrimes  tty->print("<ciSignature symbol=");
1491558Srgrimes  print_signature();
1501558Srgrimes tty->print(" accessing_klass=");
1511558Srgrimes  _accessing_klass->print();
1521558Srgrimes  tty->print(" address=" INTPTR_FORMAT ">", p2i((address)this));
1531558Srgrimes}
1541558Srgrimes