Mercurial > hg > truffle
annotate src/share/vm/interpreter/bytecode.cpp @ 4181:319860ae697a
Simplify FrameMap: make offsets of spill slots and outgoing parameters independent so that they can be allocated at the same time, eliminating the separate phases. This makes the separate StackBlock unnecesary. Change CiStackSlot to use byte offsets instead of spill slot index. This makes CiTarget.spillSlotSize unnecessary.
author | Christian Wimmer <Christian.Wimmer@Oracle.com> |
---|---|
date | Mon, 02 Jan 2012 14:16:08 -0800 |
parents | 3582bf76420e |
children | 1d7922586cf6 |
rev | line source |
---|---|
0 | 1 /* |
2142 | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1135
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1135
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1135
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "interpreter/bytecode.hpp" | |
27 #include "interpreter/linkResolver.hpp" | |
28 #include "oops/constantPoolOop.hpp" | |
29 #include "oops/oop.inline.hpp" | |
30 #include "runtime/fieldType.hpp" | |
31 #include "runtime/handles.inline.hpp" | |
32 #include "runtime/safepoint.hpp" | |
33 #include "runtime/signature.hpp" | |
0 | 34 |
35 // Implementation of Bytecode | |
36 | |
1565 | 37 #ifdef ASSERT |
38 | |
39 void Bytecode::assert_same_format_as(Bytecodes::Code testbc, bool is_wide) const { | |
40 Bytecodes::Code thisbc = Bytecodes::cast(byte_at(0)); | |
41 if (thisbc == Bytecodes::_breakpoint) return; // let the assertion fail silently | |
42 if (is_wide) { | |
43 assert(thisbc == Bytecodes::_wide, "expected a wide instruction"); | |
44 thisbc = Bytecodes::cast(byte_at(1)); | |
45 if (thisbc == Bytecodes::_breakpoint) return; | |
46 } | |
47 int thisflags = Bytecodes::flags(testbc, is_wide) & Bytecodes::_all_fmt_bits; | |
48 int testflags = Bytecodes::flags(thisbc, is_wide) & Bytecodes::_all_fmt_bits; | |
49 if (thisflags != testflags) | |
50 tty->print_cr("assert_same_format_as(%d) failed on bc=%d%s; %d != %d", | |
51 (int)testbc, (int)thisbc, (is_wide?"/wide":""), testflags, thisflags); | |
52 assert(thisflags == testflags, "expected format"); | |
53 } | |
54 | |
55 void Bytecode::assert_index_size(int size, Bytecodes::Code bc, bool is_wide) { | |
56 int have_fmt = (Bytecodes::flags(bc, is_wide) | |
57 & (Bytecodes::_fmt_has_u2 | Bytecodes::_fmt_has_u4 | | |
58 Bytecodes::_fmt_not_simple | | |
59 // Not an offset field: | |
60 Bytecodes::_fmt_has_o)); | |
61 int need_fmt = -1; | |
62 switch (size) { | |
63 case 1: need_fmt = 0; break; | |
64 case 2: need_fmt = Bytecodes::_fmt_has_u2; break; | |
65 case 4: need_fmt = Bytecodes::_fmt_has_u4; break; | |
66 } | |
67 if (is_wide) need_fmt |= Bytecodes::_fmt_not_simple; | |
68 if (have_fmt != need_fmt) { | |
69 tty->print_cr("assert_index_size %d: bc=%d%s %d != %d", size, bc, (is_wide?"/wide":""), have_fmt, need_fmt); | |
70 assert(have_fmt == need_fmt, "assert_index_size"); | |
71 } | |
72 } | |
73 | |
74 void Bytecode::assert_offset_size(int size, Bytecodes::Code bc, bool is_wide) { | |
75 int have_fmt = Bytecodes::flags(bc, is_wide) & Bytecodes::_all_fmt_bits; | |
76 int need_fmt = -1; | |
77 switch (size) { | |
78 case 2: need_fmt = Bytecodes::_fmt_bo2; break; | |
79 case 4: need_fmt = Bytecodes::_fmt_bo4; break; | |
80 } | |
81 if (is_wide) need_fmt |= Bytecodes::_fmt_not_simple; | |
82 if (have_fmt != need_fmt) { | |
83 tty->print_cr("assert_offset_size %d: bc=%d%s %d != %d", size, bc, (is_wide?"/wide":""), have_fmt, need_fmt); | |
84 assert(have_fmt == need_fmt, "assert_offset_size"); | |
85 } | |
86 } | |
87 | |
88 void Bytecode::assert_constant_size(int size, int where, Bytecodes::Code bc, bool is_wide) { | |
89 int have_fmt = Bytecodes::flags(bc, is_wide) & (Bytecodes::_all_fmt_bits | |
90 // Ignore any 'i' field (for iinc): | |
91 & ~Bytecodes::_fmt_has_i); | |
92 int need_fmt = -1; | |
93 switch (size) { | |
94 case 1: need_fmt = Bytecodes::_fmt_bc; break; | |
95 case 2: need_fmt = Bytecodes::_fmt_bc | Bytecodes::_fmt_has_u2; break; | |
96 } | |
97 if (is_wide) need_fmt |= Bytecodes::_fmt_not_simple; | |
98 int length = is_wide ? Bytecodes::wide_length_for(bc) : Bytecodes::length_for(bc); | |
99 if (have_fmt != need_fmt || where + size != length) { | |
100 tty->print_cr("assert_constant_size %d @%d: bc=%d%s %d != %d", size, where, bc, (is_wide?"/wide":""), have_fmt, need_fmt); | |
101 } | |
102 assert(have_fmt == need_fmt, "assert_constant_size"); | |
103 assert(where + size == length, "assert_constant_size oob"); | |
104 } | |
105 | |
106 void Bytecode::assert_native_index(Bytecodes::Code bc, bool is_wide) { | |
107 assert((Bytecodes::flags(bc, is_wide) & Bytecodes::_fmt_has_nbo) != 0, "native index"); | |
108 } | |
109 | |
110 #endif //ASSERT | |
0 | 111 |
112 // Implementation of Bytecode_tableupswitch | |
113 | |
114 int Bytecode_tableswitch::dest_offset_at(int i) const { | |
1565 | 115 return get_Java_u4_at(aligned_offset(1 + (3 + i)*jintSize)); |
0 | 116 } |
117 | |
118 | |
119 // Implementation of Bytecode_invoke | |
120 | |
121 void Bytecode_invoke::verify() const { | |
122 assert(is_valid(), "check invoke"); | |
1565 | 123 assert(method()->constants()->cache() != NULL, "do not call this from verifier or rewriter"); |
0 | 124 } |
125 | |
126 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
127 Symbol* Bytecode_member_ref::signature() const { |
0 | 128 constantPoolOop constants = method()->constants(); |
129 return constants->signature_ref_at(index()); | |
130 } | |
131 | |
132 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
133 Symbol* Bytecode_member_ref::name() const { |
0 | 134 constantPoolOop constants = method()->constants(); |
135 return constants->name_ref_at(index()); | |
136 } | |
137 | |
138 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
139 BasicType Bytecode_member_ref::result_type() const { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
140 ResultTypeFinder rts(signature()); |
0 | 141 rts.iterate(); |
142 return rts.type(); | |
143 } | |
144 | |
145 | |
146 methodHandle Bytecode_invoke::static_target(TRAPS) { | |
147 methodHandle m; | |
148 KlassHandle resolved_klass; | |
149 constantPoolHandle constants(THREAD, _method->constants()); | |
150 | |
1602 | 151 if (java_code() == Bytecodes::_invokedynamic) { |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
844
diff
changeset
|
152 LinkResolver::resolve_dynamic_method(m, resolved_klass, constants, index(), CHECK_(methodHandle())); |
1602 | 153 } else if (java_code() != Bytecodes::_invokeinterface) { |
0 | 154 LinkResolver::resolve_method(m, resolved_klass, constants, index(), CHECK_(methodHandle())); |
155 } else { | |
156 LinkResolver::resolve_interface_method(m, resolved_klass, constants, index(), CHECK_(methodHandle())); | |
157 } | |
158 return m; | |
159 } | |
160 | |
161 | |
1602 | 162 int Bytecode_member_ref::index() const { |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
163 // Note: Rewriter::rewrite changes the Java_u2 of an invokedynamic to a native_u4, |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
164 // at the same time it allocates per-call-site CP cache entries. |
1602 | 165 Bytecodes::Code rawc = code(); |
2142 | 166 if (has_index_u4(rawc)) |
167 return get_index_u4(rawc); | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
0
diff
changeset
|
168 else |
2142 | 169 return get_index_u2_cpcache(rawc); |
0 | 170 } |
171 | |
1602 | 172 int Bytecode_member_ref::pool_index() const { |
173 int index = this->index(); | |
174 DEBUG_ONLY({ | |
2142 | 175 if (!has_index_u4(code())) |
1602 | 176 index -= constantPoolOopDesc::CPCACHE_INDEX_TAG; |
177 }); | |
178 return _method->constants()->cache()->entry_at(index)->constant_pool_index(); | |
179 } | |
0 | 180 |
181 // Implementation of Bytecode_field | |
182 | |
183 void Bytecode_field::verify() const { | |
1602 | 184 assert(is_valid(), "check field"); |
0 | 185 } |
186 | |
187 | |
1602 | 188 // Implementation of Bytecode_loadconstant |
189 | |
190 int Bytecode_loadconstant::raw_index() const { | |
2142 | 191 Bytecodes::Code rawc = code(); |
1602 | 192 assert(rawc != Bytecodes::_wide, "verifier prevents this"); |
193 if (Bytecodes::java_code(rawc) == Bytecodes::_ldc) | |
2142 | 194 return get_index_u1(rawc); |
1602 | 195 else |
2142 | 196 return get_index_u2(rawc, false); |
0 | 197 } |
198 | |
1602 | 199 int Bytecode_loadconstant::pool_index() const { |
200 int index = raw_index(); | |
201 if (has_cache_index()) { | |
202 return _method->constants()->cache()->entry_at(index)->constant_pool_index(); | |
203 } | |
204 return index; | |
205 } | |
0 | 206 |
1602 | 207 BasicType Bytecode_loadconstant::result_type() const { |
208 int index = pool_index(); | |
209 constantTag tag = _method->constants()->tag_at(index); | |
210 return tag.basic_type(); | |
211 } | |
212 | |
213 oop Bytecode_loadconstant::resolve_constant(TRAPS) const { | |
214 assert(_method.not_null(), "must supply method to resolve constant"); | |
215 int index = raw_index(); | |
216 constantPoolOop constants = _method->constants(); | |
217 if (has_cache_index()) { | |
218 return constants->resolve_cached_constant_at(index, THREAD); | |
219 } else { | |
220 return constants->resolve_constant_at(index, THREAD); | |
1574 | 221 } |
0 | 222 } |
223 | |
224 //------------------------------------------------------------------------------ | |
225 // Non-product code | |
226 | |
227 #ifndef PRODUCT | |
228 | |
229 void Bytecode_lookupswitch::verify() const { | |
230 switch (Bytecodes::java_code(code())) { | |
231 case Bytecodes::_lookupswitch: | |
232 { int i = number_of_pairs() - 1; | |
233 while (i-- > 0) { | |
2142 | 234 assert(pair_at(i).match() < pair_at(i+1).match(), "unsorted table entries"); |
0 | 235 } |
236 } | |
237 break; | |
238 default: | |
239 fatal("not a lookupswitch bytecode"); | |
240 } | |
241 } | |
242 | |
243 void Bytecode_tableswitch::verify() const { | |
244 switch (Bytecodes::java_code(code())) { | |
245 case Bytecodes::_tableswitch: | |
246 { int lo = low_key(); | |
247 int hi = high_key(); | |
248 assert (hi >= lo, "incorrect hi/lo values in tableswitch"); | |
249 int i = hi - lo - 1 ; | |
250 while (i-- > 0) { | |
251 // no special check needed | |
252 } | |
253 } | |
254 break; | |
255 default: | |
256 fatal("not a tableswitch bytecode"); | |
257 } | |
258 } | |
259 | |
260 #endif |