Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/x86/vm/interp_masm_x86.cpp
32285 views
1
/*
2
* Copyright (c) 1997, 2016, 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 "interp_masm_x86.hpp"
27
#include "interpreter/interpreter.hpp"
28
#include "oops/methodData.hpp"
29
30
31
// 8u does not have InterpreterMacroAssembler::load_earlyret_value here
32
33
void InterpreterMacroAssembler::narrow(Register result) {
34
35
// Get method->_constMethod->_result_type
36
movptr(rcx, Address(rbp, frame::interpreter_frame_method_offset * wordSize));
37
movptr(rcx, Address(rcx, Method::const_offset()));
38
load_unsigned_byte(rcx, Address(rcx, ConstMethod::result_type_offset()));
39
40
Label done, notBool, notByte, notChar;
41
42
// common case first
43
cmpl(rcx, T_INT);
44
jcc(Assembler::equal, done);
45
46
// mask integer result to narrower return type.
47
cmpl(rcx, T_BOOLEAN);
48
jcc(Assembler::notEqual, notBool);
49
andl(result, 0x1);
50
jmp(done);
51
52
bind(notBool);
53
cmpl(rcx, T_BYTE);
54
jcc(Assembler::notEqual, notByte);
55
LP64_ONLY(movsbl(result, result);)
56
NOT_LP64(shll(result, 24);) // truncate upper 24 bits
57
NOT_LP64(sarl(result, 24);) // and sign-extend byte
58
jmp(done);
59
60
bind(notByte);
61
cmpl(rcx, T_CHAR);
62
jcc(Assembler::notEqual, notChar);
63
LP64_ONLY(movzwl(result, result);)
64
NOT_LP64(andl(result, 0xFFFF);) // truncate upper 16 bits
65
jmp(done);
66
67
bind(notChar);
68
// cmpl(rcx, T_SHORT); // all that's left
69
// jcc(Assembler::notEqual, done);
70
LP64_ONLY(movswl(result, result);)
71
NOT_LP64(shll(result, 16);) // truncate upper 16 bits
72
NOT_LP64(sarl(result, 16);) // and sign-extend short
73
74
// Nothing to do for T_INT
75
bind(done);
76
}
77
78
#ifndef CC_INTERP
79
void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
80
Label update, next, none;
81
82
verify_oop(obj);
83
84
testptr(obj, obj);
85
jccb(Assembler::notZero, update);
86
orptr(mdo_addr, TypeEntries::null_seen);
87
jmpb(next);
88
89
bind(update);
90
load_klass(obj, obj);
91
92
xorptr(obj, mdo_addr);
93
testptr(obj, TypeEntries::type_klass_mask);
94
jccb(Assembler::zero, next); // klass seen before, nothing to
95
// do. The unknown bit may have been
96
// set already but no need to check.
97
98
testptr(obj, TypeEntries::type_unknown);
99
jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
100
101
cmpptr(mdo_addr, 0);
102
jccb(Assembler::equal, none);
103
cmpptr(mdo_addr, TypeEntries::null_seen);
104
jccb(Assembler::equal, none);
105
// There is a chance that the checks above (re-reading profiling
106
// data from memory) fail if another thread has just set the
107
// profiling to this obj's klass
108
xorptr(obj, mdo_addr);
109
testptr(obj, TypeEntries::type_klass_mask);
110
jccb(Assembler::zero, next);
111
112
// different than before. Cannot keep accurate profile.
113
orptr(mdo_addr, TypeEntries::type_unknown);
114
jmpb(next);
115
116
bind(none);
117
// first time here. Set profile type.
118
movptr(mdo_addr, obj);
119
120
bind(next);
121
}
122
123
void InterpreterMacroAssembler::profile_arguments_type(Register mdp, Register callee, Register tmp, bool is_virtual) {
124
if (!ProfileInterpreter) {
125
return;
126
}
127
128
if (MethodData::profile_arguments() || MethodData::profile_return()) {
129
Label profile_continue;
130
131
test_method_data_pointer(mdp, profile_continue);
132
133
int off_to_start = is_virtual ? in_bytes(VirtualCallData::virtual_call_data_size()) : in_bytes(CounterData::counter_data_size());
134
135
cmpb(Address(mdp, in_bytes(DataLayout::tag_offset()) - off_to_start), is_virtual ? DataLayout::virtual_call_type_data_tag : DataLayout::call_type_data_tag);
136
jcc(Assembler::notEqual, profile_continue);
137
138
if (MethodData::profile_arguments()) {
139
Label done;
140
int off_to_args = in_bytes(TypeEntriesAtCall::args_data_offset());
141
addptr(mdp, off_to_args);
142
143
for (int i = 0; i < TypeProfileArgsLimit; i++) {
144
if (i > 0 || MethodData::profile_return()) {
145
// If return value type is profiled we may have no argument to profile
146
movptr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
147
subl(tmp, i*TypeStackSlotEntries::per_arg_count());
148
cmpl(tmp, TypeStackSlotEntries::per_arg_count());
149
jcc(Assembler::less, done);
150
}
151
movptr(tmp, Address(callee, Method::const_offset()));
152
load_unsigned_short(tmp, Address(tmp, ConstMethod::size_of_parameters_offset()));
153
// stack offset o (zero based) from the start of the argument
154
// list, for n arguments translates into offset n - o - 1 from
155
// the end of the argument list
156
subptr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::stack_slot_offset(i))-off_to_args));
157
subl(tmp, 1);
158
Address arg_addr = argument_address(tmp);
159
movptr(tmp, arg_addr);
160
161
Address mdo_arg_addr(mdp, in_bytes(TypeEntriesAtCall::argument_type_offset(i))-off_to_args);
162
profile_obj_type(tmp, mdo_arg_addr);
163
164
int to_add = in_bytes(TypeStackSlotEntries::per_arg_size());
165
addptr(mdp, to_add);
166
off_to_args += to_add;
167
}
168
169
if (MethodData::profile_return()) {
170
movptr(tmp, Address(mdp, in_bytes(TypeEntriesAtCall::cell_count_offset())-off_to_args));
171
subl(tmp, TypeProfileArgsLimit*TypeStackSlotEntries::per_arg_count());
172
}
173
174
bind(done);
175
176
if (MethodData::profile_return()) {
177
// We're right after the type profile for the last
178
// argument. tmp is the number of cells left in the
179
// CallTypeData/VirtualCallTypeData to reach its end. Non null
180
// if there's a return to profile.
181
assert(ReturnTypeEntry::static_cell_count() < TypeStackSlotEntries::per_arg_count(), "can't move past ret type");
182
shll(tmp, exact_log2(DataLayout::cell_size));
183
addptr(mdp, tmp);
184
}
185
movptr(Address(rbp, frame::interpreter_frame_mdx_offset * wordSize), mdp);
186
} else {
187
assert(MethodData::profile_return(), "either profile call args or call ret");
188
update_mdp_by_constant(mdp, in_bytes(TypeEntriesAtCall::return_only_size()));
189
}
190
191
// mdp points right after the end of the
192
// CallTypeData/VirtualCallTypeData, right after the cells for the
193
// return value type if there's one
194
195
bind(profile_continue);
196
}
197
}
198
199
void InterpreterMacroAssembler::profile_return_type(Register mdp, Register ret, Register tmp) {
200
assert_different_registers(mdp, ret, tmp, _bcp_register);
201
if (ProfileInterpreter && MethodData::profile_return()) {
202
Label profile_continue, done;
203
204
test_method_data_pointer(mdp, profile_continue);
205
206
if (MethodData::profile_return_jsr292_only()) {
207
// If we don't profile all invoke bytecodes we must make sure
208
// it's a bytecode we indeed profile. We can't go back to the
209
// begining of the ProfileData we intend to update to check its
210
// type because we're right after it and we don't known its
211
// length
212
Label do_profile;
213
cmpb(Address(_bcp_register, 0), Bytecodes::_invokedynamic);
214
jcc(Assembler::equal, do_profile);
215
cmpb(Address(_bcp_register, 0), Bytecodes::_invokehandle);
216
jcc(Assembler::equal, do_profile);
217
get_method(tmp);
218
cmpb(Address(tmp, Method::intrinsic_id_offset_in_bytes()), vmIntrinsics::_compiledLambdaForm);
219
jcc(Assembler::notEqual, profile_continue);
220
221
bind(do_profile);
222
}
223
224
Address mdo_ret_addr(mdp, -in_bytes(ReturnTypeEntry::size()));
225
mov(tmp, ret);
226
profile_obj_type(tmp, mdo_ret_addr);
227
228
bind(profile_continue);
229
}
230
}
231
232
void InterpreterMacroAssembler::profile_parameters_type(Register mdp, Register tmp1, Register tmp2) {
233
if (ProfileInterpreter && MethodData::profile_parameters()) {
234
Label profile_continue, done;
235
236
test_method_data_pointer(mdp, profile_continue);
237
238
// Load the offset of the area within the MDO used for
239
// parameters. If it's negative we're not profiling any parameters
240
movl(tmp1, Address(mdp, in_bytes(MethodData::parameters_type_data_di_offset()) - in_bytes(MethodData::data_offset())));
241
testl(tmp1, tmp1);
242
jcc(Assembler::negative, profile_continue);
243
244
// Compute a pointer to the area for parameters from the offset
245
// and move the pointer to the slot for the last
246
// parameters. Collect profiling from last parameter down.
247
// mdo start + parameters offset + array length - 1
248
addptr(mdp, tmp1);
249
movptr(tmp1, Address(mdp, ArrayData::array_len_offset()));
250
decrement(tmp1, TypeStackSlotEntries::per_arg_count());
251
252
Label loop;
253
bind(loop);
254
255
int off_base = in_bytes(ParametersTypeData::stack_slot_offset(0));
256
int type_base = in_bytes(ParametersTypeData::type_offset(0));
257
Address::ScaleFactor per_arg_scale = Address::times(DataLayout::cell_size);
258
Address arg_off(mdp, tmp1, per_arg_scale, off_base);
259
Address arg_type(mdp, tmp1, per_arg_scale, type_base);
260
261
// load offset on the stack from the slot for this parameter
262
movptr(tmp2, arg_off);
263
negptr(tmp2);
264
// read the parameter from the local area
265
movptr(tmp2, Address(_locals_register, tmp2, Interpreter::stackElementScale()));
266
267
// profile the parameter
268
profile_obj_type(tmp2, arg_type);
269
270
// go to next parameter
271
decrement(tmp1, TypeStackSlotEntries::per_arg_count());
272
jcc(Assembler::positive, loop);
273
274
bind(profile_continue);
275
}
276
}
277
#endif
278
279