ciSignature.cpp revision 9248:6ab7e19c9220
1/*
2 * Copyright (c) 1999, 2015, 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/ciUtilities.hpp"
29#include "memory/allocation.inline.hpp"
30#include "oops/oop.inline.hpp"
31#include "runtime/signature.hpp"
32
33// ciSignature
34//
35// This class represents the signature of a method.
36
37// ------------------------------------------------------------------
38// ciSignature::ciSignature
39ciSignature::ciSignature(ciKlass* accessing_klass, const constantPoolHandle& cpool, ciSymbol* symbol) {
40  ASSERT_IN_VM;
41  EXCEPTION_CONTEXT;
42  _accessing_klass = accessing_klass;
43  _symbol = symbol;
44
45  ciEnv* env = CURRENT_ENV;
46  Arena* arena = env->arena();
47  _types = new (arena) GrowableArray<ciType*>(arena, 8, 0, NULL);
48
49  int size = 0;
50  int count = 0;
51  ResourceMark rm(THREAD);
52  Symbol* sh = symbol->get_symbol();
53  SignatureStream ss(sh);
54  for (; ; ss.next()) {
55    // Process one element of the signature
56    ciType* type;
57    if (!ss.is_object()) {
58      type = ciType::make(ss.type());
59    } else {
60      Symbol* name = ss.as_symbol(THREAD);
61      if (HAS_PENDING_EXCEPTION) {
62        type = ss.is_array() ? (ciType*)ciEnv::unloaded_ciobjarrayklass()
63          : (ciType*)ciEnv::unloaded_ciinstance_klass();
64        env->record_out_of_memory_failure();
65        CLEAR_PENDING_EXCEPTION;
66      } else {
67        ciSymbol* klass_name = env->get_symbol(name);
68        type = env->get_klass_by_name_impl(_accessing_klass, cpool, klass_name, false);
69      }
70    }
71    _types->append(type);
72    if (ss.at_return_type()) {
73      // Done processing the return type; do not add it into the count.
74      break;
75    }
76    size += type->size();
77    count++;
78  }
79  _size = size;
80  _count = count;
81}
82
83// ------------------------------------------------------------------
84// ciSignature::ciSignature
85ciSignature::ciSignature(ciKlass* accessing_klass, ciSymbol* symbol, ciMethodType* method_type) :
86  _symbol(symbol),
87  _accessing_klass(accessing_klass),
88  _size( method_type->ptype_slot_count()),
89  _count(method_type->ptype_count())
90{
91  ASSERT_IN_VM;
92  EXCEPTION_CONTEXT;
93  Arena* arena = CURRENT_ENV->arena();
94  _types = new (arena) GrowableArray<ciType*>(arena, _count + 1, 0, NULL);
95  for (int i = 0; i < _count; i++) {
96    _types->append(method_type->ptype_at(i));
97  }
98  _types->append(method_type->rtype());
99}
100
101// ------------------------------------------------------------------
102// ciSignature::return_type
103//
104// What is the return type of this signature?
105ciType* ciSignature::return_type() const {
106  return _types->at(_count);
107}
108
109// ------------------------------------------------------------------
110// ciSignature::type_at
111//
112// What is the type of the index'th element of this
113// signature?
114ciType* ciSignature::type_at(int index) const {
115  assert(index < _count, "out of bounds");
116  // The first _klasses element holds the return klass.
117  return _types->at(index);
118}
119
120// ------------------------------------------------------------------
121// ciSignature::equals
122//
123// Compare this signature to another one.  Signatures with different
124// accessing classes but with signature-types resolved to the same
125// types are defined to be equal.
126bool ciSignature::equals(ciSignature* that) {
127  // Compare signature
128  if (!this->as_symbol()->equals(that->as_symbol()))  return false;
129  // Compare all types of the arguments
130  for (int i = 0; i < _count; i++) {
131    if (this->type_at(i) != that->type_at(i))         return false;
132  }
133  // Compare the return type
134  if (this->return_type() != that->return_type())     return false;
135  return true;
136}
137
138// ------------------------------------------------------------------
139// ciSignature::print_signature
140void ciSignature::print_signature() {
141  _symbol->print_symbol();
142}
143
144// ------------------------------------------------------------------
145// ciSignature::print
146void ciSignature::print() {
147  tty->print("<ciSignature symbol=");
148  print_signature();
149 tty->print(" accessing_klass=");
150  _accessing_klass->print();
151  tty->print(" address=" INTPTR_FORMAT ">", p2i((address)this));
152}
153