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/shark/sharkInliner.cpp
32285 views
1
/*
2
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3
* Copyright 2009 Red Hat, Inc.
4
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5
*
6
* This code is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License version 2 only, as
8
* published by the Free Software Foundation.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*
24
*/
25
26
#include "precompiled.hpp"
27
#include "ci/ciField.hpp"
28
#include "ci/ciMethod.hpp"
29
#include "ci/ciStreams.hpp"
30
#include "interpreter/bytecodes.hpp"
31
#include "memory/allocation.hpp"
32
#include "shark/sharkBlock.hpp"
33
#include "shark/sharkConstant.hpp"
34
#include "shark/sharkInliner.hpp"
35
#include "shark/sharkIntrinsics.hpp"
36
#include "shark/sharkState.hpp"
37
#include "shark/sharkValue.hpp"
38
#include "shark/shark_globals.hpp"
39
40
using namespace llvm;
41
42
class SharkInlineBlock : public SharkBlock {
43
public:
44
SharkInlineBlock(ciMethod* target, SharkState* state)
45
: SharkBlock(state, target),
46
_outer_state(state),
47
_entry_state(new SharkState(this)) {
48
for (int i = target->max_locals() - 1; i >= 0; i--) {
49
SharkValue *value = NULL;
50
if (i < target->arg_size())
51
value = outer_state()->pop();
52
entry_state()->set_local(i, value);
53
}
54
}
55
56
private:
57
SharkState* _outer_state;
58
SharkState* _entry_state;
59
60
private:
61
SharkState* outer_state() {
62
return _outer_state;
63
}
64
SharkState* entry_state() {
65
return _entry_state;
66
}
67
68
public:
69
void emit_IR() {
70
parse_bytecode(0, target()->code_size());
71
}
72
73
private:
74
void do_return(BasicType type) {
75
if (type != T_VOID) {
76
SharkValue *result = pop_result(type);
77
outer_state()->push(result);
78
if (result->is_two_word())
79
outer_state()->push(NULL);
80
}
81
}
82
};
83
84
class SharkInlinerHelper : public StackObj {
85
public:
86
SharkInlinerHelper(ciMethod* target, SharkState* entry_state)
87
: _target(target),
88
_entry_state(entry_state),
89
_iter(target) {}
90
91
private:
92
ciBytecodeStream _iter;
93
SharkState* _entry_state;
94
ciMethod* _target;
95
96
public:
97
ciBytecodeStream* iter() {
98
return &_iter;
99
}
100
SharkState* entry_state() const {
101
return _entry_state;
102
}
103
ciMethod* target() const {
104
return _target;
105
}
106
107
public:
108
Bytecodes::Code bc() {
109
return iter()->cur_bc();
110
}
111
int max_locals() const {
112
return target()->max_locals();
113
}
114
int max_stack() const {
115
return target()->max_stack();
116
}
117
118
// Inlinability check
119
public:
120
bool is_inlinable();
121
122
private:
123
void initialize_for_check();
124
125
bool do_getstatic() {
126
return do_field_access(true, false);
127
}
128
bool do_getfield() {
129
return do_field_access(true, true);
130
}
131
bool do_putfield() {
132
return do_field_access(false, true);
133
}
134
bool do_field_access(bool is_get, bool is_field);
135
136
// Local variables for inlinability check
137
private:
138
bool* _locals;
139
140
public:
141
bool* local_addr(int index) const {
142
assert(index >= 0 && index < max_locals(), "bad local variable index");
143
return &_locals[index];
144
}
145
bool local(int index) const {
146
return *local_addr(index);
147
}
148
void set_local(int index, bool value) {
149
*local_addr(index) = value;
150
}
151
152
// Expression stack for inlinability check
153
private:
154
bool* _stack;
155
bool* _sp;
156
157
public:
158
int stack_depth() const {
159
return _sp - _stack;
160
}
161
bool* stack_addr(int slot) const {
162
assert(slot >= 0 && slot < stack_depth(), "bad stack slot");
163
return &_sp[-(slot + 1)];
164
}
165
void push(bool value) {
166
assert(stack_depth() < max_stack(), "stack overrun");
167
*(_sp++) = value;
168
}
169
bool pop() {
170
assert(stack_depth() > 0, "stack underrun");
171
return *(--_sp);
172
}
173
174
// Methods for two-word locals
175
public:
176
void push_pair_local(int index) {
177
push(local(index));
178
push(local(index + 1));
179
}
180
void pop_pair_local(int index) {
181
set_local(index + 1, pop());
182
set_local(index, pop());
183
}
184
185
// Code generation
186
public:
187
void do_inline() {
188
(new SharkInlineBlock(target(), entry_state()))->emit_IR();
189
}
190
};
191
192
// Quick checks so we can bail out before doing too much
193
bool SharkInliner::may_be_inlinable(ciMethod *target) {
194
// We can't inline native methods
195
if (target->is_native())
196
return false;
197
198
// Not much point inlining abstract ones, and in any
199
// case we'd need a stack frame to throw the exception
200
if (target->is_abstract())
201
return false;
202
203
// Don't inline anything huge
204
if (target->code_size() > SharkMaxInlineSize)
205
return false;
206
207
// Monitors aren't allowed without a frame to put them in
208
if (target->is_synchronized() || target->has_monitor_bytecodes())
209
return false;
210
211
// We don't do control flow
212
if (target->has_exception_handlers() || target->has_jsrs())
213
return false;
214
215
// Don't try to inline constructors, as they must
216
// eventually call Object.<init> which we can't inline.
217
// Note that this catches <clinit> too, but why would
218
// we be compiling that?
219
if (target->is_initializer())
220
return false;
221
222
// Mustn't inline Object.<init>
223
// Should be caught by the above, but just in case...
224
if (target->intrinsic_id() == vmIntrinsics::_Object_init)
225
return false;
226
227
return true;
228
}
229
230
// Full-on detailed check, for methods that pass the quick checks
231
// Inlined methods have no stack frame, so we can't do anything
232
// that would require one. This means no safepoints (and hence
233
// no loops) and no VM calls. No VM calls means, amongst other
234
// things, that no exceptions can be created, which means no null
235
// checks or divide-by-zero checks are allowed. The lack of null
236
// checks in particular would eliminate practically everything,
237
// but we can get around that restriction by relying on the zero-
238
// check eliminator to strip the checks. To do that, we need to
239
// walk through the method, tracking which values are and are not
240
// zero-checked.
241
bool SharkInlinerHelper::is_inlinable() {
242
ResourceMark rm;
243
initialize_for_check();
244
245
SharkConstant *sc;
246
bool a, b, c, d;
247
248
iter()->reset_to_bci(0);
249
while (iter()->next() != ciBytecodeStream::EOBC()) {
250
switch (bc()) {
251
case Bytecodes::_nop:
252
break;
253
254
case Bytecodes::_aconst_null:
255
push(false);
256
break;
257
258
case Bytecodes::_iconst_0:
259
push(false);
260
break;
261
case Bytecodes::_iconst_m1:
262
case Bytecodes::_iconst_1:
263
case Bytecodes::_iconst_2:
264
case Bytecodes::_iconst_3:
265
case Bytecodes::_iconst_4:
266
case Bytecodes::_iconst_5:
267
push(true);
268
break;
269
270
case Bytecodes::_lconst_0:
271
push(false);
272
push(false);
273
break;
274
case Bytecodes::_lconst_1:
275
push(true);
276
push(false);
277
break;
278
279
case Bytecodes::_fconst_0:
280
case Bytecodes::_fconst_1:
281
case Bytecodes::_fconst_2:
282
push(false);
283
break;
284
285
case Bytecodes::_dconst_0:
286
case Bytecodes::_dconst_1:
287
push(false);
288
push(false);
289
break;
290
291
case Bytecodes::_bipush:
292
push(iter()->get_constant_u1() != 0);
293
break;
294
case Bytecodes::_sipush:
295
push(iter()->get_constant_u2() != 0);
296
break;
297
298
case Bytecodes::_ldc:
299
case Bytecodes::_ldc_w:
300
case Bytecodes::_ldc2_w:
301
sc = SharkConstant::for_ldc(iter());
302
if (!sc->is_loaded())
303
return false;
304
push(sc->is_nonzero());
305
if (sc->is_two_word())
306
push(false);
307
break;
308
309
case Bytecodes::_iload_0:
310
case Bytecodes::_fload_0:
311
case Bytecodes::_aload_0:
312
push(local(0));
313
break;
314
case Bytecodes::_lload_0:
315
case Bytecodes::_dload_0:
316
push_pair_local(0);
317
break;
318
319
case Bytecodes::_iload_1:
320
case Bytecodes::_fload_1:
321
case Bytecodes::_aload_1:
322
push(local(1));
323
break;
324
case Bytecodes::_lload_1:
325
case Bytecodes::_dload_1:
326
push_pair_local(1);
327
break;
328
329
case Bytecodes::_iload_2:
330
case Bytecodes::_fload_2:
331
case Bytecodes::_aload_2:
332
push(local(2));
333
break;
334
case Bytecodes::_lload_2:
335
case Bytecodes::_dload_2:
336
push_pair_local(2);
337
break;
338
339
case Bytecodes::_iload_3:
340
case Bytecodes::_fload_3:
341
case Bytecodes::_aload_3:
342
push(local(3));
343
break;
344
case Bytecodes::_lload_3:
345
case Bytecodes::_dload_3:
346
push_pair_local(3);
347
break;
348
349
case Bytecodes::_iload:
350
case Bytecodes::_fload:
351
case Bytecodes::_aload:
352
push(local(iter()->get_index()));
353
break;
354
case Bytecodes::_lload:
355
case Bytecodes::_dload:
356
push_pair_local(iter()->get_index());
357
break;
358
359
case Bytecodes::_istore_0:
360
case Bytecodes::_fstore_0:
361
case Bytecodes::_astore_0:
362
set_local(0, pop());
363
break;
364
case Bytecodes::_lstore_0:
365
case Bytecodes::_dstore_0:
366
pop_pair_local(0);
367
break;
368
369
case Bytecodes::_istore_1:
370
case Bytecodes::_fstore_1:
371
case Bytecodes::_astore_1:
372
set_local(1, pop());
373
break;
374
case Bytecodes::_lstore_1:
375
case Bytecodes::_dstore_1:
376
pop_pair_local(1);
377
break;
378
379
case Bytecodes::_istore_2:
380
case Bytecodes::_fstore_2:
381
case Bytecodes::_astore_2:
382
set_local(2, pop());
383
break;
384
case Bytecodes::_lstore_2:
385
case Bytecodes::_dstore_2:
386
pop_pair_local(2);
387
break;
388
389
case Bytecodes::_istore_3:
390
case Bytecodes::_fstore_3:
391
case Bytecodes::_astore_3:
392
set_local(3, pop());
393
break;
394
case Bytecodes::_lstore_3:
395
case Bytecodes::_dstore_3:
396
pop_pair_local(3);
397
break;
398
399
case Bytecodes::_istore:
400
case Bytecodes::_fstore:
401
case Bytecodes::_astore:
402
set_local(iter()->get_index(), pop());
403
break;
404
case Bytecodes::_lstore:
405
case Bytecodes::_dstore:
406
pop_pair_local(iter()->get_index());
407
break;
408
409
case Bytecodes::_pop:
410
pop();
411
break;
412
case Bytecodes::_pop2:
413
pop();
414
pop();
415
break;
416
case Bytecodes::_swap:
417
a = pop();
418
b = pop();
419
push(a);
420
push(b);
421
break;
422
case Bytecodes::_dup:
423
a = pop();
424
push(a);
425
push(a);
426
break;
427
case Bytecodes::_dup_x1:
428
a = pop();
429
b = pop();
430
push(a);
431
push(b);
432
push(a);
433
break;
434
case Bytecodes::_dup_x2:
435
a = pop();
436
b = pop();
437
c = pop();
438
push(a);
439
push(c);
440
push(b);
441
push(a);
442
break;
443
case Bytecodes::_dup2:
444
a = pop();
445
b = pop();
446
push(b);
447
push(a);
448
push(b);
449
push(a);
450
break;
451
case Bytecodes::_dup2_x1:
452
a = pop();
453
b = pop();
454
c = pop();
455
push(b);
456
push(a);
457
push(c);
458
push(b);
459
push(a);
460
break;
461
case Bytecodes::_dup2_x2:
462
a = pop();
463
b = pop();
464
c = pop();
465
d = pop();
466
push(b);
467
push(a);
468
push(d);
469
push(c);
470
push(b);
471
push(a);
472
break;
473
474
case Bytecodes::_getfield:
475
if (!do_getfield())
476
return false;
477
break;
478
case Bytecodes::_getstatic:
479
if (!do_getstatic())
480
return false;
481
break;
482
case Bytecodes::_putfield:
483
if (!do_putfield())
484
return false;
485
break;
486
487
case Bytecodes::_iadd:
488
case Bytecodes::_isub:
489
case Bytecodes::_imul:
490
case Bytecodes::_iand:
491
case Bytecodes::_ixor:
492
case Bytecodes::_ishl:
493
case Bytecodes::_ishr:
494
case Bytecodes::_iushr:
495
pop();
496
pop();
497
push(false);
498
break;
499
case Bytecodes::_ior:
500
a = pop();
501
b = pop();
502
push(a && b);
503
break;
504
case Bytecodes::_idiv:
505
case Bytecodes::_irem:
506
if (!pop())
507
return false;
508
pop();
509
push(false);
510
break;
511
case Bytecodes::_ineg:
512
break;
513
514
case Bytecodes::_ladd:
515
case Bytecodes::_lsub:
516
case Bytecodes::_lmul:
517
case Bytecodes::_land:
518
case Bytecodes::_lxor:
519
pop();
520
pop();
521
pop();
522
pop();
523
push(false);
524
push(false);
525
break;
526
case Bytecodes::_lor:
527
a = pop();
528
b = pop();
529
push(a && b);
530
break;
531
case Bytecodes::_ldiv:
532
case Bytecodes::_lrem:
533
pop();
534
if (!pop())
535
return false;
536
pop();
537
pop();
538
push(false);
539
push(false);
540
break;
541
case Bytecodes::_lneg:
542
break;
543
case Bytecodes::_lshl:
544
case Bytecodes::_lshr:
545
case Bytecodes::_lushr:
546
pop();
547
pop();
548
pop();
549
push(false);
550
push(false);
551
break;
552
553
case Bytecodes::_fadd:
554
case Bytecodes::_fsub:
555
case Bytecodes::_fmul:
556
case Bytecodes::_fdiv:
557
case Bytecodes::_frem:
558
pop();
559
pop();
560
push(false);
561
break;
562
case Bytecodes::_fneg:
563
break;
564
565
case Bytecodes::_dadd:
566
case Bytecodes::_dsub:
567
case Bytecodes::_dmul:
568
case Bytecodes::_ddiv:
569
case Bytecodes::_drem:
570
pop();
571
pop();
572
pop();
573
pop();
574
push(false);
575
push(false);
576
break;
577
case Bytecodes::_dneg:
578
break;
579
580
case Bytecodes::_iinc:
581
set_local(iter()->get_index(), false);
582
break;
583
584
case Bytecodes::_lcmp:
585
pop();
586
pop();
587
pop();
588
pop();
589
push(false);
590
break;
591
592
case Bytecodes::_fcmpl:
593
case Bytecodes::_fcmpg:
594
pop();
595
pop();
596
push(false);
597
break;
598
599
case Bytecodes::_dcmpl:
600
case Bytecodes::_dcmpg:
601
pop();
602
pop();
603
pop();
604
pop();
605
push(false);
606
break;
607
608
case Bytecodes::_i2l:
609
push(false);
610
break;
611
case Bytecodes::_i2f:
612
pop();
613
push(false);
614
break;
615
case Bytecodes::_i2d:
616
pop();
617
push(false);
618
push(false);
619
break;
620
621
case Bytecodes::_l2i:
622
case Bytecodes::_l2f:
623
pop();
624
pop();
625
push(false);
626
break;
627
case Bytecodes::_l2d:
628
pop();
629
pop();
630
push(false);
631
push(false);
632
break;
633
634
case Bytecodes::_f2i:
635
pop();
636
push(false);
637
break;
638
case Bytecodes::_f2l:
639
case Bytecodes::_f2d:
640
pop();
641
push(false);
642
push(false);
643
break;
644
645
case Bytecodes::_d2i:
646
case Bytecodes::_d2f:
647
pop();
648
pop();
649
push(false);
650
break;
651
case Bytecodes::_d2l:
652
pop();
653
pop();
654
push(false);
655
push(false);
656
break;
657
658
case Bytecodes::_i2b:
659
case Bytecodes::_i2c:
660
case Bytecodes::_i2s:
661
pop();
662
push(false);
663
break;
664
665
case Bytecodes::_return:
666
case Bytecodes::_ireturn:
667
case Bytecodes::_lreturn:
668
case Bytecodes::_freturn:
669
case Bytecodes::_dreturn:
670
case Bytecodes::_areturn:
671
break;
672
673
default:
674
return false;
675
}
676
}
677
678
return true;
679
}
680
681
void SharkInlinerHelper::initialize_for_check() {
682
_locals = NEW_RESOURCE_ARRAY(bool, max_locals());
683
_stack = NEW_RESOURCE_ARRAY(bool, max_stack());
684
685
memset(_locals, 0, max_locals() * sizeof(bool));
686
for (int i = 0; i < target()->arg_size(); i++) {
687
SharkValue *arg = entry_state()->stack(target()->arg_size() - 1 - i);
688
if (arg && arg->zero_checked())
689
set_local(i, true);
690
}
691
692
_sp = _stack;
693
}
694
695
bool SharkInlinerHelper::do_field_access(bool is_get, bool is_field) {
696
assert(is_get || is_field, "can't inline putstatic");
697
698
// If the holder isn't linked then there isn't a lot we can do
699
if (!target()->holder()->is_linked())
700
return false;
701
702
// Get the field
703
bool will_link;
704
ciField *field = iter()->get_field(will_link);
705
if (!will_link)
706
return false;
707
708
// If the field is mismatched then an exception needs throwing
709
if (is_field == field->is_static())
710
return false;
711
712
// Pop the value off the stack if necessary
713
if (!is_get) {
714
pop();
715
if (field->type()->is_two_word())
716
pop();
717
}
718
719
// Pop and null-check the receiver if necessary
720
if (is_field) {
721
if (!pop())
722
return false;
723
}
724
725
// Push the result if necessary
726
if (is_get) {
727
bool result_pushed = false;
728
if (field->is_constant() && field->is_static()) {
729
SharkConstant *sc = SharkConstant::for_field(iter());
730
if (sc->is_loaded()) {
731
push(sc->is_nonzero());
732
result_pushed = true;
733
}
734
}
735
736
if (!result_pushed)
737
push(false);
738
739
if (field->type()->is_two_word())
740
push(false);
741
}
742
743
return true;
744
}
745
746
bool SharkInliner::attempt_inline(ciMethod *target, SharkState *state) {
747
if (SharkIntrinsics::is_intrinsic(target)) {
748
SharkIntrinsics::inline_intrinsic(target, state);
749
return true;
750
}
751
752
if (may_be_inlinable(target)) {
753
SharkInlinerHelper inliner(target, state);
754
if (inliner.is_inlinable()) {
755
inliner.do_inline();
756
return true;
757
}
758
}
759
return false;
760
}
761
762