Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/cpu/x86/c1_Runtime1_x86.cpp
41144 views
1
/*
2
* Copyright (c) 1999, 2021, 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 "asm/assembler.hpp"
27
#include "c1/c1_Defs.hpp"
28
#include "c1/c1_MacroAssembler.hpp"
29
#include "c1/c1_Runtime1.hpp"
30
#include "ci/ciUtilities.hpp"
31
#include "compiler/oopMap.hpp"
32
#include "gc/shared/cardTable.hpp"
33
#include "gc/shared/cardTableBarrierSet.hpp"
34
#include "gc/shared/collectedHeap.hpp"
35
#include "gc/shared/tlab_globals.hpp"
36
#include "interpreter/interpreter.hpp"
37
#include "memory/universe.hpp"
38
#include "nativeInst_x86.hpp"
39
#include "oops/compiledICHolder.hpp"
40
#include "oops/oop.inline.hpp"
41
#include "prims/jvmtiExport.hpp"
42
#include "register_x86.hpp"
43
#include "runtime/sharedRuntime.hpp"
44
#include "runtime/signature.hpp"
45
#include "runtime/stubRoutines.hpp"
46
#include "runtime/vframeArray.hpp"
47
#include "utilities/macros.hpp"
48
#include "vmreg_x86.inline.hpp"
49
50
// Implementation of StubAssembler
51
52
int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, int args_size) {
53
// setup registers
54
const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions)
55
assert(!(oop_result1->is_valid() || metadata_result->is_valid()) || oop_result1 != metadata_result, "registers must be different");
56
assert(oop_result1 != thread && metadata_result != thread, "registers must be different");
57
assert(args_size >= 0, "illegal args_size");
58
bool align_stack = false;
59
#ifdef _LP64
60
// At a method handle call, the stack may not be properly aligned
61
// when returning with an exception.
62
align_stack = (stub_id() == Runtime1::handle_exception_from_callee_id);
63
#endif
64
65
#ifdef _LP64
66
mov(c_rarg0, thread);
67
set_num_rt_args(0); // Nothing on stack
68
#else
69
set_num_rt_args(1 + args_size);
70
71
// push java thread (becomes first argument of C function)
72
get_thread(thread);
73
push(thread);
74
#endif // _LP64
75
76
int call_offset = -1;
77
if (!align_stack) {
78
set_last_Java_frame(thread, noreg, rbp, NULL);
79
} else {
80
address the_pc = pc();
81
call_offset = offset();
82
set_last_Java_frame(thread, noreg, rbp, the_pc);
83
andptr(rsp, -(StackAlignmentInBytes)); // Align stack
84
}
85
86
// do the call
87
call(RuntimeAddress(entry));
88
if (!align_stack) {
89
call_offset = offset();
90
}
91
// verify callee-saved register
92
#ifdef ASSERT
93
guarantee(thread != rax, "change this code");
94
push(rax);
95
{ Label L;
96
get_thread(rax);
97
cmpptr(thread, rax);
98
jcc(Assembler::equal, L);
99
int3();
100
stop("StubAssembler::call_RT: rdi not callee saved?");
101
bind(L);
102
}
103
pop(rax);
104
#endif
105
reset_last_Java_frame(thread, true);
106
107
// discard thread and arguments
108
NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
109
110
// check for pending exceptions
111
{ Label L;
112
cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
113
jcc(Assembler::equal, L);
114
// exception pending => remove activation and forward to exception handler
115
movptr(rax, Address(thread, Thread::pending_exception_offset()));
116
// make sure that the vm_results are cleared
117
if (oop_result1->is_valid()) {
118
movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
119
}
120
if (metadata_result->is_valid()) {
121
movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
122
}
123
if (frame_size() == no_frame_size) {
124
leave();
125
jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
126
} else if (_stub_id == Runtime1::forward_exception_id) {
127
should_not_reach_here();
128
} else {
129
jump(RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id)));
130
}
131
bind(L);
132
}
133
// get oop results if there are any and reset the values in the thread
134
if (oop_result1->is_valid()) {
135
get_vm_result(oop_result1, thread);
136
}
137
if (metadata_result->is_valid()) {
138
get_vm_result_2(metadata_result, thread);
139
}
140
141
assert(call_offset >= 0, "Should be set");
142
return call_offset;
143
}
144
145
146
int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1) {
147
#ifdef _LP64
148
mov(c_rarg1, arg1);
149
#else
150
push(arg1);
151
#endif // _LP64
152
return call_RT(oop_result1, metadata_result, entry, 1);
153
}
154
155
156
int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2) {
157
#ifdef _LP64
158
if (c_rarg1 == arg2) {
159
if (c_rarg2 == arg1) {
160
xchgq(arg1, arg2);
161
} else {
162
mov(c_rarg2, arg2);
163
mov(c_rarg1, arg1);
164
}
165
} else {
166
mov(c_rarg1, arg1);
167
mov(c_rarg2, arg2);
168
}
169
#else
170
push(arg2);
171
push(arg1);
172
#endif // _LP64
173
return call_RT(oop_result1, metadata_result, entry, 2);
174
}
175
176
177
int StubAssembler::call_RT(Register oop_result1, Register metadata_result, address entry, Register arg1, Register arg2, Register arg3) {
178
#ifdef _LP64
179
// if there is any conflict use the stack
180
if (arg1 == c_rarg2 || arg1 == c_rarg3 ||
181
arg2 == c_rarg1 || arg2 == c_rarg3 ||
182
arg3 == c_rarg1 || arg3 == c_rarg2) {
183
push(arg3);
184
push(arg2);
185
push(arg1);
186
pop(c_rarg1);
187
pop(c_rarg2);
188
pop(c_rarg3);
189
} else {
190
mov(c_rarg1, arg1);
191
mov(c_rarg2, arg2);
192
mov(c_rarg3, arg3);
193
}
194
#else
195
push(arg3);
196
push(arg2);
197
push(arg1);
198
#endif // _LP64
199
return call_RT(oop_result1, metadata_result, entry, 3);
200
}
201
202
203
// Implementation of StubFrame
204
205
class StubFrame: public StackObj {
206
private:
207
StubAssembler* _sasm;
208
209
public:
210
StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments);
211
void load_argument(int offset_in_words, Register reg);
212
213
~StubFrame();
214
};
215
216
void StubAssembler::prologue(const char* name, bool must_gc_arguments) {
217
set_info(name, must_gc_arguments);
218
enter();
219
}
220
221
void StubAssembler::epilogue() {
222
leave();
223
ret(0);
224
}
225
226
#define __ _sasm->
227
228
StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) {
229
_sasm = sasm;
230
__ prologue(name, must_gc_arguments);
231
}
232
233
// load parameters that were stored with LIR_Assembler::store_parameter
234
// Note: offsets for store_parameter and load_argument must match
235
void StubFrame::load_argument(int offset_in_words, Register reg) {
236
__ load_parameter(offset_in_words, reg);
237
}
238
239
240
StubFrame::~StubFrame() {
241
__ epilogue();
242
}
243
244
#undef __
245
246
247
// Implementation of Runtime1
248
249
const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2;
250
const int xmm_regs_as_doubles_size_in_slots = FrameMap::nof_xmm_regs * 2;
251
252
// Stack layout for saving/restoring all the registers needed during a runtime
253
// call (this includes deoptimization)
254
// Note: note that users of this frame may well have arguments to some runtime
255
// while these values are on the stack. These positions neglect those arguments
256
// but the code in save_live_registers will take the argument count into
257
// account.
258
//
259
#ifdef _LP64
260
#define SLOT2(x) x,
261
#define SLOT_PER_WORD 2
262
#else
263
#define SLOT2(x)
264
#define SLOT_PER_WORD 1
265
#endif // _LP64
266
267
enum reg_save_layout {
268
// 64bit needs to keep stack 16 byte aligned. So we add some alignment dummies to make that
269
// happen and will assert if the stack size we create is misaligned
270
#ifdef _LP64
271
align_dummy_0, align_dummy_1,
272
#endif // _LP64
273
#ifdef _WIN64
274
// Windows always allocates space for it's argument registers (see
275
// frame::arg_reg_save_area_bytes).
276
arg_reg_save_1, arg_reg_save_1H, // 0, 4
277
arg_reg_save_2, arg_reg_save_2H, // 8, 12
278
arg_reg_save_3, arg_reg_save_3H, // 16, 20
279
arg_reg_save_4, arg_reg_save_4H, // 24, 28
280
#endif // _WIN64
281
xmm_regs_as_doubles_off, // 32
282
float_regs_as_doubles_off = xmm_regs_as_doubles_off + xmm_regs_as_doubles_size_in_slots, // 160
283
fpu_state_off = float_regs_as_doubles_off + float_regs_as_doubles_size_in_slots, // 224
284
// fpu_state_end_off is exclusive
285
fpu_state_end_off = fpu_state_off + (FPUStateSizeInWords / SLOT_PER_WORD), // 352
286
marker = fpu_state_end_off, SLOT2(markerH) // 352, 356
287
extra_space_offset, // 360
288
#ifdef _LP64
289
r15_off = extra_space_offset, r15H_off, // 360, 364
290
r14_off, r14H_off, // 368, 372
291
r13_off, r13H_off, // 376, 380
292
r12_off, r12H_off, // 384, 388
293
r11_off, r11H_off, // 392, 396
294
r10_off, r10H_off, // 400, 404
295
r9_off, r9H_off, // 408, 412
296
r8_off, r8H_off, // 416, 420
297
rdi_off, rdiH_off, // 424, 428
298
#else
299
rdi_off = extra_space_offset,
300
#endif // _LP64
301
rsi_off, SLOT2(rsiH_off) // 432, 436
302
rbp_off, SLOT2(rbpH_off) // 440, 444
303
rsp_off, SLOT2(rspH_off) // 448, 452
304
rbx_off, SLOT2(rbxH_off) // 456, 460
305
rdx_off, SLOT2(rdxH_off) // 464, 468
306
rcx_off, SLOT2(rcxH_off) // 472, 476
307
rax_off, SLOT2(raxH_off) // 480, 484
308
saved_rbp_off, SLOT2(saved_rbpH_off) // 488, 492
309
return_off, SLOT2(returnH_off) // 496, 500
310
reg_save_frame_size // As noted: neglects any parameters to runtime // 504
311
};
312
313
// Save off registers which might be killed by calls into the runtime.
314
// Tries to smart of about FP registers. In particular we separate
315
// saving and describing the FPU registers for deoptimization since we
316
// have to save the FPU registers twice if we describe them and on P4
317
// saving FPU registers which don't contain anything appears
318
// expensive. The deopt blob is the only thing which needs to
319
// describe FPU registers. In all other cases it should be sufficient
320
// to simply save their current value.
321
322
static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args,
323
bool save_fpu_registers = true) {
324
325
// In 64bit all the args are in regs so there are no additional stack slots
326
LP64_ONLY(num_rt_args = 0);
327
LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");)
328
int frame_size_in_slots = reg_save_frame_size + num_rt_args; // args + thread
329
sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word);
330
331
// record saved value locations in an OopMap
332
// locations are offsets from sp after runtime call; num_rt_args is number of arguments in call, including thread
333
OopMap* map = new OopMap(frame_size_in_slots, 0);
334
map->set_callee_saved(VMRegImpl::stack2reg(rax_off + num_rt_args), rax->as_VMReg());
335
map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx->as_VMReg());
336
map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx->as_VMReg());
337
map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx->as_VMReg());
338
map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi->as_VMReg());
339
map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi->as_VMReg());
340
#ifdef _LP64
341
map->set_callee_saved(VMRegImpl::stack2reg(r8_off + num_rt_args), r8->as_VMReg());
342
map->set_callee_saved(VMRegImpl::stack2reg(r9_off + num_rt_args), r9->as_VMReg());
343
map->set_callee_saved(VMRegImpl::stack2reg(r10_off + num_rt_args), r10->as_VMReg());
344
map->set_callee_saved(VMRegImpl::stack2reg(r11_off + num_rt_args), r11->as_VMReg());
345
map->set_callee_saved(VMRegImpl::stack2reg(r12_off + num_rt_args), r12->as_VMReg());
346
map->set_callee_saved(VMRegImpl::stack2reg(r13_off + num_rt_args), r13->as_VMReg());
347
map->set_callee_saved(VMRegImpl::stack2reg(r14_off + num_rt_args), r14->as_VMReg());
348
map->set_callee_saved(VMRegImpl::stack2reg(r15_off + num_rt_args), r15->as_VMReg());
349
350
// This is stupid but needed.
351
map->set_callee_saved(VMRegImpl::stack2reg(raxH_off + num_rt_args), rax->as_VMReg()->next());
352
map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx->as_VMReg()->next());
353
map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx->as_VMReg()->next());
354
map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx->as_VMReg()->next());
355
map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi->as_VMReg()->next());
356
map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi->as_VMReg()->next());
357
358
map->set_callee_saved(VMRegImpl::stack2reg(r8H_off + num_rt_args), r8->as_VMReg()->next());
359
map->set_callee_saved(VMRegImpl::stack2reg(r9H_off + num_rt_args), r9->as_VMReg()->next());
360
map->set_callee_saved(VMRegImpl::stack2reg(r10H_off + num_rt_args), r10->as_VMReg()->next());
361
map->set_callee_saved(VMRegImpl::stack2reg(r11H_off + num_rt_args), r11->as_VMReg()->next());
362
map->set_callee_saved(VMRegImpl::stack2reg(r12H_off + num_rt_args), r12->as_VMReg()->next());
363
map->set_callee_saved(VMRegImpl::stack2reg(r13H_off + num_rt_args), r13->as_VMReg()->next());
364
map->set_callee_saved(VMRegImpl::stack2reg(r14H_off + num_rt_args), r14->as_VMReg()->next());
365
map->set_callee_saved(VMRegImpl::stack2reg(r15H_off + num_rt_args), r15->as_VMReg()->next());
366
#endif // _LP64
367
368
int xmm_bypass_limit = FrameMap::nof_xmm_regs;
369
#ifdef _LP64
370
if (UseAVX < 3) {
371
xmm_bypass_limit = xmm_bypass_limit / 2;
372
}
373
#endif
374
375
if (save_fpu_registers) {
376
#ifndef _LP64
377
if (UseSSE < 2) {
378
int fpu_off = float_regs_as_doubles_off;
379
for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
380
VMReg fpu_name_0 = FrameMap::fpu_regname(n);
381
map->set_callee_saved(VMRegImpl::stack2reg(fpu_off + num_rt_args), fpu_name_0);
382
// %%% This is really a waste but we'll keep things as they were for now
383
if (true) {
384
map->set_callee_saved(VMRegImpl::stack2reg(fpu_off + 1 + num_rt_args), fpu_name_0->next());
385
}
386
fpu_off += 2;
387
}
388
assert(fpu_off == fpu_state_off, "incorrect number of fpu stack slots");
389
390
if (UseSSE == 1) {
391
int xmm_off = xmm_regs_as_doubles_off;
392
for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
393
VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
394
map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
395
xmm_off += 2;
396
}
397
assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
398
}
399
}
400
#endif // !LP64
401
402
if (UseSSE >= 2) {
403
int xmm_off = xmm_regs_as_doubles_off;
404
for (int n = 0; n < FrameMap::nof_xmm_regs; n++) {
405
if (n < xmm_bypass_limit) {
406
VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg();
407
map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0);
408
// %%% This is really a waste but we'll keep things as they were for now
409
if (true) {
410
map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + 1 + num_rt_args), xmm_name_0->next());
411
}
412
}
413
xmm_off += 2;
414
}
415
assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers");
416
}
417
}
418
419
return map;
420
}
421
422
#define __ this->
423
424
void C1_MacroAssembler::save_live_registers_no_oop_map(bool save_fpu_registers) {
425
__ block_comment("save_live_registers");
426
427
__ pusha(); // integer registers
428
429
// assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset");
430
// assert(xmm_regs_as_doubles_off % 2 == 0, "misaligned offset");
431
432
__ subptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);
433
434
#ifdef ASSERT
435
__ movptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef);
436
#endif
437
438
if (save_fpu_registers) {
439
#ifndef _LP64
440
if (UseSSE < 2) {
441
// save FPU stack
442
__ fnsave(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size));
443
__ fwait();
444
445
#ifdef ASSERT
446
Label ok;
447
__ cmpw(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size), StubRoutines::x86::fpu_cntrl_wrd_std());
448
__ jccb(Assembler::equal, ok);
449
__ stop("corrupted control word detected");
450
__ bind(ok);
451
#endif
452
453
// Reset the control word to guard against exceptions being unmasked
454
// since fstp_d can cause FPU stack underflow exceptions. Write it
455
// into the on stack copy and then reload that to make sure that the
456
// current and future values are correct.
457
__ movw(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size), StubRoutines::x86::fpu_cntrl_wrd_std());
458
__ frstor(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size));
459
460
// Save the FPU registers in de-opt-able form
461
int offset = 0;
462
for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
463
__ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset));
464
offset += 8;
465
}
466
467
if (UseSSE == 1) {
468
// save XMM registers as float because double not supported without SSE2(num MMX == num fpu)
469
int offset = 0;
470
for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
471
XMMRegister xmm_name = as_XMMRegister(n);
472
__ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset), xmm_name);
473
offset += 8;
474
}
475
}
476
}
477
#endif // !_LP64
478
479
if (UseSSE >= 2) {
480
// save XMM registers
481
// XMM registers can contain float or double values, but this is not known here,
482
// so always save them as doubles.
483
// note that float values are _not_ converted automatically, so for float values
484
// the second word contains only garbage data.
485
int xmm_bypass_limit = FrameMap::nof_xmm_regs;
486
int offset = 0;
487
#ifdef _LP64
488
if (UseAVX < 3) {
489
xmm_bypass_limit = xmm_bypass_limit / 2;
490
}
491
#endif
492
for (int n = 0; n < xmm_bypass_limit; n++) {
493
XMMRegister xmm_name = as_XMMRegister(n);
494
__ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset), xmm_name);
495
offset += 8;
496
}
497
}
498
}
499
500
// FPU stack must be empty now
501
NOT_LP64( __ verify_FPU(0, "save_live_registers"); )
502
}
503
504
#undef __
505
#define __ sasm->
506
507
static void restore_fpu(C1_MacroAssembler* sasm, bool restore_fpu_registers) {
508
#ifdef _LP64
509
if (restore_fpu_registers) {
510
// restore XMM registers
511
int xmm_bypass_limit = FrameMap::nof_xmm_regs;
512
if (UseAVX < 3) {
513
xmm_bypass_limit = xmm_bypass_limit / 2;
514
}
515
int offset = 0;
516
for (int n = 0; n < xmm_bypass_limit; n++) {
517
XMMRegister xmm_name = as_XMMRegister(n);
518
__ movdbl(xmm_name, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset));
519
offset += 8;
520
}
521
}
522
#else
523
if (restore_fpu_registers) {
524
if (UseSSE >= 2) {
525
// restore XMM registers
526
int xmm_bypass_limit = FrameMap::nof_xmm_regs;
527
int offset = 0;
528
for (int n = 0; n < xmm_bypass_limit; n++) {
529
XMMRegister xmm_name = as_XMMRegister(n);
530
__ movdbl(xmm_name, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset));
531
offset += 8;
532
}
533
} else if (UseSSE == 1) {
534
// restore XMM registers(num MMX == num fpu)
535
int offset = 0;
536
for (int n = 0; n < FrameMap::nof_fpu_regs; n++) {
537
XMMRegister xmm_name = as_XMMRegister(n);
538
__ movflt(xmm_name, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + offset));
539
offset += 8;
540
}
541
}
542
543
if (UseSSE < 2) {
544
__ frstor(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size));
545
} else {
546
// check that FPU stack is really empty
547
__ verify_FPU(0, "restore_live_registers");
548
}
549
} else {
550
// check that FPU stack is really empty
551
__ verify_FPU(0, "restore_live_registers");
552
}
553
#endif // _LP64
554
555
#ifdef ASSERT
556
{
557
Label ok;
558
__ cmpptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef);
559
__ jcc(Assembler::equal, ok);
560
__ stop("bad offsets in frame");
561
__ bind(ok);
562
}
563
#endif // ASSERT
564
565
__ addptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size);
566
}
567
568
#undef __
569
#define __ this->
570
571
void C1_MacroAssembler::restore_live_registers(bool restore_fpu_registers) {
572
__ block_comment("restore_live_registers");
573
574
restore_fpu(this, restore_fpu_registers);
575
__ popa();
576
}
577
578
579
void C1_MacroAssembler::restore_live_registers_except_rax(bool restore_fpu_registers) {
580
__ block_comment("restore_live_registers_except_rax");
581
582
restore_fpu(this, restore_fpu_registers);
583
584
#ifdef _LP64
585
__ movptr(r15, Address(rsp, 0));
586
__ movptr(r14, Address(rsp, wordSize));
587
__ movptr(r13, Address(rsp, 2 * wordSize));
588
__ movptr(r12, Address(rsp, 3 * wordSize));
589
__ movptr(r11, Address(rsp, 4 * wordSize));
590
__ movptr(r10, Address(rsp, 5 * wordSize));
591
__ movptr(r9, Address(rsp, 6 * wordSize));
592
__ movptr(r8, Address(rsp, 7 * wordSize));
593
__ movptr(rdi, Address(rsp, 8 * wordSize));
594
__ movptr(rsi, Address(rsp, 9 * wordSize));
595
__ movptr(rbp, Address(rsp, 10 * wordSize));
596
// skip rsp
597
__ movptr(rbx, Address(rsp, 12 * wordSize));
598
__ movptr(rdx, Address(rsp, 13 * wordSize));
599
__ movptr(rcx, Address(rsp, 14 * wordSize));
600
601
__ addptr(rsp, 16 * wordSize);
602
#else
603
604
__ pop(rdi);
605
__ pop(rsi);
606
__ pop(rbp);
607
__ pop(rbx); // skip this value
608
__ pop(rbx);
609
__ pop(rdx);
610
__ pop(rcx);
611
__ addptr(rsp, BytesPerWord);
612
#endif // _LP64
613
}
614
615
#undef __
616
#define __ sasm->
617
618
static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args,
619
bool save_fpu_registers = true) {
620
__ save_live_registers_no_oop_map(save_fpu_registers);
621
return generate_oop_map(sasm, num_rt_args, save_fpu_registers);
622
}
623
624
static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true) {
625
__ restore_live_registers(restore_fpu_registers);
626
}
627
628
static void restore_live_registers_except_rax(StubAssembler* sasm, bool restore_fpu_registers = true) {
629
sasm->restore_live_registers_except_rax(restore_fpu_registers);
630
}
631
632
633
void Runtime1::initialize_pd() {
634
// nothing to do
635
}
636
637
638
// Target: the entry point of the method that creates and posts the exception oop.
639
// has_argument: true if the exception needs arguments (passed on the stack because
640
// registers must be preserved).
641
OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) {
642
// Preserve all registers.
643
int num_rt_args = has_argument ? (2 + 1) : 1;
644
OopMap* oop_map = save_live_registers(sasm, num_rt_args);
645
646
// Now all registers are saved and can be used freely.
647
// Verify that no old value is used accidentally.
648
__ invalidate_registers(true, true, true, true, true, true);
649
650
// Registers used by this stub.
651
const Register temp_reg = rbx;
652
653
// Load arguments for exception that are passed as arguments into the stub.
654
if (has_argument) {
655
#ifdef _LP64
656
__ movptr(c_rarg1, Address(rbp, 2*BytesPerWord));
657
__ movptr(c_rarg2, Address(rbp, 3*BytesPerWord));
658
#else
659
__ movptr(temp_reg, Address(rbp, 3*BytesPerWord));
660
__ push(temp_reg);
661
__ movptr(temp_reg, Address(rbp, 2*BytesPerWord));
662
__ push(temp_reg);
663
#endif // _LP64
664
}
665
int call_offset = __ call_RT(noreg, noreg, target, num_rt_args - 1);
666
667
OopMapSet* oop_maps = new OopMapSet();
668
oop_maps->add_gc_map(call_offset, oop_map);
669
670
__ stop("should not reach here");
671
672
return oop_maps;
673
}
674
675
676
OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) {
677
__ block_comment("generate_handle_exception");
678
679
// incoming parameters
680
const Register exception_oop = rax;
681
const Register exception_pc = rdx;
682
// other registers used in this stub
683
const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
684
685
// Save registers, if required.
686
OopMapSet* oop_maps = new OopMapSet();
687
OopMap* oop_map = NULL;
688
switch (id) {
689
case forward_exception_id:
690
// We're handling an exception in the context of a compiled frame.
691
// The registers have been saved in the standard places. Perform
692
// an exception lookup in the caller and dispatch to the handler
693
// if found. Otherwise unwind and dispatch to the callers
694
// exception handler.
695
oop_map = generate_oop_map(sasm, 1 /*thread*/);
696
697
// load and clear pending exception oop into RAX
698
__ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
699
__ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
700
701
// load issuing PC (the return address for this stub) into rdx
702
__ movptr(exception_pc, Address(rbp, 1*BytesPerWord));
703
704
// make sure that the vm_results are cleared (may be unnecessary)
705
__ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD);
706
__ movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD);
707
break;
708
case handle_exception_nofpu_id:
709
case handle_exception_id:
710
// At this point all registers MAY be live.
711
oop_map = save_live_registers(sasm, 1 /*thread*/, id != handle_exception_nofpu_id);
712
break;
713
case handle_exception_from_callee_id: {
714
// At this point all registers except exception oop (RAX) and
715
// exception pc (RDX) are dead.
716
const int frame_size = 2 /*BP, return address*/ NOT_LP64(+ 1 /*thread*/) WIN64_ONLY(+ frame::arg_reg_save_area_bytes / BytesPerWord);
717
oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0);
718
sasm->set_frame_size(frame_size);
719
WIN64_ONLY(__ subq(rsp, frame::arg_reg_save_area_bytes));
720
break;
721
}
722
default: ShouldNotReachHere();
723
}
724
725
#if !defined(_LP64) && defined(COMPILER2)
726
if (UseSSE < 2 && !CompilerConfig::is_c1_only_no_jvmci()) {
727
// C2 can leave the fpu stack dirty
728
__ empty_FPU_stack();
729
}
730
#endif // !_LP64 && COMPILER2
731
732
// verify that only rax, and rdx is valid at this time
733
__ invalidate_registers(false, true, true, false, true, true);
734
// verify that rax, contains a valid exception
735
__ verify_not_null_oop(exception_oop);
736
737
// load address of JavaThread object for thread-local data
738
NOT_LP64(__ get_thread(thread);)
739
740
#ifdef ASSERT
741
// check that fields in JavaThread for exception oop and issuing pc are
742
// empty before writing to them
743
Label oop_empty;
744
__ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t) NULL_WORD);
745
__ jcc(Assembler::equal, oop_empty);
746
__ stop("exception oop already set");
747
__ bind(oop_empty);
748
749
Label pc_empty;
750
__ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0);
751
__ jcc(Assembler::equal, pc_empty);
752
__ stop("exception pc already set");
753
__ bind(pc_empty);
754
#endif
755
756
// save exception oop and issuing pc into JavaThread
757
// (exception handler will load it from here)
758
__ movptr(Address(thread, JavaThread::exception_oop_offset()), exception_oop);
759
__ movptr(Address(thread, JavaThread::exception_pc_offset()), exception_pc);
760
761
// patch throwing pc into return address (has bci & oop map)
762
__ movptr(Address(rbp, 1*BytesPerWord), exception_pc);
763
764
// compute the exception handler.
765
// the exception oop and the throwing pc are read from the fields in JavaThread
766
int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc));
767
oop_maps->add_gc_map(call_offset, oop_map);
768
769
// rax: handler address
770
// will be the deopt blob if nmethod was deoptimized while we looked up
771
// handler regardless of whether handler existed in the nmethod.
772
773
// only rax, is valid at this time, all other registers have been destroyed by the runtime call
774
__ invalidate_registers(false, true, true, true, true, true);
775
776
// patch the return address, this stub will directly return to the exception handler
777
__ movptr(Address(rbp, 1*BytesPerWord), rax);
778
779
switch (id) {
780
case forward_exception_id:
781
case handle_exception_nofpu_id:
782
case handle_exception_id:
783
// Restore the registers that were saved at the beginning.
784
restore_live_registers(sasm, id != handle_exception_nofpu_id);
785
break;
786
case handle_exception_from_callee_id:
787
// WIN64_ONLY: No need to add frame::arg_reg_save_area_bytes to SP
788
// since we do a leave anyway.
789
790
// Pop the return address.
791
__ leave();
792
__ pop(rcx);
793
__ jmp(rcx); // jump to exception handler
794
break;
795
default: ShouldNotReachHere();
796
}
797
798
return oop_maps;
799
}
800
801
802
void Runtime1::generate_unwind_exception(StubAssembler *sasm) {
803
// incoming parameters
804
const Register exception_oop = rax;
805
// callee-saved copy of exception_oop during runtime call
806
const Register exception_oop_callee_saved = NOT_LP64(rsi) LP64_ONLY(r14);
807
// other registers used in this stub
808
const Register exception_pc = rdx;
809
const Register handler_addr = rbx;
810
const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
811
812
// verify that only rax, is valid at this time
813
__ invalidate_registers(false, true, true, true, true, true);
814
815
#ifdef ASSERT
816
// check that fields in JavaThread for exception oop and issuing pc are empty
817
NOT_LP64(__ get_thread(thread);)
818
Label oop_empty;
819
__ cmpptr(Address(thread, JavaThread::exception_oop_offset()), 0);
820
__ jcc(Assembler::equal, oop_empty);
821
__ stop("exception oop must be empty");
822
__ bind(oop_empty);
823
824
Label pc_empty;
825
__ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0);
826
__ jcc(Assembler::equal, pc_empty);
827
__ stop("exception pc must be empty");
828
__ bind(pc_empty);
829
#endif
830
831
// clear the FPU stack in case any FPU results are left behind
832
NOT_LP64( __ empty_FPU_stack(); )
833
834
// save exception_oop in callee-saved register to preserve it during runtime calls
835
__ verify_not_null_oop(exception_oop);
836
__ movptr(exception_oop_callee_saved, exception_oop);
837
838
NOT_LP64(__ get_thread(thread);)
839
// Get return address (is on top of stack after leave).
840
__ movptr(exception_pc, Address(rsp, 0));
841
842
// search the exception handler address of the caller (using the return address)
843
__ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
844
// rax: exception handler address of the caller
845
846
// Only RAX and RSI are valid at this time, all other registers have been destroyed by the call.
847
__ invalidate_registers(false, true, true, true, false, true);
848
849
// move result of call into correct register
850
__ movptr(handler_addr, rax);
851
852
// Restore exception oop to RAX (required convention of exception handler).
853
__ movptr(exception_oop, exception_oop_callee_saved);
854
855
// verify that there is really a valid exception in rax
856
__ verify_not_null_oop(exception_oop);
857
858
// get throwing pc (= return address).
859
// rdx has been destroyed by the call, so it must be set again
860
// the pop is also necessary to simulate the effect of a ret(0)
861
__ pop(exception_pc);
862
863
// continue at exception handler (return address removed)
864
// note: do *not* remove arguments when unwinding the
865
// activation since the caller assumes having
866
// all arguments on the stack when entering the
867
// runtime to determine the exception handler
868
// (GC happens at call site with arguments!)
869
// rax: exception oop
870
// rdx: throwing pc
871
// rbx: exception handler
872
__ jmp(handler_addr);
873
}
874
875
876
OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) {
877
// use the maximum number of runtime-arguments here because it is difficult to
878
// distinguish each RT-Call.
879
// Note: This number affects also the RT-Call in generate_handle_exception because
880
// the oop-map is shared for all calls.
881
const int num_rt_args = 2; // thread + dummy
882
883
DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
884
assert(deopt_blob != NULL, "deoptimization blob must have been created");
885
886
OopMap* oop_map = save_live_registers(sasm, num_rt_args);
887
888
#ifdef _LP64
889
const Register thread = r15_thread;
890
// No need to worry about dummy
891
__ mov(c_rarg0, thread);
892
#else
893
__ push(rax); // push dummy
894
895
const Register thread = rdi; // is callee-saved register (Visual C++ calling conventions)
896
// push java thread (becomes first argument of C function)
897
__ get_thread(thread);
898
__ push(thread);
899
#endif // _LP64
900
__ set_last_Java_frame(thread, noreg, rbp, NULL);
901
// do the call
902
__ call(RuntimeAddress(target));
903
OopMapSet* oop_maps = new OopMapSet();
904
oop_maps->add_gc_map(__ offset(), oop_map);
905
// verify callee-saved register
906
#ifdef ASSERT
907
guarantee(thread != rax, "change this code");
908
__ push(rax);
909
{ Label L;
910
__ get_thread(rax);
911
__ cmpptr(thread, rax);
912
__ jcc(Assembler::equal, L);
913
__ stop("StubAssembler::call_RT: rdi/r15 not callee saved?");
914
__ bind(L);
915
}
916
__ pop(rax);
917
#endif
918
__ reset_last_Java_frame(thread, true);
919
#ifndef _LP64
920
__ pop(rcx); // discard thread arg
921
__ pop(rcx); // discard dummy
922
#endif // _LP64
923
924
// check for pending exceptions
925
{ Label L;
926
__ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
927
__ jcc(Assembler::equal, L);
928
// exception pending => remove activation and forward to exception handler
929
930
__ testptr(rax, rax); // have we deoptimized?
931
__ jump_cc(Assembler::equal,
932
RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id)));
933
934
// the deopt blob expects exceptions in the special fields of
935
// JavaThread, so copy and clear pending exception.
936
937
// load and clear pending exception
938
__ movptr(rax, Address(thread, Thread::pending_exception_offset()));
939
__ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
940
941
// check that there is really a valid exception
942
__ verify_not_null_oop(rax);
943
944
// load throwing pc: this is the return address of the stub
945
__ movptr(rdx, Address(rsp, return_off * VMRegImpl::stack_slot_size));
946
947
#ifdef ASSERT
948
// check that fields in JavaThread for exception oop and issuing pc are empty
949
Label oop_empty;
950
__ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD);
951
__ jcc(Assembler::equal, oop_empty);
952
__ stop("exception oop must be empty");
953
__ bind(oop_empty);
954
955
Label pc_empty;
956
__ cmpptr(Address(thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD);
957
__ jcc(Assembler::equal, pc_empty);
958
__ stop("exception pc must be empty");
959
__ bind(pc_empty);
960
#endif
961
962
// store exception oop and throwing pc to JavaThread
963
__ movptr(Address(thread, JavaThread::exception_oop_offset()), rax);
964
__ movptr(Address(thread, JavaThread::exception_pc_offset()), rdx);
965
966
restore_live_registers(sasm);
967
968
__ leave();
969
__ addptr(rsp, BytesPerWord); // remove return address from stack
970
971
// Forward the exception directly to deopt blob. We can blow no
972
// registers and must leave throwing pc on the stack. A patch may
973
// have values live in registers so the entry point with the
974
// exception in tls.
975
__ jump(RuntimeAddress(deopt_blob->unpack_with_exception_in_tls()));
976
977
__ bind(L);
978
}
979
980
981
// Runtime will return true if the nmethod has been deoptimized during
982
// the patching process. In that case we must do a deopt reexecute instead.
983
984
Label cont;
985
986
__ testptr(rax, rax); // have we deoptimized?
987
__ jcc(Assembler::equal, cont); // no
988
989
// Will reexecute. Proper return address is already on the stack we just restore
990
// registers, pop all of our frame but the return address and jump to the deopt blob
991
restore_live_registers(sasm);
992
__ leave();
993
__ jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
994
995
__ bind(cont);
996
restore_live_registers(sasm);
997
__ leave();
998
__ ret(0);
999
1000
return oop_maps;
1001
}
1002
1003
1004
OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) {
1005
1006
// for better readability
1007
const bool must_gc_arguments = true;
1008
const bool dont_gc_arguments = false;
1009
1010
// default value; overwritten for some optimized stubs that are called from methods that do not use the fpu
1011
bool save_fpu_registers = true;
1012
1013
// stub code & info for the different stubs
1014
OopMapSet* oop_maps = NULL;
1015
switch (id) {
1016
case forward_exception_id:
1017
{
1018
oop_maps = generate_handle_exception(id, sasm);
1019
__ leave();
1020
__ ret(0);
1021
}
1022
break;
1023
1024
case new_instance_id:
1025
case fast_new_instance_id:
1026
case fast_new_instance_init_check_id:
1027
{
1028
Register klass = rdx; // Incoming
1029
Register obj = rax; // Result
1030
1031
if (id == new_instance_id) {
1032
__ set_info("new_instance", dont_gc_arguments);
1033
} else if (id == fast_new_instance_id) {
1034
__ set_info("fast new_instance", dont_gc_arguments);
1035
} else {
1036
assert(id == fast_new_instance_init_check_id, "bad StubID");
1037
__ set_info("fast new_instance init check", dont_gc_arguments);
1038
}
1039
1040
// If TLAB is disabled, see if there is support for inlining contiguous
1041
// allocations.
1042
// Otherwise, just go to the slow path.
1043
if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) && !UseTLAB
1044
&& Universe::heap()->supports_inline_contig_alloc()) {
1045
Label slow_path;
1046
Register obj_size = rcx;
1047
Register t1 = rbx;
1048
Register t2 = rsi;
1049
assert_different_registers(klass, obj, obj_size, t1, t2);
1050
1051
__ push(rdi);
1052
__ push(rbx);
1053
1054
if (id == fast_new_instance_init_check_id) {
1055
// make sure the klass is initialized
1056
__ cmpb(Address(klass, InstanceKlass::init_state_offset()), InstanceKlass::fully_initialized);
1057
__ jcc(Assembler::notEqual, slow_path);
1058
}
1059
1060
#ifdef ASSERT
1061
// assert object can be fast path allocated
1062
{
1063
Label ok, not_ok;
1064
__ movl(obj_size, Address(klass, Klass::layout_helper_offset()));
1065
__ cmpl(obj_size, 0); // make sure it's an instance (LH > 0)
1066
__ jcc(Assembler::lessEqual, not_ok);
1067
__ testl(obj_size, Klass::_lh_instance_slow_path_bit);
1068
__ jcc(Assembler::zero, ok);
1069
__ bind(not_ok);
1070
__ stop("assert(can be fast path allocated)");
1071
__ should_not_reach_here();
1072
__ bind(ok);
1073
}
1074
#endif // ASSERT
1075
1076
const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread);
1077
NOT_LP64(__ get_thread(thread));
1078
1079
// get the instance size (size is postive so movl is fine for 64bit)
1080
__ movl(obj_size, Address(klass, Klass::layout_helper_offset()));
1081
1082
__ eden_allocate(thread, obj, obj_size, 0, t1, slow_path);
1083
1084
__ initialize_object(obj, klass, obj_size, 0, t1, t2, /* is_tlab_allocated */ false);
1085
__ verify_oop(obj);
1086
__ pop(rbx);
1087
__ pop(rdi);
1088
__ ret(0);
1089
1090
__ bind(slow_path);
1091
__ pop(rbx);
1092
__ pop(rdi);
1093
}
1094
1095
__ enter();
1096
OopMap* map = save_live_registers(sasm, 2);
1097
int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass);
1098
oop_maps = new OopMapSet();
1099
oop_maps->add_gc_map(call_offset, map);
1100
restore_live_registers_except_rax(sasm);
1101
__ verify_oop(obj);
1102
__ leave();
1103
__ ret(0);
1104
1105
// rax,: new instance
1106
}
1107
1108
break;
1109
1110
case counter_overflow_id:
1111
{
1112
Register bci = rax, method = rbx;
1113
__ enter();
1114
OopMap* map = save_live_registers(sasm, 3);
1115
// Retrieve bci
1116
__ movl(bci, Address(rbp, 2*BytesPerWord));
1117
// And a pointer to the Method*
1118
__ movptr(method, Address(rbp, 3*BytesPerWord));
1119
int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method);
1120
oop_maps = new OopMapSet();
1121
oop_maps->add_gc_map(call_offset, map);
1122
restore_live_registers(sasm);
1123
__ leave();
1124
__ ret(0);
1125
}
1126
break;
1127
1128
case new_type_array_id:
1129
case new_object_array_id:
1130
{
1131
Register length = rbx; // Incoming
1132
Register klass = rdx; // Incoming
1133
Register obj = rax; // Result
1134
1135
if (id == new_type_array_id) {
1136
__ set_info("new_type_array", dont_gc_arguments);
1137
} else {
1138
__ set_info("new_object_array", dont_gc_arguments);
1139
}
1140
1141
#ifdef ASSERT
1142
// assert object type is really an array of the proper kind
1143
{
1144
Label ok;
1145
Register t0 = obj;
1146
__ movl(t0, Address(klass, Klass::layout_helper_offset()));
1147
__ sarl(t0, Klass::_lh_array_tag_shift);
1148
int tag = ((id == new_type_array_id)
1149
? Klass::_lh_array_tag_type_value
1150
: Klass::_lh_array_tag_obj_value);
1151
__ cmpl(t0, tag);
1152
__ jcc(Assembler::equal, ok);
1153
__ stop("assert(is an array klass)");
1154
__ should_not_reach_here();
1155
__ bind(ok);
1156
}
1157
#endif // ASSERT
1158
1159
// If TLAB is disabled, see if there is support for inlining contiguous
1160
// allocations.
1161
// Otherwise, just go to the slow path.
1162
if (!UseTLAB && Universe::heap()->supports_inline_contig_alloc()) {
1163
Register arr_size = rsi;
1164
Register t1 = rcx; // must be rcx for use as shift count
1165
Register t2 = rdi;
1166
Label slow_path;
1167
1168
// get the allocation size: round_up(hdr + length << (layout_helper & 0x1F))
1169
// since size is positive movl does right thing on 64bit
1170
__ movl(t1, Address(klass, Klass::layout_helper_offset()));
1171
// since size is postive movl does right thing on 64bit
1172
__ movl(arr_size, length);
1173
assert(t1 == rcx, "fixed register usage");
1174
__ shlptr(arr_size /* by t1=rcx, mod 32 */);
1175
__ shrptr(t1, Klass::_lh_header_size_shift);
1176
__ andptr(t1, Klass::_lh_header_size_mask);
1177
__ addptr(arr_size, t1);
1178
__ addptr(arr_size, MinObjAlignmentInBytesMask); // align up
1179
__ andptr(arr_size, ~MinObjAlignmentInBytesMask);
1180
1181
// Using t2 for non 64-bit.
1182
const Register thread = NOT_LP64(t2) LP64_ONLY(r15_thread);
1183
NOT_LP64(__ get_thread(thread));
1184
__ eden_allocate(thread, obj, arr_size, 0, t1, slow_path); // preserves arr_size
1185
1186
__ initialize_header(obj, klass, length, t1, t2);
1187
__ movb(t1, Address(klass, in_bytes(Klass::layout_helper_offset()) + (Klass::_lh_header_size_shift / BitsPerByte)));
1188
assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise");
1189
assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise");
1190
__ andptr(t1, Klass::_lh_header_size_mask);
1191
__ subptr(arr_size, t1); // body length
1192
__ addptr(t1, obj); // body start
1193
__ initialize_body(t1, arr_size, 0, t2);
1194
__ verify_oop(obj);
1195
__ ret(0);
1196
1197
__ bind(slow_path);
1198
}
1199
1200
__ enter();
1201
OopMap* map = save_live_registers(sasm, 3);
1202
int call_offset;
1203
if (id == new_type_array_id) {
1204
call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length);
1205
} else {
1206
call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length);
1207
}
1208
1209
oop_maps = new OopMapSet();
1210
oop_maps->add_gc_map(call_offset, map);
1211
restore_live_registers_except_rax(sasm);
1212
1213
__ verify_oop(obj);
1214
__ leave();
1215
__ ret(0);
1216
1217
// rax,: new array
1218
}
1219
break;
1220
1221
case new_multi_array_id:
1222
{ StubFrame f(sasm, "new_multi_array", dont_gc_arguments);
1223
// rax,: klass
1224
// rbx,: rank
1225
// rcx: address of 1st dimension
1226
OopMap* map = save_live_registers(sasm, 4);
1227
int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx);
1228
1229
oop_maps = new OopMapSet();
1230
oop_maps->add_gc_map(call_offset, map);
1231
restore_live_registers_except_rax(sasm);
1232
1233
// rax,: new multi array
1234
__ verify_oop(rax);
1235
}
1236
break;
1237
1238
case register_finalizer_id:
1239
{
1240
__ set_info("register_finalizer", dont_gc_arguments);
1241
1242
// This is called via call_runtime so the arguments
1243
// will be place in C abi locations
1244
1245
#ifdef _LP64
1246
__ verify_oop(c_rarg0);
1247
__ mov(rax, c_rarg0);
1248
#else
1249
// The object is passed on the stack and we haven't pushed a
1250
// frame yet so it's one work away from top of stack.
1251
__ movptr(rax, Address(rsp, 1 * BytesPerWord));
1252
__ verify_oop(rax);
1253
#endif // _LP64
1254
1255
// load the klass and check the has finalizer flag
1256
Label register_finalizer;
1257
Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
1258
Register t = rsi;
1259
__ load_klass(t, rax, tmp_load_klass);
1260
__ movl(t, Address(t, Klass::access_flags_offset()));
1261
__ testl(t, JVM_ACC_HAS_FINALIZER);
1262
__ jcc(Assembler::notZero, register_finalizer);
1263
__ ret(0);
1264
1265
__ bind(register_finalizer);
1266
__ enter();
1267
OopMap* oop_map = save_live_registers(sasm, 2 /*num_rt_args */);
1268
int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), rax);
1269
oop_maps = new OopMapSet();
1270
oop_maps->add_gc_map(call_offset, oop_map);
1271
1272
// Now restore all the live registers
1273
restore_live_registers(sasm);
1274
1275
__ leave();
1276
__ ret(0);
1277
}
1278
break;
1279
1280
case throw_range_check_failed_id:
1281
{ StubFrame f(sasm, "range_check_failed", dont_gc_arguments);
1282
oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_range_check_exception), true);
1283
}
1284
break;
1285
1286
case throw_index_exception_id:
1287
{ StubFrame f(sasm, "index_range_check_failed", dont_gc_arguments);
1288
oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true);
1289
}
1290
break;
1291
1292
case throw_div0_exception_id:
1293
{ StubFrame f(sasm, "throw_div0_exception", dont_gc_arguments);
1294
oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false);
1295
}
1296
break;
1297
1298
case throw_null_pointer_exception_id:
1299
{ StubFrame f(sasm, "throw_null_pointer_exception", dont_gc_arguments);
1300
oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false);
1301
}
1302
break;
1303
1304
case handle_exception_nofpu_id:
1305
case handle_exception_id:
1306
{ StubFrame f(sasm, "handle_exception", dont_gc_arguments);
1307
oop_maps = generate_handle_exception(id, sasm);
1308
}
1309
break;
1310
1311
case handle_exception_from_callee_id:
1312
{ StubFrame f(sasm, "handle_exception_from_callee", dont_gc_arguments);
1313
oop_maps = generate_handle_exception(id, sasm);
1314
}
1315
break;
1316
1317
case unwind_exception_id:
1318
{ __ set_info("unwind_exception", dont_gc_arguments);
1319
// note: no stubframe since we are about to leave the current
1320
// activation and we are calling a leaf VM function only.
1321
generate_unwind_exception(sasm);
1322
}
1323
break;
1324
1325
case throw_array_store_exception_id:
1326
{ StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments);
1327
// tos + 0: link
1328
// + 1: return address
1329
oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true);
1330
}
1331
break;
1332
1333
case throw_class_cast_exception_id:
1334
{ StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments);
1335
oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true);
1336
}
1337
break;
1338
1339
case throw_incompatible_class_change_error_id:
1340
{ StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments);
1341
oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false);
1342
}
1343
break;
1344
1345
case slow_subtype_check_id:
1346
{
1347
// Typical calling sequence:
1348
// __ push(klass_RInfo); // object klass or other subclass
1349
// __ push(sup_k_RInfo); // array element klass or other superclass
1350
// __ call(slow_subtype_check);
1351
// Note that the subclass is pushed first, and is therefore deepest.
1352
// Previous versions of this code reversed the names 'sub' and 'super'.
1353
// This was operationally harmless but made the code unreadable.
1354
enum layout {
1355
rax_off, SLOT2(raxH_off)
1356
rcx_off, SLOT2(rcxH_off)
1357
rsi_off, SLOT2(rsiH_off)
1358
rdi_off, SLOT2(rdiH_off)
1359
// saved_rbp_off, SLOT2(saved_rbpH_off)
1360
return_off, SLOT2(returnH_off)
1361
sup_k_off, SLOT2(sup_kH_off)
1362
klass_off, SLOT2(superH_off)
1363
framesize,
1364
result_off = klass_off // deepest argument is also the return value
1365
};
1366
1367
__ set_info("slow_subtype_check", dont_gc_arguments);
1368
__ push(rdi);
1369
__ push(rsi);
1370
__ push(rcx);
1371
__ push(rax);
1372
1373
// This is called by pushing args and not with C abi
1374
__ movptr(rsi, Address(rsp, (klass_off) * VMRegImpl::stack_slot_size)); // subclass
1375
__ movptr(rax, Address(rsp, (sup_k_off) * VMRegImpl::stack_slot_size)); // superclass
1376
1377
Label miss;
1378
__ check_klass_subtype_slow_path(rsi, rax, rcx, rdi, NULL, &miss);
1379
1380
// fallthrough on success:
1381
__ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), 1); // result
1382
__ pop(rax);
1383
__ pop(rcx);
1384
__ pop(rsi);
1385
__ pop(rdi);
1386
__ ret(0);
1387
1388
__ bind(miss);
1389
__ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), NULL_WORD); // result
1390
__ pop(rax);
1391
__ pop(rcx);
1392
__ pop(rsi);
1393
__ pop(rdi);
1394
__ ret(0);
1395
}
1396
break;
1397
1398
case monitorenter_nofpu_id:
1399
save_fpu_registers = false;
1400
// fall through
1401
case monitorenter_id:
1402
{
1403
StubFrame f(sasm, "monitorenter", dont_gc_arguments);
1404
OopMap* map = save_live_registers(sasm, 3, save_fpu_registers);
1405
1406
// Called with store_parameter and not C abi
1407
1408
f.load_argument(1, rax); // rax,: object
1409
f.load_argument(0, rbx); // rbx,: lock address
1410
1411
int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), rax, rbx);
1412
1413
oop_maps = new OopMapSet();
1414
oop_maps->add_gc_map(call_offset, map);
1415
restore_live_registers(sasm, save_fpu_registers);
1416
}
1417
break;
1418
1419
case monitorexit_nofpu_id:
1420
save_fpu_registers = false;
1421
// fall through
1422
case monitorexit_id:
1423
{
1424
StubFrame f(sasm, "monitorexit", dont_gc_arguments);
1425
OopMap* map = save_live_registers(sasm, 2, save_fpu_registers);
1426
1427
// Called with store_parameter and not C abi
1428
1429
f.load_argument(0, rax); // rax,: lock address
1430
1431
// note: really a leaf routine but must setup last java sp
1432
// => use call_RT for now (speed can be improved by
1433
// doing last java sp setup manually)
1434
int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), rax);
1435
1436
oop_maps = new OopMapSet();
1437
oop_maps->add_gc_map(call_offset, map);
1438
restore_live_registers(sasm, save_fpu_registers);
1439
}
1440
break;
1441
1442
case deoptimize_id:
1443
{
1444
StubFrame f(sasm, "deoptimize", dont_gc_arguments);
1445
const int num_rt_args = 2; // thread, trap_request
1446
OopMap* oop_map = save_live_registers(sasm, num_rt_args);
1447
f.load_argument(0, rax);
1448
int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize), rax);
1449
oop_maps = new OopMapSet();
1450
oop_maps->add_gc_map(call_offset, oop_map);
1451
restore_live_registers(sasm);
1452
DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1453
assert(deopt_blob != NULL, "deoptimization blob must have been created");
1454
__ leave();
1455
__ jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1456
}
1457
break;
1458
1459
case access_field_patching_id:
1460
{ StubFrame f(sasm, "access_field_patching", dont_gc_arguments);
1461
// we should set up register map
1462
oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, access_field_patching));
1463
}
1464
break;
1465
1466
case load_klass_patching_id:
1467
{ StubFrame f(sasm, "load_klass_patching", dont_gc_arguments);
1468
// we should set up register map
1469
oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_klass_patching));
1470
}
1471
break;
1472
1473
case load_mirror_patching_id:
1474
{ StubFrame f(sasm, "load_mirror_patching", dont_gc_arguments);
1475
// we should set up register map
1476
oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_mirror_patching));
1477
}
1478
break;
1479
1480
case load_appendix_patching_id:
1481
{ StubFrame f(sasm, "load_appendix_patching", dont_gc_arguments);
1482
// we should set up register map
1483
oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_appendix_patching));
1484
}
1485
break;
1486
1487
case dtrace_object_alloc_id:
1488
{ // rax,: object
1489
StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments);
1490
// we can't gc here so skip the oopmap but make sure that all
1491
// the live registers get saved.
1492
save_live_registers(sasm, 1);
1493
1494
__ NOT_LP64(push(rax)) LP64_ONLY(mov(c_rarg0, rax));
1495
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc)));
1496
NOT_LP64(__ pop(rax));
1497
1498
restore_live_registers(sasm);
1499
}
1500
break;
1501
1502
case fpu2long_stub_id:
1503
{
1504
#ifdef _LP64
1505
Label done;
1506
__ cvttsd2siq(rax, Address(rsp, wordSize));
1507
__ cmp64(rax, ExternalAddress((address) StubRoutines::x86::double_sign_flip()));
1508
__ jccb(Assembler::notEqual, done);
1509
__ movq(rax, Address(rsp, wordSize));
1510
__ subptr(rsp, 8);
1511
__ movq(Address(rsp, 0), rax);
1512
__ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::d2l_fixup())));
1513
__ pop(rax);
1514
__ bind(done);
1515
__ ret(0);
1516
#else
1517
// rax, and rdx are destroyed, but should be free since the result is returned there
1518
// preserve rsi,ecx
1519
__ push(rsi);
1520
__ push(rcx);
1521
1522
// check for NaN
1523
Label return0, do_return, return_min_jlong, do_convert;
1524
1525
Address value_high_word(rsp, wordSize + 4);
1526
Address value_low_word(rsp, wordSize);
1527
Address result_high_word(rsp, 3*wordSize + 4);
1528
Address result_low_word(rsp, 3*wordSize);
1529
1530
__ subptr(rsp, 32); // more than enough on 32bit
1531
__ fst_d(value_low_word);
1532
__ movl(rax, value_high_word);
1533
__ andl(rax, 0x7ff00000);
1534
__ cmpl(rax, 0x7ff00000);
1535
__ jcc(Assembler::notEqual, do_convert);
1536
__ movl(rax, value_high_word);
1537
__ andl(rax, 0xfffff);
1538
__ orl(rax, value_low_word);
1539
__ jcc(Assembler::notZero, return0);
1540
1541
__ bind(do_convert);
1542
__ fnstcw(Address(rsp, 0));
1543
__ movzwl(rax, Address(rsp, 0));
1544
__ orl(rax, 0xc00);
1545
__ movw(Address(rsp, 2), rax);
1546
__ fldcw(Address(rsp, 2));
1547
__ fwait();
1548
__ fistp_d(result_low_word);
1549
__ fldcw(Address(rsp, 0));
1550
__ fwait();
1551
// This gets the entire long in rax on 64bit
1552
__ movptr(rax, result_low_word);
1553
// testing of high bits
1554
__ movl(rdx, result_high_word);
1555
__ mov(rcx, rax);
1556
// What the heck is the point of the next instruction???
1557
__ xorl(rcx, 0x0);
1558
__ movl(rsi, 0x80000000);
1559
__ xorl(rsi, rdx);
1560
__ orl(rcx, rsi);
1561
__ jcc(Assembler::notEqual, do_return);
1562
__ fldz();
1563
__ fcomp_d(value_low_word);
1564
__ fnstsw_ax();
1565
__ sahf();
1566
__ jcc(Assembler::above, return_min_jlong);
1567
// return max_jlong
1568
__ movl(rdx, 0x7fffffff);
1569
__ movl(rax, 0xffffffff);
1570
__ jmp(do_return);
1571
1572
__ bind(return_min_jlong);
1573
__ movl(rdx, 0x80000000);
1574
__ xorl(rax, rax);
1575
__ jmp(do_return);
1576
1577
__ bind(return0);
1578
__ fpop();
1579
__ xorptr(rdx,rdx);
1580
__ xorptr(rax,rax);
1581
1582
__ bind(do_return);
1583
__ addptr(rsp, 32);
1584
__ pop(rcx);
1585
__ pop(rsi);
1586
__ ret(0);
1587
#endif // _LP64
1588
}
1589
break;
1590
1591
case predicate_failed_trap_id:
1592
{
1593
StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments);
1594
1595
OopMap* map = save_live_registers(sasm, 1);
1596
1597
int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap));
1598
oop_maps = new OopMapSet();
1599
oop_maps->add_gc_map(call_offset, map);
1600
restore_live_registers(sasm);
1601
__ leave();
1602
DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob();
1603
assert(deopt_blob != NULL, "deoptimization blob must have been created");
1604
1605
__ jump(RuntimeAddress(deopt_blob->unpack_with_reexecution()));
1606
}
1607
break;
1608
1609
default:
1610
{ StubFrame f(sasm, "unimplemented entry", dont_gc_arguments);
1611
__ movptr(rax, (int)id);
1612
__ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), rax);
1613
__ should_not_reach_here();
1614
}
1615
break;
1616
}
1617
return oop_maps;
1618
}
1619
1620
#undef __
1621
1622
const char *Runtime1::pd_name_for_address(address entry) {
1623
return "<unknown function>";
1624
}
1625
1626