Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/compiler/codegen/J9TreeEvaluator.cpp
6000 views
1
/*******************************************************************************
2
* Copyright (c) 2000, 2021 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
7
* or the Apache License, Version 2.0 which accompanies this distribution and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
20
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
21
*******************************************************************************/
22
23
#include "codegen/TreeEvaluator.hpp"
24
#include "codegen/CodeGenerator.hpp"
25
#include "codegen/J9WatchedInstanceFieldSnippet.hpp"
26
#include "codegen/J9WatchedStaticFieldSnippet.hpp"
27
#include "env/CompilerEnv.hpp"
28
#include "env/IO.hpp"
29
#include "env/PersistentCHTable.hpp"
30
#include "env/VMJ9.h"
31
#include "il/Node.hpp"
32
#include "il/Node_inlines.hpp"
33
#include "il/StaticSymbol.hpp"
34
#include "runtime/RuntimeAssumptions.hpp"
35
#include "runtime/J9Profiler.hpp"
36
#include "runtime/J9ValueProfiler.hpp"
37
#include "util_api.h"
38
39
TR::Register*
40
J9::TreeEvaluator::zdloadEvaluator(TR::Node *node, TR::CodeGenerator *cg)
41
{
42
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
43
}
44
45
TR::Register*
46
J9::TreeEvaluator::zdloadiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
47
{
48
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
49
}
50
51
TR::Register*
52
J9::TreeEvaluator::zdstoreEvaluator(TR::Node *node, TR::CodeGenerator *cg)
53
{
54
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
55
}
56
57
TR::Register*
58
J9::TreeEvaluator::zdstoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
59
{
60
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
61
}
62
63
TR::Register*
64
J9::TreeEvaluator::pd2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
65
{
66
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
67
}
68
69
TR::Register*
70
J9::TreeEvaluator::zd2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
71
{
72
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
73
}
74
75
TR::Register*
76
J9::TreeEvaluator::zdsleLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg)
77
{
78
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
79
}
80
81
TR::Register*
82
J9::TreeEvaluator::zdslsLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg)
83
{
84
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
85
}
86
87
TR::Register*
88
J9::TreeEvaluator::zdstsLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg)
89
{
90
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
91
}
92
93
TR::Register*
94
J9::TreeEvaluator::zdsleLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
95
{
96
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
97
}
98
99
TR::Register*
100
J9::TreeEvaluator::zdslsLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
101
{
102
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
103
}
104
105
TR::Register*
106
J9::TreeEvaluator::zdstsLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
107
{
108
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
109
}
110
111
TR::Register*
112
J9::TreeEvaluator::zdsleStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg)
113
{
114
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
115
}
116
117
TR::Register*
118
J9::TreeEvaluator::zdslsStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg)
119
{
120
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
121
}
122
123
TR::Register*
124
J9::TreeEvaluator::zdstsStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg)
125
{
126
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
127
}
128
129
TR::Register*
130
J9::TreeEvaluator::zdsleStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
131
{
132
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
133
}
134
135
TR::Register*
136
J9::TreeEvaluator::zdslsStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
137
{
138
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
139
}
140
141
TR::Register*
142
J9::TreeEvaluator::zdstsStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
143
{
144
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
145
}
146
147
TR::Register*
148
J9::TreeEvaluator::zd2zdsleEvaluator(TR::Node *node, TR::CodeGenerator *cg)
149
{
150
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
151
}
152
153
TR::Register*
154
J9::TreeEvaluator::zd2zdslsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
155
{
156
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
157
}
158
159
TR::Register*
160
J9::TreeEvaluator::zd2zdstsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
161
{
162
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
163
}
164
165
TR::Register*
166
J9::TreeEvaluator::zdsle2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
167
{
168
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
169
}
170
171
TR::Register*
172
J9::TreeEvaluator::zdsls2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
173
{
174
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
175
}
176
177
TR::Register*
178
J9::TreeEvaluator::zdsts2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
179
{
180
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
181
}
182
183
TR::Register*
184
J9::TreeEvaluator::zdsle2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
185
{
186
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
187
}
188
189
TR::Register*
190
J9::TreeEvaluator::zdsls2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
191
{
192
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
193
}
194
195
TR::Register*
196
J9::TreeEvaluator::zdsts2zdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
197
{
198
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
199
}
200
201
TR::Register*
202
J9::TreeEvaluator::pd2zdslsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
203
{
204
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
205
}
206
207
TR::Register*
208
J9::TreeEvaluator::pd2zdslsSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg)
209
{
210
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
211
}
212
213
TR::Register*
214
J9::TreeEvaluator::pd2zdstsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
215
{
216
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
217
}
218
219
TR::Register*
220
J9::TreeEvaluator::pd2zdstsSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg)
221
{
222
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
223
}
224
225
TR::Register*
226
J9::TreeEvaluator::udLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg)
227
{
228
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
229
}
230
231
TR::Register*
232
J9::TreeEvaluator::udslLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg)
233
{
234
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
235
}
236
237
TR::Register*
238
J9::TreeEvaluator::udstLoadEvaluator(TR::Node *node, TR::CodeGenerator *cg)
239
{
240
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
241
}
242
243
TR::Register*
244
J9::TreeEvaluator::udLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
245
{
246
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
247
}
248
249
TR::Register*
250
J9::TreeEvaluator::udslLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
251
{
252
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
253
}
254
255
TR::Register*
256
J9::TreeEvaluator::udstLoadiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
257
{
258
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
259
}
260
261
TR::Register*
262
J9::TreeEvaluator::udStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg)
263
{
264
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
265
}
266
267
TR::Register*
268
J9::TreeEvaluator::udslStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg)
269
{
270
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
271
}
272
273
TR::Register*
274
J9::TreeEvaluator::udstStoreEvaluator(TR::Node *node, TR::CodeGenerator *cg)
275
{
276
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
277
}
278
279
TR::Register*
280
J9::TreeEvaluator::udStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
281
{
282
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
283
}
284
285
TR::Register*
286
J9::TreeEvaluator::udslStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
287
{
288
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
289
}
290
291
TR::Register*
292
J9::TreeEvaluator::udstStoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
293
{
294
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
295
}
296
297
TR::Register*
298
J9::TreeEvaluator::pd2udEvaluator(TR::Node *node, TR::CodeGenerator *cg)
299
{
300
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
301
}
302
303
TR::Register*
304
J9::TreeEvaluator::pd2udslEvaluator(TR::Node *node, TR::CodeGenerator *cg)
305
{
306
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
307
}
308
309
TR::Register*
310
J9::TreeEvaluator::pd2udstEvaluator(TR::Node *node, TR::CodeGenerator *cg)
311
{
312
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
313
}
314
315
TR::Register*
316
J9::TreeEvaluator::udsl2udEvaluator(TR::Node *node, TR::CodeGenerator *cg)
317
{
318
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
319
}
320
321
TR::Register*
322
J9::TreeEvaluator::udst2udEvaluator(TR::Node *node, TR::CodeGenerator *cg)
323
{
324
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
325
}
326
327
TR::Register*
328
J9::TreeEvaluator::ud2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
329
{
330
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
331
}
332
333
TR::Register*
334
J9::TreeEvaluator::udsl2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
335
{
336
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
337
}
338
339
TR::Register*
340
J9::TreeEvaluator::udst2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
341
{
342
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
343
}
344
345
TR::Register*
346
J9::TreeEvaluator::pdloadEvaluator(TR::Node *node, TR::CodeGenerator *cg)
347
{
348
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
349
}
350
351
TR::Register*
352
J9::TreeEvaluator::pdloadiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
353
{
354
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
355
}
356
357
TR::Register*
358
J9::TreeEvaluator::pdstoreEvaluator(TR::Node *node, TR::CodeGenerator *cg)
359
{
360
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
361
}
362
363
TR::Register*
364
J9::TreeEvaluator::pdstoreiEvaluator(TR::Node *node, TR::CodeGenerator *cg)
365
{
366
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
367
}
368
369
TR::Register*
370
J9::TreeEvaluator::pdaddEvaluator(TR::Node *node, TR::CodeGenerator *cg)
371
{
372
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
373
}
374
375
TR::Register*
376
J9::TreeEvaluator::pdsubEvaluator(TR::Node *node, TR::CodeGenerator *cg)
377
{
378
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
379
}
380
381
TR::Register*
382
J9::TreeEvaluator::pdmulEvaluator(TR::Node *node, TR::CodeGenerator *cg)
383
{
384
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
385
}
386
387
TR::Register*
388
J9::TreeEvaluator::pddivEvaluator(TR::Node *node, TR::CodeGenerator *cg)
389
{
390
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
391
}
392
393
TR::Register*
394
J9::TreeEvaluator::pdremEvaluator(TR::Node *node, TR::CodeGenerator *cg)
395
{
396
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
397
}
398
399
TR::Register*
400
J9::TreeEvaluator::pdnegEvaluator(TR::Node *node, TR::CodeGenerator *cg)
401
{
402
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
403
}
404
405
TR::Register*
406
J9::TreeEvaluator::pdabsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
407
{
408
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
409
}
410
411
TR::Register*
412
J9::TreeEvaluator::pdshrEvaluator(TR::Node *node, TR::CodeGenerator *cg)
413
{
414
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
415
}
416
417
TR::Register*
418
J9::TreeEvaluator::pdshlEvaluator(TR::Node *node, TR::CodeGenerator *cg)
419
{
420
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
421
}
422
423
TR::Register*
424
J9::TreeEvaluator::pdshrSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg)
425
{
426
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
427
}
428
429
TR::Register*
430
J9::TreeEvaluator::pdshlSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg)
431
{
432
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
433
}
434
435
TR::Register*
436
J9::TreeEvaluator::pdshlOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg)
437
{
438
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
439
}
440
441
TR::Register*
442
J9::TreeEvaluator::pdchkEvaluator(TR::Node *node, TR::CodeGenerator *cg)
443
{
444
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
445
}
446
447
TR::Register*
448
J9::TreeEvaluator::pd2iEvaluator(TR::Node *node, TR::CodeGenerator *cg)
449
{
450
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
451
}
452
453
TR::Register*
454
J9::TreeEvaluator::pd2iuEvaluator(TR::Node *node, TR::CodeGenerator *cg)
455
{
456
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
457
}
458
459
TR::Register*
460
J9::TreeEvaluator::pd2iOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg)
461
{
462
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
463
}
464
465
TR::Register*
466
J9::TreeEvaluator::i2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
467
{
468
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
469
}
470
471
TR::Register*
472
J9::TreeEvaluator::iu2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
473
{
474
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
475
}
476
477
TR::Register*
478
J9::TreeEvaluator::pd2lEvaluator(TR::Node *node, TR::CodeGenerator *cg)
479
{
480
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
481
}
482
483
TR::Register*
484
J9::TreeEvaluator::pd2luEvaluator(TR::Node *node, TR::CodeGenerator *cg)
485
{
486
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
487
}
488
489
TR::Register*
490
J9::TreeEvaluator::pd2lOverflowEvaluator(TR::Node *node, TR::CodeGenerator *cg)
491
{
492
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
493
}
494
495
TR::Register*
496
J9::TreeEvaluator::l2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
497
{
498
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
499
}
500
501
TR::Register*
502
J9::TreeEvaluator::lu2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
503
{
504
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
505
}
506
507
TR::Register*
508
J9::TreeEvaluator::pd2fEvaluator(TR::Node *node, TR::CodeGenerator *cg)
509
{
510
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
511
}
512
513
TR::Register*
514
J9::TreeEvaluator::pd2dEvaluator(TR::Node *node, TR::CodeGenerator *cg)
515
{
516
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
517
}
518
519
TR::Register*
520
J9::TreeEvaluator::f2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
521
{
522
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
523
}
524
525
TR::Register*
526
J9::TreeEvaluator::d2pdEvaluator(TR::Node *node, TR::CodeGenerator *cg)
527
{
528
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
529
}
530
531
TR::Register*
532
J9::TreeEvaluator::pdcmpeqEvaluator(TR::Node *node, TR::CodeGenerator *cg)
533
{
534
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
535
}
536
537
TR::Register*
538
J9::TreeEvaluator::pdcmpneEvaluator(TR::Node *node, TR::CodeGenerator *cg)
539
{
540
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
541
}
542
543
TR::Register*
544
J9::TreeEvaluator::pdcmpltEvaluator(TR::Node *node, TR::CodeGenerator *cg)
545
{
546
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
547
}
548
549
TR::Register*
550
J9::TreeEvaluator::pdcmpgeEvaluator(TR::Node *node, TR::CodeGenerator *cg)
551
{
552
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
553
}
554
555
TR::Register*
556
J9::TreeEvaluator::pdcmpgtEvaluator(TR::Node *node, TR::CodeGenerator *cg)
557
{
558
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
559
}
560
561
TR::Register*
562
J9::TreeEvaluator::pdcmpleEvaluator(TR::Node *node, TR::CodeGenerator *cg)
563
{
564
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
565
}
566
567
TR::Register*
568
J9::TreeEvaluator::pdcleanEvaluator(TR::Node *node, TR::CodeGenerator *cg)
569
{
570
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
571
}
572
573
TR::Register*
574
J9::TreeEvaluator::pdclearEvaluator(TR::Node *node, TR::CodeGenerator *cg)
575
{
576
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
577
}
578
579
TR::Register*
580
J9::TreeEvaluator::pdclearSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg)
581
{
582
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
583
}
584
585
TR::Register*
586
J9::TreeEvaluator::pdSetSignEvaluator(TR::Node *node, TR::CodeGenerator *cg)
587
{
588
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
589
}
590
591
TR::Register*
592
J9::TreeEvaluator::pdModifyPrecisionEvaluator(TR::Node *node, TR::CodeGenerator *cg)
593
{
594
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
595
}
596
597
TR::Register*
598
J9::TreeEvaluator::countDigitsEvaluator(TR::Node *node, TR::CodeGenerator *cg)
599
{
600
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
601
}
602
603
TR::Register*
604
J9::TreeEvaluator::BCDCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg)
605
{
606
return TR::TreeEvaluator::unImpOpEvaluator(node, cg);
607
}
608
609
TR::Snippet *
610
J9::TreeEvaluator::getFieldWatchInstanceSnippet(TR::CodeGenerator *cg, TR::Node *node, J9Method *m, UDATA loc, UDATA os)
611
{
612
return new (cg->trHeapMemory()) TR::J9WatchedInstanceFieldSnippet(cg, node, m, loc, os);
613
}
614
615
TR::Snippet *
616
J9::TreeEvaluator::getFieldWatchStaticSnippet(TR::CodeGenerator *cg, TR::Node *node, J9Method *m, UDATA loc, void *fieldAddress, J9Class *fieldClass)
617
{
618
return new (cg->trHeapMemory()) TR::J9WatchedStaticFieldSnippet(cg, node, m, loc, fieldAddress, fieldClass);
619
}
620
621
void
622
J9::TreeEvaluator::rdWrtbarHelperForFieldWatch(TR::Node *node, TR::CodeGenerator *cg, TR::Register *sideEffectRegister, TR::Register *valueReg)
623
{
624
TR_ASSERT_FATAL(J9ClassHasWatchedFields >= std::numeric_limits<uint16_t>::min() && J9ClassHasWatchedFields <= std::numeric_limits<uint16_t>::max(), "Expecting value of J9ClassHasWatchedFields to be within 16 bits. Currently it's %d(%p).", J9ClassHasWatchedFields, J9ClassHasWatchedFields);
625
626
// Populate a data snippet with the required information so we can call a VM helper to report the Field Watch event.
627
TR::SymbolReference *symRef = node->getSymbolReference();
628
J9Method *owningMethod = reinterpret_cast<J9Method *>(node->getOwningMethod());
629
TR::Register *dataSnippetRegister = cg->allocateRegister();
630
bool isWrite = node->getOpCode().isWrtBar();
631
bool isUnresolved = symRef->isUnresolved();
632
int32_t bcIndex = node->getByteCodeInfo().getByteCodeIndex();
633
634
TR::Snippet *dataSnippet = NULL;
635
if (symRef->getSymbol()->isStatic())
636
{
637
void *fieldAddress = isUnresolved ? reinterpret_cast<void *>(-1) : symRef->getSymbol()->getStaticSymbol()->getStaticAddress();
638
J9Class *fieldClass = isUnresolved ? NULL : reinterpret_cast<J9Class *>(symRef->getOwningMethod(cg->comp())->getDeclaringClassFromFieldOrStatic(cg->comp(), symRef->getCPIndex()));
639
dataSnippet = TR::TreeEvaluator::getFieldWatchStaticSnippet(cg, node, owningMethod, bcIndex, fieldAddress, fieldClass);
640
}
641
else
642
{
643
dataSnippet = TR::TreeEvaluator::getFieldWatchInstanceSnippet(cg, node, owningMethod, bcIndex, isUnresolved ? -1 : symRef->getOffset() - TR::Compiler->om.objectHeaderSizeInBytes());
644
}
645
cg->addSnippet(dataSnippet);
646
647
// If unresolved, then we generate instructions to populate the data snippet's fields correctly at runtime.
648
// Note: We also call the VM Helper routine to fill in the data snippet's fields if this is an AOT compilation.
649
// Once the infrastructure to support AOT during fieldwatch is enabled and functionally correct, we can remove is check.
650
if (isUnresolved || cg->needClassAndMethodPointerRelocations())
651
{
652
// Resolve and populate dataSnippet fields.
653
TR::TreeEvaluator::generateFillInDataBlockSequenceForUnresolvedField(cg, node, dataSnippet, isWrite, sideEffectRegister, dataSnippetRegister);
654
}
655
// Generate instructions to call the VM helper and report the fieldwatch event
656
TR::TreeEvaluator::generateTestAndReportFieldWatchInstructions(cg, node, dataSnippet, isWrite, sideEffectRegister, valueReg, dataSnippetRegister);
657
658
cg->stopUsingRegister(dataSnippetRegister);
659
}
660
661
TR::Register *
662
J9::TreeEvaluator::bwrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg)
663
{
664
// For rdbar and wrtbar nodes we first evaluate the children we need to
665
// handle the side effects. Then we delegate the evaluation of the remaining
666
// children and the load/store operation to the appropriate load/store evaluator.
667
TR::Register *valueReg = cg->evaluate(node->getFirstChild());
668
TR::Node *sideEffectNode = node->getSecondChild();
669
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
670
671
if (cg->comp()->getOption(TR_EnableFieldWatch))
672
{
673
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, valueReg);
674
}
675
676
// Note: The reference count for valueReg's node is not decremented here because the
677
// store evaluator also uses it and so it will evaluate+decrement it. Thus we must skip decrementing here
678
// to avoid double decrementing.
679
cg->decReferenceCount(sideEffectNode);
680
return TR::TreeEvaluator::bstoreEvaluator(node, cg);
681
}
682
683
TR::Register *
684
J9::TreeEvaluator::bwrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg)
685
{
686
// For rdbar and wrtbar nodes we first evaluate the children we need to
687
// handle the side effects. Then we delegate the evaluation of the remaining
688
// children and the load/store operation to the appropriate load/store evaluator.
689
TR::Register *valueReg = cg->evaluate(node->getSecondChild());
690
TR::Node *sideEffectNode = node->getThirdChild();
691
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
692
693
if (cg->comp()->getOption(TR_EnableFieldWatch))
694
{
695
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, valueReg);
696
}
697
698
// Note: The reference count for valueReg's node is not decremented here because the
699
// store evaluator also uses it and so it will evaluate+decrement it. Thus we must skip decrementing here
700
// to avoid double decrementing.
701
cg->decReferenceCount(sideEffectNode);
702
return TR::TreeEvaluator::bstoreEvaluator(node, cg);
703
}
704
705
TR::Register *
706
J9::TreeEvaluator::swrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg)
707
{
708
// For rdbar and wrtbar nodes we first evaluate the children we need to
709
// handle the side effects. Then we delegate the evaluation of the remaining
710
// children and the load/store operation to the appropriate load/store evaluator.
711
TR::Register *valueReg = cg->evaluate(node->getFirstChild());
712
TR::Node *sideEffectNode = node->getSecondChild();
713
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
714
715
if (cg->comp()->getOption(TR_EnableFieldWatch))
716
{
717
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, valueReg);
718
}
719
720
// Note: The reference count for valueReg's node is not decremented here because the
721
// store evaluator also uses it and so it will evaluate+decrement it. Thus we must skip decrementing here
722
// to avoid double decrementing.
723
cg->decReferenceCount(sideEffectNode);
724
return TR::TreeEvaluator::sstoreEvaluator(node, cg);
725
}
726
727
TR::Register *
728
J9::TreeEvaluator::swrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg)
729
{
730
// For rdbar and wrtbar nodes we first evaluate the children we need to
731
// handle the side effects. Then we delegate the evaluation of the remaining
732
// children and the load/store operation to the appropriate load/store evaluator.
733
TR::Register *valueReg = cg->evaluate(node->getSecondChild());
734
TR::Node *sideEffectNode = node->getThirdChild();
735
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
736
737
if (cg->comp()->getOption(TR_EnableFieldWatch))
738
{
739
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, valueReg);
740
}
741
742
// Note: The reference count for valueReg's node is not decremented here because the
743
// store evaluator also uses it and so it will evaluate+decrement it. Thus we must skip decrementing here
744
// to avoid double decrementing.
745
cg->decReferenceCount(sideEffectNode);
746
return TR::TreeEvaluator::sstoreEvaluator(node, cg);
747
}
748
749
TR::Register *
750
J9::TreeEvaluator::iwrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg)
751
{
752
// For rdbar and wrtbar nodes we first evaluate the children we need to
753
// handle the side effects. Then we delegate the evaluation of the remaining
754
// children and the load/store operation to the appropriate load/store evaluator.
755
TR::Register *valueReg = cg->evaluate(node->getFirstChild());
756
TR::Node *sideEffectNode = node->getSecondChild();
757
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
758
759
if (cg->comp()->getOption(TR_EnableFieldWatch))
760
{
761
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, valueReg);
762
}
763
764
// Note: The reference count for valueReg's node is not decremented here because the
765
// store evaluator also uses it and so it will evaluate+decrement it. Thus we must skip decrementing here
766
// to avoid double decrementing.
767
cg->decReferenceCount(sideEffectNode);
768
return TR::TreeEvaluator::istoreEvaluator(node, cg);
769
}
770
771
TR::Register *
772
J9::TreeEvaluator::iwrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg)
773
{
774
// For rdbar and wrtbar nodes we first evaluate the children we need to
775
// handle the side effects. Then we delegate the evaluation of the remaining
776
// children and the load/store operation to the appropriate load/store evaluator.
777
TR::Register *valueReg = cg->evaluate(node->getSecondChild());
778
TR::Node *sideEffectNode = node->getThirdChild();
779
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
780
781
if (cg->comp()->getOption(TR_EnableFieldWatch))
782
{
783
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, valueReg);
784
}
785
786
// Note: The reference count for valueReg's node is not decremented here because the
787
// store evaluator also uses it and so it will evaluate+decrement it. Thus we must skip decrementing here
788
// to avoid double decrementing.
789
cg->decReferenceCount(sideEffectNode);
790
return TR::TreeEvaluator::istoreEvaluator(node, cg);
791
}
792
793
TR::Register *
794
J9::TreeEvaluator::lwrtbarEvaluator(TR::Node *node, TR::CodeGenerator *cg)
795
{
796
// For rdbar and wrtbar nodes we first evaluate the children we need to
797
// handle the side effects. Then we delegate the evaluation of the remaining
798
// children and the load/store operation to the appropriate load/store evaluator.
799
TR::Register *valueReg = cg->evaluate(node->getFirstChild());
800
TR::Node *sideEffectNode = node->getSecondChild();
801
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
802
803
if (cg->comp()->getOption(TR_EnableFieldWatch))
804
{
805
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, valueReg);
806
}
807
808
// Note: The reference count for valueReg's node is not decremented here because the
809
// store evaluator also uses it and so it will evaluate+decrement it. Thus we must skip decrementing here
810
// to avoid double decrementing.
811
cg->decReferenceCount(sideEffectNode);
812
return TR::TreeEvaluator::lstoreEvaluator(node, cg);
813
}
814
815
TR::Register *
816
J9::TreeEvaluator::lwrtbariEvaluator(TR::Node *node, TR::CodeGenerator *cg)
817
{
818
// For rdbar and wrtbar nodes we first evaluate the children we need to
819
// handle the side effects. Then we delegate the evaluation of the remaining
820
// children and the load/store operation to the appropriate load/store evaluator.
821
TR::Register *valueReg = cg->evaluate(node->getSecondChild());
822
TR::Node *sideEffectNode = node->getThirdChild();
823
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
824
825
if (cg->comp()->getOption(TR_EnableFieldWatch))
826
{
827
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, valueReg);
828
}
829
830
// Note: The reference count for valueReg's node is not decremented here because the
831
// store evaluator also uses it and so it will evaluate+decrement it. Thus we must skip decrementing here
832
// to avoid double decrementing.
833
cg->decReferenceCount(sideEffectNode);
834
return TR::TreeEvaluator::lstoreEvaluator(node, cg);
835
}
836
837
TR::Register *
838
J9::TreeEvaluator::frdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg)
839
{
840
// For rdbar and wrtbar nodes we first evaluate the children we need to
841
// handle the side effects. Then we delegate the evaluation of the remaining
842
// children and the load/store operation to the appropriate load/store evaluator.
843
TR::Node *sideEffectNode = node->getFirstChild();
844
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
845
846
if (cg->comp()->getOption(TR_EnableFieldWatch))
847
{
848
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, NULL);
849
}
850
851
cg->decReferenceCount(sideEffectNode);
852
return TR::TreeEvaluator::floadEvaluator(node, cg);
853
}
854
855
TR::Register *
856
J9::TreeEvaluator::frdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg)
857
{
858
// For rdbar and wrtbar nodes we first evaluate the children we need to
859
// handle the side effects. Then we delegate the evaluation of the remaining
860
// children and the load/store operation to the appropriate load/store evaluator.
861
TR::Register *sideEffectRegister = cg->evaluate(node->getFirstChild());
862
863
if (cg->comp()->getOption(TR_EnableFieldWatch))
864
{
865
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, NULL);
866
}
867
// Note: For indirect rdbar nodes, the first child (sideEffectNode) is also used by the
868
// load evaluator. The load evaluator will also evaluate+decrement it. In order to avoid double
869
// decrementing the node we skip doing it here and let the load evaluator do it.
870
return TR::TreeEvaluator::floadEvaluator(node, cg);
871
}
872
873
TR::Register *
874
J9::TreeEvaluator::drdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg)
875
{
876
// For rdbar and wrtbar nodes we first evaluate the children we need to
877
// handle the side effects. Then we delegate the evaluation of the remaining
878
// children and the load/store operation to the appropriate load/store evaluator.
879
TR::Node *sideEffectNode = node->getFirstChild();
880
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
881
882
if (cg->comp()->getOption(TR_EnableFieldWatch))
883
{
884
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, NULL);
885
}
886
887
cg->decReferenceCount(sideEffectNode);
888
return TR::TreeEvaluator::dloadEvaluator(node, cg);
889
}
890
891
TR::Register *
892
J9::TreeEvaluator::drdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg)
893
{
894
// For rdbar and wrtbar nodes we first evaluate the children we need to
895
// handle the side effects. Then we delegate the evaluation of the remaining
896
// children and the load/store operation to the appropriate load/store evaluator.
897
TR::Register *sideEffectRegister = cg->evaluate(node->getFirstChild());
898
899
if (cg->comp()->getOption(TR_EnableFieldWatch))
900
{
901
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, NULL);
902
}
903
904
// Note: For indirect rdbar nodes, the first child (sideEffectNode) is also used by the
905
// load evaluator. The load evaluator will also evaluate+decrement it. In order to avoid double
906
// decrementing the node we skip doing it here and let the load evaluator do it.
907
return TR::TreeEvaluator::dloadEvaluator(node, cg);
908
}
909
910
TR::Register *
911
J9::TreeEvaluator::brdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg)
912
{
913
// For rdbar and wrtbar nodes we first evaluate the children we need to
914
// handle the side effects. Then we delegate the evaluation of the remaining
915
// children and the load/store operation to the appropriate load/store evaluator.
916
TR::Node *sideEffectNode = node->getFirstChild();
917
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
918
919
if (cg->comp()->getOption(TR_EnableFieldWatch))
920
{
921
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, NULL);
922
}
923
924
cg->decReferenceCount(sideEffectNode);
925
return TR::TreeEvaluator::bloadEvaluator(node, cg);
926
}
927
928
TR::Register *
929
J9::TreeEvaluator::brdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg)
930
{
931
// For rdbar and wrtbar nodes we first evaluate the children we need to
932
// handle the side effects. Then we delegate the evaluation of the remaining
933
// children and the load/store operation to the appropriate load/store evaluator.
934
TR::Register *sideEffectRegister = cg->evaluate(node->getFirstChild());
935
936
if (cg->comp()->getOption(TR_EnableFieldWatch))
937
{
938
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, NULL);
939
}
940
941
// Note: For indirect rdbar nodes, the first child (sideEffectNode) is also used by the
942
// load evaluator. The load evaluator will also evaluate+decrement it. In order to avoid double
943
// decrementing the node we skip doing it here and let the load evaluator do it.
944
return TR::TreeEvaluator::bloadEvaluator(node, cg);
945
}
946
947
TR::Register *
948
J9::TreeEvaluator::srdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg)
949
{
950
// For rdbar and wrtbar nodes we first evaluate the children we need to
951
// handle the side effects. Then we delegate the evaluation of the remaining
952
// children and the load/store operation to the appropriate load/store evaluator.
953
TR::Node *sideEffectNode = node->getFirstChild();
954
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
955
956
if (cg->comp()->getOption(TR_EnableFieldWatch))
957
{
958
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, NULL);
959
}
960
961
cg->decReferenceCount(sideEffectNode);
962
return TR::TreeEvaluator::sloadEvaluator(node, cg);
963
}
964
965
TR::Register *
966
J9::TreeEvaluator::srdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg)
967
{
968
// For rdbar and wrtbar nodes we first evaluate the children we need to
969
// handle the side effects. Then we delegate the evaluation of the remaining
970
// children and the load/store operation to the appropriate load/store evaluator.
971
TR::Register *sideEffectRegister = cg->evaluate(node->getFirstChild());
972
973
if (cg->comp()->getOption(TR_EnableFieldWatch))
974
{
975
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, NULL);
976
}
977
978
// Note: For indirect rdbar nodes, the first child (sideEffectNode) is also used by the
979
// load evaluator. The load evaluator will also evaluate+decrement it. In order to avoid double
980
// decrementing the node we skip doing it here and let the load evaluator do it.
981
return TR::TreeEvaluator::sloadEvaluator(node, cg);
982
}
983
984
TR::Register *
985
J9::TreeEvaluator::lrdbarEvaluator(TR::Node *node, TR::CodeGenerator *cg)
986
{
987
// For rdbar and wrtbar nodes we first evaluate the children we need to
988
// handle the side effects. Then we delegate the evaluation of the remaining
989
// children and the load/store operation to the appropriate load/store evaluator.
990
TR::Node *sideEffectNode = node->getFirstChild();
991
TR::Register *sideEffectRegister = cg->evaluate(sideEffectNode);
992
993
if (cg->comp()->getOption(TR_EnableFieldWatch))
994
{
995
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, NULL);
996
}
997
998
cg->decReferenceCount(sideEffectNode);
999
return TR::TreeEvaluator::lloadEvaluator(node, cg);
1000
}
1001
1002
TR::Register *
1003
J9::TreeEvaluator::lrdbariEvaluator(TR::Node *node, TR::CodeGenerator *cg)
1004
{
1005
// For rdbar and wrtbar nodes we first evaluate the children we need to
1006
// handle the side effects. Then we delegate the evaluation of the remaining
1007
// children and the load/store operation to the appropriate load/store evaluator.
1008
TR::Register *sideEffectRegister = cg->evaluate(node->getFirstChild());
1009
1010
if (cg->comp()->getOption(TR_EnableFieldWatch))
1011
{
1012
TR::TreeEvaluator::rdWrtbarHelperForFieldWatch(node, cg, sideEffectRegister, NULL);
1013
}
1014
1015
// Note: For indirect rdbar nodes, the first child (sideEffectNode) is also used by the
1016
// load evaluator. The load evaluator will also evaluate+decrement it. In order to avoid double
1017
// decrementing the node we skip doing it here and let the load evaluator do it.
1018
return TR::TreeEvaluator::lloadEvaluator(node, cg);
1019
}
1020
1021
///////////////////////////////////////////////////////////////////////////////////////
1022
// monexitfence -- do nothing, just a placeholder for live monitor meta data
1023
///////////////////////////////////////////////////////////////////////////////////////
1024
TR::Register *
1025
J9::TreeEvaluator::monexitfenceEvaluator(TR::Node *node, TR::CodeGenerator *cg)
1026
{
1027
return NULL;
1028
}
1029
1030
bool J9::TreeEvaluator::getIndirectWrtbarValueNode(TR::CodeGenerator *cg, TR::Node *node, TR::Node*& sourceChild, bool incSrcRefCount)
1031
{
1032
TR_ASSERT_FATAL(node->getOpCode().isIndirect() && node->getOpCode().isWrtBar(), "getIndirectWrtbarValueNode expects indirect wrtbar nodes only n%dn (%p)\n", node->getGlobalIndex(), node);
1033
bool usingCompressedPointers = false;
1034
sourceChild = node->getSecondChild();
1035
1036
if (cg->comp()->useCompressedPointers() && (node->getSymbolReference()->getSymbol()->getDataType() == TR::Address) &&
1037
(node->getSecondChild()->getDataType() != TR::Address))
1038
{
1039
// pattern match the sequence
1040
// awrtbari f awrtbari f <- node
1041
// aload O aload O
1042
// value l2i
1043
// lshr
1044
// lsub <- translatedNode
1045
// a2l
1046
// value <- sourceChild
1047
// lconst HB
1048
// iconst shftKonst
1049
//
1050
// -or- if the field is known to be null
1051
// awrtbari f
1052
// aload O
1053
// l2i
1054
// a2l
1055
// value <- sourceChild
1056
//
1057
TR::Node *translatedNode = sourceChild;
1058
if (translatedNode->getOpCodeValue() == TR::l2i)
1059
{
1060
translatedNode = translatedNode->getFirstChild();
1061
}
1062
if (translatedNode->getOpCode().isRightShift())
1063
{
1064
TR::Node *shiftAmountChild = translatedNode->getSecondChild();
1065
TR_ASSERT_FATAL(TR::Compiler->om.compressedReferenceShiftOffset() == shiftAmountChild->getConstValue(),
1066
"Expect shift amount in the compressedref conversion sequence to be %d but get %d for indirect wrtbar node n%dn (%p)\n",
1067
TR::Compiler->om.compressedReferenceShiftOffset(), shiftAmountChild->getConstValue(), node->getGlobalIndex(), node);
1068
1069
translatedNode = translatedNode->getFirstChild();
1070
}
1071
1072
usingCompressedPointers = true;
1073
1074
while ((sourceChild->getNumChildren() > 0) && (sourceChild->getOpCodeValue() != TR::a2l))
1075
{
1076
sourceChild = sourceChild->getFirstChild();
1077
}
1078
if (sourceChild->getOpCodeValue() == TR::a2l)
1079
{
1080
sourceChild = sourceChild->getFirstChild();
1081
}
1082
1083
// Artificially bump up the refCount on the value so
1084
// that different registers are allocated for the actual
1085
// and compressed values. This is done so that the VMwrtbarEvaluator
1086
// uses the uncompressed value. We only need to do this when the caller
1087
// is evaluating the actual write barrier.
1088
if (incSrcRefCount)
1089
{
1090
sourceChild->incReferenceCount();
1091
}
1092
}
1093
return usingCompressedPointers;
1094
}
1095
1096
static
1097
void traceInstanceOfOrCheckCastProfilingInfo(TR::CodeGenerator *cg, TR::Node *node, TR_OpaqueClassBlock *castClass)
1098
{
1099
TR::Compilation *comp = cg->comp();
1100
TR_J9VMBase *fej9 = (TR_J9VMBase *)(cg->fe());
1101
TR_ByteCodeInfo bcInfo = node->getByteCodeInfo();
1102
TR_ValueProfileInfoManager *valueProfileInfo = TR_ValueProfileInfoManager::get(comp);
1103
1104
if (!valueProfileInfo)
1105
{
1106
return;
1107
}
1108
1109
TR_AddressInfo * valueInfo = static_cast<TR_AddressInfo*>(valueProfileInfo->getValueInfo(bcInfo, comp, AddressInfo, TR_ValueProfileInfoManager::justInterpreterProfileInfo));
1110
if (!valueInfo || valueInfo->getNumProfiledValues() == 0)
1111
{
1112
return;
1113
}
1114
1115
traceMsg(comp, "%s:\n", __func__);
1116
1117
TR_ScratchList<TR_ExtraAddressInfo> valuesSortedByFrequency(comp->trMemory());
1118
1119
valueInfo->getSortedList(comp, &valuesSortedByFrequency);
1120
1121
ListIterator<TR_ExtraAddressInfo> sortedValuesIt(&valuesSortedByFrequency);
1122
for (TR_ExtraAddressInfo *profiledInfo = sortedValuesIt.getFirst(); profiledInfo != NULL; profiledInfo = sortedValuesIt.getNext())
1123
{
1124
TR_OpaqueClassBlock *profiledClass = fej9->getProfiledClassFromProfiledInfo(profiledInfo);
1125
1126
traceMsg(comp, "%s:\tProfiled class [" POINTER_PRINTF_FORMAT "] (%u/%u)\n",
1127
node->getOpCode().getName(), profiledClass, profiledInfo->_frequency, valueInfo->getTotalFrequency());
1128
1129
if (!profiledClass)
1130
continue;
1131
1132
if (comp->getPersistentInfo()->isObsoleteClass(profiledClass, fej9))
1133
{
1134
traceMsg(comp, "%s:\tProfiled class [" POINTER_PRINTF_FORMAT "] is obsolete\n",
1135
node->getOpCode().getName(), profiledClass);
1136
continue;
1137
}
1138
1139
bool isInstanceOf = fej9->instanceOfOrCheckCastNoCacheUpdate((J9Class *)profiledClass, (J9Class *)castClass);
1140
traceMsg(comp, "%s:\tProfiled class [" POINTER_PRINTF_FORMAT "] is %san instance of cast class\n",
1141
node->getOpCode().getName(), profiledClass, isInstanceOf ? "" : "not ");
1142
}
1143
}
1144
/** \brief Generates an array of profiled classes with the boolean representing if the profiled class is instanceOf cast class or not
1145
** \param profiledClassList
1146
** An array of InstanceOfOrCheckCasrProfiledClasses structure passed from the main evaluator to fill up with profiled classes info
1147
** \param topClassProbability
1148
** float pointer passed from main evaluator, we update the value with the probability for the top profiled class to be castClass
1149
** \param maxProfiledClass
1150
** An int denoting how many profiled classes we want
1151
**/
1152
static
1153
uint32_t getInstanceOfOrCheckCastTopProfiledClass(TR::CodeGenerator *cg, TR::Node *node, TR_OpaqueClassBlock *castClass, J9::TreeEvaluator::InstanceOfOrCheckCastProfiledClasses *profiledClassList, bool *topClassWasCastClass, uint32_t maxProfiledClass, float *topClassProbability)
1154
{
1155
TR::Compilation *comp = cg->comp();
1156
1157
if (comp->getOption(TR_TraceCG))
1158
{
1159
static bool traceProfilingInfo = feGetEnv("TR_traceInstanceOfOrCheckCastProfilingInfo") != NULL;
1160
if (traceProfilingInfo)
1161
traceInstanceOfOrCheckCastProfilingInfo(cg, node, castClass);
1162
}
1163
1164
TR_J9VMBase *fej9 = (TR_J9VMBase *)(cg->fe());
1165
TR_ByteCodeInfo bcInfo = node->getByteCodeInfo();
1166
TR_ValueProfileInfoManager *valueProfileInfo = TR_ValueProfileInfoManager::get(comp);
1167
1168
// We do not have validation record to verify that relocated profiled class
1169
// in the load run is instanceof castclass or not. So without that
1170
// verification, we could end up generating code where we have a defined
1171
// relationship between profiled class and cast class which could not be
1172
// true in load run and we could end up with incorrect execution in the
1173
// application.
1174
// TODO: Once we have validation record for instanceOfOrCheckCastNoCacheUpdate
1175
// enable profiled class test in AOT when SVM is enabled.
1176
if (!valueProfileInfo || comp->compileRelocatableCode())
1177
{
1178
return 0;
1179
}
1180
1181
TR_AddressInfo * valueInfo = static_cast<TR_AddressInfo*>(valueProfileInfo->getValueInfo(bcInfo, comp, AddressInfo, TR_ValueProfileInfoManager::justInterpreterProfileInfo));
1182
if (!valueInfo || valueInfo->getNumProfiledValues() == 0)
1183
{
1184
return 0;
1185
}
1186
1187
if (topClassWasCastClass)
1188
*topClassWasCastClass = false;
1189
1190
TR_ScratchList<TR_ExtraAddressInfo> valuesSortedByFrequency(comp->trMemory());
1191
1192
valueInfo->getSortedList(comp, &valuesSortedByFrequency);
1193
1194
float totalFrequency = valueInfo->getTotalFrequency();
1195
1196
ListIterator<TR_ExtraAddressInfo> sortedValuesIt(&valuesSortedByFrequency);
1197
uint32_t numProfiledClasses = 0;
1198
for (TR_ExtraAddressInfo *profiledInfo = sortedValuesIt.getFirst(); profiledInfo != NULL && numProfiledClasses < maxProfiledClass ; profiledInfo = sortedValuesIt.getNext())
1199
{
1200
TR_OpaqueClassBlock *tempProfiledClass = fej9->getProfiledClassFromProfiledInfo(profiledInfo);
1201
1202
if (!tempProfiledClass)
1203
continue;
1204
1205
// Skip unloaded classes.
1206
//
1207
if (comp->getPersistentInfo()->isObsoleteClass(tempProfiledClass, fej9))
1208
{
1209
if (comp->getOption(TR_TraceCG))
1210
{
1211
traceMsg(comp, "%s: Profiled class [" POINTER_PRINTF_FORMAT "] is obsolete, skipping\n",
1212
node->getOpCode().getName(), tempProfiledClass);
1213
}
1214
continue;
1215
}
1216
1217
// For checkcast, skip classes that will fail the cast, not much value in optimizing for those cases.
1218
// We also don't want to pollute the cast class cache with a failing class for the same reason.
1219
//
1220
bool isInstanceOf = fej9->instanceOfOrCheckCastNoCacheUpdate((J9Class *)tempProfiledClass, (J9Class *)castClass);
1221
if (node->getOpCode().isCheckCast() && !isInstanceOf)
1222
{
1223
if (comp->getOption(TR_TraceCG))
1224
{
1225
traceMsg(comp, "%s: Profiled class [" POINTER_PRINTF_FORMAT "] is not an instance of cast class, skipping\n",
1226
node->getOpCode().getName(), tempProfiledClass);
1227
}
1228
continue;
1229
}
1230
1231
// If the cast class is the top class skip it and return the next highest class if the caller requested it by providing an output param.
1232
//
1233
if (tempProfiledClass == castClass && topClassWasCastClass && numProfiledClasses == 0)
1234
{
1235
if (comp->getOption(TR_TraceCG))
1236
{
1237
traceMsg(comp, "%s: Profiled class [" POINTER_PRINTF_FORMAT "] is the cast class, informing caller and skipping\n",
1238
node->getOpCode().getName(), tempProfiledClass);
1239
}
1240
*topClassWasCastClass = true;
1241
*topClassProbability = profiledInfo->_frequency / totalFrequency;
1242
continue;
1243
}
1244
1245
// For AOT compiles with a SymbolValidationManager, skip any classes which cannot be verified.
1246
//
1247
if (comp->compileRelocatableCode() && comp->getOption(TR_UseSymbolValidationManager))
1248
if (!comp->getSymbolValidationManager()->addProfiledClassRecord(tempProfiledClass))
1249
continue;
1250
1251
float frequency = profiledInfo->_frequency / totalFrequency;
1252
if ( frequency >= TR::Options::getMinProfiledCheckcastFrequency() )
1253
{
1254
// We have a winner.
1255
//
1256
profiledClassList[numProfiledClasses].profiledClass = tempProfiledClass;
1257
profiledClassList[numProfiledClasses].isProfiledClassInstanceOfCastClass = isInstanceOf;
1258
profiledClassList[numProfiledClasses].frequency = frequency;
1259
numProfiledClasses++;
1260
}
1261
else
1262
{
1263
// Profiled Class is sorted by frequency so if the frequency is less than the Minimum don't bother with generating another profiled Class
1264
break;
1265
}
1266
}
1267
return numProfiledClasses;
1268
}
1269
1270
/** \brief Generates an array of profiled classes with the boolean representing if the profiled class is instanceOf cast class or not
1271
** \param profiledClassList
1272
** An array of InstanceOfOrCheckCasrProfiledClasses structure passed from the main evaluator to fill up with profiled classes info
1273
** \param numberOfProfiledClass
1274
** An int pointer passed from main evaluator, we update the value with the number of classes we get from profilef info
1275
** \param maxProfiledClass
1276
** An int denoting how many profiled classes we want
1277
** \param topClassProbability
1278
** Probability of having topClass to be castClass.
1279
** \param topClassWasCastClass
1280
** Boolean pointer which will be set to true or false depending on if top profiled class was cast class or not
1281
**/
1282
uint32_t J9::TreeEvaluator::calculateInstanceOfOrCheckCastSequences(TR::Node *instanceOfOrCheckCastNode, InstanceOfOrCheckCastSequences *sequences, TR_OpaqueClassBlock **compileTimeGuessClass, TR::CodeGenerator *cg, InstanceOfOrCheckCastProfiledClasses *profiledClassList, uint32_t *numberOfProfiledClass, uint32_t maxProfiledClass, float * topClassProbability, bool *topClassWasCastClass)
1283
{
1284
TR_J9VMBase *fej9 = (TR_J9VMBase *)(cg->fe());
1285
TR_ASSERT(instanceOfOrCheckCastNode->getOpCode().isCheckCast() || instanceOfOrCheckCastNode->getOpCodeValue() == TR::instanceof, "Unexpected node opcode");
1286
1287
TR::Node *objectNode = instanceOfOrCheckCastNode->getFirstChild();
1288
TR::Node *castClassNode = instanceOfOrCheckCastNode->getSecondChild();
1289
1290
bool isInstanceOf = instanceOfOrCheckCastNode->getOpCodeValue() == TR::instanceof;
1291
bool mayBeNull = !instanceOfOrCheckCastNode->isReferenceNonNull() && !objectNode->isNonNull();
1292
1293
// By default maxOnsiteCacheSlotForInstanceOf is set to 0 which means cache is disable.
1294
// To enable test pass JIT option maxOnsiteCacheSlotForInstanceOf=<number_of_slots>
1295
bool createDynamicCacheTests = cg->comp()->getOptions()->getMaxOnsiteCacheSlotForInstanceOf() > 0;
1296
1297
1298
uint32_t i = 0;
1299
uint32_t numProfiledClasses = 0;
1300
1301
if (castClassNode->getReferenceCount() > 1)
1302
{
1303
sequences[i++] = EvaluateCastClass;
1304
}
1305
1306
TR::SymbolReference *castClassSymRef = castClassNode->getSymbolReference();
1307
1308
if ((cg->comp()->getOption(TR_DisableInlineCheckCast) && (instanceOfOrCheckCastNode->getOpCodeValue() == TR::checkcast || instanceOfOrCheckCastNode->getOpCodeValue() == TR::checkcastAndNULLCHK)) || (cg->comp()->getOption(TR_DisableInlineInstanceOf) && instanceOfOrCheckCastNode->getOpCodeValue() == TR::instanceof))
1309
{
1310
if (instanceOfOrCheckCastNode->getOpCodeValue() == TR::checkcastAndNULLCHK)
1311
sequences[i++] = NullTest;
1312
sequences[i++] = HelperCall;
1313
}
1314
// Object is known to be null, usually removed by the optimizer, but in case they're not we know the result of the cast/instanceof.
1315
//
1316
else if (objectNode->isNull())
1317
{
1318
if (instanceOfOrCheckCastNode->getOpCodeValue() == TR::checkcastAndNULLCHK)
1319
sequences[i++] = NullTest;
1320
sequences[i++] = isInstanceOf ? GoToFalse : GoToTrue;
1321
}
1322
// Cast class is unresolved, not a lot of room to be fancy here.
1323
//
1324
else if (castClassSymRef->isUnresolved())
1325
{
1326
if (cg->comp()->getOption(TR_TraceCG))
1327
traceMsg(cg->comp(),"Cast Class unresolved\n");
1328
if (mayBeNull)
1329
sequences[i++] = NullTest;
1330
sequences[i++] = ClassEqualityTest;
1331
// There is a possibility of attempt to cast object to another class and having cache on that object updated by helper.
1332
// Before going to helper checking the cache.
1333
sequences[i++] = CastClassCacheTest;
1334
if (createDynamicCacheTests)
1335
sequences[i++] = DynamicCacheObjectClassTest;
1336
sequences[i++] = HelperCall;
1337
}
1338
// Cast class is a runtime variable, still not a lot of room to be fancy.
1339
//
1340
else if (!OMR::TreeEvaluator::isStaticClassSymRef(castClassSymRef))
1341
{
1342
traceMsg(cg->comp(),"Cast Class runtimeVariable\n");
1343
TR_ASSERT(isInstanceOf, "Expecting instanceof when cast class is a runtime variable");
1344
if (mayBeNull)
1345
sequences[i++] = NullTest;
1346
sequences[i++] = ClassEqualityTest;
1347
sequences[i++] = CastClassCacheTest;
1348
// On Z, We were having support for Super Class Test for dynamic Cast Class so adding it here. It can be guarded if Power/X do not need it.
1349
if (cg->supportsInliningOfIsInstance() &&
1350
instanceOfOrCheckCastNode->getOpCodeValue() == TR::instanceof &&
1351
instanceOfOrCheckCastNode->getSecondChild()->getOpCodeValue() != TR::loadaddr)
1352
sequences[i++] = SuperClassTest;
1353
if (createDynamicCacheTests)
1354
sequences[i++] = DynamicCacheDynamicCastClassTest;
1355
sequences[i++] = HelperCall;
1356
}
1357
1358
// Cast class is a compile-time constant, we can generate better code in this case.
1359
//
1360
else
1361
{
1362
1363
TR::StaticSymbol *castClassSym = castClassSymRef->getSymbol()->getStaticSymbol();
1364
TR_OpaqueClassBlock *castClass = (TR_OpaqueClassBlock *)castClassSym->getStaticAddress();
1365
J9UTF8 *castClassName = J9ROMCLASS_CLASSNAME(TR::Compiler->cls.romClassOf((TR_OpaqueClassBlock *) castClass));
1366
// Cast class is a primitive (implies this is an instanceof, since you can't cast an object to a primitive).
1367
// Usually removed by the optimizer, but in case they're not we know they'll always fail, no object can be of a primitive type.
1368
// We don't even need to do a null test unless it's a checkcastAndNULLCHK node.
1369
//
1370
if (TR::Compiler->cls.isPrimitiveClass(cg->comp(), castClass))
1371
{
1372
TR_ASSERT(isInstanceOf, "Expecting instanceof when cast class is a primitive");
1373
if (instanceOfOrCheckCastNode->getOpCodeValue() == TR::checkcastAndNULLCHK)
1374
sequences[i++] = NullTest;
1375
sequences[i++] = GoToFalse;
1376
}
1377
// Cast class is java/lang/Object.
1378
// Usually removed by the optimizer, if not we know everything is an Object, instanceof on null is the only thing that needs to be checked.
1379
//
1380
else if (cg->comp()->getObjectClassPointer() == castClass)
1381
{
1382
if (isInstanceOf)
1383
{
1384
if (mayBeNull)
1385
sequences[i++] = NullTest;
1386
sequences[i++] = GoToTrue;
1387
}
1388
else
1389
{
1390
if (instanceOfOrCheckCastNode->getOpCodeValue() == TR::checkcastAndNULLCHK)
1391
sequences[i++] = NullTest;
1392
sequences[i++] = GoToTrue;
1393
}
1394
}
1395
else
1396
{
1397
if (mayBeNull)
1398
{
1399
sequences[i++] = NullTest;
1400
}
1401
1402
TR_OpaqueClassBlock *topProfiledClass = NULL;
1403
1404
// If the caller doesn't provide the output param don't bother with profiling.
1405
//
1406
if (profiledClassList)
1407
{
1408
*numberOfProfiledClass = getInstanceOfOrCheckCastTopProfiledClass(cg, instanceOfOrCheckCastNode, castClass, profiledClassList, topClassWasCastClass, maxProfiledClass, topClassProbability);
1409
numProfiledClasses = *numberOfProfiledClass;
1410
if (cg->comp()->getOption(TR_TraceCG))
1411
{
1412
for (int i=0; i<numProfiledClasses; i++)
1413
{
1414
J9UTF8 *profiledClassName = J9ROMCLASS_CLASSNAME(TR::Compiler->cls.romClassOf((TR_OpaqueClassBlock *) profiledClassList[i].profiledClass));
1415
traceMsg(cg->comp(), "%s:Interpreter profiling instance class: [" POINTER_PRINTF_FORMAT "] %.*s, probability=%.1f\n",
1416
instanceOfOrCheckCastNode->getOpCode().getName(), profiledClassList[i].profiledClass, J9UTF8_LENGTH(profiledClassName), J9UTF8_DATA(profiledClassName), profiledClassList[i].frequency);
1417
}
1418
}
1419
}
1420
1421
TR_OpaqueClassBlock *singleImplementerClass = NULL;
1422
1423
// If the caller doesn't provide the output param don't bother with guessing.
1424
//
1425
if ((!cg->comp()->compileRelocatableCode() || cg->comp()->getOption(TR_UseSymbolValidationManager))
1426
&& compileTimeGuessClass
1427
&& !TR::Compiler->cls.isConcreteClass(cg->comp(), castClass))
1428
{
1429
// Figuring out that an interface/abstract class has a single concrete implementation is not as useful for instanceof as it is for checkcast.
1430
// For checkcast we expect the cast to succeed and the single concrete implementation is the logical class to do a quick up front test against.
1431
// For instanceof false can be a common result and the single concrete implementation doesn't tell us anything special.
1432
//
1433
if (!isInstanceOf)
1434
{
1435
singleImplementerClass = cg->comp()->getPersistentInfo()->getPersistentCHTable()->findSingleConcreteSubClass(castClass, cg->comp());
1436
if (cg->comp()->getOption(TR_TraceCG))
1437
{
1438
if (singleImplementerClass)
1439
{
1440
J9UTF8 *singleImplementerClassName = J9ROMCLASS_CLASSNAME(TR::Compiler->cls.romClassOf((TR_OpaqueClassBlock *) singleImplementerClass));
1441
traceMsg(cg->comp(), "%s: Single implementer for interface/abstract class: [" POINTER_PRINTF_FORMAT "] %.*s\n",
1442
instanceOfOrCheckCastNode->getOpCode().getName(), singleImplementerClass, J9UTF8_LENGTH(singleImplementerClassName), J9UTF8_DATA(singleImplementerClassName));
1443
}
1444
}
1445
}
1446
*compileTimeGuessClass = singleImplementerClass;
1447
}
1448
1449
if (TR::Compiler->cls.isClassArray(cg->comp(), castClass))
1450
{
1451
if (TR::Compiler->cls.isReferenceArray(cg->comp(), castClass))
1452
{
1453
TR_OpaqueClassBlock *componentClass = fej9->getComponentClassFromArrayClass(castClass);
1454
TR_OpaqueClassBlock *leafClass = fej9->getLeafComponentClassFromArrayClass(castClass);
1455
1456
// Cast class is a single dim array of java/lang/Object, all we need to do is check if the object is an array of non-primitives.
1457
//
1458
if (cg->comp()->getObjectClassPointer() == componentClass && componentClass == leafClass)
1459
{
1460
sequences[i++] = ArrayOfJavaLangObjectTest;
1461
sequences[i++] = GoToFalse;
1462
}
1463
// Cast class is a single dim array of a final class, all we need to do is check if the object is of this type, anything else is false.
1464
//
1465
else if (fej9->isClassFinal(componentClass) && componentClass == leafClass)
1466
{
1467
sequences[i++] = ClassEqualityTest;
1468
sequences[i++] = GoToFalse;
1469
}
1470
// Cast class is an array of some non-final class or multiple dimensions.
1471
//
1472
else
1473
{
1474
if (numProfiledClasses > 0)
1475
{
1476
if (!*topClassWasCastClass)
1477
{
1478
sequences[i++] = ProfiledClassTest;
1479
sequences[i++] = CastClassCacheTest;
1480
}
1481
else
1482
{
1483
sequences[i++] = ClassEqualityTest;
1484
sequences[i++] = ProfiledClassTest;
1485
sequences[i++] = CastClassCacheTest;
1486
}
1487
}
1488
else
1489
{
1490
sequences[i++] = ClassEqualityTest;
1491
sequences[i++] = CastClassCacheTest;
1492
}
1493
1494
sequences[i++] = HelperCall;
1495
}
1496
}
1497
// Cast class is an array of some primitive, all we need to do is check if the object is of this type, anything else is false.
1498
//
1499
else
1500
{
1501
sequences[i++] = ClassEqualityTest;
1502
sequences[i++] = GoToFalse;
1503
}
1504
}
1505
// Cast class is an interface, we can skip the class equality test.
1506
//
1507
else if (TR::Compiler->cls.isInterfaceClass(cg->comp(), castClass))
1508
{
1509
if (singleImplementerClass)
1510
{
1511
sequences[i++] = CompileTimeGuessClassTest;
1512
}
1513
else if (numProfiledClasses > 0)
1514
{
1515
sequences[i++] = ProfiledClassTest;
1516
sequences[i++] = CastClassCacheTest;
1517
}
1518
else
1519
{
1520
sequences[i++] = CastClassCacheTest;
1521
}
1522
if (createDynamicCacheTests)
1523
sequences[i++] = DynamicCacheObjectClassTest;
1524
sequences[i++] = HelperCall;
1525
}
1526
// Cast class is an abstract class, we can skip the class equality test, a superclass test is enough.
1527
//
1528
else if (fej9->isAbstractClass(castClass))
1529
{
1530
// Don't bother with the cast class cache, it's not updated by the VM when the cast can be determined via a superclass test.
1531
//
1532
if (singleImplementerClass)
1533
sequences[i++] = CompileTimeGuessClassTest;
1534
else if (numProfiledClasses > 0)
1535
sequences[i++] = ProfiledClassTest;
1536
1537
sequences[i++] = SuperClassTest;
1538
sequences[i++] = GoToFalse;
1539
}
1540
// Cast class is a final class, all we need to do is check if the object is of this type, anything else is false.
1541
//
1542
else if (fej9->isClassFinal(castClass))
1543
{
1544
sequences[i++] = ClassEqualityTest;
1545
sequences[i++] = GoToFalse;
1546
}
1547
// Arbitrary concrete class.
1548
//
1549
else
1550
{
1551
// Don't bother with the cast class cache, it's not updated by the VM when the cast can be determined via a superclass test.
1552
//
1553
if (numProfiledClasses > 0)
1554
{
1555
if (!*topClassWasCastClass)
1556
{
1557
sequences[i++] = ProfiledClassTest;
1558
sequences[i++] = ClassEqualityTest;
1559
}
1560
else
1561
{
1562
sequences[i++] = ClassEqualityTest;
1563
sequences[i++] = ProfiledClassTest;
1564
}
1565
}
1566
else
1567
{
1568
sequences[i++] = ClassEqualityTest;
1569
}
1570
1571
sequences[i++] = SuperClassTest;
1572
sequences[i++] = GoToFalse;
1573
}
1574
}
1575
}
1576
1577
// Insert LoadObjectClass and/or EvaluateCastClass where required.
1578
//
1579
bool objectClassLoaded = false;
1580
bool castClassEvaluated = false;
1581
1582
for (uint32_t j = 0; j < i; ++j)
1583
{
1584
InstanceOfOrCheckCastSequences s = sequences[j];
1585
if (s == EvaluateCastClass)
1586
{
1587
castClassEvaluated = true;
1588
}
1589
else if (s == LoadObjectClass)
1590
{
1591
objectClassLoaded = true;
1592
}
1593
else
1594
{
1595
if (s == ProfiledClassTest ||
1596
s == CompileTimeGuessClassTest ||
1597
s == ArrayOfJavaLangObjectTest ||
1598
s == ClassEqualityTest ||
1599
s == SuperClassTest ||
1600
s == CastClassCacheTest)
1601
{
1602
if (!objectClassLoaded)
1603
{
1604
memmove(&sequences[j + 1], &sequences[j], (i - j) * sizeof(InstanceOfOrCheckCastSequences));
1605
sequences[j] = LoadObjectClass;
1606
i += 1;
1607
objectClassLoaded = true;
1608
}
1609
}
1610
// Even though the helper call also needs the cast class, we expect to generate the helper call out of line
1611
// and can load it there. Here we just want to know whether the cast class is needed in the main line sequence.
1612
//
1613
if (s == ClassEqualityTest ||
1614
s == SuperClassTest ||
1615
s == CastClassCacheTest)
1616
{
1617
if (!castClassEvaluated)
1618
{
1619
// Ideally we would insert EvaluateCastClass at sequences[j], however
1620
// if the cast class needs to be evaluated it needs to be done before carrying out any tests
1621
// in order to prevent evaluation inside internal control flow. Therefore,
1622
// we insert it at the front of the list rather than at 'j'.
1623
const uint32_t insertAt = 0;
1624
memmove(&sequences[insertAt + 1], &sequences[insertAt], (i - insertAt) * sizeof(InstanceOfOrCheckCastSequences));
1625
sequences[insertAt] = EvaluateCastClass;
1626
i += 1;
1627
castClassEvaluated = true;
1628
}
1629
}
1630
}
1631
}
1632
1633
TR_ASSERT(sequences[i - 1] == HelperCall ||
1634
sequences[i - 1] == GoToTrue ||
1635
sequences[i - 1] == GoToFalse,
1636
"Expecting last sequence to be a terminal sequence (that provides a definitive answer)");
1637
1638
return i;
1639
}
1640
1641
/*
1642
* if recordAll is true, record all result in classArray, skip MinProfiledCheckcastFrequency check
1643
* if probability is not null, record class' corresponding probability in this array. Used for cost/benefit analysis for profiled check.
1644
*/
1645
uint8_t
1646
J9::TreeEvaluator::interpreterProfilingInstanceOfOrCheckCastInfo(
1647
TR::CodeGenerator * cg,
1648
TR::Node * node,
1649
TR_OpaqueClassBlock **classArray,
1650
float* probability,
1651
bool recordAll)
1652
{
1653
TR_ByteCodeInfo bcInfo = node->getByteCodeInfo();
1654
TR::Compilation *comp = cg->comp();
1655
TR_ValueProfileInfoManager * valueProfileInfo = TR_ValueProfileInfoManager::get(comp);
1656
static const char *p = feGetEnv("TR_TracePIC");
1657
bool p1 = p && comp->getOption(TR_TraceCG); // allow per method tracing
1658
1659
if (!valueProfileInfo)
1660
return 0;
1661
1662
TR_AddressInfo * valueInfo = static_cast<TR_AddressInfo*>(valueProfileInfo->getValueInfo(bcInfo, comp, AddressInfo, TR_ValueProfileInfoManager::justInterpreterProfileInfo));
1663
if (!valueInfo || valueInfo->getNumProfiledValues()==0)
1664
{
1665
if (p1) traceMsg(comp, "==TPIC==No IProfiler info on node %p in %s\n", node, comp->signature());
1666
return 0;
1667
}
1668
1669
TR_OpaqueClassBlock *topValue = (TR_OpaqueClassBlock *) valueInfo->getTopValue();
1670
if (!topValue)
1671
{
1672
if (p1) traceMsg(comp, "==TPIC==No topvalue on node %p in %s\n", node, comp->signature());
1673
return 0;
1674
}
1675
1676
if ((recordAll == false) && valueInfo->getTopProbability() < TR::Options::getMinProfiledCheckcastFrequency())
1677
{
1678
if (p1) traceMsg(comp, "==TPIC==low top probability on node %p in %s\n", node, comp->signature());
1679
return 0;
1680
}
1681
1682
if (comp->getPersistentInfo()->isObsoleteClass(topValue, cg->fe()))
1683
{
1684
if (p1) traceMsg(comp, "==TPIC==%p unloaded on node %p in %s\n", topValue, node, comp->signature());
1685
return 0;
1686
}
1687
1688
uintptr_t totalFrequency = valueInfo->getTotalFrequency();
1689
TR_ScratchList<TR_ExtraAddressInfo> valuesSortedByFrequency(comp->trMemory());
1690
valueInfo->getSortedList(comp, &valuesSortedByFrequency);
1691
1692
ListIterator<TR_ExtraAddressInfo> sortedValuesIt(&valuesSortedByFrequency);
1693
TR_ExtraAddressInfo *profiledInfo;
1694
uint8_t number = 0;
1695
for (profiledInfo = sortedValuesIt.getFirst(); profiledInfo != NULL; profiledInfo = sortedValuesIt.getNext())
1696
{
1697
TR_OpaqueClassBlock * classPointer = (TR_OpaqueClassBlock *)(profiledInfo->_value);
1698
if (!classPointer)
1699
continue;
1700
1701
if (comp->getPersistentInfo()->isObsoleteClass((void *)classPointer, cg->fe()))
1702
{
1703
return 0;
1704
}
1705
1706
TR_OpaqueClassBlock *thisType = cg->fej9()->getProfiledClassFromProfiledInfo(profiledInfo);
1707
if (!thisType)
1708
continue;
1709
if (p1)
1710
{
1711
char *name;
1712
int32_t len;
1713
name = comp->fej9()->getClassNameChars(thisType, len);
1714
traceMsg(comp, "==TPIC==Freq %d (%.2f%%) %.*s @ %p\n", profiledInfo->_frequency, (float) profiledInfo->_frequency/totalFrequency, len, name, thisType); fflush(stdout);
1715
}
1716
if ((recordAll == false) && ((float) profiledInfo->_frequency/totalFrequency) < TR::Options::getMinProfiledCheckcastFrequency())
1717
continue;
1718
1719
classArray[number] = thisType;
1720
if (probability)
1721
{
1722
probability[number] = ((float)profiledInfo->_frequency)/totalFrequency;
1723
}
1724
number++;
1725
}
1726
return number;
1727
}
1728
1729
1730
TR_OpaqueClassBlock *
1731
J9::TreeEvaluator::interpreterProfilingInstanceOfOrCheckCastInfo(TR::CodeGenerator * cg, TR::Node * node)
1732
{
1733
TR::Compilation *comp= cg->comp();
1734
TR_ByteCodeInfo bcInfo = node->getByteCodeInfo();
1735
TR_ValueProfileInfoManager * valueProfileInfo = TR_ValueProfileInfoManager::get(comp);
1736
1737
if (!valueProfileInfo)
1738
return NULL;
1739
1740
TR_AddressInfo * valueInfo = static_cast<TR_AddressInfo*>(valueProfileInfo->getValueInfo(bcInfo, comp, AddressInfo, TR_ValueProfileInfoManager::justInterpreterProfileInfo));
1741
if (!valueInfo || valueInfo->getNumProfiledValues()==0)
1742
{
1743
return NULL;
1744
}
1745
1746
TR_OpaqueClassBlock *topValue = (TR_OpaqueClassBlock *) valueInfo->getTopValue();
1747
if (!topValue)
1748
{
1749
return NULL;
1750
}
1751
1752
if (valueInfo->getTopProbability() < TR::Options::getMinProfiledCheckcastFrequency())
1753
return NULL;
1754
1755
if (comp->getPersistentInfo()->isObsoleteClass(topValue, cg->fe()))
1756
{
1757
return NULL;
1758
}
1759
1760
return topValue;
1761
}
1762
1763
1764
bool
1765
J9::TreeEvaluator::checkcastShouldOutlineSuperClassTest(TR::Node *node, TR::CodeGenerator *cg)
1766
{
1767
// caller should always first call instanceOfOrCheckCastNeedSuperTest
1768
TR::Node *castClassNode = node->getSecondChild();
1769
TR::MethodSymbol *helperSym = node->getSymbol()->castToMethodSymbol();
1770
TR::SymbolReference *castClassSymRef = castClassNode->getSymbolReference();
1771
TR_ByteCodeInfo bcInfo = node->getByteCodeInfo();
1772
TR::Compilation *comp= cg->comp();
1773
1774
TR_ValueProfileInfoManager * valueProfileInfo = TR_ValueProfileInfoManager::get(comp);
1775
1776
if (castClassSymRef->isUnresolved())
1777
{
1778
return false;
1779
}
1780
1781
if (!TR::TreeEvaluator::isStaticClassSymRef(castClassSymRef))
1782
{
1783
// We could theoretically do a super test on something with no sym, but it would require significant
1784
// changes to platform code. The benefit is little at this point (shows up from reference arraycopy reductions)
1785
return false;
1786
}
1787
1788
TR::StaticSymbol *castClassSym = castClassSymRef->getSymbol()->getStaticSymbol();
1789
1790
if (!valueProfileInfo)
1791
return false;
1792
1793
TR_AddressInfo * valueInfo = static_cast<TR_AddressInfo*>(valueProfileInfo->getValueInfo(bcInfo, comp, AddressInfo, TR_ValueProfileInfoManager::justInterpreterProfileInfo));
1794
1795
if (!valueInfo || valueInfo->getNumProfiledValues()==0)
1796
{
1797
return false;
1798
}
1799
1800
TR_OpaqueClassBlock *topValue = (TR_OpaqueClassBlock *) valueInfo->getTopValue();
1801
1802
if (!topValue)
1803
{
1804
return false;
1805
}
1806
1807
if (valueInfo->getTopProbability() < TR::Options::getMinProfiledCheckcastFrequency())
1808
return false;
1809
1810
if (comp->getPersistentInfo()->isObsoleteClass(topValue, cg->fe()))
1811
{
1812
return false;
1813
}
1814
1815
if (topValue == (TR_OpaqueClassBlock *) castClassSym->getStaticAddress())
1816
{
1817
return true;
1818
}
1819
1820
return false;
1821
}
1822
1823
1824
bool
1825
J9::TreeEvaluator::loadLookaheadAfterHeaderAccess(TR::Node *node, int32_t &fieldOffset, TR::CodeGenerator *cg)
1826
{
1827
TR::Node *object = node->getFirstChild();
1828
1829
TR::TreeTop *currTree = cg->getCurrentEvaluationTreeTop()->getNextTreeTop();
1830
while (currTree)
1831
{
1832
TR::Node *currNode = currTree->getNode();
1833
if (currNode->getOpCodeValue() == TR::aloadi || currNode->getOpCodeValue() == TR::iloadi)
1834
{
1835
if (currNode->getFirstChild() == object)
1836
{
1837
int displacement = 0;
1838
TR::Symbol *sym = currNode->getSymbolReference()->getSymbol();
1839
if (sym)
1840
{
1841
if (sym->isRegisterMappedSymbol() &&
1842
sym->getRegisterMappedSymbol()->getOffset() != 0)
1843
{
1844
displacement = sym->getRegisterMappedSymbol()->getOffset();
1845
}
1846
}
1847
1848
1849
fieldOffset = displacement + currNode->getSymbolReference()->getOffset();
1850
return true;
1851
}
1852
}
1853
else if (currNode->getNumChildren() > 0 &&
1854
currNode->getFirstChild()->getNumChildren() > 0 &&
1855
(currNode->getFirstChild()->getOpCodeValue() == TR::aloadi || currNode->getFirstChild()->getOpCodeValue() == TR::iloadi))
1856
{
1857
if (currNode->getFirstChild()->getFirstChild() == object)
1858
{
1859
int displacement = 0;
1860
TR::Symbol *sym = currNode->getFirstChild()->getSymbolReference()->getSymbol();
1861
if (sym)
1862
{
1863
if (sym->isRegisterMappedSymbol() &&
1864
sym->getRegisterMappedSymbol()->getOffset() != 0)
1865
{
1866
displacement = sym->getRegisterMappedSymbol()->getOffset();
1867
}
1868
}
1869
1870
fieldOffset = displacement + currNode->getFirstChild()->getSymbolReference()->getOffset();
1871
return true;
1872
}
1873
}
1874
currTree = currTree->getNextTreeTop();
1875
}
1876
1877
return false;
1878
}
1879
1880
1881
// only need a helper call if the class is not super and not final, otherwise
1882
// it can be determined without a call-out
1883
bool J9::TreeEvaluator::instanceOfNeedHelperCall(bool testCastClassIsSuper, bool isFinalClass)
1884
{
1885
return !testCastClassIsSuper && !isFinalClass;
1886
}
1887
1888
1889
bool J9::TreeEvaluator::instanceOfOrCheckCastIsJavaLangObjectArray(TR::Node * node, TR::CodeGenerator *cg)
1890
{
1891
TR::Node *castClassNode = node->getSecondChild();
1892
TR::SymbolReference *castClassSymRef = castClassNode->getSymbolReference();
1893
1894
if (!TR::TreeEvaluator::isStaticClassSymRef(castClassSymRef))
1895
{
1896
return false;
1897
}
1898
1899
TR::StaticSymbol *castClassSym = castClassSymRef->getSymbol()->getStaticSymbol();
1900
1901
if (castClassSymRef->isUnresolved())
1902
{
1903
return false;
1904
}
1905
else
1906
{
1907
TR_OpaqueClassBlock * clazz;
1908
if (castClassSym &&
1909
(clazz = (TR_OpaqueClassBlock *) castClassSym->getStaticAddress()) &&
1910
TR::Compiler->cls.isClassArray(cg->comp(), clazz))
1911
{
1912
TR_OpaqueClassBlock *objectClass = cg->fej9()->getSystemClassFromClassName("java/lang/Object", 16);
1913
clazz = cg->fej9()->getComponentClassFromArrayClass(clazz);
1914
return (objectClass) && objectClass == clazz;
1915
}
1916
}
1917
return false;
1918
}
1919
1920
1921
TR_OpaqueClassBlock *
1922
J9::TreeEvaluator::getCastClassAddress(TR::Node * castClassNode)
1923
{
1924
TR::SymbolReference * symRef = castClassNode->getSymbolReference();
1925
if (!TR::TreeEvaluator::isStaticClassSymRef(symRef))
1926
{
1927
return NULL;
1928
}
1929
1930
TR::Symbol * symbol = symRef->getSymbol();
1931
1932
if (symRef->isUnresolved())
1933
{
1934
return NULL; // node is unresolved - class address not known yet
1935
}
1936
TR_OpaqueClassBlock * staticAddressValue = (TR_OpaqueClassBlock*) symbol->castToStaticSymbol()->getStaticAddress();
1937
return staticAddressValue;
1938
}
1939
1940
1941
/*
1942
* return true if instanceof/checkcast's checking class is final array
1943
*/
1944
bool
1945
J9::TreeEvaluator::instanceOfOrCheckCastIsFinalArray(TR::Node * node, TR::CodeGenerator *cg)
1946
{
1947
TR::Node *castClassNode = node->getSecondChild();
1948
TR::SymbolReference *castClassSymRef = castClassNode->getSymbolReference();
1949
1950
if (!TR::TreeEvaluator::isStaticClassSymRef(castClassSymRef))
1951
{
1952
return false;
1953
}
1954
1955
TR::StaticSymbol *castClassSym = castClassSymRef->getSymbol()->getStaticSymbol();
1956
1957
if (castClassSymRef->isUnresolved())
1958
{
1959
return false;
1960
}
1961
else
1962
{
1963
TR_OpaqueClassBlock * clazz;
1964
// If the class is a regular class (i.e., not an interface nor an array) and
1965
// not known to be a final class, an inline superclass test can be generated.
1966
// If the helper does not preserve all the registers there will not be
1967
// enough registers to do the superclass test inline.
1968
// Also, don't generate the superclass test if optimizing for space.
1969
//
1970
if (castClassSym &&
1971
(clazz = (TR_OpaqueClassBlock *) castClassSym->getStaticAddress()) &&
1972
TR::Compiler->cls.isClassArray(cg->comp(), clazz) &&
1973
(clazz = cg->fej9()->getLeafComponentClassFromArrayClass(clazz)) &&
1974
(cg->fej9()->isClassFinal(clazz) || TR::Compiler->cls.isPrimitiveClass(cg->comp(), clazz))
1975
)
1976
return true;
1977
}
1978
return false;
1979
}
1980
1981
1982
void
1983
J9::TreeEvaluator::evaluateLockForReservation(TR::Node *node, bool *reservingLock, bool *normalLockPreservingReservation, TR::CodeGenerator *cg)
1984
{
1985
static const char *allPreserving = feGetEnv("TR_AllLocksPreserving");
1986
TR::Compilation *comp= cg->comp();
1987
1988
if (!node->isSyncMethodMonitor())
1989
{
1990
*reservingLock = false;
1991
*normalLockPreservingReservation = false;
1992
return;
1993
}
1994
1995
if (comp->getOption(TR_ReserveAllLocks))
1996
{
1997
*reservingLock = true;
1998
*normalLockPreservingReservation = false;
1999
return;
2000
}
2001
2002
if (allPreserving)
2003
{
2004
*reservingLock = false;
2005
*normalLockPreservingReservation = true;
2006
return;
2007
}
2008
2009
TR_OpaqueMethodBlock *owningMethod = node->getOwningMethod();
2010
TR_OpaqueClassBlock *classPointer = cg->fej9()->getClassOfMethod(owningMethod);
2011
TR_PersistentClassInfo * persistentClassInfo =
2012
comp->getPersistentInfo()->getPersistentCHTable()->findClassInfoAfterLocking(classPointer, comp);
2013
2014
if (persistentClassInfo && persistentClassInfo->isReservable())
2015
{
2016
if (comp->getMethodHotness() >= warm)
2017
*reservingLock = true;
2018
else
2019
*normalLockPreservingReservation = true;
2020
}
2021
}
2022
2023
2024
2025
static TR::Node *scanForMonitorExitNode(TR::TreeTop *firstTree)
2026
{
2027
TR::TreeTop *currTree = firstTree;
2028
while (currTree)
2029
{
2030
TR::Node *currNode = currTree->getNode();
2031
if (currNode->getOpCodeValue() == TR::monexit)
2032
{
2033
if (currNode->isSyncMethodMonitor())
2034
return currNode;
2035
else
2036
return NULL;
2037
}
2038
else if (currNode->getNumChildren() > 0 &&
2039
currNode->getFirstChild()->getNumChildren() > 0 &&
2040
currNode->getFirstChild()->getOpCodeValue() == TR::monexit)
2041
{
2042
if (currNode->getFirstChild()->isSyncMethodMonitor())
2043
return currNode->getFirstChild();
2044
else
2045
return NULL;
2046
}
2047
2048
if ((currNode->getOpCodeValue() == TR::monent ||
2049
currNode->exceptionsRaised() != 0 ||
2050
currNode->canCauseGC() ||
2051
currNode->getOpCode().isBranch()))
2052
{
2053
return NULL;
2054
}
2055
2056
currTree = currTree->getNextTreeTop();
2057
}
2058
2059
return NULL;
2060
}
2061
2062
2063
bool
2064
J9::TreeEvaluator::isPrimitiveMonitor(TR::Node *monNode, TR::CodeGenerator *cg)
2065
{
2066
// TODO: enable primitive monitors once we have the standard ones working
2067
// The primitive monitors will need separate monexit helper where the
2068
// recursive count is incremented in case FLC is set. The state of RES and FLC set
2069
// while the count is 0 is illegal.
2070
static const char *allReservingPrimitive = feGetEnv("TR_AllLocksReservingPrimitive");
2071
static const char *noReservingPrimitiveLocks = feGetEnv("TR_NoReservingPrimitiveLocks");
2072
2073
if (allReservingPrimitive)
2074
return true;
2075
2076
if (noReservingPrimitiveLocks)
2077
return false;
2078
2079
TR::Node *object = monNode->getFirstChild();
2080
2081
TR_ASSERT(monNode->getOpCodeValue() == TR::monent, "Primitive monitor region check should only be done on monitor enter node");
2082
2083
TR::Node *guardExit = NULL;
2084
2085
TR::TreeTop *currTree = cg->getCurrentEvaluationTreeTop()->getNextTreeTop();
2086
while (currTree)
2087
{
2088
TR::Node *currNode = currTree->getNode();
2089
if (currNode->getOpCodeValue() == TR::monexit)
2090
{
2091
if (currNode->getFirstChild() == object)
2092
{
2093
monNode->setPrimitiveLockedRegion();
2094
currNode->setPrimitiveLockedRegion();
2095
2096
if (guardExit != NULL)
2097
{
2098
guardExit->setPrimitiveLockedRegion();
2099
}
2100
return true;
2101
}
2102
else
2103
return false;
2104
}
2105
else if (currNode->getNumChildren() > 0 &&
2106
currNode->getFirstChild()->getNumChildren() > 0 &&
2107
currNode->getFirstChild()->getOpCodeValue() == TR::monexit)
2108
{
2109
if (currNode->getFirstChild()->getFirstChild() == object)
2110
{
2111
monNode->setPrimitiveLockedRegion();
2112
currNode->getFirstChild()->setPrimitiveLockedRegion();
2113
2114
if (guardExit != NULL)
2115
{
2116
guardExit->setPrimitiveLockedRegion();
2117
}
2118
return true;
2119
}
2120
else
2121
return false;
2122
}
2123
2124
if ((currNode->getOpCodeValue() == TR::monent ||
2125
currNode->exceptionsRaised() != 0 ||
2126
currNode->canCauseGC() ||
2127
currNode->getOpCode().isBranch() ||
2128
(currNode->getOpCodeValue() == TR::BBStart && !currNode->getBlock()->isExtensionOfPreviousBlock())
2129
))
2130
{
2131
if ((currNode->getOpCode().isIf() && currNode->isNonoverriddenGuard()))
2132
{
2133
guardExit = scanForMonitorExitNode( currNode->getBranchDestination());
2134
2135
if (!guardExit && monNode->isSyncMethodMonitor())
2136
return false;
2137
}
2138
else
2139
return false;
2140
}
2141
2142
currTree = currTree->getNextTreeTop();
2143
}
2144
2145
return false;
2146
}
2147
2148
bool
2149
J9::TreeEvaluator::isDummyMonitorEnter(TR::Node *monNode, TR::CodeGenerator *cg)
2150
{
2151
TR::Node *object = monNode->getFirstChild();
2152
2153
TR_ASSERT(monNode->getOpCodeValue() == TR::monent, "Primitive monitor region check should only be done on monitor enter node");
2154
2155
TR::Node *guardExit = NULL;
2156
2157
TR::TreeTop *currTree = cg->getCurrentEvaluationTreeTop()->getNextTreeTop();
2158
TR::Node *currNode = currTree->getNode();
2159
2160
2161
if (currNode->getOpCode().isIf() && currNode->isNonoverriddenGuard() && monNode->isSyncMethodMonitor())
2162
{
2163
guardExit = scanForMonitorExitNode(currNode->getBranchDestination());
2164
2165
if (!guardExit)
2166
return false;
2167
2168
currTree = currTree->getNextTreeTop();
2169
}
2170
2171
if (currTree)
2172
{
2173
currNode = currTree->getNode();
2174
if (currNode->getOpCodeValue() == TR::monexit)
2175
{
2176
if (currNode->getFirstChild() == object)
2177
{
2178
return true;
2179
}
2180
else
2181
return false;
2182
}
2183
else if (currNode->getNumChildren() > 0 &&
2184
currNode->getFirstChild()->getNumChildren() > 0 &&
2185
currNode->getFirstChild()->getOpCodeValue() == TR::monexit)
2186
{
2187
if (currNode->getFirstChild()->getFirstChild() == object)
2188
{
2189
return true;
2190
}
2191
else
2192
return false;
2193
}
2194
}
2195
2196
return false;
2197
}
2198
2199
bool
2200
J9::TreeEvaluator::isDummyMonitorExit(TR::Node *monNode, TR::CodeGenerator *cg)
2201
{
2202
TR::Node *object = monNode->getFirstChild();
2203
2204
TR_ASSERT(monNode->getOpCodeValue() == TR::monexit, "Primitive monitor region check should only be done on monitor exit node");
2205
2206
TR::TreeTop *currTree = cg->getCurrentEvaluationTreeTop()->getPrevTreeTop();
2207
TR::Node *currNode = currTree->getNode();
2208
2209
if (currNode->getOpCode().isIf() && currNode->isNonoverriddenGuard() && monNode->isSyncMethodMonitor())
2210
{
2211
currTree = currTree->getPrevTreeTop();
2212
}
2213
2214
if (currTree)
2215
{
2216
currNode = currTree->getNode();
2217
if (currNode->getOpCodeValue() == TR::monent)
2218
{
2219
if (currNode->getFirstChild() == object)
2220
{
2221
return true;
2222
}
2223
else
2224
return false;
2225
}
2226
else if (currNode->getNumChildren() > 0 &&
2227
currNode->getFirstChild()->getNumChildren() > 0 &&
2228
currNode->getFirstChild()->getOpCodeValue() == TR::monent)
2229
{
2230
if (currNode->getFirstChild()->getFirstChild() == object)
2231
{
2232
return true;
2233
}
2234
else
2235
return false;
2236
}
2237
}
2238
2239
return false;
2240
}
2241
2242
2243
// Helper Functions for BNDCHKwithSpineCHK
2244
2245
// Evaluate all subtrees whose first reference is under the root node and whose
2246
// last reference is not.
2247
//
2248
// Evaluate every subtree S of a node N that meets the following criteria:
2249
//
2250
// (1) the first reference to S is in a subtree of N, and
2251
// (2) not all references to S appear under N
2252
//
2253
// All subtrees will be evaluated as soon as they are discovered.
2254
//
2255
//
2256
// TODO: do not pre-evaluate nodes under a spinechk if all other references are also under
2257
// a spinechk (there could be some complications here though).
2258
//
2259
void J9::TreeEvaluator::preEvaluateEscapingNodesForSpineCheck(TR::Node *root, TR::CodeGenerator *cg)
2260
{
2261
TR::TreeEvaluator::initializeStrictlyFutureUseCounts(root, cg->comp()->incVisitCount(), cg);
2262
TR::TreeEvaluator::evaluateNodesWithFutureUses(root, cg);
2263
}
2264
2265
2266
///////////////////////////////////////////////////////////////////////////////////////
2267
// resolveCHKEvaluator - Resolve check a static, field or method. child 1 is reference
2268
// to be resolved. Symbolref indicates failure action/destination
2269
///////////////////////////////////////////////////////////////////////////////////////
2270
TR::Register *J9::TreeEvaluator::resolveCHKEvaluator(TR::Node *node, TR::CodeGenerator *cg)
2271
{
2272
// No code is generated for the resolve check. The child will reference an
2273
// unresolved symbol and all check handling is done via the corresponding
2274
// snippet.
2275
//
2276
TR::Node *firstChild = node->getFirstChild();
2277
cg->evaluate(firstChild);
2278
cg->decReferenceCount(firstChild);
2279
return NULL;
2280
}
2281
2282
2283
bool
2284
J9::TreeEvaluator::requireHelperCallValueTypeAllocation(TR::Node *node, TR::CodeGenerator *cg)
2285
{
2286
if (TR::Compiler->om.areValueTypesEnabled() && node->getOpCodeValue() == TR::New)
2287
{
2288
TR::Compilation *comp = cg->comp();
2289
TR::SymbolReference *newValueSymRef = comp->getSymRefTab()->findOrCreateNewValueSymbolRef(comp->getMethodSymbol());
2290
TR::SymbolReference *nodeSymRef = node->getSymbolReference();
2291
TR::SymbolReference *classSymRef = node->getFirstChild()->getSymbolReference();
2292
2293
TR_OpaqueClassBlock *clazz = NULL;
2294
if (!classSymRef->isUnresolved())
2295
clazz = (TR_OpaqueClassBlock *)classSymRef->getSymbol()->getStaticSymbol()->getStaticAddress();
2296
2297
bool isValueTypeClass = clazz ? TR::Compiler->cls.isValueTypeClass(clazz) : false;
2298
2299
// If "new jitNewValue" is used to create a non value type, or if "new jitNewObject" is used to
2300
// create a value type, InstantiationError exception needs to be thrown. Use helper call in these cases.
2301
if (((nodeSymRef == newValueSymRef) && !isValueTypeClass)
2302
|| ((nodeSymRef != newValueSymRef) && isValueTypeClass))
2303
{
2304
return true;
2305
}
2306
}
2307
return false;
2308
}
2309
2310