Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/interpreter/bytecode.cpp
32285 views
1
/*
2
* Copyright (c) 1997, 2012, 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 "interpreter/bytecode.hpp"
27
#include "interpreter/linkResolver.hpp"
28
#include "oops/constantPool.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"
34
35
// Implementation of Bytecode
36
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
111
112
// Implementation of Bytecode_tableupswitch
113
114
int Bytecode_tableswitch::dest_offset_at(int i) const {
115
return get_Java_u4_at(aligned_offset(1 + (3 + i)*jintSize));
116
}
117
118
119
// Implementation of Bytecode_invoke
120
121
void Bytecode_invoke::verify() const {
122
assert(is_valid(), "check invoke");
123
assert(cpcache() != NULL, "do not call this from verifier or rewriter");
124
}
125
126
127
Symbol* Bytecode_member_ref::klass() const {
128
return constants()->klass_ref_at_noresolve(index());
129
}
130
131
132
Symbol* Bytecode_member_ref::name() const {
133
return constants()->name_ref_at(index());
134
}
135
136
137
Symbol* Bytecode_member_ref::signature() const {
138
return constants()->signature_ref_at(index());
139
}
140
141
142
BasicType Bytecode_member_ref::result_type() const {
143
ResultTypeFinder rts(signature());
144
rts.iterate();
145
return rts.type();
146
}
147
148
149
methodHandle Bytecode_invoke::static_target(TRAPS) {
150
methodHandle m;
151
KlassHandle resolved_klass;
152
constantPoolHandle constants(THREAD, this->constants());
153
154
Bytecodes::Code bc = invoke_code();
155
LinkResolver::resolve_method_statically(m, resolved_klass, bc, constants, index(), CHECK_(methodHandle()));
156
return m;
157
}
158
159
Handle Bytecode_invoke::appendix(TRAPS) {
160
ConstantPoolCacheEntry* cpce = cpcache_entry();
161
if (cpce->has_appendix())
162
return Handle(THREAD, cpce->appendix_if_resolved(constants()));
163
return Handle(); // usual case
164
}
165
166
int Bytecode_member_ref::index() const {
167
// Note: Rewriter::rewrite changes the Java_u2 of an invokedynamic to a native_u4,
168
// at the same time it allocates per-call-site CP cache entries.
169
Bytecodes::Code rawc = code();
170
if (has_index_u4(rawc))
171
return get_index_u4(rawc);
172
else
173
return get_index_u2_cpcache(rawc);
174
}
175
176
int Bytecode_member_ref::pool_index() const {
177
return cpcache_entry()->constant_pool_index();
178
}
179
180
ConstantPoolCacheEntry* Bytecode_member_ref::cpcache_entry() const {
181
int index = this->index();
182
return cpcache()->entry_at(ConstantPool::decode_cpcache_index(index, true));
183
}
184
185
// Implementation of Bytecode_field
186
187
void Bytecode_field::verify() const {
188
assert(is_valid(), "check field");
189
}
190
191
192
// Implementation of Bytecode_loadconstant
193
194
int Bytecode_loadconstant::raw_index() const {
195
Bytecodes::Code rawc = code();
196
assert(rawc != Bytecodes::_wide, "verifier prevents this");
197
if (Bytecodes::java_code(rawc) == Bytecodes::_ldc)
198
return get_index_u1(rawc);
199
else
200
return get_index_u2(rawc, false);
201
}
202
203
int Bytecode_loadconstant::pool_index() const {
204
int index = raw_index();
205
if (has_cache_index()) {
206
return _method->constants()->object_to_cp_index(index);
207
}
208
return index;
209
}
210
211
BasicType Bytecode_loadconstant::result_type() const {
212
int index = pool_index();
213
constantTag tag = _method->constants()->tag_at(index);
214
return tag.basic_type();
215
}
216
217
oop Bytecode_loadconstant::resolve_constant(TRAPS) const {
218
assert(_method.not_null(), "must supply method to resolve constant");
219
int index = raw_index();
220
ConstantPool* constants = _method->constants();
221
if (has_cache_index()) {
222
return constants->resolve_cached_constant_at(index, THREAD);
223
} else {
224
return constants->resolve_constant_at(index, THREAD);
225
}
226
}
227
228
//------------------------------------------------------------------------------
229
// Non-product code
230
231
#ifndef PRODUCT
232
233
void Bytecode_lookupswitch::verify() const {
234
switch (Bytecodes::java_code(code())) {
235
case Bytecodes::_lookupswitch:
236
{ int i = number_of_pairs() - 1;
237
while (i-- > 0) {
238
assert(pair_at(i).match() < pair_at(i+1).match(), "unsorted table entries");
239
}
240
}
241
break;
242
default:
243
fatal("not a lookupswitch bytecode");
244
}
245
}
246
247
void Bytecode_tableswitch::verify() const {
248
switch (Bytecodes::java_code(code())) {
249
case Bytecodes::_tableswitch:
250
{ int lo = low_key();
251
int hi = high_key();
252
assert (hi >= lo, "incorrect hi/lo values in tableswitch");
253
int i = hi - lo - 1 ;
254
while (i-- > 0) {
255
// no special check needed
256
}
257
}
258
break;
259
default:
260
fatal("not a tableswitch bytecode");
261
}
262
}
263
264
#endif
265
266