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/oops/generateOopMap.cpp
32285 views
1
/*
2
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "interpreter/bytecodeStream.hpp"
27
#include "oops/generateOopMap.hpp"
28
#include "oops/oop.inline.hpp"
29
#include "oops/symbol.hpp"
30
#include "runtime/handles.inline.hpp"
31
#include "runtime/java.hpp"
32
#include "runtime/os.hpp"
33
#include "runtime/relocator.hpp"
34
#include "utilities/bitMap.inline.hpp"
35
#include "prims/methodHandles.hpp"
36
37
//
38
//
39
// Compute stack layouts for each instruction in method.
40
//
41
// Problems:
42
// - What to do about jsr with different types of local vars?
43
// Need maps that are conditional on jsr path?
44
// - Jsr and exceptions should be done more efficiently (the retAddr stuff)
45
//
46
// Alternative:
47
// - Could extend verifier to provide this information.
48
// For: one fewer abstract interpreter to maintain. Against: the verifier
49
// solves a bigger problem so slower (undesirable to force verification of
50
// everything?).
51
//
52
// Algorithm:
53
// Partition bytecodes into basic blocks
54
// For each basic block: store entry state (vars, stack). For instructions
55
// inside basic blocks we do not store any state (instead we recompute it
56
// from state produced by previous instruction).
57
//
58
// Perform abstract interpretation of bytecodes over this lattice:
59
//
60
// _--'#'--_
61
// / / \ \
62
// / / \ \
63
// / | | \
64
// 'r' 'v' 'p' ' '
65
// \ | | /
66
// \ \ / /
67
// \ \ / /
68
// -- '@' --
69
//
70
// '#' top, result of conflict merge
71
// 'r' reference type
72
// 'v' value type
73
// 'p' pc type for jsr/ret
74
// ' ' uninitialized; never occurs on operand stack in Java
75
// '@' bottom/unexecuted; initial state each bytecode.
76
//
77
// Basic block headers are the only merge points. We use this iteration to
78
// compute the information:
79
//
80
// find basic blocks;
81
// initialize them with uninitialized state;
82
// initialize first BB according to method signature;
83
// mark first BB changed
84
// while (some BB is changed) do {
85
// perform abstract interpration of all bytecodes in BB;
86
// merge exit state of BB into entry state of all successor BBs,
87
// noting if any of these change;
88
// }
89
//
90
// One additional complication is necessary. The jsr instruction pushes
91
// a return PC on the stack (a 'p' type in the abstract interpretation).
92
// To be able to process "ret" bytecodes, we keep track of these return
93
// PC's in a 'retAddrs' structure in abstract interpreter context (when
94
// processing a "ret" bytecodes, it is not sufficient to know that it gets
95
// an argument of the right type 'p'; we need to know which address it
96
// returns to).
97
//
98
// (Note this comment is borrowed form the original author of the algorithm)
99
100
// ComputeCallStack
101
//
102
// Specialization of SignatureIterator - compute the effects of a call
103
//
104
class ComputeCallStack : public SignatureIterator {
105
CellTypeState *_effect;
106
int _idx;
107
108
void setup();
109
void set(CellTypeState state) { _effect[_idx++] = state; }
110
int length() { return _idx; };
111
112
virtual void do_bool () { set(CellTypeState::value); };
113
virtual void do_char () { set(CellTypeState::value); };
114
virtual void do_float () { set(CellTypeState::value); };
115
virtual void do_byte () { set(CellTypeState::value); };
116
virtual void do_short () { set(CellTypeState::value); };
117
virtual void do_int () { set(CellTypeState::value); };
118
virtual void do_void () { set(CellTypeState::bottom);};
119
virtual void do_object(int begin, int end) { set(CellTypeState::ref); };
120
virtual void do_array (int begin, int end) { set(CellTypeState::ref); };
121
122
void do_double() { set(CellTypeState::value);
123
set(CellTypeState::value); }
124
void do_long () { set(CellTypeState::value);
125
set(CellTypeState::value); }
126
127
public:
128
ComputeCallStack(Symbol* signature) : SignatureIterator(signature) {};
129
130
// Compute methods
131
int compute_for_parameters(bool is_static, CellTypeState *effect) {
132
_idx = 0;
133
_effect = effect;
134
135
if (!is_static)
136
effect[_idx++] = CellTypeState::ref;
137
138
iterate_parameters();
139
140
return length();
141
};
142
143
int compute_for_returntype(CellTypeState *effect) {
144
_idx = 0;
145
_effect = effect;
146
iterate_returntype();
147
set(CellTypeState::bottom); // Always terminate with a bottom state, so ppush works
148
149
return length();
150
}
151
};
152
153
//=========================================================================================
154
// ComputeEntryStack
155
//
156
// Specialization of SignatureIterator - in order to set up first stack frame
157
//
158
class ComputeEntryStack : public SignatureIterator {
159
CellTypeState *_effect;
160
int _idx;
161
162
void setup();
163
void set(CellTypeState state) { _effect[_idx++] = state; }
164
int length() { return _idx; };
165
166
virtual void do_bool () { set(CellTypeState::value); };
167
virtual void do_char () { set(CellTypeState::value); };
168
virtual void do_float () { set(CellTypeState::value); };
169
virtual void do_byte () { set(CellTypeState::value); };
170
virtual void do_short () { set(CellTypeState::value); };
171
virtual void do_int () { set(CellTypeState::value); };
172
virtual void do_void () { set(CellTypeState::bottom);};
173
virtual void do_object(int begin, int end) { set(CellTypeState::make_slot_ref(_idx)); }
174
virtual void do_array (int begin, int end) { set(CellTypeState::make_slot_ref(_idx)); }
175
176
void do_double() { set(CellTypeState::value);
177
set(CellTypeState::value); }
178
void do_long () { set(CellTypeState::value);
179
set(CellTypeState::value); }
180
181
public:
182
ComputeEntryStack(Symbol* signature) : SignatureIterator(signature) {};
183
184
// Compute methods
185
int compute_for_parameters(bool is_static, CellTypeState *effect) {
186
_idx = 0;
187
_effect = effect;
188
189
if (!is_static)
190
effect[_idx++] = CellTypeState::make_slot_ref(0);
191
192
iterate_parameters();
193
194
return length();
195
};
196
197
int compute_for_returntype(CellTypeState *effect) {
198
_idx = 0;
199
_effect = effect;
200
iterate_returntype();
201
set(CellTypeState::bottom); // Always terminate with a bottom state, so ppush works
202
203
return length();
204
}
205
};
206
207
//=====================================================================================
208
//
209
// Implementation of RetTable/RetTableEntry
210
//
211
// Contains function to itereate through all bytecodes
212
// and find all return entry points
213
//
214
int RetTable::_init_nof_entries = 10;
215
int RetTableEntry::_init_nof_jsrs = 5;
216
217
void RetTableEntry::add_delta(int bci, int delta) {
218
if (_target_bci > bci) _target_bci += delta;
219
220
for (int k = 0; k < _jsrs->length(); k++) {
221
int jsr = _jsrs->at(k);
222
if (jsr > bci) _jsrs->at_put(k, jsr+delta);
223
}
224
}
225
226
void RetTable::compute_ret_table(methodHandle method) {
227
BytecodeStream i(method);
228
Bytecodes::Code bytecode;
229
230
while( (bytecode = i.next()) >= 0) {
231
switch (bytecode) {
232
case Bytecodes::_jsr:
233
add_jsr(i.next_bci(), i.dest());
234
break;
235
case Bytecodes::_jsr_w:
236
add_jsr(i.next_bci(), i.dest_w());
237
break;
238
}
239
}
240
}
241
242
void RetTable::add_jsr(int return_bci, int target_bci) {
243
RetTableEntry* entry = _first;
244
245
// Scan table for entry
246
for (;entry && entry->target_bci() != target_bci; entry = entry->next());
247
248
if (!entry) {
249
// Allocate new entry and put in list
250
entry = new RetTableEntry(target_bci, _first);
251
_first = entry;
252
}
253
254
// Now "entry" is set. Make sure that the entry is initialized
255
// and has room for the new jsr.
256
entry->add_jsr(return_bci);
257
}
258
259
RetTableEntry* RetTable::find_jsrs_for_target(int targBci) {
260
RetTableEntry *cur = _first;
261
262
while(cur) {
263
assert(cur->target_bci() != -1, "sanity check");
264
if (cur->target_bci() == targBci) return cur;
265
cur = cur->next();
266
}
267
ShouldNotReachHere();
268
return NULL;
269
}
270
271
// The instruction at bci is changing size by "delta". Update the return map.
272
void RetTable::update_ret_table(int bci, int delta) {
273
RetTableEntry *cur = _first;
274
while(cur) {
275
cur->add_delta(bci, delta);
276
cur = cur->next();
277
}
278
}
279
280
//
281
// Celltype state
282
//
283
284
CellTypeState CellTypeState::bottom = CellTypeState::make_bottom();
285
CellTypeState CellTypeState::uninit = CellTypeState::make_any(uninit_value);
286
CellTypeState CellTypeState::ref = CellTypeState::make_any(ref_conflict);
287
CellTypeState CellTypeState::value = CellTypeState::make_any(val_value);
288
CellTypeState CellTypeState::refUninit = CellTypeState::make_any(ref_conflict | uninit_value);
289
CellTypeState CellTypeState::top = CellTypeState::make_top();
290
CellTypeState CellTypeState::addr = CellTypeState::make_any(addr_conflict);
291
292
// Commonly used constants
293
static CellTypeState epsilonCTS[1] = { CellTypeState::bottom };
294
static CellTypeState refCTS = CellTypeState::ref;
295
static CellTypeState valCTS = CellTypeState::value;
296
static CellTypeState vCTS[2] = { CellTypeState::value, CellTypeState::bottom };
297
static CellTypeState rCTS[2] = { CellTypeState::ref, CellTypeState::bottom };
298
static CellTypeState rrCTS[3] = { CellTypeState::ref, CellTypeState::ref, CellTypeState::bottom };
299
static CellTypeState vrCTS[3] = { CellTypeState::value, CellTypeState::ref, CellTypeState::bottom };
300
static CellTypeState vvCTS[3] = { CellTypeState::value, CellTypeState::value, CellTypeState::bottom };
301
static CellTypeState rvrCTS[4] = { CellTypeState::ref, CellTypeState::value, CellTypeState::ref, CellTypeState::bottom };
302
static CellTypeState vvrCTS[4] = { CellTypeState::value, CellTypeState::value, CellTypeState::ref, CellTypeState::bottom };
303
static CellTypeState vvvCTS[4] = { CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::bottom };
304
static CellTypeState vvvrCTS[5] = { CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::ref, CellTypeState::bottom };
305
static CellTypeState vvvvCTS[5] = { CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::bottom };
306
307
char CellTypeState::to_char() const {
308
if (can_be_reference()) {
309
if (can_be_value() || can_be_address())
310
return '#'; // Conflict that needs to be rewritten
311
else
312
return 'r';
313
} else if (can_be_value())
314
return 'v';
315
else if (can_be_address())
316
return 'p';
317
else if (can_be_uninit())
318
return ' ';
319
else
320
return '@';
321
}
322
323
324
// Print a detailed CellTypeState. Indicate all bits that are set. If
325
// the CellTypeState represents an address or a reference, print the
326
// value of the additional information.
327
void CellTypeState::print(outputStream *os) {
328
if (can_be_address()) {
329
os->print("(p");
330
} else {
331
os->print("( ");
332
}
333
if (can_be_reference()) {
334
os->print("r");
335
} else {
336
os->print(" ");
337
}
338
if (can_be_value()) {
339
os->print("v");
340
} else {
341
os->print(" ");
342
}
343
if (can_be_uninit()) {
344
os->print("u|");
345
} else {
346
os->print(" |");
347
}
348
if (is_info_top()) {
349
os->print("Top)");
350
} else if (is_info_bottom()) {
351
os->print("Bot)");
352
} else {
353
if (is_reference()) {
354
int info = get_info();
355
int data = info & ~(ref_not_lock_bit | ref_slot_bit);
356
if (info & ref_not_lock_bit) {
357
// Not a monitor lock reference.
358
if (info & ref_slot_bit) {
359
// slot
360
os->print("slot%d)", data);
361
} else {
362
// line
363
os->print("line%d)", data);
364
}
365
} else {
366
// lock
367
os->print("lock%d)", data);
368
}
369
} else {
370
os->print("%d)", get_info());
371
}
372
}
373
}
374
375
//
376
// Basicblock handling methods
377
//
378
379
void GenerateOopMap ::initialize_bb() {
380
_gc_points = 0;
381
_bb_count = 0;
382
_bb_hdr_bits.clear();
383
_bb_hdr_bits.resize(method()->code_size());
384
}
385
386
void GenerateOopMap::bb_mark_fct(GenerateOopMap *c, int bci, int *data) {
387
assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");
388
if (c->is_bb_header(bci))
389
return;
390
391
if (TraceNewOopMapGeneration) {
392
tty->print_cr("Basicblock#%d begins at: %d", c->_bb_count, bci);
393
}
394
c->set_bbmark_bit(bci);
395
c->_bb_count++;
396
}
397
398
399
void GenerateOopMap::mark_bbheaders_and_count_gc_points() {
400
initialize_bb();
401
402
bool fellThrough = false; // False to get first BB marked.
403
404
// First mark all exception handlers as start of a basic-block
405
ExceptionTable excps(method());
406
for(int i = 0; i < excps.length(); i ++) {
407
bb_mark_fct(this, excps.handler_pc(i), NULL);
408
}
409
410
// Then iterate through the code
411
BytecodeStream bcs(_method);
412
Bytecodes::Code bytecode;
413
414
while( (bytecode = bcs.next()) >= 0) {
415
int bci = bcs.bci();
416
417
if (!fellThrough)
418
bb_mark_fct(this, bci, NULL);
419
420
fellThrough = jump_targets_do(&bcs, &GenerateOopMap::bb_mark_fct, NULL);
421
422
/* We will also mark successors of jsr's as basic block headers. */
423
switch (bytecode) {
424
case Bytecodes::_jsr:
425
assert(!fellThrough, "should not happen");
426
bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);
427
break;
428
case Bytecodes::_jsr_w:
429
assert(!fellThrough, "should not happen");
430
bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);
431
break;
432
}
433
434
if (possible_gc_point(&bcs))
435
_gc_points++;
436
}
437
}
438
439
void GenerateOopMap::reachable_basicblock(GenerateOopMap *c, int bci, int *data) {
440
assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");
441
BasicBlock* bb = c->get_basic_block_at(bci);
442
if (bb->is_dead()) {
443
bb->mark_as_alive();
444
*data = 1; // Mark basicblock as changed
445
}
446
}
447
448
449
void GenerateOopMap::mark_reachable_code() {
450
int change = 1; // int to get function pointers to work
451
452
// Mark entry basic block as alive and all exception handlers
453
_basic_blocks[0].mark_as_alive();
454
ExceptionTable excps(method());
455
for(int i = 0; i < excps.length(); i++) {
456
BasicBlock *bb = get_basic_block_at(excps.handler_pc(i));
457
// If block is not already alive (due to multiple exception handlers to same bb), then
458
// make it alive
459
if (bb->is_dead()) bb->mark_as_alive();
460
}
461
462
BytecodeStream bcs(_method);
463
464
// Iterate through all basic blocks until we reach a fixpoint
465
while (change) {
466
change = 0;
467
468
for (int i = 0; i < _bb_count; i++) {
469
BasicBlock *bb = &_basic_blocks[i];
470
if (bb->is_alive()) {
471
// Position bytecodestream at last bytecode in basicblock
472
bcs.set_start(bb->_end_bci);
473
bcs.next();
474
Bytecodes::Code bytecode = bcs.code();
475
int bci = bcs.bci();
476
assert(bci == bb->_end_bci, "wrong bci");
477
478
bool fell_through = jump_targets_do(&bcs, &GenerateOopMap::reachable_basicblock, &change);
479
480
// We will also mark successors of jsr's as alive.
481
switch (bytecode) {
482
case Bytecodes::_jsr:
483
case Bytecodes::_jsr_w:
484
assert(!fell_through, "should not happen");
485
reachable_basicblock(this, bci + Bytecodes::length_for(bytecode), &change);
486
break;
487
}
488
if (fell_through) {
489
// Mark successor as alive
490
if (bb[1].is_dead()) {
491
bb[1].mark_as_alive();
492
change = 1;
493
}
494
}
495
}
496
}
497
}
498
}
499
500
/* If the current instruction in "c" has no effect on control flow,
501
returns "true". Otherwise, calls "jmpFct" one or more times, with
502
"c", an appropriate "pcDelta", and "data" as arguments, then
503
returns "false". There is one exception: if the current
504
instruction is a "ret", returns "false" without calling "jmpFct".
505
Arrangements for tracking the control flow of a "ret" must be made
506
externally. */
507
bool GenerateOopMap::jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int *data) {
508
int bci = bcs->bci();
509
510
switch (bcs->code()) {
511
case Bytecodes::_ifeq:
512
case Bytecodes::_ifne:
513
case Bytecodes::_iflt:
514
case Bytecodes::_ifge:
515
case Bytecodes::_ifgt:
516
case Bytecodes::_ifle:
517
case Bytecodes::_if_icmpeq:
518
case Bytecodes::_if_icmpne:
519
case Bytecodes::_if_icmplt:
520
case Bytecodes::_if_icmpge:
521
case Bytecodes::_if_icmpgt:
522
case Bytecodes::_if_icmple:
523
case Bytecodes::_if_acmpeq:
524
case Bytecodes::_if_acmpne:
525
case Bytecodes::_ifnull:
526
case Bytecodes::_ifnonnull:
527
(*jmpFct)(this, bcs->dest(), data);
528
(*jmpFct)(this, bci + 3, data);
529
break;
530
531
case Bytecodes::_goto:
532
(*jmpFct)(this, bcs->dest(), data);
533
break;
534
case Bytecodes::_goto_w:
535
(*jmpFct)(this, bcs->dest_w(), data);
536
break;
537
case Bytecodes::_tableswitch:
538
{ Bytecode_tableswitch tableswitch(method(), bcs->bcp());
539
int len = tableswitch.length();
540
541
(*jmpFct)(this, bci + tableswitch.default_offset(), data); /* Default. jump address */
542
while (--len >= 0) {
543
(*jmpFct)(this, bci + tableswitch.dest_offset_at(len), data);
544
}
545
break;
546
}
547
548
case Bytecodes::_lookupswitch:
549
{ Bytecode_lookupswitch lookupswitch(method(), bcs->bcp());
550
int npairs = lookupswitch.number_of_pairs();
551
(*jmpFct)(this, bci + lookupswitch.default_offset(), data); /* Default. */
552
while(--npairs >= 0) {
553
LookupswitchPair pair = lookupswitch.pair_at(npairs);
554
(*jmpFct)(this, bci + pair.offset(), data);
555
}
556
break;
557
}
558
case Bytecodes::_jsr:
559
assert(bcs->is_wide()==false, "sanity check");
560
(*jmpFct)(this, bcs->dest(), data);
561
562
563
564
break;
565
case Bytecodes::_jsr_w:
566
(*jmpFct)(this, bcs->dest_w(), data);
567
break;
568
case Bytecodes::_wide:
569
ShouldNotReachHere();
570
return true;
571
break;
572
case Bytecodes::_athrow:
573
case Bytecodes::_ireturn:
574
case Bytecodes::_lreturn:
575
case Bytecodes::_freturn:
576
case Bytecodes::_dreturn:
577
case Bytecodes::_areturn:
578
case Bytecodes::_return:
579
case Bytecodes::_ret:
580
break;
581
default:
582
return true;
583
}
584
return false;
585
}
586
587
/* Requires "pc" to be the head of a basic block; returns that basic
588
block. */
589
BasicBlock *GenerateOopMap::get_basic_block_at(int bci) const {
590
BasicBlock* bb = get_basic_block_containing(bci);
591
assert(bb->_bci == bci, "should have found BB");
592
return bb;
593
}
594
595
// Requires "pc" to be the start of an instruction; returns the basic
596
// block containing that instruction. */
597
BasicBlock *GenerateOopMap::get_basic_block_containing(int bci) const {
598
BasicBlock *bbs = _basic_blocks;
599
int lo = 0, hi = _bb_count - 1;
600
601
while (lo <= hi) {
602
int m = (lo + hi) / 2;
603
int mbci = bbs[m]._bci;
604
int nbci;
605
606
if ( m == _bb_count-1) {
607
assert( bci >= mbci && bci < method()->code_size(), "sanity check failed");
608
return bbs+m;
609
} else {
610
nbci = bbs[m+1]._bci;
611
}
612
613
if ( mbci <= bci && bci < nbci) {
614
return bbs+m;
615
} else if (mbci < bci) {
616
lo = m + 1;
617
} else {
618
assert(mbci > bci, "sanity check");
619
hi = m - 1;
620
}
621
}
622
623
fatal("should have found BB");
624
return NULL;
625
}
626
627
void GenerateOopMap::restore_state(BasicBlock *bb)
628
{
629
memcpy(_state, bb->_state, _state_len*sizeof(CellTypeState));
630
_stack_top = bb->_stack_top;
631
_monitor_top = bb->_monitor_top;
632
}
633
634
int GenerateOopMap::next_bb_start_pc(BasicBlock *bb) {
635
int bbNum = bb - _basic_blocks + 1;
636
if (bbNum == _bb_count)
637
return method()->code_size();
638
639
return _basic_blocks[bbNum]._bci;
640
}
641
642
//
643
// CellType handling methods
644
//
645
646
// Allocate memory and throw LinkageError if failure.
647
#define ALLOC_RESOURCE_ARRAY(var, type, count) \
648
var = NEW_RESOURCE_ARRAY_RETURN_NULL(type, count); \
649
if (var == NULL) { \
650
report_error("Cannot reserve enough memory to analyze this method"); \
651
return; \
652
}
653
654
655
void GenerateOopMap::init_state() {
656
_state_len = _max_locals + _max_stack + _max_monitors;
657
ALLOC_RESOURCE_ARRAY(_state, CellTypeState, _state_len);
658
memset(_state, 0, _state_len * sizeof(CellTypeState));
659
int count = MAX3(_max_locals, _max_stack, _max_monitors) + 1/*for null terminator char */;
660
ALLOC_RESOURCE_ARRAY(_state_vec_buf, char, count);
661
}
662
663
void GenerateOopMap::make_context_uninitialized() {
664
CellTypeState* vs = vars();
665
666
for (int i = 0; i < _max_locals; i++)
667
vs[i] = CellTypeState::uninit;
668
669
_stack_top = 0;
670
_monitor_top = 0;
671
}
672
673
int GenerateOopMap::methodsig_to_effect(Symbol* signature, bool is_static, CellTypeState* effect) {
674
ComputeEntryStack ces(signature);
675
return ces.compute_for_parameters(is_static, effect);
676
}
677
678
// Return result of merging cts1 and cts2.
679
CellTypeState CellTypeState::merge(CellTypeState cts, int slot) const {
680
CellTypeState result;
681
682
assert(!is_bottom() && !cts.is_bottom(),
683
"merge of bottom values is handled elsewhere");
684
685
result._state = _state | cts._state;
686
687
// If the top bit is set, we don't need to do any more work.
688
if (!result.is_info_top()) {
689
assert((result.can_be_address() || result.can_be_reference()),
690
"only addresses and references have non-top info");
691
692
if (!equal(cts)) {
693
// The two values being merged are different. Raise to top.
694
if (result.is_reference()) {
695
result = CellTypeState::make_slot_ref(slot);
696
} else {
697
result._state |= info_conflict;
698
}
699
}
700
}
701
assert(result.is_valid_state(), "checking that CTS merge maintains legal state");
702
703
return result;
704
}
705
706
// Merge the variable state for locals and stack from cts into bbts.
707
bool GenerateOopMap::merge_local_state_vectors(CellTypeState* cts,
708
CellTypeState* bbts) {
709
int i;
710
int len = _max_locals + _stack_top;
711
bool change = false;
712
713
for (i = len - 1; i >= 0; i--) {
714
CellTypeState v = cts[i].merge(bbts[i], i);
715
change = change || !v.equal(bbts[i]);
716
bbts[i] = v;
717
}
718
719
return change;
720
}
721
722
// Merge the monitor stack state from cts into bbts.
723
bool GenerateOopMap::merge_monitor_state_vectors(CellTypeState* cts,
724
CellTypeState* bbts) {
725
bool change = false;
726
if (_max_monitors > 0 && _monitor_top != bad_monitors) {
727
// If there are no monitors in the program, or there has been
728
// a monitor matching error before this point in the program,
729
// then we do not merge in the monitor state.
730
731
int base = _max_locals + _max_stack;
732
int len = base + _monitor_top;
733
for (int i = len - 1; i >= base; i--) {
734
CellTypeState v = cts[i].merge(bbts[i], i);
735
736
// Can we prove that, when there has been a change, it will already
737
// have been detected at this point? That would make this equal
738
// check here unnecessary.
739
change = change || !v.equal(bbts[i]);
740
bbts[i] = v;
741
}
742
}
743
744
return change;
745
}
746
747
void GenerateOopMap::copy_state(CellTypeState *dst, CellTypeState *src) {
748
int len = _max_locals + _stack_top;
749
for (int i = 0; i < len; i++) {
750
if (src[i].is_nonlock_reference()) {
751
dst[i] = CellTypeState::make_slot_ref(i);
752
} else {
753
dst[i] = src[i];
754
}
755
}
756
if (_max_monitors > 0 && _monitor_top != bad_monitors) {
757
int base = _max_locals + _max_stack;
758
len = base + _monitor_top;
759
for (int i = base; i < len; i++) {
760
dst[i] = src[i];
761
}
762
}
763
}
764
765
766
// Merge the states for the current block and the next. As long as a
767
// block is reachable the locals and stack must be merged. If the
768
// stack heights don't match then this is a verification error and
769
// it's impossible to interpret the code. Simultaneously monitor
770
// states are being check to see if they nest statically. If monitor
771
// depths match up then their states are merged. Otherwise the
772
// mismatch is simply recorded and interpretation continues since
773
// monitor matching is purely informational and doesn't say anything
774
// about the correctness of the code.
775
void GenerateOopMap::merge_state_into_bb(BasicBlock *bb) {
776
guarantee(bb != NULL, "null basicblock");
777
assert(bb->is_alive(), "merging state into a dead basicblock");
778
779
if (_stack_top == bb->_stack_top) {
780
// always merge local state even if monitors don't match.
781
if (merge_local_state_vectors(_state, bb->_state)) {
782
bb->set_changed(true);
783
}
784
if (_monitor_top == bb->_monitor_top) {
785
// monitors still match so continue merging monitor states.
786
if (merge_monitor_state_vectors(_state, bb->_state)) {
787
bb->set_changed(true);
788
}
789
} else {
790
if (TraceMonitorMismatch) {
791
report_monitor_mismatch("monitor stack height merge conflict");
792
}
793
// When the monitor stacks are not matched, we set _monitor_top to
794
// bad_monitors. This signals that, from here on, the monitor stack cannot
795
// be trusted. In particular, monitorexit bytecodes may throw
796
// exceptions. We mark this block as changed so that the change
797
// propagates properly.
798
bb->_monitor_top = bad_monitors;
799
bb->set_changed(true);
800
_monitor_safe = false;
801
}
802
} else if (!bb->is_reachable()) {
803
// First time we look at this BB
804
copy_state(bb->_state, _state);
805
bb->_stack_top = _stack_top;
806
bb->_monitor_top = _monitor_top;
807
bb->set_changed(true);
808
} else {
809
verify_error("stack height conflict: %d vs. %d", _stack_top, bb->_stack_top);
810
}
811
}
812
813
void GenerateOopMap::merge_state(GenerateOopMap *gom, int bci, int* data) {
814
gom->merge_state_into_bb(gom->get_basic_block_at(bci));
815
}
816
817
void GenerateOopMap::set_var(int localNo, CellTypeState cts) {
818
assert(cts.is_reference() || cts.is_value() || cts.is_address(),
819
"wrong celltypestate");
820
if (localNo < 0 || localNo > _max_locals) {
821
verify_error("variable write error: r%d", localNo);
822
return;
823
}
824
vars()[localNo] = cts;
825
}
826
827
CellTypeState GenerateOopMap::get_var(int localNo) {
828
assert(localNo < _max_locals + _nof_refval_conflicts, "variable read error");
829
if (localNo < 0 || localNo > _max_locals) {
830
verify_error("variable read error: r%d", localNo);
831
return valCTS; // just to pick something;
832
}
833
return vars()[localNo];
834
}
835
836
CellTypeState GenerateOopMap::pop() {
837
if ( _stack_top <= 0) {
838
verify_error("stack underflow");
839
return valCTS; // just to pick something
840
}
841
return stack()[--_stack_top];
842
}
843
844
void GenerateOopMap::push(CellTypeState cts) {
845
if ( _stack_top >= _max_stack) {
846
verify_error("stack overflow");
847
return;
848
}
849
stack()[_stack_top++] = cts;
850
}
851
852
CellTypeState GenerateOopMap::monitor_pop() {
853
assert(_monitor_top != bad_monitors, "monitor_pop called on error monitor stack");
854
if (_monitor_top == 0) {
855
// We have detected a pop of an empty monitor stack.
856
_monitor_safe = false;
857
_monitor_top = bad_monitors;
858
859
if (TraceMonitorMismatch) {
860
report_monitor_mismatch("monitor stack underflow");
861
}
862
return CellTypeState::ref; // just to keep the analysis going.
863
}
864
return monitors()[--_monitor_top];
865
}
866
867
void GenerateOopMap::monitor_push(CellTypeState cts) {
868
assert(_monitor_top != bad_monitors, "monitor_push called on error monitor stack");
869
if (_monitor_top >= _max_monitors) {
870
// Some monitorenter is being executed more than once.
871
// This means that the monitor stack cannot be simulated.
872
_monitor_safe = false;
873
_monitor_top = bad_monitors;
874
875
if (TraceMonitorMismatch) {
876
report_monitor_mismatch("monitor stack overflow");
877
}
878
return;
879
}
880
monitors()[_monitor_top++] = cts;
881
}
882
883
//
884
// Interpretation handling methods
885
//
886
887
void GenerateOopMap::do_interpretation()
888
{
889
// "i" is just for debugging, so we can detect cases where this loop is
890
// iterated more than once.
891
int i = 0;
892
do {
893
#ifndef PRODUCT
894
if (TraceNewOopMapGeneration) {
895
tty->print("\n\nIteration #%d of do_interpretation loop, method:\n", i);
896
method()->print_name(tty);
897
tty->print("\n\n");
898
}
899
#endif
900
_conflict = false;
901
_monitor_safe = true;
902
// init_state is now called from init_basic_blocks. The length of a
903
// state vector cannot be determined until we have made a pass through
904
// the bytecodes counting the possible monitor entries.
905
if (!_got_error) init_basic_blocks();
906
if (!_got_error) setup_method_entry_state();
907
if (!_got_error) interp_all();
908
if (!_got_error) rewrite_refval_conflicts();
909
i++;
910
} while (_conflict && !_got_error);
911
}
912
913
void GenerateOopMap::init_basic_blocks() {
914
// Note: Could consider reserving only the needed space for each BB's state
915
// (entry stack may not be of maximal height for every basic block).
916
// But cumbersome since we don't know the stack heights yet. (Nor the
917
// monitor stack heights...)
918
919
ALLOC_RESOURCE_ARRAY(_basic_blocks, BasicBlock, _bb_count);
920
921
// Make a pass through the bytecodes. Count the number of monitorenters.
922
// This can be used an upper bound on the monitor stack depth in programs
923
// which obey stack discipline with their monitor usage. Initialize the
924
// known information about basic blocks.
925
BytecodeStream j(_method);
926
Bytecodes::Code bytecode;
927
928
int bbNo = 0;
929
int monitor_count = 0;
930
int prev_bci = -1;
931
while( (bytecode = j.next()) >= 0) {
932
if (j.code() == Bytecodes::_monitorenter) {
933
monitor_count++;
934
}
935
936
int bci = j.bci();
937
if (is_bb_header(bci)) {
938
// Initialize the basicblock structure
939
BasicBlock *bb = _basic_blocks + bbNo;
940
bb->_bci = bci;
941
bb->_max_locals = _max_locals;
942
bb->_max_stack = _max_stack;
943
bb->set_changed(false);
944
bb->_stack_top = BasicBlock::_dead_basic_block; // Initialize all basicblocks are dead.
945
bb->_monitor_top = bad_monitors;
946
947
if (bbNo > 0) {
948
_basic_blocks[bbNo - 1]._end_bci = prev_bci;
949
}
950
951
bbNo++;
952
}
953
// Remember prevous bci.
954
prev_bci = bci;
955
}
956
// Set
957
_basic_blocks[bbNo-1]._end_bci = prev_bci;
958
959
960
// Check that the correct number of basicblocks was found
961
if (bbNo !=_bb_count) {
962
if (bbNo < _bb_count) {
963
verify_error("jump into the middle of instruction?");
964
return;
965
} else {
966
verify_error("extra basic blocks - should not happen?");
967
return;
968
}
969
}
970
971
_max_monitors = monitor_count;
972
973
// Now that we have a bound on the depth of the monitor stack, we can
974
// initialize the CellTypeState-related information.
975
init_state();
976
977
// We allocate space for all state-vectors for all basicblocks in one huge
978
// chunk. Then in the next part of the code, we set a pointer in each
979
// _basic_block that points to each piece.
980
981
// The product of bbNo and _state_len can get large if there are lots of
982
// basic blocks and stack/locals/monitors. Need to check to make sure
983
// we don't overflow the capacity of a pointer.
984
if ((unsigned)bbNo > UINTPTR_MAX / sizeof(CellTypeState) / _state_len) {
985
report_error("The amount of memory required to analyze this method "
986
"exceeds addressable range");
987
return;
988
}
989
990
CellTypeState *basicBlockState;
991
ALLOC_RESOURCE_ARRAY(basicBlockState, CellTypeState, bbNo * _state_len);
992
memset(basicBlockState, 0, bbNo * _state_len * sizeof(CellTypeState));
993
994
// Make a pass over the basicblocks and assign their state vectors.
995
for (int blockNum=0; blockNum < bbNo; blockNum++) {
996
BasicBlock *bb = _basic_blocks + blockNum;
997
bb->_state = basicBlockState + blockNum * _state_len;
998
999
#ifdef ASSERT
1000
if (blockNum + 1 < bbNo) {
1001
address bcp = _method->bcp_from(bb->_end_bci);
1002
int bc_len = Bytecodes::java_length_at(_method(), bcp);
1003
assert(bb->_end_bci + bc_len == bb[1]._bci, "unmatched bci info in basicblock");
1004
}
1005
#endif
1006
}
1007
#ifdef ASSERT
1008
{ BasicBlock *bb = &_basic_blocks[bbNo-1];
1009
address bcp = _method->bcp_from(bb->_end_bci);
1010
int bc_len = Bytecodes::java_length_at(_method(), bcp);
1011
assert(bb->_end_bci + bc_len == _method->code_size(), "wrong end bci");
1012
}
1013
#endif
1014
1015
// Mark all alive blocks
1016
mark_reachable_code();
1017
}
1018
1019
void GenerateOopMap::setup_method_entry_state() {
1020
1021
// Initialize all locals to 'uninit' and set stack-height to 0
1022
make_context_uninitialized();
1023
1024
// Initialize CellState type of arguments
1025
methodsig_to_effect(method()->signature(), method()->is_static(), vars());
1026
1027
// If some references must be pre-assigned to null, then set that up
1028
initialize_vars();
1029
1030
// This is the start state
1031
merge_state_into_bb(&_basic_blocks[0]);
1032
1033
assert(_basic_blocks[0].changed(), "we are not getting off the ground");
1034
}
1035
1036
// The instruction at bci is changing size by "delta". Update the basic blocks.
1037
void GenerateOopMap::update_basic_blocks(int bci, int delta,
1038
int new_method_size) {
1039
assert(new_method_size >= method()->code_size() + delta,
1040
"new method size is too small");
1041
1042
BitMap::bm_word_t* new_bb_hdr_bits =
1043
NEW_RESOURCE_ARRAY(BitMap::bm_word_t,
1044
BitMap::word_align_up(new_method_size));
1045
_bb_hdr_bits.set_map(new_bb_hdr_bits);
1046
_bb_hdr_bits.set_size(new_method_size);
1047
_bb_hdr_bits.clear();
1048
1049
1050
for(int k = 0; k < _bb_count; k++) {
1051
if (_basic_blocks[k]._bci > bci) {
1052
_basic_blocks[k]._bci += delta;
1053
_basic_blocks[k]._end_bci += delta;
1054
}
1055
_bb_hdr_bits.at_put(_basic_blocks[k]._bci, true);
1056
}
1057
}
1058
1059
//
1060
// Initvars handling
1061
//
1062
1063
void GenerateOopMap::initialize_vars() {
1064
for (int k = 0; k < _init_vars->length(); k++)
1065
_state[_init_vars->at(k)] = CellTypeState::make_slot_ref(k);
1066
}
1067
1068
void GenerateOopMap::add_to_ref_init_set(int localNo) {
1069
1070
if (TraceNewOopMapGeneration)
1071
tty->print_cr("Added init vars: %d", localNo);
1072
1073
// Is it already in the set?
1074
if (_init_vars->contains(localNo) )
1075
return;
1076
1077
_init_vars->append(localNo);
1078
}
1079
1080
//
1081
// Interpreration code
1082
//
1083
1084
void GenerateOopMap::interp_all() {
1085
bool change = true;
1086
1087
while (change && !_got_error) {
1088
change = false;
1089
for (int i = 0; i < _bb_count && !_got_error; i++) {
1090
BasicBlock *bb = &_basic_blocks[i];
1091
if (bb->changed()) {
1092
if (_got_error) return;
1093
change = true;
1094
bb->set_changed(false);
1095
interp_bb(bb);
1096
}
1097
}
1098
}
1099
}
1100
1101
void GenerateOopMap::interp_bb(BasicBlock *bb) {
1102
1103
// We do not want to do anything in case the basic-block has not been initialized. This
1104
// will happen in the case where there is dead-code hang around in a method.
1105
assert(bb->is_reachable(), "should be reachable or deadcode exist");
1106
restore_state(bb);
1107
1108
BytecodeStream itr(_method);
1109
1110
// Set iterator interval to be the current basicblock
1111
int lim_bci = next_bb_start_pc(bb);
1112
itr.set_interval(bb->_bci, lim_bci);
1113
assert(lim_bci != bb->_bci, "must be at least one instruction in a basicblock");
1114
itr.next(); // read first instruction
1115
1116
// Iterates through all bytecodes except the last in a basic block.
1117
// We handle the last one special, since there is controlflow change.
1118
while(itr.next_bci() < lim_bci && !_got_error) {
1119
if (_has_exceptions || _monitor_top != 0) {
1120
// We do not need to interpret the results of exceptional
1121
// continuation from this instruction when the method has no
1122
// exception handlers and the monitor stack is currently
1123
// empty.
1124
do_exception_edge(&itr);
1125
}
1126
interp1(&itr);
1127
itr.next();
1128
}
1129
1130
// Handle last instruction.
1131
if (!_got_error) {
1132
assert(itr.next_bci() == lim_bci, "must point to end");
1133
if (_has_exceptions || _monitor_top != 0) {
1134
do_exception_edge(&itr);
1135
}
1136
interp1(&itr);
1137
1138
bool fall_through = jump_targets_do(&itr, GenerateOopMap::merge_state, NULL);
1139
if (_got_error) return;
1140
1141
if (itr.code() == Bytecodes::_ret) {
1142
assert(!fall_through, "cannot be set if ret instruction");
1143
// Automatically handles 'wide' ret indicies
1144
ret_jump_targets_do(&itr, GenerateOopMap::merge_state, itr.get_index(), NULL);
1145
} else if (fall_through) {
1146
// Hit end of BB, but the instr. was a fall-through instruction,
1147
// so perform transition as if the BB ended in a "jump".
1148
if (lim_bci != bb[1]._bci) {
1149
verify_error("bytecodes fell through last instruction");
1150
return;
1151
}
1152
merge_state_into_bb(bb + 1);
1153
}
1154
}
1155
}
1156
1157
void GenerateOopMap::do_exception_edge(BytecodeStream* itr) {
1158
// Only check exception edge, if bytecode can trap
1159
if (!Bytecodes::can_trap(itr->code())) return;
1160
switch (itr->code()) {
1161
case Bytecodes::_aload_0:
1162
// These bytecodes can trap for rewriting. We need to assume that
1163
// they do not throw exceptions to make the monitor analysis work.
1164
return;
1165
1166
case Bytecodes::_ireturn:
1167
case Bytecodes::_lreturn:
1168
case Bytecodes::_freturn:
1169
case Bytecodes::_dreturn:
1170
case Bytecodes::_areturn:
1171
case Bytecodes::_return:
1172
// If the monitor stack height is not zero when we leave the method,
1173
// then we are either exiting with a non-empty stack or we have
1174
// found monitor trouble earlier in our analysis. In either case,
1175
// assume an exception could be taken here.
1176
if (_monitor_top == 0) {
1177
return;
1178
}
1179
break;
1180
1181
case Bytecodes::_monitorexit:
1182
// If the monitor stack height is bad_monitors, then we have detected a
1183
// monitor matching problem earlier in the analysis. If the
1184
// monitor stack height is 0, we are about to pop a monitor
1185
// off of an empty stack. In either case, the bytecode
1186
// could throw an exception.
1187
if (_monitor_top != bad_monitors && _monitor_top != 0) {
1188
return;
1189
}
1190
break;
1191
}
1192
1193
if (_has_exceptions) {
1194
int bci = itr->bci();
1195
ExceptionTable exct(method());
1196
for(int i = 0; i< exct.length(); i++) {
1197
int start_pc = exct.start_pc(i);
1198
int end_pc = exct.end_pc(i);
1199
int handler_pc = exct.handler_pc(i);
1200
int catch_type = exct.catch_type_index(i);
1201
1202
if (start_pc <= bci && bci < end_pc) {
1203
BasicBlock *excBB = get_basic_block_at(handler_pc);
1204
guarantee(excBB != NULL, "no basic block for exception");
1205
CellTypeState *excStk = excBB->stack();
1206
CellTypeState *cOpStck = stack();
1207
CellTypeState cOpStck_0 = cOpStck[0];
1208
int cOpStackTop = _stack_top;
1209
1210
// Exception stacks are always the same.
1211
assert(method()->max_stack() > 0, "sanity check");
1212
1213
// We remembered the size and first element of "cOpStck"
1214
// above; now we temporarily set them to the appropriate
1215
// values for an exception handler. */
1216
cOpStck[0] = CellTypeState::make_slot_ref(_max_locals);
1217
_stack_top = 1;
1218
1219
merge_state_into_bb(excBB);
1220
1221
// Now undo the temporary change.
1222
cOpStck[0] = cOpStck_0;
1223
_stack_top = cOpStackTop;
1224
1225
// If this is a "catch all" handler, then we do not need to
1226
// consider any additional handlers.
1227
if (catch_type == 0) {
1228
return;
1229
}
1230
}
1231
}
1232
}
1233
1234
// It is possible that none of the exception handlers would have caught
1235
// the exception. In this case, we will exit the method. We must
1236
// ensure that the monitor stack is empty in this case.
1237
if (_monitor_top == 0) {
1238
return;
1239
}
1240
1241
// We pessimistically assume that this exception can escape the
1242
// method. (It is possible that it will always be caught, but
1243
// we don't care to analyse the types of the catch clauses.)
1244
1245
// We don't set _monitor_top to bad_monitors because there are no successors
1246
// to this exceptional exit.
1247
1248
if (TraceMonitorMismatch && _monitor_safe) {
1249
// We check _monitor_safe so that we only report the first mismatched
1250
// exceptional exit.
1251
report_monitor_mismatch("non-empty monitor stack at exceptional exit");
1252
}
1253
_monitor_safe = false;
1254
1255
}
1256
1257
void GenerateOopMap::report_monitor_mismatch(const char *msg) {
1258
#ifndef PRODUCT
1259
tty->print(" Monitor mismatch in method ");
1260
method()->print_short_name(tty);
1261
tty->print_cr(": %s", msg);
1262
#endif
1263
}
1264
1265
void GenerateOopMap::print_states(outputStream *os,
1266
CellTypeState* vec, int num) {
1267
for (int i = 0; i < num; i++) {
1268
vec[i].print(tty);
1269
}
1270
}
1271
1272
// Print the state values at the current bytecode.
1273
void GenerateOopMap::print_current_state(outputStream *os,
1274
BytecodeStream *currentBC,
1275
bool detailed) {
1276
1277
if (detailed) {
1278
os->print(" %4d vars = ", currentBC->bci());
1279
print_states(os, vars(), _max_locals);
1280
os->print(" %s", Bytecodes::name(currentBC->code()));
1281
switch(currentBC->code()) {
1282
case Bytecodes::_invokevirtual:
1283
case Bytecodes::_invokespecial:
1284
case Bytecodes::_invokestatic:
1285
case Bytecodes::_invokedynamic:
1286
case Bytecodes::_invokeinterface:
1287
int idx = currentBC->has_index_u4() ? currentBC->get_index_u4() : currentBC->get_index_u2_cpcache();
1288
ConstantPool* cp = method()->constants();
1289
int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx);
1290
int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx);
1291
Symbol* signature = cp->symbol_at(signatureIdx);
1292
os->print("%s", signature->as_C_string());
1293
}
1294
os->cr();
1295
os->print(" stack = ");
1296
print_states(os, stack(), _stack_top);
1297
os->cr();
1298
if (_monitor_top != bad_monitors) {
1299
os->print(" monitors = ");
1300
print_states(os, monitors(), _monitor_top);
1301
} else {
1302
os->print(" [bad monitor stack]");
1303
}
1304
os->cr();
1305
} else {
1306
os->print(" %4d vars = '%s' ", currentBC->bci(), state_vec_to_string(vars(), _max_locals));
1307
os->print(" stack = '%s' ", state_vec_to_string(stack(), _stack_top));
1308
if (_monitor_top != bad_monitors) {
1309
os->print(" monitors = '%s' \t%s", state_vec_to_string(monitors(), _monitor_top), Bytecodes::name(currentBC->code()));
1310
} else {
1311
os->print(" [bad monitor stack]");
1312
}
1313
switch(currentBC->code()) {
1314
case Bytecodes::_invokevirtual:
1315
case Bytecodes::_invokespecial:
1316
case Bytecodes::_invokestatic:
1317
case Bytecodes::_invokedynamic:
1318
case Bytecodes::_invokeinterface:
1319
int idx = currentBC->has_index_u4() ? currentBC->get_index_u4() : currentBC->get_index_u2_cpcache();
1320
ConstantPool* cp = method()->constants();
1321
int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx);
1322
int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx);
1323
Symbol* signature = cp->symbol_at(signatureIdx);
1324
os->print("%s", signature->as_C_string());
1325
}
1326
os->cr();
1327
}
1328
}
1329
1330
// Sets the current state to be the state after executing the
1331
// current instruction, starting in the current state.
1332
void GenerateOopMap::interp1(BytecodeStream *itr) {
1333
if (TraceNewOopMapGeneration) {
1334
print_current_state(tty, itr, TraceNewOopMapGenerationDetailed);
1335
}
1336
1337
// Should we report the results? Result is reported *before* the instruction at the current bci is executed.
1338
// However, not for calls. For calls we do not want to include the arguments, so we postpone the reporting until
1339
// they have been popped (in method ppl).
1340
if (_report_result == true) {
1341
switch(itr->code()) {
1342
case Bytecodes::_invokevirtual:
1343
case Bytecodes::_invokespecial:
1344
case Bytecodes::_invokestatic:
1345
case Bytecodes::_invokedynamic:
1346
case Bytecodes::_invokeinterface:
1347
_itr_send = itr;
1348
_report_result_for_send = true;
1349
break;
1350
default:
1351
fill_stackmap_for_opcodes(itr, vars(), stack(), _stack_top);
1352
break;
1353
}
1354
}
1355
1356
// abstract interpretation of current opcode
1357
switch(itr->code()) {
1358
case Bytecodes::_nop: break;
1359
case Bytecodes::_goto: break;
1360
case Bytecodes::_goto_w: break;
1361
case Bytecodes::_iinc: break;
1362
case Bytecodes::_return: do_return_monitor_check();
1363
break;
1364
1365
case Bytecodes::_aconst_null:
1366
case Bytecodes::_new: ppush1(CellTypeState::make_line_ref(itr->bci()));
1367
break;
1368
1369
case Bytecodes::_iconst_m1:
1370
case Bytecodes::_iconst_0:
1371
case Bytecodes::_iconst_1:
1372
case Bytecodes::_iconst_2:
1373
case Bytecodes::_iconst_3:
1374
case Bytecodes::_iconst_4:
1375
case Bytecodes::_iconst_5:
1376
case Bytecodes::_fconst_0:
1377
case Bytecodes::_fconst_1:
1378
case Bytecodes::_fconst_2:
1379
case Bytecodes::_bipush:
1380
case Bytecodes::_sipush: ppush1(valCTS); break;
1381
1382
case Bytecodes::_lconst_0:
1383
case Bytecodes::_lconst_1:
1384
case Bytecodes::_dconst_0:
1385
case Bytecodes::_dconst_1: ppush(vvCTS); break;
1386
1387
case Bytecodes::_ldc2_w: ppush(vvCTS); break;
1388
1389
case Bytecodes::_ldc: // fall through:
1390
case Bytecodes::_ldc_w: do_ldc(itr->bci()); break;
1391
1392
case Bytecodes::_iload:
1393
case Bytecodes::_fload: ppload(vCTS, itr->get_index()); break;
1394
1395
case Bytecodes::_lload:
1396
case Bytecodes::_dload: ppload(vvCTS,itr->get_index()); break;
1397
1398
case Bytecodes::_aload: ppload(rCTS, itr->get_index()); break;
1399
1400
case Bytecodes::_iload_0:
1401
case Bytecodes::_fload_0: ppload(vCTS, 0); break;
1402
case Bytecodes::_iload_1:
1403
case Bytecodes::_fload_1: ppload(vCTS, 1); break;
1404
case Bytecodes::_iload_2:
1405
case Bytecodes::_fload_2: ppload(vCTS, 2); break;
1406
case Bytecodes::_iload_3:
1407
case Bytecodes::_fload_3: ppload(vCTS, 3); break;
1408
1409
case Bytecodes::_lload_0:
1410
case Bytecodes::_dload_0: ppload(vvCTS, 0); break;
1411
case Bytecodes::_lload_1:
1412
case Bytecodes::_dload_1: ppload(vvCTS, 1); break;
1413
case Bytecodes::_lload_2:
1414
case Bytecodes::_dload_2: ppload(vvCTS, 2); break;
1415
case Bytecodes::_lload_3:
1416
case Bytecodes::_dload_3: ppload(vvCTS, 3); break;
1417
1418
case Bytecodes::_aload_0: ppload(rCTS, 0); break;
1419
case Bytecodes::_aload_1: ppload(rCTS, 1); break;
1420
case Bytecodes::_aload_2: ppload(rCTS, 2); break;
1421
case Bytecodes::_aload_3: ppload(rCTS, 3); break;
1422
1423
case Bytecodes::_iaload:
1424
case Bytecodes::_faload:
1425
case Bytecodes::_baload:
1426
case Bytecodes::_caload:
1427
case Bytecodes::_saload: pp(vrCTS, vCTS); break;
1428
1429
case Bytecodes::_laload: pp(vrCTS, vvCTS); break;
1430
case Bytecodes::_daload: pp(vrCTS, vvCTS); break;
1431
1432
case Bytecodes::_aaload: pp_new_ref(vrCTS, itr->bci()); break;
1433
1434
case Bytecodes::_istore:
1435
case Bytecodes::_fstore: ppstore(vCTS, itr->get_index()); break;
1436
1437
case Bytecodes::_lstore:
1438
case Bytecodes::_dstore: ppstore(vvCTS, itr->get_index()); break;
1439
1440
case Bytecodes::_astore: do_astore(itr->get_index()); break;
1441
1442
case Bytecodes::_istore_0:
1443
case Bytecodes::_fstore_0: ppstore(vCTS, 0); break;
1444
case Bytecodes::_istore_1:
1445
case Bytecodes::_fstore_1: ppstore(vCTS, 1); break;
1446
case Bytecodes::_istore_2:
1447
case Bytecodes::_fstore_2: ppstore(vCTS, 2); break;
1448
case Bytecodes::_istore_3:
1449
case Bytecodes::_fstore_3: ppstore(vCTS, 3); break;
1450
1451
case Bytecodes::_lstore_0:
1452
case Bytecodes::_dstore_0: ppstore(vvCTS, 0); break;
1453
case Bytecodes::_lstore_1:
1454
case Bytecodes::_dstore_1: ppstore(vvCTS, 1); break;
1455
case Bytecodes::_lstore_2:
1456
case Bytecodes::_dstore_2: ppstore(vvCTS, 2); break;
1457
case Bytecodes::_lstore_3:
1458
case Bytecodes::_dstore_3: ppstore(vvCTS, 3); break;
1459
1460
case Bytecodes::_astore_0: do_astore(0); break;
1461
case Bytecodes::_astore_1: do_astore(1); break;
1462
case Bytecodes::_astore_2: do_astore(2); break;
1463
case Bytecodes::_astore_3: do_astore(3); break;
1464
1465
case Bytecodes::_iastore:
1466
case Bytecodes::_fastore:
1467
case Bytecodes::_bastore:
1468
case Bytecodes::_castore:
1469
case Bytecodes::_sastore: ppop(vvrCTS); break;
1470
case Bytecodes::_lastore:
1471
case Bytecodes::_dastore: ppop(vvvrCTS); break;
1472
case Bytecodes::_aastore: ppop(rvrCTS); break;
1473
1474
case Bytecodes::_pop: ppop_any(1); break;
1475
case Bytecodes::_pop2: ppop_any(2); break;
1476
1477
case Bytecodes::_dup: ppdupswap(1, "11"); break;
1478
case Bytecodes::_dup_x1: ppdupswap(2, "121"); break;
1479
case Bytecodes::_dup_x2: ppdupswap(3, "1321"); break;
1480
case Bytecodes::_dup2: ppdupswap(2, "2121"); break;
1481
case Bytecodes::_dup2_x1: ppdupswap(3, "21321"); break;
1482
case Bytecodes::_dup2_x2: ppdupswap(4, "214321"); break;
1483
case Bytecodes::_swap: ppdupswap(2, "12"); break;
1484
1485
case Bytecodes::_iadd:
1486
case Bytecodes::_fadd:
1487
case Bytecodes::_isub:
1488
case Bytecodes::_fsub:
1489
case Bytecodes::_imul:
1490
case Bytecodes::_fmul:
1491
case Bytecodes::_idiv:
1492
case Bytecodes::_fdiv:
1493
case Bytecodes::_irem:
1494
case Bytecodes::_frem:
1495
case Bytecodes::_ishl:
1496
case Bytecodes::_ishr:
1497
case Bytecodes::_iushr:
1498
case Bytecodes::_iand:
1499
case Bytecodes::_ior:
1500
case Bytecodes::_ixor:
1501
case Bytecodes::_l2f:
1502
case Bytecodes::_l2i:
1503
case Bytecodes::_d2f:
1504
case Bytecodes::_d2i:
1505
case Bytecodes::_fcmpl:
1506
case Bytecodes::_fcmpg: pp(vvCTS, vCTS); break;
1507
1508
case Bytecodes::_ladd:
1509
case Bytecodes::_dadd:
1510
case Bytecodes::_lsub:
1511
case Bytecodes::_dsub:
1512
case Bytecodes::_lmul:
1513
case Bytecodes::_dmul:
1514
case Bytecodes::_ldiv:
1515
case Bytecodes::_ddiv:
1516
case Bytecodes::_lrem:
1517
case Bytecodes::_drem:
1518
case Bytecodes::_land:
1519
case Bytecodes::_lor:
1520
case Bytecodes::_lxor: pp(vvvvCTS, vvCTS); break;
1521
1522
case Bytecodes::_ineg:
1523
case Bytecodes::_fneg:
1524
case Bytecodes::_i2f:
1525
case Bytecodes::_f2i:
1526
case Bytecodes::_i2c:
1527
case Bytecodes::_i2s:
1528
case Bytecodes::_i2b: pp(vCTS, vCTS); break;
1529
1530
case Bytecodes::_lneg:
1531
case Bytecodes::_dneg:
1532
case Bytecodes::_l2d:
1533
case Bytecodes::_d2l: pp(vvCTS, vvCTS); break;
1534
1535
case Bytecodes::_lshl:
1536
case Bytecodes::_lshr:
1537
case Bytecodes::_lushr: pp(vvvCTS, vvCTS); break;
1538
1539
case Bytecodes::_i2l:
1540
case Bytecodes::_i2d:
1541
case Bytecodes::_f2l:
1542
case Bytecodes::_f2d: pp(vCTS, vvCTS); break;
1543
1544
case Bytecodes::_lcmp: pp(vvvvCTS, vCTS); break;
1545
case Bytecodes::_dcmpl:
1546
case Bytecodes::_dcmpg: pp(vvvvCTS, vCTS); break;
1547
1548
case Bytecodes::_ifeq:
1549
case Bytecodes::_ifne:
1550
case Bytecodes::_iflt:
1551
case Bytecodes::_ifge:
1552
case Bytecodes::_ifgt:
1553
case Bytecodes::_ifle:
1554
case Bytecodes::_tableswitch: ppop1(valCTS);
1555
break;
1556
case Bytecodes::_ireturn:
1557
case Bytecodes::_freturn: do_return_monitor_check();
1558
ppop1(valCTS);
1559
break;
1560
case Bytecodes::_if_icmpeq:
1561
case Bytecodes::_if_icmpne:
1562
case Bytecodes::_if_icmplt:
1563
case Bytecodes::_if_icmpge:
1564
case Bytecodes::_if_icmpgt:
1565
case Bytecodes::_if_icmple: ppop(vvCTS);
1566
break;
1567
1568
case Bytecodes::_lreturn: do_return_monitor_check();
1569
ppop(vvCTS);
1570
break;
1571
1572
case Bytecodes::_dreturn: do_return_monitor_check();
1573
ppop(vvCTS);
1574
break;
1575
1576
case Bytecodes::_if_acmpeq:
1577
case Bytecodes::_if_acmpne: ppop(rrCTS); break;
1578
1579
case Bytecodes::_jsr: do_jsr(itr->dest()); break;
1580
case Bytecodes::_jsr_w: do_jsr(itr->dest_w()); break;
1581
1582
case Bytecodes::_getstatic: do_field(true, true, itr->get_index_u2_cpcache(), itr->bci()); break;
1583
case Bytecodes::_putstatic: do_field(false, true, itr->get_index_u2_cpcache(), itr->bci()); break;
1584
case Bytecodes::_getfield: do_field(true, false, itr->get_index_u2_cpcache(), itr->bci()); break;
1585
case Bytecodes::_putfield: do_field(false, false, itr->get_index_u2_cpcache(), itr->bci()); break;
1586
1587
case Bytecodes::_invokevirtual:
1588
case Bytecodes::_invokespecial: do_method(false, false, itr->get_index_u2_cpcache(), itr->bci()); break;
1589
case Bytecodes::_invokestatic: do_method(true, false, itr->get_index_u2_cpcache(), itr->bci()); break;
1590
case Bytecodes::_invokedynamic: do_method(true, false, itr->get_index_u4(), itr->bci()); break;
1591
case Bytecodes::_invokeinterface: do_method(false, true, itr->get_index_u2_cpcache(), itr->bci()); break;
1592
case Bytecodes::_newarray:
1593
case Bytecodes::_anewarray: pp_new_ref(vCTS, itr->bci()); break;
1594
case Bytecodes::_checkcast: do_checkcast(); break;
1595
case Bytecodes::_arraylength:
1596
case Bytecodes::_instanceof: pp(rCTS, vCTS); break;
1597
case Bytecodes::_monitorenter: do_monitorenter(itr->bci()); break;
1598
case Bytecodes::_monitorexit: do_monitorexit(itr->bci()); break;
1599
1600
case Bytecodes::_athrow: // handled by do_exception_edge() BUT ...
1601
// vlh(apple): do_exception_edge() does not get
1602
// called if method has no exception handlers
1603
if ((!_has_exceptions) && (_monitor_top > 0)) {
1604
_monitor_safe = false;
1605
}
1606
break;
1607
1608
case Bytecodes::_areturn: do_return_monitor_check();
1609
ppop1(refCTS);
1610
break;
1611
case Bytecodes::_ifnull:
1612
case Bytecodes::_ifnonnull: ppop1(refCTS); break;
1613
case Bytecodes::_multianewarray: do_multianewarray(*(itr->bcp()+3), itr->bci()); break;
1614
1615
case Bytecodes::_wide: fatal("Iterator should skip this bytecode"); break;
1616
case Bytecodes::_ret: break;
1617
1618
// Java opcodes
1619
case Bytecodes::_lookupswitch: ppop1(valCTS); break;
1620
1621
default:
1622
tty->print("unexpected opcode: %d\n", itr->code());
1623
ShouldNotReachHere();
1624
break;
1625
}
1626
}
1627
1628
void GenerateOopMap::check_type(CellTypeState expected, CellTypeState actual) {
1629
if (!expected.equal_kind(actual)) {
1630
verify_error("wrong type on stack (found: %c expected: %c)", actual.to_char(), expected.to_char());
1631
}
1632
}
1633
1634
void GenerateOopMap::ppstore(CellTypeState *in, int loc_no) {
1635
while(!(*in).is_bottom()) {
1636
CellTypeState expected =*in++;
1637
CellTypeState actual = pop();
1638
check_type(expected, actual);
1639
assert(loc_no >= 0, "sanity check");
1640
set_var(loc_no++, actual);
1641
}
1642
}
1643
1644
void GenerateOopMap::ppload(CellTypeState *out, int loc_no) {
1645
while(!(*out).is_bottom()) {
1646
CellTypeState out1 = *out++;
1647
CellTypeState vcts = get_var(loc_no);
1648
assert(out1.can_be_reference() || out1.can_be_value(),
1649
"can only load refs. and values.");
1650
if (out1.is_reference()) {
1651
assert(loc_no>=0, "sanity check");
1652
if (!vcts.is_reference()) {
1653
// We were asked to push a reference, but the type of the
1654
// variable can be something else
1655
_conflict = true;
1656
if (vcts.can_be_uninit()) {
1657
// It is a ref-uninit conflict (at least). If there are other
1658
// problems, we'll get them in the next round
1659
add_to_ref_init_set(loc_no);
1660
vcts = out1;
1661
} else {
1662
// It wasn't a ref-uninit conflict. So must be a
1663
// ref-val or ref-pc conflict. Split the variable.
1664
record_refval_conflict(loc_no);
1665
vcts = out1;
1666
}
1667
push(out1); // recover...
1668
} else {
1669
push(vcts); // preserve reference.
1670
}
1671
// Otherwise it is a conflict, but one that verification would
1672
// have caught if illegal. In particular, it can't be a topCTS
1673
// resulting from mergeing two difference pcCTS's since the verifier
1674
// would have rejected any use of such a merge.
1675
} else {
1676
push(out1); // handle val/init conflict
1677
}
1678
loc_no++;
1679
}
1680
}
1681
1682
void GenerateOopMap::ppdupswap(int poplen, const char *out) {
1683
CellTypeState actual[5];
1684
assert(poplen < 5, "this must be less than length of actual vector");
1685
1686
// pop all arguments
1687
for(int i = 0; i < poplen; i++) actual[i] = pop();
1688
1689
// put them back
1690
char push_ch = *out++;
1691
while (push_ch != '\0') {
1692
int idx = push_ch - '1';
1693
assert(idx >= 0 && idx < poplen, "wrong arguments");
1694
push(actual[idx]);
1695
push_ch = *out++;
1696
}
1697
}
1698
1699
void GenerateOopMap::ppop1(CellTypeState out) {
1700
CellTypeState actual = pop();
1701
check_type(out, actual);
1702
}
1703
1704
void GenerateOopMap::ppop(CellTypeState *out) {
1705
while (!(*out).is_bottom()) {
1706
ppop1(*out++);
1707
}
1708
}
1709
1710
void GenerateOopMap::ppush1(CellTypeState in) {
1711
assert(in.is_reference() | in.is_value(), "sanity check");
1712
push(in);
1713
}
1714
1715
void GenerateOopMap::ppush(CellTypeState *in) {
1716
while (!(*in).is_bottom()) {
1717
ppush1(*in++);
1718
}
1719
}
1720
1721
void GenerateOopMap::pp(CellTypeState *in, CellTypeState *out) {
1722
ppop(in);
1723
ppush(out);
1724
}
1725
1726
void GenerateOopMap::pp_new_ref(CellTypeState *in, int bci) {
1727
ppop(in);
1728
ppush1(CellTypeState::make_line_ref(bci));
1729
}
1730
1731
void GenerateOopMap::ppop_any(int poplen) {
1732
if (_stack_top >= poplen) {
1733
_stack_top -= poplen;
1734
} else {
1735
verify_error("stack underflow");
1736
}
1737
}
1738
1739
// Replace all occurences of the state 'match' with the state 'replace'
1740
// in our current state vector.
1741
void GenerateOopMap::replace_all_CTS_matches(CellTypeState match,
1742
CellTypeState replace) {
1743
int i;
1744
int len = _max_locals + _stack_top;
1745
bool change = false;
1746
1747
for (i = len - 1; i >= 0; i--) {
1748
if (match.equal(_state[i])) {
1749
_state[i] = replace;
1750
}
1751
}
1752
1753
if (_monitor_top > 0) {
1754
int base = _max_locals + _max_stack;
1755
len = base + _monitor_top;
1756
for (i = len - 1; i >= base; i--) {
1757
if (match.equal(_state[i])) {
1758
_state[i] = replace;
1759
}
1760
}
1761
}
1762
}
1763
1764
void GenerateOopMap::do_checkcast() {
1765
CellTypeState actual = pop();
1766
check_type(refCTS, actual);
1767
push(actual);
1768
}
1769
1770
void GenerateOopMap::do_monitorenter(int bci) {
1771
CellTypeState actual = pop();
1772
if (_monitor_top == bad_monitors) {
1773
return;
1774
}
1775
1776
// Bail out when we get repeated locks on an identical monitor. This case
1777
// isn't too hard to handle and can be made to work if supporting nested
1778
// redundant synchronized statements becomes a priority.
1779
//
1780
// See also "Note" in do_monitorexit(), below.
1781
if (actual.is_lock_reference()) {
1782
_monitor_top = bad_monitors;
1783
_monitor_safe = false;
1784
1785
if (TraceMonitorMismatch) {
1786
report_monitor_mismatch("nested redundant lock -- bailout...");
1787
}
1788
return;
1789
}
1790
1791
CellTypeState lock = CellTypeState::make_lock_ref(bci);
1792
check_type(refCTS, actual);
1793
if (!actual.is_info_top()) {
1794
replace_all_CTS_matches(actual, lock);
1795
monitor_push(lock);
1796
}
1797
}
1798
1799
void GenerateOopMap::do_monitorexit(int bci) {
1800
CellTypeState actual = pop();
1801
if (_monitor_top == bad_monitors) {
1802
return;
1803
}
1804
check_type(refCTS, actual);
1805
CellTypeState expected = monitor_pop();
1806
if (!actual.is_lock_reference() || !expected.equal(actual)) {
1807
// The monitor we are exiting is not verifiably the one
1808
// on the top of our monitor stack. This causes a monitor
1809
// mismatch.
1810
_monitor_top = bad_monitors;
1811
_monitor_safe = false;
1812
1813
// We need to mark this basic block as changed so that
1814
// this monitorexit will be visited again. We need to
1815
// do this to ensure that we have accounted for the
1816
// possibility that this bytecode will throw an
1817
// exception.
1818
BasicBlock* bb = get_basic_block_containing(bci);
1819
guarantee(bb != NULL, "no basic block for bci");
1820
bb->set_changed(true);
1821
bb->_monitor_top = bad_monitors;
1822
1823
if (TraceMonitorMismatch) {
1824
report_monitor_mismatch("improper monitor pair");
1825
}
1826
} else {
1827
// This code is a fix for the case where we have repeated
1828
// locking of the same object in straightline code. We clear
1829
// out the lock when it is popped from the monitor stack
1830
// and replace it with an unobtrusive reference value that can
1831
// be locked again.
1832
//
1833
// Note: when generateOopMap is fixed to properly handle repeated,
1834
// nested, redundant locks on the same object, then this
1835
// fix will need to be removed at that time.
1836
replace_all_CTS_matches(actual, CellTypeState::make_line_ref(bci));
1837
}
1838
}
1839
1840
void GenerateOopMap::do_return_monitor_check() {
1841
if (_monitor_top > 0) {
1842
// The monitor stack must be empty when we leave the method
1843
// for the monitors to be properly matched.
1844
_monitor_safe = false;
1845
1846
// Since there are no successors to the *return bytecode, it
1847
// isn't necessary to set _monitor_top to bad_monitors.
1848
1849
if (TraceMonitorMismatch) {
1850
report_monitor_mismatch("non-empty monitor stack at return");
1851
}
1852
}
1853
}
1854
1855
void GenerateOopMap::do_jsr(int targ_bci) {
1856
push(CellTypeState::make_addr(targ_bci));
1857
}
1858
1859
1860
1861
void GenerateOopMap::do_ldc(int bci) {
1862
Bytecode_loadconstant ldc(method(), bci);
1863
ConstantPool* cp = method()->constants();
1864
constantTag tag = cp->tag_at(ldc.pool_index()); // idx is index in resolved_references
1865
BasicType bt = ldc.result_type();
1866
CellTypeState cts;
1867
if (tag.basic_type() == T_OBJECT) {
1868
assert(!tag.is_string_index() && !tag.is_klass_index(), "Unexpected index tag");
1869
assert(bt == T_OBJECT, "Guard is incorrect");
1870
cts = CellTypeState::make_line_ref(bci);
1871
} else {
1872
assert(bt != T_OBJECT, "Guard is incorrect");
1873
cts = valCTS;
1874
}
1875
ppush1(cts);
1876
}
1877
1878
void GenerateOopMap::do_multianewarray(int dims, int bci) {
1879
assert(dims >= 1, "sanity check");
1880
for(int i = dims -1; i >=0; i--) {
1881
ppop1(valCTS);
1882
}
1883
ppush1(CellTypeState::make_line_ref(bci));
1884
}
1885
1886
void GenerateOopMap::do_astore(int idx) {
1887
CellTypeState r_or_p = pop();
1888
if (!r_or_p.is_address() && !r_or_p.is_reference()) {
1889
// We actually expected ref or pc, but we only report that we expected a ref. It does not
1890
// really matter (at least for now)
1891
verify_error("wrong type on stack (found: %c, expected: {pr})", r_or_p.to_char());
1892
return;
1893
}
1894
set_var(idx, r_or_p);
1895
}
1896
1897
// Copies bottom/zero terminated CTS string from "src" into "dst".
1898
// Does NOT terminate with a bottom. Returns the number of cells copied.
1899
int GenerateOopMap::copy_cts(CellTypeState *dst, CellTypeState *src) {
1900
int idx = 0;
1901
while (!src[idx].is_bottom()) {
1902
dst[idx] = src[idx];
1903
idx++;
1904
}
1905
return idx;
1906
}
1907
1908
void GenerateOopMap::do_field(int is_get, int is_static, int idx, int bci) {
1909
// Dig up signature for field in constant pool
1910
ConstantPool* cp = method()->constants();
1911
int nameAndTypeIdx = cp->name_and_type_ref_index_at(idx);
1912
int signatureIdx = cp->signature_ref_index_at(nameAndTypeIdx);
1913
Symbol* signature = cp->symbol_at(signatureIdx);
1914
1915
// Parse signature (espcially simple for fields)
1916
assert(signature->utf8_length() > 0, "field signatures cannot have zero length");
1917
// The signature is UFT8 encoded, but the first char is always ASCII for signatures.
1918
char sigch = (char)*(signature->base());
1919
CellTypeState temp[4];
1920
CellTypeState *eff = sigchar_to_effect(sigch, bci, temp);
1921
1922
CellTypeState in[4];
1923
CellTypeState *out;
1924
int i = 0;
1925
1926
if (is_get) {
1927
out = eff;
1928
} else {
1929
out = epsilonCTS;
1930
i = copy_cts(in, eff);
1931
}
1932
if (!is_static) in[i++] = CellTypeState::ref;
1933
in[i] = CellTypeState::bottom;
1934
assert(i<=3, "sanity check");
1935
pp(in, out);
1936
}
1937
1938
void GenerateOopMap::do_method(int is_static, int is_interface, int idx, int bci) {
1939
// Dig up signature for field in constant pool
1940
ConstantPool* cp = _method->constants();
1941
Symbol* signature = cp->signature_ref_at(idx);
1942
1943
// Parse method signature
1944
CellTypeState out[4];
1945
CellTypeState in[MAXARGSIZE+1]; // Includes result
1946
ComputeCallStack cse(signature);
1947
1948
// Compute return type
1949
int res_length= cse.compute_for_returntype(out);
1950
1951
// Temporary hack.
1952
if (out[0].equal(CellTypeState::ref) && out[1].equal(CellTypeState::bottom)) {
1953
out[0] = CellTypeState::make_line_ref(bci);
1954
}
1955
1956
assert(res_length<=4, "max value should be vv");
1957
1958
// Compute arguments
1959
int arg_length = cse.compute_for_parameters(is_static != 0, in);
1960
assert(arg_length<=MAXARGSIZE, "too many locals");
1961
1962
// Pop arguments
1963
for (int i = arg_length - 1; i >= 0; i--) ppop1(in[i]);// Do args in reverse order.
1964
1965
// Report results
1966
if (_report_result_for_send == true) {
1967
fill_stackmap_for_opcodes(_itr_send, vars(), stack(), _stack_top);
1968
_report_result_for_send = false;
1969
}
1970
1971
// Push return address
1972
ppush(out);
1973
}
1974
1975
// This is used to parse the signature for fields, since they are very simple...
1976
CellTypeState *GenerateOopMap::sigchar_to_effect(char sigch, int bci, CellTypeState *out) {
1977
// Object and array
1978
if (sigch=='L' || sigch=='[') {
1979
out[0] = CellTypeState::make_line_ref(bci);
1980
out[1] = CellTypeState::bottom;
1981
return out;
1982
}
1983
if (sigch == 'J' || sigch == 'D' ) return vvCTS; // Long and Double
1984
if (sigch == 'V' ) return epsilonCTS; // Void
1985
return vCTS; // Otherwise
1986
}
1987
1988
long GenerateOopMap::_total_byte_count = 0;
1989
elapsedTimer GenerateOopMap::_total_oopmap_time;
1990
1991
// This function assumes "bcs" is at a "ret" instruction and that the vars
1992
// state is valid for that instruction. Furthermore, the ret instruction
1993
// must be the last instruction in "bb" (we store information about the
1994
// "ret" in "bb").
1995
void GenerateOopMap::ret_jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int varNo, int *data) {
1996
CellTypeState ra = vars()[varNo];
1997
if (!ra.is_good_address()) {
1998
verify_error("ret returns from two jsr subroutines?");
1999
return;
2000
}
2001
int target = ra.get_info();
2002
2003
RetTableEntry* rtEnt = _rt.find_jsrs_for_target(target);
2004
int bci = bcs->bci();
2005
for (int i = 0; i < rtEnt->nof_jsrs(); i++) {
2006
int target_bci = rtEnt->jsrs(i);
2007
// Make sure a jrtRet does not set the changed bit for dead basicblock.
2008
BasicBlock* jsr_bb = get_basic_block_containing(target_bci - 1);
2009
debug_only(BasicBlock* target_bb = &jsr_bb[1];)
2010
assert(target_bb == get_basic_block_at(target_bci), "wrong calc. of successor basicblock");
2011
bool alive = jsr_bb->is_alive();
2012
if (TraceNewOopMapGeneration) {
2013
tty->print("pc = %d, ret -> %d alive: %s\n", bci, target_bci, alive ? "true" : "false");
2014
}
2015
if (alive) jmpFct(this, target_bci, data);
2016
}
2017
}
2018
2019
//
2020
// Debug method
2021
//
2022
char* GenerateOopMap::state_vec_to_string(CellTypeState* vec, int len) {
2023
#ifdef ASSERT
2024
int checklen = MAX3(_max_locals, _max_stack, _max_monitors) + 1;
2025
assert(len < checklen, "state_vec_buf overflow");
2026
#endif
2027
for (int i = 0; i < len; i++) _state_vec_buf[i] = vec[i].to_char();
2028
_state_vec_buf[len] = 0;
2029
return _state_vec_buf;
2030
}
2031
2032
void GenerateOopMap::print_time() {
2033
tty->print_cr ("Accumulated oopmap times:");
2034
tty->print_cr ("---------------------------");
2035
tty->print_cr (" Total : %3.3f sec.", GenerateOopMap::_total_oopmap_time.seconds());
2036
tty->print_cr (" (%3.0f bytecodes per sec) ",
2037
GenerateOopMap::_total_byte_count / GenerateOopMap::_total_oopmap_time.seconds());
2038
}
2039
2040
//
2041
// ============ Main Entry Point ===========
2042
//
2043
GenerateOopMap::GenerateOopMap(methodHandle method) {
2044
// We have to initialize all variables here, that can be queried directly
2045
_method = method;
2046
_max_locals=0;
2047
_init_vars = NULL;
2048
2049
#ifndef PRODUCT
2050
// If we are doing a detailed trace, include the regular trace information.
2051
if (TraceNewOopMapGenerationDetailed) {
2052
TraceNewOopMapGeneration = true;
2053
}
2054
#endif
2055
}
2056
2057
void GenerateOopMap::compute_map(TRAPS) {
2058
#ifndef PRODUCT
2059
if (TimeOopMap2) {
2060
method()->print_short_name(tty);
2061
tty->print(" ");
2062
}
2063
if (TimeOopMap) {
2064
_total_byte_count += method()->code_size();
2065
}
2066
#endif
2067
TraceTime t_single("oopmap time", TimeOopMap2);
2068
TraceTime t_all(NULL, &_total_oopmap_time, TimeOopMap);
2069
2070
// Initialize values
2071
_got_error = false;
2072
_conflict = false;
2073
_max_locals = method()->max_locals();
2074
_max_stack = method()->max_stack();
2075
_has_exceptions = (method()->has_exception_handler());
2076
_nof_refval_conflicts = 0;
2077
_init_vars = new GrowableArray<intptr_t>(5); // There are seldom more than 5 init_vars
2078
_report_result = false;
2079
_report_result_for_send = false;
2080
_new_var_map = NULL;
2081
_ret_adr_tos = new GrowableArray<intptr_t>(5); // 5 seems like a good number;
2082
_did_rewriting = false;
2083
_did_relocation = false;
2084
2085
if (TraceNewOopMapGeneration) {
2086
tty->print("Method name: %s\n", method()->name()->as_C_string());
2087
if (Verbose) {
2088
_method->print_codes();
2089
tty->print_cr("Exception table:");
2090
ExceptionTable excps(method());
2091
for(int i = 0; i < excps.length(); i ++) {
2092
tty->print_cr("[%d - %d] -> %d",
2093
excps.start_pc(i), excps.end_pc(i), excps.handler_pc(i));
2094
}
2095
}
2096
}
2097
2098
// if no code - do nothing
2099
// compiler needs info
2100
if (method()->code_size() == 0 || _max_locals + method()->max_stack() == 0) {
2101
fill_stackmap_prolog(0);
2102
fill_stackmap_epilog();
2103
return;
2104
}
2105
// Step 1: Compute all jump targets and their return value
2106
if (!_got_error)
2107
_rt.compute_ret_table(_method);
2108
2109
// Step 2: Find all basic blocks and count GC points
2110
if (!_got_error)
2111
mark_bbheaders_and_count_gc_points();
2112
2113
// Step 3: Calculate stack maps
2114
if (!_got_error)
2115
do_interpretation();
2116
2117
// Step 4:Return results
2118
if (!_got_error && report_results())
2119
report_result();
2120
2121
if (_got_error) {
2122
THROW_HANDLE(_exception);
2123
}
2124
}
2125
2126
// Error handling methods
2127
// These methods create an exception for the current thread which is thrown
2128
// at the bottom of the call stack, when it returns to compute_map(). The
2129
// _got_error flag controls execution. NOT TODO: The VM exception propagation
2130
// mechanism using TRAPS/CHECKs could be used here instead but it would need
2131
// to be added as a parameter to every function and checked for every call.
2132
// The tons of extra code it would generate didn't seem worth the change.
2133
//
2134
void GenerateOopMap::error_work(const char *format, va_list ap) {
2135
_got_error = true;
2136
char msg_buffer[512];
2137
os::vsnprintf(msg_buffer, sizeof(msg_buffer), format, ap);
2138
// Append method name
2139
char msg_buffer2[512];
2140
os::snprintf(msg_buffer2, sizeof(msg_buffer2), "%s in method %s", msg_buffer, method()->name()->as_C_string());
2141
_exception = Exceptions::new_exception(Thread::current(),
2142
vmSymbols::java_lang_LinkageError(), msg_buffer2);
2143
}
2144
2145
void GenerateOopMap::report_error(const char *format, ...) {
2146
va_list ap;
2147
va_start(ap, format);
2148
error_work(format, ap);
2149
}
2150
2151
void GenerateOopMap::verify_error(const char *format, ...) {
2152
// We do not distinguish between different types of errors for verification
2153
// errors. Let the verifier give a better message.
2154
const char *msg = "Illegal class file encountered. Try running with -Xverify:all";
2155
_got_error = true;
2156
// Append method name
2157
char msg_buffer2[512];
2158
os::snprintf(msg_buffer2, sizeof(msg_buffer2), "%s in method %s", msg,
2159
method()->name()->as_C_string());
2160
_exception = Exceptions::new_exception(Thread::current(),
2161
vmSymbols::java_lang_LinkageError(), msg_buffer2);
2162
}
2163
2164
//
2165
// Report result opcodes
2166
//
2167
void GenerateOopMap::report_result() {
2168
2169
if (TraceNewOopMapGeneration) tty->print_cr("Report result pass");
2170
2171
// We now want to report the result of the parse
2172
_report_result = true;
2173
2174
// Prolog code
2175
fill_stackmap_prolog(_gc_points);
2176
2177
// Mark everything changed, then do one interpretation pass.
2178
for (int i = 0; i<_bb_count; i++) {
2179
if (_basic_blocks[i].is_reachable()) {
2180
_basic_blocks[i].set_changed(true);
2181
interp_bb(&_basic_blocks[i]);
2182
}
2183
}
2184
2185
// Note: Since we are skipping dead-code when we are reporting results, then
2186
// the no. of encountered gc-points might be fewer than the previously number
2187
// we have counted. (dead-code is a pain - it should be removed before we get here)
2188
fill_stackmap_epilog();
2189
2190
// Report initvars
2191
fill_init_vars(_init_vars);
2192
2193
_report_result = false;
2194
}
2195
2196
void GenerateOopMap::result_for_basicblock(int bci) {
2197
if (TraceNewOopMapGeneration) tty->print_cr("Report result pass for basicblock");
2198
2199
// We now want to report the result of the parse
2200
_report_result = true;
2201
2202
// Find basicblock and report results
2203
BasicBlock* bb = get_basic_block_containing(bci);
2204
guarantee(bb != NULL, "no basic block for bci");
2205
assert(bb->is_reachable(), "getting result from unreachable basicblock");
2206
bb->set_changed(true);
2207
interp_bb(bb);
2208
}
2209
2210
//
2211
// Conflict handling code
2212
//
2213
2214
void GenerateOopMap::record_refval_conflict(int varNo) {
2215
assert(varNo>=0 && varNo< _max_locals, "index out of range");
2216
2217
if (TraceOopMapRewrites) {
2218
tty->print("### Conflict detected (local no: %d)\n", varNo);
2219
}
2220
2221
if (!_new_var_map) {
2222
_new_var_map = NEW_RESOURCE_ARRAY(int, _max_locals);
2223
for (int k = 0; k < _max_locals; k++) _new_var_map[k] = k;
2224
}
2225
2226
if ( _new_var_map[varNo] == varNo) {
2227
// Check if max. number of locals has been reached
2228
if (_max_locals + _nof_refval_conflicts >= MAX_LOCAL_VARS) {
2229
report_error("Rewriting exceeded local variable limit");
2230
return;
2231
}
2232
_new_var_map[varNo] = _max_locals + _nof_refval_conflicts;
2233
_nof_refval_conflicts++;
2234
}
2235
}
2236
2237
void GenerateOopMap::rewrite_refval_conflicts()
2238
{
2239
// We can get here two ways: Either a rewrite conflict was detected, or
2240
// an uninitialize reference was detected. In the second case, we do not
2241
// do any rewriting, we just want to recompute the reference set with the
2242
// new information
2243
2244
int nof_conflicts = 0; // Used for debugging only
2245
2246
if ( _nof_refval_conflicts == 0 )
2247
return;
2248
2249
// Check if rewrites are allowed in this parse.
2250
if (!allow_rewrites() && !IgnoreRewrites) {
2251
fatal("Rewriting method not allowed at this stage");
2252
}
2253
2254
2255
// This following flag is to tempoary supress rewrites. The locals that might conflict will
2256
// all be set to contain values. This is UNSAFE - however, until the rewriting has been completely
2257
// tested it is nice to have.
2258
if (IgnoreRewrites) {
2259
if (Verbose) {
2260
tty->print("rewrites suppressed for local no. ");
2261
for (int l = 0; l < _max_locals; l++) {
2262
if (_new_var_map[l] != l) {
2263
tty->print("%d ", l);
2264
vars()[l] = CellTypeState::value;
2265
}
2266
}
2267
tty->cr();
2268
}
2269
2270
// That was that...
2271
_new_var_map = NULL;
2272
_nof_refval_conflicts = 0;
2273
_conflict = false;
2274
2275
return;
2276
}
2277
2278
// Tracing flag
2279
_did_rewriting = true;
2280
2281
if (TraceOopMapRewrites) {
2282
tty->print_cr("ref/value conflict for method %s - bytecodes are getting rewritten", method()->name()->as_C_string());
2283
method()->print();
2284
method()->print_codes();
2285
}
2286
2287
assert(_new_var_map!=NULL, "nothing to rewrite");
2288
assert(_conflict==true, "We should not be here");
2289
2290
compute_ret_adr_at_TOS();
2291
if (!_got_error) {
2292
for (int k = 0; k < _max_locals && !_got_error; k++) {
2293
if (_new_var_map[k] != k) {
2294
if (TraceOopMapRewrites) {
2295
tty->print_cr("Rewriting: %d -> %d", k, _new_var_map[k]);
2296
}
2297
rewrite_refval_conflict(k, _new_var_map[k]);
2298
if (_got_error) return;
2299
nof_conflicts++;
2300
}
2301
}
2302
}
2303
2304
assert(nof_conflicts == _nof_refval_conflicts, "sanity check");
2305
2306
// Adjust the number of locals
2307
method()->set_max_locals(_max_locals+_nof_refval_conflicts);
2308
_max_locals += _nof_refval_conflicts;
2309
2310
// That was that...
2311
_new_var_map = NULL;
2312
_nof_refval_conflicts = 0;
2313
}
2314
2315
void GenerateOopMap::rewrite_refval_conflict(int from, int to) {
2316
bool startOver;
2317
do {
2318
// Make sure that the BytecodeStream is constructed in the loop, since
2319
// during rewriting a new method oop is going to be used, and the next time
2320
// around we want to use that.
2321
BytecodeStream bcs(_method);
2322
startOver = false;
2323
2324
while( !startOver && !_got_error &&
2325
// test bcs in case method changed and it became invalid
2326
bcs.next() >=0) {
2327
startOver = rewrite_refval_conflict_inst(&bcs, from, to);
2328
}
2329
} while (startOver && !_got_error);
2330
}
2331
2332
/* If the current instruction is one that uses local variable "from"
2333
in a ref way, change it to use "to". There's a subtle reason why we
2334
renumber the ref uses and not the non-ref uses: non-ref uses may be
2335
2 slots wide (double, long) which would necessitate keeping track of
2336
whether we should add one or two variables to the method. If the change
2337
affected the width of some instruction, returns "TRUE"; otherwise, returns "FALSE".
2338
Another reason for moving ref's value is for solving (addr, ref) conflicts, which
2339
both uses aload/astore methods.
2340
*/
2341
bool GenerateOopMap::rewrite_refval_conflict_inst(BytecodeStream *itr, int from, int to) {
2342
Bytecodes::Code bc = itr->code();
2343
int index;
2344
int bci = itr->bci();
2345
2346
if (is_aload(itr, &index) && index == from) {
2347
if (TraceOopMapRewrites) {
2348
tty->print_cr("Rewriting aload at bci: %d", bci);
2349
}
2350
return rewrite_load_or_store(itr, Bytecodes::_aload, Bytecodes::_aload_0, to);
2351
}
2352
2353
if (is_astore(itr, &index) && index == from) {
2354
if (!stack_top_holds_ret_addr(bci)) {
2355
if (TraceOopMapRewrites) {
2356
tty->print_cr("Rewriting astore at bci: %d", bci);
2357
}
2358
return rewrite_load_or_store(itr, Bytecodes::_astore, Bytecodes::_astore_0, to);
2359
} else {
2360
if (TraceOopMapRewrites) {
2361
tty->print_cr("Supress rewriting of astore at bci: %d", bci);
2362
}
2363
}
2364
}
2365
2366
return false;
2367
}
2368
2369
// The argument to this method is:
2370
// bc : Current bytecode
2371
// bcN : either _aload or _astore
2372
// bc0 : either _aload_0 or _astore_0
2373
bool GenerateOopMap::rewrite_load_or_store(BytecodeStream *bcs, Bytecodes::Code bcN, Bytecodes::Code bc0, unsigned int varNo) {
2374
assert(bcN == Bytecodes::_astore || bcN == Bytecodes::_aload, "wrong argument (bcN)");
2375
assert(bc0 == Bytecodes::_astore_0 || bc0 == Bytecodes::_aload_0, "wrong argument (bc0)");
2376
int ilen = Bytecodes::length_at(_method(), bcs->bcp());
2377
int newIlen;
2378
2379
if (ilen == 4) {
2380
// Original instruction was wide; keep it wide for simplicity
2381
newIlen = 4;
2382
} else if (varNo < 4)
2383
newIlen = 1;
2384
else if (varNo >= 256)
2385
newIlen = 4;
2386
else
2387
newIlen = 2;
2388
2389
// If we need to relocate in order to patch the byte, we
2390
// do the patching in a temp. buffer, that is passed to the reloc.
2391
// The patching of the bytecode stream is then done by the Relocator.
2392
// This is neccesary, since relocating the instruction at a certain bci, might
2393
// also relocate that instruction, e.g., if a _goto before it gets widen to a _goto_w.
2394
// Hence, we do not know which bci to patch after relocation.
2395
2396
assert(newIlen <= 4, "sanity check");
2397
u_char inst_buffer[4]; // Max. instruction size is 4.
2398
address bcp;
2399
2400
if (newIlen != ilen) {
2401
// Relocation needed do patching in temp. buffer
2402
bcp = (address)inst_buffer;
2403
} else {
2404
bcp = _method->bcp_from(bcs->bci());
2405
}
2406
2407
// Patch either directly in Method* or in temp. buffer
2408
if (newIlen == 1) {
2409
assert(varNo < 4, "varNo too large");
2410
*bcp = bc0 + varNo;
2411
} else if (newIlen == 2) {
2412
assert(varNo < 256, "2-byte index needed!");
2413
*(bcp + 0) = bcN;
2414
*(bcp + 1) = varNo;
2415
} else {
2416
assert(newIlen == 4, "Wrong instruction length");
2417
*(bcp + 0) = Bytecodes::_wide;
2418
*(bcp + 1) = bcN;
2419
Bytes::put_Java_u2(bcp+2, varNo);
2420
}
2421
2422
if (newIlen != ilen) {
2423
expand_current_instr(bcs->bci(), ilen, newIlen, inst_buffer);
2424
}
2425
2426
2427
return (newIlen != ilen);
2428
}
2429
2430
class RelocCallback : public RelocatorListener {
2431
private:
2432
GenerateOopMap* _gom;
2433
public:
2434
RelocCallback(GenerateOopMap* gom) { _gom = gom; };
2435
2436
// Callback method
2437
virtual void relocated(int bci, int delta, int new_code_length) {
2438
_gom->update_basic_blocks (bci, delta, new_code_length);
2439
_gom->update_ret_adr_at_TOS(bci, delta);
2440
_gom->_rt.update_ret_table (bci, delta);
2441
}
2442
};
2443
2444
// Returns true if expanding was succesful. Otherwise, reports an error and
2445
// returns false.
2446
void GenerateOopMap::expand_current_instr(int bci, int ilen, int newIlen, u_char inst_buffer[]) {
2447
Thread *THREAD = Thread::current(); // Could really have TRAPS argument.
2448
RelocCallback rcb(this);
2449
Relocator rc(_method, &rcb);
2450
methodHandle m= rc.insert_space_at(bci, newIlen, inst_buffer, THREAD);
2451
if (m.is_null() || HAS_PENDING_EXCEPTION) {
2452
report_error("could not rewrite method - exception occurred or bytecode buffer overflow");
2453
return;
2454
}
2455
2456
// Relocator returns a new method oop.
2457
_did_relocation = true;
2458
_method = m;
2459
}
2460
2461
2462
bool GenerateOopMap::is_astore(BytecodeStream *itr, int *index) {
2463
Bytecodes::Code bc = itr->code();
2464
switch(bc) {
2465
case Bytecodes::_astore_0:
2466
case Bytecodes::_astore_1:
2467
case Bytecodes::_astore_2:
2468
case Bytecodes::_astore_3:
2469
*index = bc - Bytecodes::_astore_0;
2470
return true;
2471
case Bytecodes::_astore:
2472
*index = itr->get_index();
2473
return true;
2474
}
2475
return false;
2476
}
2477
2478
bool GenerateOopMap::is_aload(BytecodeStream *itr, int *index) {
2479
Bytecodes::Code bc = itr->code();
2480
switch(bc) {
2481
case Bytecodes::_aload_0:
2482
case Bytecodes::_aload_1:
2483
case Bytecodes::_aload_2:
2484
case Bytecodes::_aload_3:
2485
*index = bc - Bytecodes::_aload_0;
2486
return true;
2487
2488
case Bytecodes::_aload:
2489
*index = itr->get_index();
2490
return true;
2491
}
2492
return false;
2493
}
2494
2495
2496
// Return true iff the top of the operand stack holds a return address at
2497
// the current instruction
2498
bool GenerateOopMap::stack_top_holds_ret_addr(int bci) {
2499
for(int i = 0; i < _ret_adr_tos->length(); i++) {
2500
if (_ret_adr_tos->at(i) == bci)
2501
return true;
2502
}
2503
2504
return false;
2505
}
2506
2507
void GenerateOopMap::compute_ret_adr_at_TOS() {
2508
assert(_ret_adr_tos != NULL, "must be initialized");
2509
_ret_adr_tos->clear();
2510
2511
for (int i = 0; i < bb_count(); i++) {
2512
BasicBlock* bb = &_basic_blocks[i];
2513
2514
// Make sure to only check basicblocks that are reachable
2515
if (bb->is_reachable()) {
2516
2517
// For each Basic block we check all instructions
2518
BytecodeStream bcs(_method);
2519
bcs.set_interval(bb->_bci, next_bb_start_pc(bb));
2520
2521
restore_state(bb);
2522
2523
while (bcs.next()>=0 && !_got_error) {
2524
// TDT: should this be is_good_address() ?
2525
if (_stack_top > 0 && stack()[_stack_top-1].is_address()) {
2526
_ret_adr_tos->append(bcs.bci());
2527
if (TraceNewOopMapGeneration) {
2528
tty->print_cr("Ret_adr TOS at bci: %d", bcs.bci());
2529
}
2530
}
2531
interp1(&bcs);
2532
}
2533
}
2534
}
2535
}
2536
2537
void GenerateOopMap::update_ret_adr_at_TOS(int bci, int delta) {
2538
for(int i = 0; i < _ret_adr_tos->length(); i++) {
2539
int v = _ret_adr_tos->at(i);
2540
if (v > bci) _ret_adr_tos->at_put(i, v + delta);
2541
}
2542
}
2543
2544
// ===================================================================
2545
2546
#ifndef PRODUCT
2547
int ResolveOopMapConflicts::_nof_invocations = 0;
2548
int ResolveOopMapConflicts::_nof_rewrites = 0;
2549
int ResolveOopMapConflicts::_nof_relocations = 0;
2550
#endif
2551
2552
methodHandle ResolveOopMapConflicts::do_potential_rewrite(TRAPS) {
2553
compute_map(CHECK_(methodHandle()));
2554
2555
#ifndef PRODUCT
2556
// Tracking and statistics
2557
if (PrintRewrites) {
2558
_nof_invocations++;
2559
if (did_rewriting()) {
2560
_nof_rewrites++;
2561
if (did_relocation()) _nof_relocations++;
2562
tty->print("Method was rewritten %s: ", (did_relocation()) ? "and relocated" : "");
2563
method()->print_value(); tty->cr();
2564
tty->print_cr("Cand.: %d rewrts: %d (%d%%) reloc.: %d (%d%%)",
2565
_nof_invocations,
2566
_nof_rewrites, (_nof_rewrites * 100) / _nof_invocations,
2567
_nof_relocations, (_nof_relocations * 100) / _nof_invocations);
2568
}
2569
}
2570
#endif
2571
return methodHandle(THREAD, method());
2572
}
2573
2574