bytecode.cpp revision 0:a61af66fc99e
1/*
2 * Copyright 1997-2002 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25#include "incls/_precompiled.incl"
26#include "incls/_bytecode.cpp.incl"
27
28// Implementation of Bytecode
29// Should eventually get rid of these functions and use ThisRelativeObj methods instead
30
31void Bytecode::set_code(Bytecodes::Code code) {
32  Bytecodes::check(code);
33  *addr_at(0) = u_char(code);
34}
35
36
37void Bytecode::set_fast_index(int i) {
38  assert(0 <= i && i < 0x10000, "illegal index value");
39  Bytes::put_native_u2(addr_at(1), (jushort)i);
40}
41
42
43bool Bytecode::check_must_rewrite() const {
44  assert(Bytecodes::can_rewrite(code()), "post-check only");
45
46  // Some codes are conditionally rewriting.  Look closely at them.
47  switch (code()) {
48  case Bytecodes::_aload_0:
49    // Even if RewriteFrequentPairs is turned on,
50    // the _aload_0 code might delay its rewrite until
51    // a following _getfield rewrites itself.
52    return false;
53
54  case Bytecodes::_lookupswitch:
55    return false;  // the rewrite is not done by the interpreter
56
57  case Bytecodes::_new:
58    // (Could actually look at the class here, but the profit would be small.)
59    return false;  // the rewrite is not always done
60  }
61
62  // No other special cases.
63  return true;
64}
65
66
67
68// Implementation of Bytecode_tableupswitch
69
70int Bytecode_tableswitch::dest_offset_at(int i) const {
71  address x = aligned_addr_at(1);
72  int x2 = aligned_offset(1 + (3 + i)*jintSize);
73  int val = java_signed_word_at(x2);
74  return java_signed_word_at(aligned_offset(1 + (3 + i)*jintSize));
75}
76
77
78// Implementation of Bytecode_invoke
79
80void Bytecode_invoke::verify() const {
81  Bytecodes::Code bc = adjusted_invoke_code();
82  assert(is_valid(), "check invoke");
83}
84
85
86symbolOop Bytecode_invoke::signature() const {
87  constantPoolOop constants = method()->constants();
88  return constants->signature_ref_at(index());
89}
90
91
92symbolOop Bytecode_invoke::name() const {
93  constantPoolOop constants = method()->constants();
94  return constants->name_ref_at(index());
95}
96
97
98BasicType Bytecode_invoke::result_type(Thread *thread) const {
99  symbolHandle sh(thread, signature());
100  ResultTypeFinder rts(sh);
101  rts.iterate();
102  return rts.type();
103}
104
105
106methodHandle Bytecode_invoke::static_target(TRAPS) {
107  methodHandle m;
108  KlassHandle resolved_klass;
109  constantPoolHandle constants(THREAD, _method->constants());
110
111  if (adjusted_invoke_code() != Bytecodes::_invokeinterface) {
112    LinkResolver::resolve_method(m, resolved_klass, constants, index(), CHECK_(methodHandle()));
113  } else {
114    LinkResolver::resolve_interface_method(m, resolved_klass, constants, index(), CHECK_(methodHandle()));
115  }
116  return m;
117}
118
119
120int Bytecode_invoke::index() const {
121  return Bytes::get_Java_u2(bcp() + 1);
122}
123
124
125// Implementation of Bytecode_static
126
127void Bytecode_static::verify() const {
128  assert(Bytecodes::java_code(code()) == Bytecodes::_putstatic
129      || Bytecodes::java_code(code()) == Bytecodes::_getstatic, "check static");
130}
131
132
133BasicType Bytecode_static::result_type(methodOop method) const {
134  int index = java_hwrd_at(1);
135  constantPoolOop constants = method->constants();
136  symbolOop field_type = constants->signature_ref_at(index);
137  BasicType basic_type = FieldType::basic_type(field_type);
138  return basic_type;
139}
140
141
142// Implementation of Bytecode_field
143
144void Bytecode_field::verify() const {
145  Bytecodes::Code stdc = Bytecodes::java_code(code());
146  assert(stdc == Bytecodes::_putstatic || stdc == Bytecodes::_getstatic ||
147         stdc == Bytecodes::_putfield  || stdc == Bytecodes::_getfield, "check field");
148}
149
150
151bool Bytecode_field::is_static() const {
152  Bytecodes::Code stdc = Bytecodes::java_code(code());
153  return stdc == Bytecodes::_putstatic || stdc == Bytecodes::_getstatic;
154}
155
156
157int Bytecode_field::index() const {
158  return java_hwrd_at(1);
159}
160
161
162// Implementation of Bytecodes loac constant
163
164int Bytecode_loadconstant::index() const {
165  Bytecodes::Code stdc = Bytecodes::java_code(code());
166  return stdc == Bytecodes::_ldc ? java_byte_at(1) : java_hwrd_at(1);
167}
168
169//------------------------------------------------------------------------------
170// Non-product code
171
172#ifndef PRODUCT
173
174void Bytecode_lookupswitch::verify() const {
175  switch (Bytecodes::java_code(code())) {
176    case Bytecodes::_lookupswitch:
177      { int i = number_of_pairs() - 1;
178        while (i-- > 0) {
179          assert(pair_at(i)->match() < pair_at(i+1)->match(), "unsorted table entries");
180        }
181      }
182      break;
183    default:
184      fatal("not a lookupswitch bytecode");
185  }
186}
187
188void Bytecode_tableswitch::verify() const {
189  switch (Bytecodes::java_code(code())) {
190    case Bytecodes::_tableswitch:
191      { int lo = low_key();
192        int hi = high_key();
193        assert (hi >= lo, "incorrect hi/lo values in tableswitch");
194        int i  = hi - lo - 1 ;
195        while (i-- > 0) {
196          // no special check needed
197        }
198      }
199      break;
200    default:
201      fatal("not a tableswitch bytecode");
202  }
203}
204
205#endif
206