generateOopMap.cpp revision 342:37f87013dfd8
1148330Snetchild/*
2148330Snetchild * Copyright 1997-2005 Sun Microsystems, Inc.  All Rights Reserved.
3148330Snetchild * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4148330Snetchild *
5148330Snetchild * This code is free software; you can redistribute it and/or modify it
6148330Snetchild * under the terms of the GNU General Public License version 2 only, as
7148330Snetchild * published by the Free Software Foundation.
8148330Snetchild *
9148330Snetchild * This code is distributed in the hope that it will be useful, but WITHOUT
10148330Snetchild * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11148330Snetchild * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12148330Snetchild * version 2 for more details (a copy is included in the LICENSE file that
13148330Snetchild * accompanied this code).
14148543Snetchild *
15148543Snetchild * You should have received a copy of the GNU General Public License version
16148330Snetchild * 2 along with this work; if not, write to the Free Software Foundation,
17160983Sbrooks * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18160983Sbrooks *
19158687Sphk * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20158687Sphk * CA 95054 USA or visit www.sun.com if you need additional information or
21158687Sphk * have any questions.
22158687Sphk *
23158687Sphk */
24158687Sphk
25158687Sphk//
26158687Sphk//
27158687Sphk// Compute stack layouts for each instruction in method.
28158687Sphk//
29158687Sphk//  Problems:
30158687Sphk//  - What to do about jsr with different types of local vars?
31158687Sphk//  Need maps that are conditional on jsr path?
32158687Sphk//  - Jsr and exceptions should be done more efficiently (the retAddr stuff)
33158687Sphk//
34158687Sphk//  Alternative:
35158687Sphk//  - Could extend verifier to provide this information.
36158687Sphk//    For: one fewer abstract interpreter to maintain. Against: the verifier
37158687Sphk//    solves a bigger problem so slower (undesirable to force verification of
38158687Sphk//    everything?).
39158687Sphk//
40158687Sphk//  Algorithm:
41158687Sphk//    Partition bytecodes into basic blocks
42158687Sphk//    For each basic block: store entry state (vars, stack). For instructions
43158687Sphk//    inside basic blocks we do not store any state (instead we recompute it
44158687Sphk//    from state produced by previous instruction).
45158687Sphk//
46158687Sphk//    Perform abstract interpretation of bytecodes over this lattice:
47158687Sphk//
48158687Sphk//                _--'#'--_
49158687Sphk//               /  /  \   \
50158687Sphk//             /   /     \   \
51158687Sphk//            /    |     |     \
52158687Sphk//          'r'   'v'   'p'   ' '
53158687Sphk//           \     |     |     /
54158687Sphk//            \    \     /    /
55158687Sphk//              \   \   /    /
56158687Sphk//                -- '@' --
57158687Sphk//
58158687Sphk//    '#'  top, result of conflict merge
59158687Sphk//    'r'  reference type
60158687Sphk//    'v'  value type
61158687Sphk//    'p'  pc type for jsr/ret
62158687Sphk//    ' '  uninitialized; never occurs on operand stack in Java
63158687Sphk//    '@'  bottom/unexecuted; initial state each bytecode.
64158687Sphk//
65158687Sphk//    Basic block headers are the only merge points. We use this iteration to
66158687Sphk//    compute the information:
67158687Sphk//
68158687Sphk//    find basic blocks;
69158687Sphk//    initialize them with uninitialized state;
70158687Sphk//    initialize first BB according to method signature;
71158687Sphk//    mark first BB changed
72158618Smaxim//    while (some BB is changed) do {
73158618Smaxim//      perform abstract interpration of all bytecodes in BB;
74158618Smaxim//      merge exit state of BB into entry state of all successor BBs,
75158512Smlaier//      noting if any of these change;
76158512Smlaier//    }
77158512Smlaier//
78158512Smlaier//  One additional complication is necessary. The jsr instruction pushes
79158512Smlaier//  a return PC on the stack (a 'p' type in the abstract interpretation).
80158754Smarcel//  To be able to process "ret" bytecodes, we keep track of these return
81158754Smarcel//  PC's in a 'retAddrs' structure in abstract interpreter context (when
82157221Ssimon//  processing a "ret" bytecodes, it is not sufficient to know that it gets
83157221Ssimon//  an argument of the right type 'p'; we need to know which address it
84156676Sharti//  returns to).
85156676Sharti//
86153662Sjhb// (Note this comment is borrowed form the original author of the algorithm)
87153662Sjhb
88153430Siedowse#include "incls/_precompiled.incl"
89153430Siedowse#include "incls/_generateOopMap.cpp.incl"
90153430Siedowse
91153430Siedowse// ComputeCallStack
92153430Siedowse//
93151845Syar// Specialization of SignatureIterator - compute the effects of a call
94151845Syar//
95151271Spjdclass ComputeCallStack : public SignatureIterator {
96151271Spjd  CellTypeState *_effect;
97150676Smlaier  int _idx;
98150677Smlaier
99150002Snetchild  void setup();
100150002Snetchild  void set(CellTypeState state)         { _effect[_idx++] = state; }
101150002Snetchild  int  length()                         { return _idx; };
102150002Snetchild
103149454Sglebius  virtual void do_bool  ()              { set(CellTypeState::value); };
104148808Sru  virtual void do_char  ()              { set(CellTypeState::value); };
105148808Sru  virtual void do_float ()              { set(CellTypeState::value); };
106148825Snetchild  virtual void do_byte  ()              { set(CellTypeState::value); };
107148825Snetchild  virtual void do_short ()              { set(CellTypeState::value); };
108148356Sdougb  virtual void do_int   ()              { set(CellTypeState::value); };
109148356Sdougb  virtual void do_void  ()              { set(CellTypeState::bottom);};
110148572Snetchild  virtual void do_object(int begin, int end)  { set(CellTypeState::ref); };
111148330Snetchild  virtual void do_array (int begin, int end)  { set(CellTypeState::ref); };
112148330Snetchild
113148330Snetchild  void do_double()                      { set(CellTypeState::value);
114148330Snetchild                                          set(CellTypeState::value); }
115148572Snetchild  void do_long  ()                      { set(CellTypeState::value);
116148572Snetchild                                           set(CellTypeState::value); }
117149105Simp
118148572Snetchildpublic:
119148572Snetchild  ComputeCallStack(symbolOop signature) : SignatureIterator(signature) {};
120148572Snetchild
121148572Snetchild  // Compute methods
122148572Snetchild  int compute_for_parameters(bool is_static, CellTypeState *effect) {
123148572Snetchild    _idx    = 0;
124148572Snetchild    _effect = effect;
125148572Snetchild
126148572Snetchild    if (!is_static)
127148572Snetchild      effect[_idx++] = CellTypeState::ref;
128148572Snetchild
129148572Snetchild    iterate_parameters();
130148572Snetchild
131148572Snetchild    return length();
132153939Snetchild  };
133153939Snetchild
134153939Snetchild  int compute_for_returntype(CellTypeState *effect) {
135153939Snetchild    _idx    = 0;
136148330Snetchild    _effect = effect;
137148330Snetchild    iterate_returntype();
138148423Sdougb    set(CellTypeState::bottom);  // Always terminate with a bottom state, so ppush works
139148423Sdougb
140148330Snetchild    return length();
141148330Snetchild  }
142148330Snetchild};
143148330Snetchild
144148572Snetchild//=========================================================================================
145148572Snetchild// ComputeEntryStack
146148353Sdougb//
147148353Sdougb// Specialization of SignatureIterator - in order to set up first stack frame
148149105Simp//
149149105Simpclass ComputeEntryStack : public SignatureIterator {
150148572Snetchild  CellTypeState *_effect;
151148572Snetchild  int _idx;
152149105Simp
153148572Snetchild  void setup();
154155813Snetchild  void set(CellTypeState state)         { _effect[_idx++] = state; }
155155813Snetchild  int  length()                         { return _idx; };
156155813Snetchild
157155813Snetchild  virtual void do_bool  ()              { set(CellTypeState::value); };
158148330Snetchild  virtual void do_char  ()              { set(CellTypeState::value); };
159148330Snetchild  virtual void do_float ()              { set(CellTypeState::value); };
160148330Snetchild  virtual void do_byte  ()              { set(CellTypeState::value); };
161148330Snetchild  virtual void do_short ()              { set(CellTypeState::value); };
162148330Snetchild  virtual void do_int   ()              { set(CellTypeState::value); };
163148330Snetchild  virtual void do_void  ()              { set(CellTypeState::bottom);};
164148330Snetchild  virtual void do_object(int begin, int end)  { set(CellTypeState::make_slot_ref(_idx)); }
165155813Snetchild  virtual void do_array (int begin, int end)  { set(CellTypeState::make_slot_ref(_idx)); }
166148330Snetchild
167148330Snetchild  void do_double()                      { set(CellTypeState::value);
168148330Snetchild                                          set(CellTypeState::value); }
169148330Snetchild  void do_long  ()                      { set(CellTypeState::value);
170148330Snetchild                                          set(CellTypeState::value); }
171148330Snetchild
172148543Snetchildpublic:
173148543Snetchild  ComputeEntryStack(symbolOop signature) : SignatureIterator(signature) {};
174148543Snetchild
175148543Snetchild  // Compute methods
176148543Snetchild  int compute_for_parameters(bool is_static, CellTypeState *effect) {
177148543Snetchild    _idx    = 0;
178148543Snetchild    _effect = effect;
179148543Snetchild
180148543Snetchild    if (!is_static)
181148543Snetchild      effect[_idx++] = CellTypeState::make_slot_ref(0);
182148543Snetchild
183148543Snetchild    iterate_parameters();
184148543Snetchild
185148543Snetchild    return length();
186148543Snetchild  };
187148543Snetchild
188148543Snetchild  int compute_for_returntype(CellTypeState *effect) {
189148543Snetchild    _idx    = 0;
190148543Snetchild    _effect = effect;
191148543Snetchild    iterate_returntype();
192148543Snetchild    set(CellTypeState::bottom);  // Always terminate with a bottom state, so ppush works
193148572Snetchild
194148572Snetchild    return length();
195148572Snetchild  }
196148572Snetchild};
197148572Snetchild
198148572Snetchild//=====================================================================================
199148572Snetchild//
200148572Snetchild// Implementation of RetTable/RetTableEntry
201148572Snetchild//
202148572Snetchild// Contains function to itereate through all bytecodes
203148572Snetchild// and find all return entry points
204148572Snetchild//
205148572Snetchildint RetTable::_init_nof_entries = 10;
206148572Snetchildint RetTableEntry::_init_nof_jsrs = 5;
207148572Snetchild
208148572Snetchildvoid RetTableEntry::add_delta(int bci, int delta) {
209148572Snetchild  if (_target_bci > bci) _target_bci += delta;
210148572Snetchild
211148572Snetchild  for (int k = 0; k < _jsrs->length(); k++) {
212148572Snetchild    int jsr = _jsrs->at(k);
213148572Snetchild    if (jsr > bci) _jsrs->at_put(k, jsr+delta);
214148572Snetchild  }
215148572Snetchild}
216148572Snetchild
217148572Snetchildvoid RetTable::compute_ret_table(methodHandle method) {
218148572Snetchild  BytecodeStream i(method);
219148572Snetchild  Bytecodes::Code bytecode;
220148572Snetchild
221148572Snetchild  while( (bytecode = i.next()) >= 0) {
222148572Snetchild    switch (bytecode) {
223148572Snetchild      case Bytecodes::_jsr:
224148572Snetchild        add_jsr(i.next_bci(), i.dest());
225148572Snetchild        break;
226148572Snetchild      case Bytecodes::_jsr_w:
227148572Snetchild        add_jsr(i.next_bci(), i.dest_w());
228148572Snetchild        break;
229148572Snetchild    }
230148572Snetchild  }
231148572Snetchild}
232148572Snetchild
233148572Snetchildvoid RetTable::add_jsr(int return_bci, int target_bci) {
234148572Snetchild  RetTableEntry* entry = _first;
235148572Snetchild
236148572Snetchild  // Scan table for entry
237148572Snetchild  for (;entry && entry->target_bci() != target_bci; entry = entry->next());
238148572Snetchild
239148572Snetchild  if (!entry) {
240148572Snetchild    // Allocate new entry and put in list
241148572Snetchild    entry = new RetTableEntry(target_bci, _first);
242148572Snetchild    _first = entry;
243148572Snetchild  }
244148572Snetchild
245148572Snetchild  // Now "entry" is set.  Make sure that the entry is initialized
246148572Snetchild  // and has room for the new jsr.
247148572Snetchild  entry->add_jsr(return_bci);
248148572Snetchild}
249148572Snetchild
250148572SnetchildRetTableEntry* RetTable::find_jsrs_for_target(int targBci) {
251148572Snetchild  RetTableEntry *cur = _first;
252148572Snetchild
253148572Snetchild  while(cur) {
254148572Snetchild    assert(cur->target_bci() != -1, "sanity check");
255148572Snetchild    if (cur->target_bci() == targBci)  return cur;
256148572Snetchild    cur = cur->next();
257148572Snetchild  }
258148572Snetchild  ShouldNotReachHere();
259148572Snetchild  return NULL;
260148572Snetchild}
261148572Snetchild
262148572Snetchild// The instruction at bci is changing size by "delta".  Update the return map.
263148572Snetchildvoid RetTable::update_ret_table(int bci, int delta) {
264148572Snetchild  RetTableEntry *cur = _first;
265148572Snetchild  while(cur) {
266148572Snetchild    cur->add_delta(bci, delta);
267148572Snetchild    cur = cur->next();
268148572Snetchild  }
269148572Snetchild}
270148572Snetchild
271148572Snetchild//
272148572Snetchild// Celltype state
273148572Snetchild//
274148572Snetchild
275148572SnetchildCellTypeState CellTypeState::bottom      = CellTypeState::make_bottom();
276148572SnetchildCellTypeState CellTypeState::uninit      = CellTypeState::make_any(uninit_value);
277148572SnetchildCellTypeState CellTypeState::ref         = CellTypeState::make_any(ref_conflict);
278148572SnetchildCellTypeState CellTypeState::value       = CellTypeState::make_any(val_value);
279148572SnetchildCellTypeState CellTypeState::refUninit   = CellTypeState::make_any(ref_conflict | uninit_value);
280148572SnetchildCellTypeState CellTypeState::top         = CellTypeState::make_top();
281148572SnetchildCellTypeState CellTypeState::addr        = CellTypeState::make_any(addr_conflict);
282148572Snetchild
283148572Snetchild// Commonly used constants
284148572Snetchildstatic CellTypeState epsilonCTS[1] = { CellTypeState::bottom };
285148572Snetchildstatic CellTypeState   refCTS   = CellTypeState::ref;
286148572Snetchildstatic CellTypeState   valCTS   = CellTypeState::value;
287148572Snetchildstatic CellTypeState    vCTS[2] = { CellTypeState::value, CellTypeState::bottom };
288148572Snetchildstatic CellTypeState    rCTS[2] = { CellTypeState::ref,   CellTypeState::bottom };
289148572Snetchildstatic CellTypeState   rrCTS[3] = { CellTypeState::ref,   CellTypeState::ref,   CellTypeState::bottom };
290148572Snetchildstatic CellTypeState   vrCTS[3] = { CellTypeState::value, CellTypeState::ref,   CellTypeState::bottom };
291148572Snetchildstatic CellTypeState   vvCTS[3] = { CellTypeState::value, CellTypeState::value, CellTypeState::bottom };
292148572Snetchildstatic CellTypeState  rvrCTS[4] = { CellTypeState::ref,   CellTypeState::value, CellTypeState::ref,   CellTypeState::bottom };
293148572Snetchildstatic CellTypeState  vvrCTS[4] = { CellTypeState::value, CellTypeState::value, CellTypeState::ref,   CellTypeState::bottom };
294148572Snetchildstatic CellTypeState  vvvCTS[4] = { CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::bottom };
295148572Snetchildstatic CellTypeState vvvrCTS[5] = { CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::ref,   CellTypeState::bottom };
296148572Snetchildstatic CellTypeState vvvvCTS[5] = { CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::value, CellTypeState::bottom };
297148572Snetchild
298148572Snetchildchar CellTypeState::to_char() const {
299148572Snetchild  if (can_be_reference()) {
300148572Snetchild    if (can_be_value() || can_be_address())
301148330Snetchild      return '#';    // Conflict that needs to be rewritten
302148330Snetchild    else
303148330Snetchild      return 'r';
304148330Snetchild  } else if (can_be_value())
305148330Snetchild    return 'v';
306148572Snetchild  else if (can_be_address())
307148572Snetchild    return 'p';
308148572Snetchild  else if (can_be_uninit())
309148572Snetchild    return ' ';
310148572Snetchild  else
311148572Snetchild    return '@';
312148572Snetchild}
313148572Snetchild
314148572Snetchild
315148572Snetchild// Print a detailed CellTypeState.  Indicate all bits that are set.  If
316149113Simp// the CellTypeState represents an address or a reference, print the
317149113Simp// value of the additional information.
318149113Simpvoid CellTypeState::print(outputStream *os) {
319149113Simp  if (can_be_address()) {
320149113Simp    os->print("(p");
321149113Simp  } else {
322149113Simp    os->print("( ");
323148572Snetchild  }
324148572Snetchild  if (can_be_reference()) {
325148572Snetchild    os->print("r");
326148572Snetchild  } else {
327148572Snetchild    os->print(" ");
328149105Simp  }
329148572Snetchild  if (can_be_value()) {
330148572Snetchild    os->print("v");
331148572Snetchild  } else {
332148572Snetchild    os->print(" ");
333148572Snetchild  }
334148572Snetchild  if (can_be_uninit()) {
335148572Snetchild    os->print("u|");
336148572Snetchild  } else {
337148683Sru    os->print(" |");
338148330Snetchild  }
339148330Snetchild  if (is_info_top()) {
340148330Snetchild    os->print("Top)");
341148330Snetchild  } else if (is_info_bottom()) {
342156385Syar    os->print("Bot)");
343156385Syar  } else {
344148330Snetchild    if (is_reference()) {
345148330Snetchild      int info = get_info();
346148330Snetchild      int data = info & ~(ref_not_lock_bit | ref_slot_bit);
347148330Snetchild      if (info & ref_not_lock_bit) {
348148330Snetchild        // Not a monitor lock reference.
349148330Snetchild        if (info & ref_slot_bit) {
350148330Snetchild          // slot
351148330Snetchild          os->print("slot%d)", data);
352148330Snetchild        } else {
353148330Snetchild          // line
354148330Snetchild          os->print("line%d)", data);
355148330Snetchild        }
356148330Snetchild      } else {
357148330Snetchild        // lock
358148330Snetchild        os->print("lock%d)", data);
359148330Snetchild      }
360148330Snetchild    } else {
361148330Snetchild      os->print("%d)", get_info());
362148330Snetchild    }
363148330Snetchild  }
364148330Snetchild}
365148572Snetchild
366148572Snetchild//
367149105Simp// Basicblock handling methods
368148572Snetchild//
369148572Snetchild
370148572Snetchildvoid GenerateOopMap ::initialize_bb() {
371148572Snetchild  _gc_points = 0;
372148572Snetchild  _bb_count  = 0;
373148572Snetchild  _bb_hdr_bits.clear();
374148572Snetchild  _bb_hdr_bits.resize(method()->code_size());
375155279Savatar}
376155279Savatar
377155279Savatarvoid GenerateOopMap::bb_mark_fct(GenerateOopMap *c, int bci, int *data) {
378155279Savatar  assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");
379148572Snetchild  if (c->is_bb_header(bci))
380148572Snetchild     return;
381148572Snetchild
382148330Snetchild  if (TraceNewOopMapGeneration) {
383148330Snetchild     tty->print_cr("Basicblock#%d begins at: %d", c->_bb_count, bci);
384148330Snetchild  }
385148330Snetchild  c->set_bbmark_bit(bci);
386148330Snetchild  c->_bb_count++;
387148330Snetchild}
388148330Snetchild
389148330Snetchild
390148330Snetchildvoid GenerateOopMap::mark_bbheaders_and_count_gc_points() {
391148330Snetchild  initialize_bb();
392148330Snetchild
393148330Snetchild  bool fellThrough = false;  // False to get first BB marked.
394148330Snetchild
395148330Snetchild  // First mark all exception handlers as start of a basic-block
396148330Snetchild  typeArrayOop excps = method()->exception_table();
397148330Snetchild  for(int i = 0; i < excps->length(); i += 4) {
398149105Simp    int handler_pc_idx = i+2;
399149105Simp    bb_mark_fct(this, excps->int_at(handler_pc_idx), NULL);
400148572Snetchild  }
401148572Snetchild
402148572Snetchild  // Then iterate through the code
403148572Snetchild  BytecodeStream bcs(_method);
404148330Snetchild  Bytecodes::Code bytecode;
405148330Snetchild
406148330Snetchild  while( (bytecode = bcs.next()) >= 0) {
407148330Snetchild    int bci = bcs.bci();
408148330Snetchild
409148330Snetchild    if (!fellThrough)
410148330Snetchild        bb_mark_fct(this, bci, NULL);
411148330Snetchild
412148330Snetchild    fellThrough = jump_targets_do(&bcs, &GenerateOopMap::bb_mark_fct, NULL);
413148330Snetchild
414148330Snetchild     /* We will also mark successors of jsr's as basic block headers. */
415148330Snetchild    switch (bytecode) {
416148330Snetchild      case Bytecodes::_jsr:
417148330Snetchild        assert(!fellThrough, "should not happen");
418148330Snetchild        bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);
419148330Snetchild        break;
420148330Snetchild      case Bytecodes::_jsr_w:
421148330Snetchild        assert(!fellThrough, "should not happen");
422148330Snetchild        bb_mark_fct(this, bci + Bytecodes::length_for(bytecode), NULL);
423148330Snetchild        break;
424148330Snetchild    }
425148330Snetchild
426148330Snetchild    if (possible_gc_point(&bcs))
427148572Snetchild      _gc_points++;
428148572Snetchild  }
429148572Snetchild}
430148572Snetchild
431148572Snetchildvoid GenerateOopMap::reachable_basicblock(GenerateOopMap *c, int bci, int *data) {
432148572Snetchild  assert(bci>= 0 && bci < c->method()->code_size(), "index out of bounds");
433148572Snetchild  BasicBlock* bb = c->get_basic_block_at(bci);
434148572Snetchild  if (bb->is_dead()) {
435148572Snetchild    bb->mark_as_alive();
436148572Snetchild    *data = 1; // Mark basicblock as changed
437148572Snetchild  }
438148572Snetchild}
439148572Snetchild
440148572Snetchild
441148572Snetchildvoid GenerateOopMap::mark_reachable_code() {
442148572Snetchild  int change = 1; // int to get function pointers to work
443148572Snetchild
444148572Snetchild  // Mark entry basic block as alive and all exception handlers
445148572Snetchild  _basic_blocks[0].mark_as_alive();
446148572Snetchild  typeArrayOop excps = method()->exception_table();
447148572Snetchild  for(int i = 0; i < excps->length(); i += 4) {
448148572Snetchild    int handler_pc_idx = i+2;
449148572Snetchild    BasicBlock *bb = get_basic_block_at(excps->int_at(handler_pc_idx));
450148572Snetchild    // If block is not already alive (due to multiple exception handlers to same bb), then
451148572Snetchild    // make it alive
452148572Snetchild    if (bb->is_dead()) bb->mark_as_alive();
453148572Snetchild  }
454148572Snetchild
455148572Snetchild  BytecodeStream bcs(_method);
456148572Snetchild
457148572Snetchild  // Iterate through all basic blocks until we reach a fixpoint
458148572Snetchild  while (change) {
459148572Snetchild    change = 0;
460148572Snetchild
461148572Snetchild    for (int i = 0; i < _bb_count; i++) {
462148572Snetchild      BasicBlock *bb = &_basic_blocks[i];
463148572Snetchild      if (bb->is_alive()) {
464148572Snetchild        // Position bytecodestream at last bytecode in basicblock
465148572Snetchild        bcs.set_start(bb->_end_bci);
466148572Snetchild        bcs.next();
467148572Snetchild        Bytecodes::Code bytecode = bcs.code();
468148572Snetchild        int bci = bcs.bci();
469148572Snetchild        assert(bci == bb->_end_bci, "wrong bci");
470148572Snetchild
471148572Snetchild        bool fell_through = jump_targets_do(&bcs, &GenerateOopMap::reachable_basicblock, &change);
472148572Snetchild
473148572Snetchild        // We will also mark successors of jsr's as alive.
474148572Snetchild        switch (bytecode) {
475148572Snetchild          case Bytecodes::_jsr:
476148572Snetchild          case Bytecodes::_jsr_w:
477148572Snetchild            assert(!fell_through, "should not happen");
478148572Snetchild            reachable_basicblock(this, bci + Bytecodes::length_for(bytecode), &change);
479148572Snetchild            break;
480148572Snetchild        }
481148572Snetchild        if (fell_through) {
482148572Snetchild          // Mark successor as alive
483148572Snetchild          if (bb[1].is_dead()) {
484148572Snetchild            bb[1].mark_as_alive();
485148572Snetchild            change = 1;
486148572Snetchild          }
487148572Snetchild        }
488148572Snetchild      }
489148572Snetchild    }
490148572Snetchild  }
491148572Snetchild}
492148572Snetchild
493148572Snetchild/* If the current instruction in "c" has no effect on control flow,
494148572Snetchild   returns "true".  Otherwise, calls "jmpFct" one or more times, with
495148572Snetchild   "c", an appropriate "pcDelta", and "data" as arguments, then
496148572Snetchild   returns "false".  There is one exception: if the current
497148572Snetchild   instruction is a "ret", returns "false" without calling "jmpFct".
498148572Snetchild   Arrangements for tracking the control flow of a "ret" must be made
499148572Snetchild   externally. */
500148572Snetchildbool GenerateOopMap::jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int *data) {
501148572Snetchild  int bci = bcs->bci();
502148572Snetchild
503148572Snetchild  switch (bcs->code()) {
504148572Snetchild    case Bytecodes::_ifeq:
505148572Snetchild    case Bytecodes::_ifne:
506148572Snetchild    case Bytecodes::_iflt:
507148572Snetchild    case Bytecodes::_ifge:
508148572Snetchild    case Bytecodes::_ifgt:
509148572Snetchild    case Bytecodes::_ifle:
510148572Snetchild    case Bytecodes::_if_icmpeq:
511148572Snetchild    case Bytecodes::_if_icmpne:
512148572Snetchild    case Bytecodes::_if_icmplt:
513148572Snetchild    case Bytecodes::_if_icmpge:
514148572Snetchild    case Bytecodes::_if_icmpgt:
515148572Snetchild    case Bytecodes::_if_icmple:
516148572Snetchild    case Bytecodes::_if_acmpeq:
517148572Snetchild    case Bytecodes::_if_acmpne:
518148572Snetchild    case Bytecodes::_ifnull:
519148572Snetchild    case Bytecodes::_ifnonnull:
520148572Snetchild      (*jmpFct)(this, bcs->dest(), data);
521148572Snetchild      (*jmpFct)(this, bci + 3, data);
522148572Snetchild      break;
523148572Snetchild
524148572Snetchild    case Bytecodes::_goto:
525148572Snetchild      (*jmpFct)(this, bcs->dest(), data);
526149105Simp      break;
527149105Simp    case Bytecodes::_goto_w:
528149105Simp      (*jmpFct)(this, bcs->dest_w(), data);
529149105Simp      break;
530148572Snetchild    case Bytecodes::_tableswitch:
531148572Snetchild      { Bytecode_tableswitch *tableswitch = Bytecode_tableswitch_at(bcs->bcp());
532148572Snetchild        int len = tableswitch->length();
533148572Snetchild
534148572Snetchild        (*jmpFct)(this, bci + tableswitch->default_offset(), data); /* Default. jump address */
535148572Snetchild        while (--len >= 0) {
536148572Snetchild          (*jmpFct)(this, bci + tableswitch->dest_offset_at(len), data);
537148572Snetchild        }
538148572Snetchild        break;
539148572Snetchild      }
540148572Snetchild
541148572Snetchild    case Bytecodes::_lookupswitch:
542148572Snetchild      { Bytecode_lookupswitch *lookupswitch = Bytecode_lookupswitch_at(bcs->bcp());
543148572Snetchild        int npairs = lookupswitch->number_of_pairs();
544148572Snetchild        (*jmpFct)(this, bci + lookupswitch->default_offset(), data); /* Default. */
545148572Snetchild        while(--npairs >= 0) {
546148572Snetchild          LookupswitchPair *pair = lookupswitch->pair_at(npairs);
547148572Snetchild          (*jmpFct)(this, bci + pair->offset(), data);
548148572Snetchild        }
549148572Snetchild        break;
550148572Snetchild      }
551148572Snetchild    case Bytecodes::_jsr:
552148572Snetchild      assert(bcs->is_wide()==false, "sanity check");
553148572Snetchild      (*jmpFct)(this, bcs->dest(), data);
554148572Snetchild
555148572Snetchild
556148572Snetchild
557148572Snetchild      break;
558148572Snetchild    case Bytecodes::_jsr_w:
559148572Snetchild      (*jmpFct)(this, bcs->dest_w(), data);
560148572Snetchild      break;
561148572Snetchild    case Bytecodes::_wide:
562148572Snetchild      ShouldNotReachHere();
563148572Snetchild      return true;
564148572Snetchild      break;
565148572Snetchild    case Bytecodes::_athrow:
566148572Snetchild    case Bytecodes::_ireturn:
567148572Snetchild    case Bytecodes::_lreturn:
568148572Snetchild    case Bytecodes::_freturn:
569148572Snetchild    case Bytecodes::_dreturn:
570148572Snetchild    case Bytecodes::_areturn:
571148572Snetchild    case Bytecodes::_return:
572148572Snetchild    case Bytecodes::_ret:
573148572Snetchild      break;
574148572Snetchild    default:
575148572Snetchild      return true;
576148572Snetchild  }
577148572Snetchild  return false;
578148572Snetchild}
579148572Snetchild
580148572Snetchild/* Requires "pc" to be the head of a basic block; returns that basic
581148572Snetchild   block. */
582148572SnetchildBasicBlock *GenerateOopMap::get_basic_block_at(int bci) const {
583148572Snetchild  BasicBlock* bb = get_basic_block_containing(bci);
584148572Snetchild  assert(bb->_bci == bci, "should have found BB");
585148572Snetchild  return bb;
586148572Snetchild}
587148572Snetchild
588148572Snetchild// Requires "pc" to be the start of an instruction; returns the basic
589149105Simp//   block containing that instruction. */
590149105SimpBasicBlock  *GenerateOopMap::get_basic_block_containing(int bci) const {
591149105Simp  BasicBlock *bbs = _basic_blocks;
592149105Simp  int lo = 0, hi = _bb_count - 1;
593149105Simp
594149105Simp  while (lo <= hi) {
595149105Simp    int m = (lo + hi) / 2;
596149105Simp    int mbci = bbs[m]._bci;
597148572Snetchild    int nbci;
598148572Snetchild
599160165Savatar    if ( m == _bb_count-1) {
600160165Savatar      assert( bci >= mbci && bci < method()->code_size(), "sanity check failed");
601148330Snetchild      return bbs+m;
602148330Snetchild    } else {
603148330Snetchild      nbci = bbs[m+1]._bci;
604149105Simp    }
605149105Simp
606149105Simp    if ( mbci <= bci && bci < nbci) {
607149105Simp      return bbs+m;
608149105Simp    } else if (mbci < bci) {
609149105Simp      lo = m + 1;
610149105Simp    } else {
611149105Simp      assert(mbci > bci, "sanity check");
612149105Simp      hi = m - 1;
613149105Simp    }
614149105Simp  }
615149105Simp
616149105Simp  fatal("should have found BB");
617149105Simp  return NULL;
618149105Simp}
619149105Simp
620149105Simpvoid GenerateOopMap::restore_state(BasicBlock *bb)
621149105Simp{
622149105Simp  memcpy(_state, bb->_state, _state_len*sizeof(CellTypeState));
623149105Simp  _stack_top = bb->_stack_top;
624149105Simp  _monitor_top = bb->_monitor_top;
625149105Simp}
626149105Simp
627149105Simpint GenerateOopMap::next_bb_start_pc(BasicBlock *bb) {
628149105Simp int bbNum = bb - _basic_blocks + 1;
629160165Savatar if (bbNum == _bb_count)
630160165Savatar    return method()->code_size();
631160165Savatar
632148330Snetchild return _basic_blocks[bbNum]._bci;
633148330Snetchild}
634148330Snetchild
635148330Snetchild//
636148330Snetchild// CellType handling methods
637148330Snetchild//
638148330Snetchild
639148330Snetchildvoid GenerateOopMap::init_state() {
640149105Simp  _state_len     = _max_locals + _max_stack + _max_monitors;
641149105Simp  _state         = NEW_RESOURCE_ARRAY(CellTypeState, _state_len);
642149105Simp  memset(_state, 0, _state_len * sizeof(CellTypeState));
643149105Simp  _state_vec_buf = NEW_RESOURCE_ARRAY(char, MAX3(_max_locals, _max_stack, _max_monitors) + 1/*for null terminator char */);
644149105Simp}
645148330Snetchild
646149105Simpvoid GenerateOopMap::make_context_uninitialized() {
647149105Simp  CellTypeState* vs = vars();
648149105Simp
649149105Simp  for (int i = 0; i < _max_locals; i++)
650149105Simp      vs[i] = CellTypeState::uninit;
651149105Simp
652149105Simp  _stack_top = 0;
653149105Simp  _monitor_top = 0;
654149105Simp}
655149105Simp
656149105Simpint GenerateOopMap::methodsig_to_effect(symbolOop signature, bool is_static, CellTypeState* effect) {
657149105Simp  ComputeEntryStack ces(signature);
658149105Simp  return ces.compute_for_parameters(is_static, effect);
659160165Savatar}
660160165Savatar
661160165Savatar// Return result of merging cts1 and cts2.
662148330SnetchildCellTypeState CellTypeState::merge(CellTypeState cts, int slot) const {
663148330Snetchild  CellTypeState result;
664148330Snetchild
665148330Snetchild  assert(!is_bottom() && !cts.is_bottom(),
666149105Simp         "merge of bottom values is handled elsewhere");
667149105Simp
668149105Simp  result._state = _state | cts._state;
669148330Snetchild
670148330Snetchild  // If the top bit is set, we don't need to do any more work.
671148330Snetchild  if (!result.is_info_top()) {
672148330Snetchild    assert((result.can_be_address() || result.can_be_reference()),
673148330Snetchild           "only addresses and references have non-top info");
674148330Snetchild
675148330Snetchild    if (!equal(cts)) {
676148330Snetchild      // The two values being merged are different.  Raise to top.
677148330Snetchild      if (result.is_reference()) {
678148330Snetchild        result = CellTypeState::make_slot_ref(slot);
679148330Snetchild      } else {
680148330Snetchild        result._state |= info_conflict;
681148330Snetchild      }
682148330Snetchild    }
683148330Snetchild  }
684148330Snetchild  assert(result.is_valid_state(), "checking that CTS merge maintains legal state");
685148543Snetchild
686149113Simp  return result;
687149113Simp}
688149113Simp
689149113Simp// Merge the variable state for locals and stack from cts into bbts.
690149113Simpbool GenerateOopMap::merge_local_state_vectors(CellTypeState* cts,
691149113Simp                                               CellTypeState* bbts) {
692149113Simp  int i;
693149113Simp  int len = _max_locals + _stack_top;
694149113Simp  bool change = false;
695149113Simp
696149113Simp  for (i = len - 1; i >= 0; i--) {
697148330Snetchild    CellTypeState v = cts[i].merge(bbts[i], i);
698148330Snetchild    change = change || !v.equal(bbts[i]);
699149113Simp    bbts[i] = v;
700149113Simp  }
701149113Simp
702149113Simp  return change;
703149113Simp}
704149113Simp
705149113Simp// Merge the monitor stack state from cts into bbts.
706149113Simpbool GenerateOopMap::merge_monitor_state_vectors(CellTypeState* cts,
707149113Simp                                                 CellTypeState* bbts) {
708149113Simp  bool change = false;
709149113Simp  if (_max_monitors > 0 && _monitor_top != bad_monitors) {
710149113Simp    // If there are no monitors in the program, or there has been
711149113Simp    // a monitor matching error before this point in the program,
712149113Simp    // then we do not merge in the monitor state.
713149113Simp
714149113Simp    int base = _max_locals + _max_stack;
715149113Simp    int len = base + _monitor_top;
716149113Simp    for (int i = len - 1; i >= base; i--) {
717149113Simp      CellTypeState v = cts[i].merge(bbts[i], i);
718149113Simp
719149113Simp      // Can we prove that, when there has been a change, it will already
720149113Simp      // have been detected at this point?  That would make this equal
721149113Simp      // check here unnecessary.
722149113Simp      change = change || !v.equal(bbts[i]);
723149113Simp      bbts[i] = v;
724149113Simp    }
725149113Simp  }
726149113Simp
727149113Simp  return change;
728149113Simp}
729149113Simp
730149113Simpvoid GenerateOopMap::copy_state(CellTypeState *dst, CellTypeState *src) {
731148330Snetchild  int len = _max_locals + _stack_top;
732148330Snetchild  for (int i = 0; i < len; i++) {
733148330Snetchild    if (src[i].is_nonlock_reference()) {
734148330Snetchild      dst[i] = CellTypeState::make_slot_ref(i);
735148330Snetchild    } else {
736148330Snetchild      dst[i] = src[i];
737148330Snetchild    }
738151378Snetchild  }
739151378Snetchild  if (_max_monitors > 0 && _monitor_top != bad_monitors) {
740151378Snetchild    int base = _max_locals + _max_stack;
741151378Snetchild    len = base + _monitor_top;
742151378Snetchild    for (int i = base; i < len; i++) {
743151378Snetchild      dst[i] = src[i];
744151378Snetchild    }
745151378Snetchild  }
746151378Snetchild}
747151378Snetchild
748151378Snetchild
749151378Snetchild// Merge the states for the current block and the next.  As long as a
750151378Snetchild// block is reachable the locals and stack must be merged.  If the
751151378Snetchild// stack heights don't match then this is a verification error and
752151378Snetchild// it's impossible to interpret the code.  Simultaneously monitor
753151378Snetchild// states are being check to see if they nest statically.  If monitor
754151378Snetchild// depths match up then their states are merged.  Otherwise the
755151378Snetchild// mismatch is simply recorded and interpretation continues since
756151378Snetchild// monitor matching is purely informational and doesn't say anything
757151378Snetchild// about the correctness of the code.
758151378Snetchildvoid GenerateOopMap::merge_state_into_bb(BasicBlock *bb) {
759151378Snetchild  assert(bb->is_alive(), "merging state into a dead basicblock");
760151378Snetchild
761151378Snetchild  if (_stack_top == bb->_stack_top) {
762151378Snetchild    // always merge local state even if monitors don't match.
763151378Snetchild    if (merge_local_state_vectors(_state, bb->_state)) {
764151378Snetchild      bb->set_changed(true);
765151378Snetchild    }
766151378Snetchild    if (_monitor_top == bb->_monitor_top) {
767151378Snetchild      // monitors still match so continue merging monitor states.
768151378Snetchild      if (merge_monitor_state_vectors(_state, bb->_state)) {
769151378Snetchild        bb->set_changed(true);
770151378Snetchild      }
771151378Snetchild    } else {
772151378Snetchild      if (TraceMonitorMismatch) {
773151378Snetchild        report_monitor_mismatch("monitor stack height merge conflict");
774151378Snetchild      }
775151378Snetchild      // When the monitor stacks are not matched, we set _monitor_top to
776151378Snetchild      // bad_monitors.  This signals that, from here on, the monitor stack cannot
777151378Snetchild      // be trusted.  In particular, monitorexit bytecodes may throw
778151378Snetchild      // exceptions.  We mark this block as changed so that the change
779151378Snetchild      // propagates properly.
780151378Snetchild      bb->_monitor_top = bad_monitors;
781151378Snetchild      bb->set_changed(true);
782151378Snetchild      _monitor_safe = false;
783151378Snetchild    }
784151378Snetchild  } else if (!bb->is_reachable()) {
785151378Snetchild    // First time we look at this  BB
786151378Snetchild    copy_state(bb->_state, _state);
787151378Snetchild    bb->_stack_top = _stack_top;
788151378Snetchild    bb->_monitor_top = _monitor_top;
789151378Snetchild    bb->set_changed(true);
790151378Snetchild  } else {
791151378Snetchild    verify_error("stack height conflict: %d vs. %d",  _stack_top, bb->_stack_top);
792151378Snetchild  }
793151378Snetchild}
794151378Snetchild
795151378Snetchildvoid GenerateOopMap::merge_state(GenerateOopMap *gom, int bci, int* data) {
796151378Snetchild   gom->merge_state_into_bb(gom->get_basic_block_at(bci));
797151378Snetchild}
798151378Snetchild
799151378Snetchildvoid GenerateOopMap::set_var(int localNo, CellTypeState cts) {
800151378Snetchild  assert(cts.is_reference() || cts.is_value() || cts.is_address(),
801151378Snetchild         "wrong celltypestate");
802151378Snetchild  if (localNo < 0 || localNo > _max_locals) {
803151378Snetchild    verify_error("variable write error: r%d", localNo);
804151378Snetchild    return;
805151378Snetchild  }
806151378Snetchild  vars()[localNo] = cts;
807151378Snetchild}
808151378Snetchild
809151378SnetchildCellTypeState GenerateOopMap::get_var(int localNo) {
810151378Snetchild  assert(localNo < _max_locals + _nof_refval_conflicts, "variable read error")
811151378Snetchild  if (localNo < 0 || localNo > _max_locals) {
812151378Snetchild    verify_error("variable read error: r%d", localNo);
813151378Snetchild    return valCTS; // just to pick something;
814151378Snetchild  }
815151378Snetchild  return vars()[localNo];
816151378Snetchild}
817151378Snetchild
818151378SnetchildCellTypeState GenerateOopMap::pop() {
819151378Snetchild  if ( _stack_top <= 0) {
820151378Snetchild    verify_error("stack underflow");
821151378Snetchild    return valCTS; // just to pick something
822151378Snetchild  }
823151378Snetchild  return  stack()[--_stack_top];
824151378Snetchild}
825151378Snetchild
826151378Snetchildvoid GenerateOopMap::push(CellTypeState cts) {
827151378Snetchild  if ( _stack_top >= _max_stack) {
828151378Snetchild    verify_error("stack overflow");
829151378Snetchild    return;
830151378Snetchild  }
831151378Snetchild  stack()[_stack_top++] = cts;
832151378Snetchild}
833151378Snetchild
834151378SnetchildCellTypeState GenerateOopMap::monitor_pop() {
835151378Snetchild  assert(_monitor_top != bad_monitors, "monitor_pop called on error monitor stack");
836151378Snetchild  if (_monitor_top == 0) {
837151378Snetchild    // We have detected a pop of an empty monitor stack.
838151378Snetchild    _monitor_safe = false;
839151378Snetchild     _monitor_top = bad_monitors;
840151378Snetchild
841151378Snetchild    if (TraceMonitorMismatch) {
842151378Snetchild      report_monitor_mismatch("monitor stack underflow");
843151378Snetchild    }
844151378Snetchild    return CellTypeState::ref; // just to keep the analysis going.
845151378Snetchild  }
846151378Snetchild  return  monitors()[--_monitor_top];
847151378Snetchild}
848151378Snetchild
849151378Snetchildvoid GenerateOopMap::monitor_push(CellTypeState cts) {
850151378Snetchild  assert(_monitor_top != bad_monitors, "monitor_push called on error monitor stack");
851151378Snetchild  if (_monitor_top >= _max_monitors) {
852151378Snetchild    // Some monitorenter is being executed more than once.
853151378Snetchild    // This means that the monitor stack cannot be simulated.
854151378Snetchild    _monitor_safe = false;
855151378Snetchild    _monitor_top = bad_monitors;
856151378Snetchild
857151378Snetchild    if (TraceMonitorMismatch) {
858151378Snetchild      report_monitor_mismatch("monitor stack overflow");
859151378Snetchild    }
860151378Snetchild    return;
861151378Snetchild  }
862151378Snetchild  monitors()[_monitor_top++] = cts;
863151378Snetchild}
864151378Snetchild
865151378Snetchild//
866151378Snetchild// Interpretation handling methods
867151378Snetchild//
868151378Snetchild
869151378Snetchildvoid GenerateOopMap::do_interpretation()
870151378Snetchild{
871151378Snetchild  // "i" is just for debugging, so we can detect cases where this loop is
872151378Snetchild  // iterated more than once.
873151378Snetchild  int i = 0;
874151378Snetchild  do {
875151378Snetchild#ifndef PRODUCT
876151378Snetchild    if (TraceNewOopMapGeneration) {
877151378Snetchild      tty->print("\n\nIteration #%d of do_interpretation loop, method:\n", i);
878151378Snetchild      method()->print_name(tty);
879151378Snetchild      tty->print("\n\n");
880151378Snetchild    }
881151378Snetchild#endif
882151378Snetchild    _conflict = false;
883151378Snetchild    _monitor_safe = true;
884151378Snetchild    // init_state is now called from init_basic_blocks.  The length of a
885151378Snetchild    // state vector cannot be determined until we have made a pass through
886151378Snetchild    // the bytecodes counting the possible monitor entries.
887151378Snetchild    if (!_got_error) init_basic_blocks();
888151378Snetchild    if (!_got_error) setup_method_entry_state();
889151378Snetchild    if (!_got_error) interp_all();
890151378Snetchild    if (!_got_error) rewrite_refval_conflicts();
891151378Snetchild    i++;
892151378Snetchild  } while (_conflict && !_got_error);
893151378Snetchild}
894151378Snetchild
895151378Snetchildvoid GenerateOopMap::init_basic_blocks() {
896151378Snetchild  // Note: Could consider reserving only the needed space for each BB's state
897151378Snetchild  // (entry stack may not be of maximal height for every basic block).
898151378Snetchild  // But cumbersome since we don't know the stack heights yet.  (Nor the
899151378Snetchild  // monitor stack heights...)
900151378Snetchild
901151378Snetchild  _basic_blocks = NEW_RESOURCE_ARRAY(BasicBlock, _bb_count);
902151378Snetchild
903151378Snetchild  // Make a pass through the bytecodes.  Count the number of monitorenters.
904151378Snetchild  // This can be used an upper bound on the monitor stack depth in programs
905151378Snetchild  // which obey stack discipline with their monitor usage.  Initialize the
906151378Snetchild  // known information about basic blocks.
907151378Snetchild  BytecodeStream j(_method);
908151378Snetchild  Bytecodes::Code bytecode;
909151378Snetchild
910151378Snetchild  int bbNo = 0;
911151378Snetchild  int monitor_count = 0;
912151378Snetchild  int prev_bci = -1;
913151378Snetchild  while( (bytecode = j.next()) >= 0) {
914151378Snetchild    if (j.code() == Bytecodes::_monitorenter) {
915151378Snetchild      monitor_count++;
916151378Snetchild    }
917151378Snetchild
918151378Snetchild    int bci = j.bci();
919151378Snetchild    if (is_bb_header(bci)) {
920151378Snetchild      // Initialize the basicblock structure
921151378Snetchild      BasicBlock *bb   = _basic_blocks + bbNo;
922151378Snetchild      bb->_bci         = bci;
923151378Snetchild      bb->_max_locals  = _max_locals;
924151378Snetchild      bb->_max_stack   = _max_stack;
925151378Snetchild      bb->set_changed(false);
926151378Snetchild      bb->_stack_top   = BasicBlock::_dead_basic_block; // Initialize all basicblocks are dead.
927151378Snetchild      bb->_monitor_top = bad_monitors;
928151378Snetchild
929151378Snetchild      if (bbNo > 0) {
930151378Snetchild        _basic_blocks[bbNo - 1]._end_bci = prev_bci;
931151378Snetchild      }
932151378Snetchild
933151378Snetchild      bbNo++;
934151378Snetchild    }
935151378Snetchild    // Remember prevous bci.
936151378Snetchild    prev_bci = bci;
937151378Snetchild  }
938151378Snetchild  // Set
939151378Snetchild  _basic_blocks[bbNo-1]._end_bci = prev_bci;
940151378Snetchild
941151378Snetchild
942151378Snetchild  // Check that the correct number of basicblocks was found
943151378Snetchild  if (bbNo !=_bb_count) {
944151378Snetchild    if (bbNo < _bb_count) {
945151378Snetchild      verify_error("jump into the middle of instruction?");
946151378Snetchild      return;
947151378Snetchild    } else {
948151378Snetchild      verify_error("extra basic blocks - should not happen?");
949151378Snetchild      return;
950151378Snetchild    }
951151378Snetchild  }
952151378Snetchild
953151378Snetchild  _max_monitors = monitor_count;
954151378Snetchild
955151378Snetchild  // Now that we have a bound on the depth of the monitor stack, we can
956151378Snetchild  // initialize the CellTypeState-related information.
957151378Snetchild  init_state();
958151378Snetchild
959151378Snetchild  // We allocate space for all state-vectors for all basicblocks in one huge chuck.
960151378Snetchild  // Then in the next part of the code, we set a pointer in each _basic_block that
961151378Snetchild  // points to each piece.
962151378Snetchild  CellTypeState *basicBlockState = NEW_RESOURCE_ARRAY(CellTypeState, bbNo * _state_len);
963151378Snetchild  memset(basicBlockState, 0, bbNo * _state_len * sizeof(CellTypeState));
964151378Snetchild
965151378Snetchild  // Make a pass over the basicblocks and assign their state vectors.
966151378Snetchild  for (int blockNum=0; blockNum < bbNo; blockNum++) {
967151378Snetchild    BasicBlock *bb = _basic_blocks + blockNum;
968151378Snetchild    bb->_state = basicBlockState + blockNum * _state_len;
969151378Snetchild
970151378Snetchild#ifdef ASSERT
971151378Snetchild    if (blockNum + 1 < bbNo) {
972151378Snetchild      address bcp = _method->bcp_from(bb->_end_bci);
973151378Snetchild      int bc_len = Bytecodes::java_length_at(bcp);
974151378Snetchild      assert(bb->_end_bci + bc_len == bb[1]._bci, "unmatched bci info in basicblock");
975151378Snetchild    }
976151378Snetchild#endif
977151378Snetchild  }
978151378Snetchild#ifdef ASSERT
979151378Snetchild  { BasicBlock *bb = &_basic_blocks[bbNo-1];
980151378Snetchild    address bcp = _method->bcp_from(bb->_end_bci);
981151378Snetchild    int bc_len = Bytecodes::java_length_at(bcp);
982151378Snetchild    assert(bb->_end_bci + bc_len == _method->code_size(), "wrong end bci");
983151378Snetchild  }
984151378Snetchild#endif
985151378Snetchild
986151378Snetchild  // Mark all alive blocks
987151378Snetchild  mark_reachable_code();
988151378Snetchild}
989151378Snetchild
990151378Snetchildvoid GenerateOopMap::setup_method_entry_state() {
991151378Snetchild
992151378Snetchild    // Initialize all locals to 'uninit' and set stack-height to 0
993151378Snetchild    make_context_uninitialized();
994151378Snetchild
995151378Snetchild    // Initialize CellState type of arguments
996151378Snetchild    methodsig_to_effect(method()->signature(), method()->is_static(), vars());
997151378Snetchild
998151378Snetchild    // If some references must be pre-assigned to null, then set that up
999151378Snetchild    initialize_vars();
1000151378Snetchild
1001151378Snetchild    // This is the start state
1002151378Snetchild    merge_state_into_bb(&_basic_blocks[0]);
1003151378Snetchild
1004151378Snetchild    assert(_basic_blocks[0].changed(), "we are not getting off the ground");
1005151378Snetchild}
1006151378Snetchild
1007151378Snetchild// The instruction at bci is changing size by "delta".  Update the basic blocks.
1008151378Snetchildvoid GenerateOopMap::update_basic_blocks(int bci, int delta,
1009151378Snetchild                                         int new_method_size) {
1010151378Snetchild  assert(new_method_size >= method()->code_size() + delta,
1011151378Snetchild         "new method size is too small");
1012151378Snetchild
1013151378Snetchild  BitMap::bm_word_t* new_bb_hdr_bits =
1014151378Snetchild    NEW_RESOURCE_ARRAY(BitMap::bm_word_t,
1015151378Snetchild                       BitMap::word_align_up(new_method_size));
1016151378Snetchild  _bb_hdr_bits.set_map(new_bb_hdr_bits);
1017151378Snetchild  _bb_hdr_bits.set_size(new_method_size);
1018151378Snetchild  _bb_hdr_bits.clear();
1019151378Snetchild
1020151378Snetchild
1021151378Snetchild  for(int k = 0; k < _bb_count; k++) {
1022151378Snetchild    if (_basic_blocks[k]._bci > bci) {
1023151378Snetchild      _basic_blocks[k]._bci     += delta;
1024151378Snetchild      _basic_blocks[k]._end_bci += delta;
1025151378Snetchild    }
1026151378Snetchild    _bb_hdr_bits.at_put(_basic_blocks[k]._bci, true);
1027151378Snetchild  }
1028151378Snetchild}
1029151378Snetchild
1030151378Snetchild//
1031151378Snetchild// Initvars handling
1032151378Snetchild//
1033151378Snetchild
1034151378Snetchildvoid GenerateOopMap::initialize_vars() {
1035151378Snetchild  for (int k = 0; k < _init_vars->length(); k++)
1036151378Snetchild    _state[_init_vars->at(k)] = CellTypeState::make_slot_ref(k);
1037151378Snetchild}
1038151378Snetchild
1039151378Snetchildvoid GenerateOopMap::add_to_ref_init_set(int localNo) {
1040151378Snetchild
1041151378Snetchild  if (TraceNewOopMapGeneration)
1042151378Snetchild    tty->print_cr("Added init vars: %d", localNo);
1043151378Snetchild
1044151378Snetchild  // Is it already in the set?
1045151378Snetchild  if (_init_vars->contains(localNo) )
1046151378Snetchild    return;
1047151378Snetchild
1048151378Snetchild   _init_vars->append(localNo);
1049151378Snetchild}
1050151378Snetchild
1051151378Snetchild//
1052151378Snetchild// Interpreration code
1053151378Snetchild//
1054151378Snetchild
1055151378Snetchildvoid GenerateOopMap::interp_all() {
1056151378Snetchild  bool change = true;
1057151378Snetchild
1058151378Snetchild  while (change && !_got_error) {
1059151378Snetchild    change = false;
1060151378Snetchild    for (int i = 0; i < _bb_count && !_got_error; i++) {
1061151378Snetchild      BasicBlock *bb = &_basic_blocks[i];
1062151378Snetchild      if (bb->changed()) {
1063151378Snetchild         if (_got_error) return;
1064151378Snetchild         change = true;
1065151378Snetchild         bb->set_changed(false);
1066151378Snetchild         interp_bb(bb);
1067151378Snetchild      }
1068151378Snetchild    }
1069151378Snetchild  }
1070151378Snetchild}
1071151378Snetchild
1072151378Snetchildvoid GenerateOopMap::interp_bb(BasicBlock *bb) {
1073151378Snetchild
1074151378Snetchild  // We do not want to do anything in case the basic-block has not been initialized. This
1075151378Snetchild  // will happen in the case where there is dead-code hang around in a method.
1076151378Snetchild  assert(bb->is_reachable(), "should be reachable or deadcode exist");
1077151378Snetchild  restore_state(bb);
1078151378Snetchild
1079151378Snetchild  BytecodeStream itr(_method);
1080151378Snetchild
1081151378Snetchild  // Set iterator interval to be the current basicblock
1082151378Snetchild  int lim_bci = next_bb_start_pc(bb);
1083151378Snetchild  itr.set_interval(bb->_bci, lim_bci);
1084151378Snetchild  assert(lim_bci != bb->_bci, "must be at least one instruction in a basicblock");
1085151378Snetchild  itr.next(); // read first instruction
1086151378Snetchild
1087151378Snetchild  // Iterates through all bytecodes except the last in a basic block.
1088151378Snetchild  // We handle the last one special, since there is controlflow change.
1089151378Snetchild  while(itr.next_bci() < lim_bci && !_got_error) {
1090151378Snetchild    if (_has_exceptions || _monitor_top != 0) {
1091151378Snetchild      // We do not need to interpret the results of exceptional
1092151378Snetchild      // continuation from this instruction when the method has no
1093151378Snetchild      // exception handlers and the monitor stack is currently
1094151378Snetchild      // empty.
1095151378Snetchild      do_exception_edge(&itr);
1096151378Snetchild    }
1097151378Snetchild    interp1(&itr);
1098151378Snetchild    itr.next();
1099151378Snetchild  }
1100151378Snetchild
1101151378Snetchild  // Handle last instruction.
1102151378Snetchild  if (!_got_error) {
1103151378Snetchild    assert(itr.next_bci() == lim_bci, "must point to end");
1104151378Snetchild    if (_has_exceptions || _monitor_top != 0) {
1105151378Snetchild      do_exception_edge(&itr);
1106151378Snetchild    }
1107151378Snetchild    interp1(&itr);
1108151378Snetchild
1109151378Snetchild    bool fall_through = jump_targets_do(&itr, GenerateOopMap::merge_state, NULL);
1110151378Snetchild    if (_got_error)  return;
1111151378Snetchild
1112151378Snetchild    if (itr.code() == Bytecodes::_ret) {
1113151378Snetchild      assert(!fall_through, "cannot be set if ret instruction");
1114151378Snetchild      // Automatically handles 'wide' ret indicies
1115151378Snetchild      ret_jump_targets_do(&itr, GenerateOopMap::merge_state, itr.get_index(), NULL);
1116151378Snetchild    } else if (fall_through) {
1117151378Snetchild     // Hit end of BB, but the instr. was a fall-through instruction,
1118151378Snetchild     // so perform transition as if the BB ended in a "jump".
1119151378Snetchild     if (lim_bci != bb[1]._bci) {
1120151378Snetchild       verify_error("bytecodes fell through last instruction");
1121151378Snetchild       return;
1122151378Snetchild     }
1123151378Snetchild     merge_state_into_bb(bb + 1);
1124151378Snetchild    }
1125151378Snetchild  }
1126151378Snetchild}
1127151378Snetchild
1128151378Snetchildvoid GenerateOopMap::do_exception_edge(BytecodeStream* itr) {
1129151378Snetchild  // Only check exception edge, if bytecode can trap
1130151378Snetchild  if (!Bytecodes::can_trap(itr->code())) return;
1131151378Snetchild  switch (itr->code()) {
1132151378Snetchild    case Bytecodes::_aload_0:
1133151378Snetchild      // These bytecodes can trap for rewriting.  We need to assume that
1134151378Snetchild      // they do not throw exceptions to make the monitor analysis work.
1135151378Snetchild      return;
1136151378Snetchild
1137151378Snetchild    case Bytecodes::_ireturn:
1138151378Snetchild    case Bytecodes::_lreturn:
1139151378Snetchild    case Bytecodes::_freturn:
1140151378Snetchild    case Bytecodes::_dreturn:
1141151378Snetchild    case Bytecodes::_areturn:
1142151378Snetchild    case Bytecodes::_return:
1143151378Snetchild      // If the monitor stack height is not zero when we leave the method,
1144151378Snetchild      // then we are either exiting with a non-empty stack or we have
1145151378Snetchild      // found monitor trouble earlier in our analysis.  In either case,
1146151378Snetchild      // assume an exception could be taken here.
1147151378Snetchild      if (_monitor_top == 0) {
1148151378Snetchild        return;
1149151378Snetchild      }
1150151378Snetchild      break;
1151151378Snetchild
1152151378Snetchild    case Bytecodes::_monitorexit:
1153151378Snetchild      // If the monitor stack height is bad_monitors, then we have detected a
1154151378Snetchild      // monitor matching problem earlier in the analysis.  If the
1155151378Snetchild      // monitor stack height is 0, we are about to pop a monitor
1156151378Snetchild      // off of an empty stack.  In either case, the bytecode
1157151378Snetchild      // could throw an exception.
1158151378Snetchild      if (_monitor_top != bad_monitors && _monitor_top != 0) {
1159151378Snetchild        return;
1160151378Snetchild      }
1161151378Snetchild      break;
1162151378Snetchild  }
1163151378Snetchild
1164151378Snetchild  if (_has_exceptions) {
1165151378Snetchild    int bci = itr->bci();
1166151378Snetchild    typeArrayOop exct  = method()->exception_table();
1167151378Snetchild    for(int i = 0; i< exct->length(); i+=4) {
1168151378Snetchild      int start_pc   = exct->int_at(i);
1169151378Snetchild      int end_pc     = exct->int_at(i+1);
1170151378Snetchild      int handler_pc = exct->int_at(i+2);
1171151378Snetchild      int catch_type = exct->int_at(i+3);
1172151378Snetchild
1173151378Snetchild      if (start_pc <= bci && bci < end_pc) {
1174151378Snetchild        BasicBlock *excBB = get_basic_block_at(handler_pc);
1175151378Snetchild        CellTypeState *excStk = excBB->stack();
1176151378Snetchild        CellTypeState *cOpStck = stack();
1177151378Snetchild        CellTypeState cOpStck_0 = cOpStck[0];
1178151378Snetchild        int cOpStackTop = _stack_top;
1179151378Snetchild
1180151378Snetchild        // Exception stacks are always the same.
1181151378Snetchild        assert(method()->max_stack() > 0, "sanity check");
1182151378Snetchild
1183151378Snetchild        // We remembered the size and first element of "cOpStck"
1184151378Snetchild        // above; now we temporarily set them to the appropriate
1185151378Snetchild        // values for an exception handler. */
1186151378Snetchild        cOpStck[0] = CellTypeState::make_slot_ref(_max_locals);
1187151378Snetchild        _stack_top = 1;
1188151378Snetchild
1189151378Snetchild        merge_state_into_bb(excBB);
1190151378Snetchild
1191151378Snetchild        // Now undo the temporary change.
1192151378Snetchild        cOpStck[0] = cOpStck_0;
1193151378Snetchild        _stack_top = cOpStackTop;
1194151378Snetchild
1195151378Snetchild        // If this is a "catch all" handler, then we do not need to
1196151378Snetchild        // consider any additional handlers.
1197151378Snetchild        if (catch_type == 0) {
1198151378Snetchild          return;
1199151378Snetchild        }
1200151378Snetchild      }
1201151378Snetchild    }
1202151378Snetchild  }
1203151378Snetchild
1204151378Snetchild  // It is possible that none of the exception handlers would have caught
1205151378Snetchild  // the exception.  In this case, we will exit the method.  We must
1206151378Snetchild  // ensure that the monitor stack is empty in this case.
1207151378Snetchild  if (_monitor_top == 0) {
1208151378Snetchild    return;
1209151378Snetchild  }
1210151378Snetchild
1211151378Snetchild  // We pessimistically assume that this exception can escape the
1212151378Snetchild  // method. (It is possible that it will always be caught, but
1213151378Snetchild  // we don't care to analyse the types of the catch clauses.)
1214151378Snetchild
1215151378Snetchild  // We don't set _monitor_top to bad_monitors because there are no successors
1216151378Snetchild  // to this exceptional exit.
1217151378Snetchild
1218151378Snetchild  if (TraceMonitorMismatch && _monitor_safe) {
1219151378Snetchild    // We check _monitor_safe so that we only report the first mismatched
1220151378Snetchild    // exceptional exit.
1221151378Snetchild    report_monitor_mismatch("non-empty monitor stack at exceptional exit");
1222151378Snetchild  }
1223151378Snetchild  _monitor_safe = false;
1224151378Snetchild
1225151378Snetchild}
1226151378Snetchild
1227151378Snetchildvoid GenerateOopMap::report_monitor_mismatch(const char *msg) {
1228151378Snetchild#ifndef PRODUCT
1229151378Snetchild  tty->print("    Monitor mismatch in method ");
1230151378Snetchild  method()->print_short_name(tty);
1231151378Snetchild  tty->print_cr(": %s", msg);
1232151378Snetchild#endif
1233151378Snetchild}
1234151378Snetchild
1235151378Snetchildvoid GenerateOopMap::print_states(outputStream *os,
1236151378Snetchild                                  CellTypeState* vec, int num) {
1237151378Snetchild  for (int i = 0; i < num; i++) {
1238151378Snetchild    vec[i].print(tty);
1239151378Snetchild  }
1240151378Snetchild}
1241151378Snetchild
1242151378Snetchild// Print the state values at the current bytecode.
1243151378Snetchildvoid GenerateOopMap::print_current_state(outputStream   *os,
1244151378Snetchild                                         BytecodeStream *currentBC,
1245151378Snetchild                                         bool            detailed) {
1246151378Snetchild
1247151378Snetchild  if (detailed) {
1248151378Snetchild    os->print("     %4d vars     = ", currentBC->bci());
1249151378Snetchild    print_states(os, vars(), _max_locals);
1250151378Snetchild    os->print("    %s", Bytecodes::name(currentBC->code()));
1251151378Snetchild    switch(currentBC->code()) {
1252151378Snetchild      case Bytecodes::_invokevirtual:
1253151378Snetchild      case Bytecodes::_invokespecial:
1254151378Snetchild      case Bytecodes::_invokestatic:
1255151378Snetchild      case Bytecodes::_invokeinterface:
1256151378Snetchild        int idx = currentBC->get_index_big();
1257151378Snetchild        constantPoolOop cp    = method()->constants();
1258151378Snetchild        int nameAndTypeIdx    = cp->name_and_type_ref_index_at(idx);
1259151378Snetchild        int signatureIdx      = cp->signature_ref_index_at(nameAndTypeIdx);
1260151378Snetchild        symbolOop signature   = cp->symbol_at(signatureIdx);
1261151378Snetchild        os->print("%s", signature->as_C_string());
1262151378Snetchild    }
1263151378Snetchild    os->cr();
1264151378Snetchild    os->print("          stack    = ");
1265151378Snetchild    print_states(os, stack(), _stack_top);
1266151378Snetchild    os->cr();
1267151378Snetchild    if (_monitor_top != bad_monitors) {
1268151378Snetchild      os->print("          monitors = ");
1269151378Snetchild      print_states(os, monitors(), _monitor_top);
1270151378Snetchild    } else {
1271151378Snetchild      os->print("          [bad monitor stack]");
1272151378Snetchild    }
1273151378Snetchild    os->cr();
1274151378Snetchild  } else {
1275151378Snetchild    os->print("    %4d  vars = '%s' ", currentBC->bci(),  state_vec_to_string(vars(), _max_locals));
1276151378Snetchild    os->print("     stack = '%s' ", state_vec_to_string(stack(), _stack_top));
1277151378Snetchild    if (_monitor_top != bad_monitors) {
1278151378Snetchild      os->print("  monitors = '%s'  \t%s", state_vec_to_string(monitors(), _monitor_top), Bytecodes::name(currentBC->code()));
1279151378Snetchild    } else {
1280151378Snetchild      os->print("  [bad monitor stack]");
1281151378Snetchild    }
1282151378Snetchild    switch(currentBC->code()) {
1283151378Snetchild      case Bytecodes::_invokevirtual:
1284151378Snetchild      case Bytecodes::_invokespecial:
1285151378Snetchild      case Bytecodes::_invokestatic:
1286151378Snetchild      case Bytecodes::_invokeinterface:
1287151378Snetchild        int idx = currentBC->get_index_big();
1288151378Snetchild        constantPoolOop cp    = method()->constants();
1289151378Snetchild        int nameAndTypeIdx    = cp->name_and_type_ref_index_at(idx);
1290151378Snetchild        int signatureIdx      = cp->signature_ref_index_at(nameAndTypeIdx);
1291151378Snetchild        symbolOop signature   = cp->symbol_at(signatureIdx);
1292151378Snetchild        os->print("%s", signature->as_C_string());
1293151378Snetchild    }
1294151378Snetchild    os->cr();
1295151378Snetchild  }
1296151378Snetchild}
1297151378Snetchild
1298151378Snetchild// Sets the current state to be the state after executing the
1299151378Snetchild// current instruction, starting in the current state.
1300151378Snetchildvoid GenerateOopMap::interp1(BytecodeStream *itr) {
1301151378Snetchild  if (TraceNewOopMapGeneration) {
1302151378Snetchild    print_current_state(tty, itr, TraceNewOopMapGenerationDetailed);
1303151378Snetchild  }
1304151378Snetchild
1305151378Snetchild  // Should we report the results? Result is reported *before* the instruction at the current bci is executed.
1306151378Snetchild  // However, not for calls. For calls we do not want to include the arguments, so we postpone the reporting until
1307151378Snetchild  // they have been popped (in method ppl).
1308151378Snetchild  if (_report_result == true) {
1309151378Snetchild    switch(itr->code()) {
1310151378Snetchild      case Bytecodes::_invokevirtual:
1311151378Snetchild      case Bytecodes::_invokespecial:
1312151378Snetchild      case Bytecodes::_invokestatic:
1313151378Snetchild      case Bytecodes::_invokeinterface:
1314151378Snetchild        _itr_send = itr;
1315151378Snetchild        _report_result_for_send = true;
1316151378Snetchild        break;
1317151378Snetchild      default:
1318151378Snetchild       fill_stackmap_for_opcodes(itr, vars(), stack(), _stack_top);
1319151378Snetchild       break;
1320151378Snetchild    }
1321151378Snetchild  }
1322151378Snetchild
1323151378Snetchild  // abstract interpretation of current opcode
1324151378Snetchild  switch(itr->code()) {
1325151378Snetchild    case Bytecodes::_nop:                                           break;
1326151378Snetchild    case Bytecodes::_goto:                                          break;
1327151378Snetchild    case Bytecodes::_goto_w:                                        break;
1328151378Snetchild    case Bytecodes::_iinc:                                          break;
1329151378Snetchild    case Bytecodes::_return:            do_return_monitor_check();
1330151378Snetchild                                        break;
1331151378Snetchild
1332151378Snetchild    case Bytecodes::_aconst_null:
1333151378Snetchild    case Bytecodes::_new:               ppush1(CellTypeState::make_line_ref(itr->bci()));
1334151378Snetchild                                        break;
1335151378Snetchild
1336151378Snetchild    case Bytecodes::_iconst_m1:
1337151378Snetchild    case Bytecodes::_iconst_0:
1338151378Snetchild    case Bytecodes::_iconst_1:
1339151378Snetchild    case Bytecodes::_iconst_2:
1340151378Snetchild    case Bytecodes::_iconst_3:
1341151378Snetchild    case Bytecodes::_iconst_4:
1342151378Snetchild    case Bytecodes::_iconst_5:
1343151378Snetchild    case Bytecodes::_fconst_0:
1344151378Snetchild    case Bytecodes::_fconst_1:
1345151378Snetchild    case Bytecodes::_fconst_2:
1346151378Snetchild    case Bytecodes::_bipush:
1347151378Snetchild    case Bytecodes::_sipush:            ppush1(valCTS);             break;
1348151378Snetchild
1349151378Snetchild    case Bytecodes::_lconst_0:
1350151378Snetchild    case Bytecodes::_lconst_1:
1351151378Snetchild    case Bytecodes::_dconst_0:
1352151378Snetchild    case Bytecodes::_dconst_1:          ppush(vvCTS);               break;
1353151378Snetchild
1354151378Snetchild    case Bytecodes::_ldc2_w:            ppush(vvCTS);               break;
1355151378Snetchild
1356151378Snetchild    case Bytecodes::_ldc:               do_ldc(itr->get_index(), itr->bci());    break;
1357151378Snetchild    case Bytecodes::_ldc_w:             do_ldc(itr->get_index_big(), itr->bci());break;
1358151378Snetchild
1359151378Snetchild    case Bytecodes::_iload:
1360151378Snetchild    case Bytecodes::_fload:             ppload(vCTS, itr->get_index()); break;
1361151378Snetchild
1362151378Snetchild    case Bytecodes::_lload:
1363151378Snetchild    case Bytecodes::_dload:             ppload(vvCTS,itr->get_index()); break;
1364151378Snetchild
1365151378Snetchild    case Bytecodes::_aload:             ppload(rCTS, itr->get_index()); break;
1366151378Snetchild
1367151378Snetchild    case Bytecodes::_iload_0:
1368151378Snetchild    case Bytecodes::_fload_0:           ppload(vCTS, 0);            break;
1369151378Snetchild    case Bytecodes::_iload_1:
1370151378Snetchild    case Bytecodes::_fload_1:           ppload(vCTS, 1);            break;
1371151378Snetchild    case Bytecodes::_iload_2:
1372151378Snetchild    case Bytecodes::_fload_2:           ppload(vCTS, 2);            break;
1373151378Snetchild    case Bytecodes::_iload_3:
1374151378Snetchild    case Bytecodes::_fload_3:           ppload(vCTS, 3);            break;
1375151378Snetchild
1376151378Snetchild    case Bytecodes::_lload_0:
1377151378Snetchild    case Bytecodes::_dload_0:           ppload(vvCTS, 0);           break;
1378151378Snetchild    case Bytecodes::_lload_1:
1379151378Snetchild    case Bytecodes::_dload_1:           ppload(vvCTS, 1);           break;
1380151378Snetchild    case Bytecodes::_lload_2:
1381151378Snetchild    case Bytecodes::_dload_2:           ppload(vvCTS, 2);           break;
1382151378Snetchild    case Bytecodes::_lload_3:
1383151378Snetchild    case Bytecodes::_dload_3:           ppload(vvCTS, 3);           break;
1384151378Snetchild
1385151378Snetchild    case Bytecodes::_aload_0:           ppload(rCTS, 0);            break;
1386151378Snetchild    case Bytecodes::_aload_1:           ppload(rCTS, 1);            break;
1387151378Snetchild    case Bytecodes::_aload_2:           ppload(rCTS, 2);            break;
1388151378Snetchild    case Bytecodes::_aload_3:           ppload(rCTS, 3);            break;
1389151378Snetchild
1390151378Snetchild    case Bytecodes::_iaload:
1391151378Snetchild    case Bytecodes::_faload:
1392151378Snetchild    case Bytecodes::_baload:
1393151378Snetchild    case Bytecodes::_caload:
1394151378Snetchild    case Bytecodes::_saload:            pp(vrCTS, vCTS); break;
1395151378Snetchild
1396151378Snetchild    case Bytecodes::_laload:            pp(vrCTS, vvCTS);  break;
1397151378Snetchild    case Bytecodes::_daload:            pp(vrCTS, vvCTS); break;
1398151378Snetchild
1399151378Snetchild    case Bytecodes::_aaload:            pp_new_ref(vrCTS, itr->bci()); break;
1400151378Snetchild
1401151378Snetchild    case Bytecodes::_istore:
1402151378Snetchild    case Bytecodes::_fstore:            ppstore(vCTS, itr->get_index()); break;
1403151378Snetchild
1404151378Snetchild    case Bytecodes::_lstore:
1405151378Snetchild    case Bytecodes::_dstore:            ppstore(vvCTS, itr->get_index()); break;
1406151378Snetchild
1407151378Snetchild    case Bytecodes::_astore:            do_astore(itr->get_index());     break;
1408151378Snetchild
1409151378Snetchild    case Bytecodes::_istore_0:
1410151378Snetchild    case Bytecodes::_fstore_0:          ppstore(vCTS, 0);           break;
1411151378Snetchild    case Bytecodes::_istore_1:
1412151378Snetchild    case Bytecodes::_fstore_1:          ppstore(vCTS, 1);           break;
1413151378Snetchild    case Bytecodes::_istore_2:
1414151378Snetchild    case Bytecodes::_fstore_2:          ppstore(vCTS, 2);           break;
1415151378Snetchild    case Bytecodes::_istore_3:
1416151378Snetchild    case Bytecodes::_fstore_3:          ppstore(vCTS, 3);           break;
1417151378Snetchild
1418151378Snetchild    case Bytecodes::_lstore_0:
1419151378Snetchild    case Bytecodes::_dstore_0:          ppstore(vvCTS, 0);          break;
1420151378Snetchild    case Bytecodes::_lstore_1:
1421151378Snetchild    case Bytecodes::_dstore_1:          ppstore(vvCTS, 1);          break;
1422151378Snetchild    case Bytecodes::_lstore_2:
1423151378Snetchild    case Bytecodes::_dstore_2:          ppstore(vvCTS, 2);          break;
1424151378Snetchild    case Bytecodes::_lstore_3:
1425151378Snetchild    case Bytecodes::_dstore_3:          ppstore(vvCTS, 3);          break;
1426151378Snetchild
1427151378Snetchild    case Bytecodes::_astore_0:          do_astore(0);               break;
1428151378Snetchild    case Bytecodes::_astore_1:          do_astore(1);               break;
1429151378Snetchild    case Bytecodes::_astore_2:          do_astore(2);               break;
1430151378Snetchild    case Bytecodes::_astore_3:          do_astore(3);               break;
1431151378Snetchild
1432151378Snetchild    case Bytecodes::_iastore:
1433151378Snetchild    case Bytecodes::_fastore:
1434151378Snetchild    case Bytecodes::_bastore:
1435151378Snetchild    case Bytecodes::_castore:
1436151378Snetchild    case Bytecodes::_sastore:           ppop(vvrCTS);               break;
1437151378Snetchild    case Bytecodes::_lastore:
1438151378Snetchild    case Bytecodes::_dastore:           ppop(vvvrCTS);              break;
1439151378Snetchild    case Bytecodes::_aastore:           ppop(rvrCTS);               break;
1440151378Snetchild
1441151378Snetchild    case Bytecodes::_pop:               ppop_any(1);                break;
1442151378Snetchild    case Bytecodes::_pop2:              ppop_any(2);                break;
1443151378Snetchild
1444151378Snetchild    case Bytecodes::_dup:               ppdupswap(1, "11");         break;
1445151378Snetchild    case Bytecodes::_dup_x1:            ppdupswap(2, "121");        break;
1446151378Snetchild    case Bytecodes::_dup_x2:            ppdupswap(3, "1321");       break;
1447151378Snetchild    case Bytecodes::_dup2:              ppdupswap(2, "2121");       break;
1448151378Snetchild    case Bytecodes::_dup2_x1:           ppdupswap(3, "21321");      break;
1449151378Snetchild    case Bytecodes::_dup2_x2:           ppdupswap(4, "214321");     break;
1450151378Snetchild    case Bytecodes::_swap:              ppdupswap(2, "12");         break;
1451151378Snetchild
1452151378Snetchild    case Bytecodes::_iadd:
1453151378Snetchild    case Bytecodes::_fadd:
1454151378Snetchild    case Bytecodes::_isub:
1455151378Snetchild    case Bytecodes::_fsub:
1456151378Snetchild    case Bytecodes::_imul:
1457151378Snetchild    case Bytecodes::_fmul:
1458151378Snetchild    case Bytecodes::_idiv:
1459151378Snetchild    case Bytecodes::_fdiv:
1460151378Snetchild    case Bytecodes::_irem:
1461151378Snetchild    case Bytecodes::_frem:
1462151378Snetchild    case Bytecodes::_ishl:
1463151378Snetchild    case Bytecodes::_ishr:
1464151378Snetchild    case Bytecodes::_iushr:
1465151378Snetchild    case Bytecodes::_iand:
1466151378Snetchild    case Bytecodes::_ior:
1467151378Snetchild    case Bytecodes::_ixor:
1468151378Snetchild    case Bytecodes::_l2f:
1469151378Snetchild    case Bytecodes::_l2i:
1470151378Snetchild    case Bytecodes::_d2f:
1471151378Snetchild    case Bytecodes::_d2i:
1472151378Snetchild    case Bytecodes::_fcmpl:
1473151378Snetchild    case Bytecodes::_fcmpg:             pp(vvCTS, vCTS); break;
1474151378Snetchild
1475151378Snetchild    case Bytecodes::_ladd:
1476151378Snetchild    case Bytecodes::_dadd:
1477151378Snetchild    case Bytecodes::_lsub:
1478151378Snetchild    case Bytecodes::_dsub:
1479151378Snetchild    case Bytecodes::_lmul:
1480151378Snetchild    case Bytecodes::_dmul:
1481151378Snetchild    case Bytecodes::_ldiv:
1482151378Snetchild    case Bytecodes::_ddiv:
1483151378Snetchild    case Bytecodes::_lrem:
1484151378Snetchild    case Bytecodes::_drem:
1485151378Snetchild    case Bytecodes::_land:
1486151378Snetchild    case Bytecodes::_lor:
1487151378Snetchild    case Bytecodes::_lxor:              pp(vvvvCTS, vvCTS); break;
1488151378Snetchild
1489151378Snetchild    case Bytecodes::_ineg:
1490151378Snetchild    case Bytecodes::_fneg:
1491151378Snetchild    case Bytecodes::_i2f:
1492151378Snetchild    case Bytecodes::_f2i:
1493151378Snetchild    case Bytecodes::_i2c:
1494151378Snetchild    case Bytecodes::_i2s:
1495151378Snetchild    case Bytecodes::_i2b:               pp(vCTS, vCTS); break;
1496151378Snetchild
1497151378Snetchild    case Bytecodes::_lneg:
1498151378Snetchild    case Bytecodes::_dneg:
1499151378Snetchild    case Bytecodes::_l2d:
1500151378Snetchild    case Bytecodes::_d2l:               pp(vvCTS, vvCTS); break;
1501151378Snetchild
1502151378Snetchild    case Bytecodes::_lshl:
1503151378Snetchild    case Bytecodes::_lshr:
1504151378Snetchild    case Bytecodes::_lushr:             pp(vvvCTS, vvCTS); break;
1505151378Snetchild
1506151378Snetchild    case Bytecodes::_i2l:
1507151378Snetchild    case Bytecodes::_i2d:
1508151378Snetchild    case Bytecodes::_f2l:
1509151378Snetchild    case Bytecodes::_f2d:               pp(vCTS, vvCTS); break;
1510151378Snetchild
1511151378Snetchild    case Bytecodes::_lcmp:              pp(vvvvCTS, vCTS); break;
1512151378Snetchild    case Bytecodes::_dcmpl:
1513151378Snetchild    case Bytecodes::_dcmpg:             pp(vvvvCTS, vCTS); break;
1514151378Snetchild
1515151378Snetchild    case Bytecodes::_ifeq:
1516151378Snetchild    case Bytecodes::_ifne:
1517151378Snetchild    case Bytecodes::_iflt:
1518151378Snetchild    case Bytecodes::_ifge:
1519151378Snetchild    case Bytecodes::_ifgt:
1520151378Snetchild    case Bytecodes::_ifle:
1521151378Snetchild    case Bytecodes::_tableswitch:       ppop1(valCTS);
1522151378Snetchild                                        break;
1523151378Snetchild    case Bytecodes::_ireturn:
1524151378Snetchild    case Bytecodes::_freturn:           do_return_monitor_check();
1525151378Snetchild                                        ppop1(valCTS);
1526151378Snetchild                                        break;
1527151378Snetchild    case Bytecodes::_if_icmpeq:
1528151378Snetchild    case Bytecodes::_if_icmpne:
1529151378Snetchild    case Bytecodes::_if_icmplt:
1530151378Snetchild    case Bytecodes::_if_icmpge:
1531151378Snetchild    case Bytecodes::_if_icmpgt:
1532151378Snetchild    case Bytecodes::_if_icmple:         ppop(vvCTS);
1533151378Snetchild                                        break;
1534151378Snetchild
1535151378Snetchild    case Bytecodes::_lreturn:           do_return_monitor_check();
1536151378Snetchild                                        ppop(vvCTS);
1537151378Snetchild                                        break;
1538151378Snetchild
1539151378Snetchild    case Bytecodes::_dreturn:           do_return_monitor_check();
1540151378Snetchild                                        ppop(vvCTS);
1541151378Snetchild                                        break;
1542151378Snetchild
1543151378Snetchild    case Bytecodes::_if_acmpeq:
1544151378Snetchild    case Bytecodes::_if_acmpne:         ppop(rrCTS);                 break;
1545151378Snetchild
1546151378Snetchild    case Bytecodes::_jsr:               do_jsr(itr->dest());         break;
1547151378Snetchild    case Bytecodes::_jsr_w:             do_jsr(itr->dest_w());       break;
1548151378Snetchild
1549151378Snetchild    case Bytecodes::_getstatic:         do_field(true,  true,
1550151378Snetchild                                                 itr->get_index_big(),
1551151378Snetchild                                                 itr->bci()); break;
1552151378Snetchild    case Bytecodes::_putstatic:         do_field(false, true,  itr->get_index_big(), itr->bci()); break;
1553151378Snetchild    case Bytecodes::_getfield:          do_field(true,  false, itr->get_index_big(), itr->bci()); break;
1554151378Snetchild    case Bytecodes::_putfield:          do_field(false, false, itr->get_index_big(), itr->bci()); break;
1555151378Snetchild
1556151378Snetchild    case Bytecodes::_invokevirtual:
1557151378Snetchild    case Bytecodes::_invokespecial:     do_method(false, false, itr->get_index_big(), itr->bci()); break;
1558151378Snetchild    case Bytecodes::_invokestatic:      do_method(true,  false, itr->get_index_big(), itr->bci()); break;
1559151378Snetchild    case Bytecodes::_invokeinterface:   do_method(false, true,  itr->get_index_big(), itr->bci()); break;
1560151378Snetchild    case Bytecodes::_newarray:
1561151378Snetchild    case Bytecodes::_anewarray:         pp_new_ref(vCTS, itr->bci()); break;
1562151378Snetchild    case Bytecodes::_checkcast:         do_checkcast(); break;
1563151378Snetchild    case Bytecodes::_arraylength:
1564151378Snetchild    case Bytecodes::_instanceof:        pp(rCTS, vCTS); break;
1565151378Snetchild    case Bytecodes::_monitorenter:      do_monitorenter(itr->bci()); break;
1566151378Snetchild    case Bytecodes::_monitorexit:       do_monitorexit(itr->bci()); break;
1567151378Snetchild
1568151378Snetchild    case Bytecodes::_athrow:            // handled by do_exception_edge() BUT ...
1569151378Snetchild                                        // vlh(apple): do_exception_edge() does not get
1570151378Snetchild                                        // called if method has no exception handlers
1571151378Snetchild                                        if ((!_has_exceptions) && (_monitor_top > 0)) {
1572151378Snetchild                                          _monitor_safe = false;
1573151378Snetchild                                        }
1574151378Snetchild                                        break;
1575151378Snetchild
1576151378Snetchild    case Bytecodes::_areturn:           do_return_monitor_check();
1577151378Snetchild                                        ppop1(refCTS);
1578151378Snetchild                                        break;
1579151378Snetchild    case Bytecodes::_ifnull:
1580151378Snetchild    case Bytecodes::_ifnonnull:         ppop1(refCTS); break;
1581151378Snetchild    case Bytecodes::_multianewarray:    do_multianewarray(*(itr->bcp()+3), itr->bci()); break;
1582151378Snetchild
1583151378Snetchild    case Bytecodes::_wide:              fatal("Iterator should skip this bytecode"); break;
1584151378Snetchild    case Bytecodes::_ret:                                           break;
1585151378Snetchild
1586151378Snetchild    // Java opcodes
1587151378Snetchild    case Bytecodes::_lookupswitch:      ppop1(valCTS);             break;
1588151378Snetchild
1589151378Snetchild    default:
1590151378Snetchild         tty->print("unexpected opcode: %d\n", itr->code());
1591151378Snetchild         ShouldNotReachHere();
1592151378Snetchild    break;
1593151378Snetchild  }
1594151378Snetchild}
1595151378Snetchild
1596151378Snetchildvoid GenerateOopMap::check_type(CellTypeState expected, CellTypeState actual) {
1597151378Snetchild  if (!expected.equal_kind(actual)) {
1598151378Snetchild    verify_error("wrong type on stack (found: %c expected: %c)", actual.to_char(), expected.to_char());
1599151378Snetchild  }
1600151378Snetchild}
1601151378Snetchild
1602151378Snetchildvoid GenerateOopMap::ppstore(CellTypeState *in, int loc_no) {
1603151378Snetchild  while(!(*in).is_bottom()) {
1604151378Snetchild    CellTypeState expected =*in++;
1605151378Snetchild    CellTypeState actual   = pop();
1606151378Snetchild    check_type(expected, actual);
1607151378Snetchild    assert(loc_no >= 0, "sanity check");
1608151378Snetchild    set_var(loc_no++, actual);
1609151378Snetchild  }
1610151378Snetchild}
1611151378Snetchild
1612151378Snetchildvoid GenerateOopMap::ppload(CellTypeState *out, int loc_no) {
1613151378Snetchild  while(!(*out).is_bottom()) {
1614151378Snetchild    CellTypeState out1 = *out++;
1615151378Snetchild    CellTypeState vcts = get_var(loc_no);
1616151378Snetchild    assert(out1.can_be_reference() || out1.can_be_value(),
1617151378Snetchild           "can only load refs. and values.");
1618151378Snetchild    if (out1.is_reference()) {
1619151378Snetchild      assert(loc_no>=0, "sanity check");
1620151378Snetchild      if (!vcts.is_reference()) {
1621151378Snetchild        // We were asked to push a reference, but the type of the
1622151378Snetchild        // variable can be something else
1623151378Snetchild        _conflict = true;
1624151378Snetchild        if (vcts.can_be_uninit()) {
1625151378Snetchild          // It is a ref-uninit conflict (at least). If there are other
1626151378Snetchild          // problems, we'll get them in the next round
1627151378Snetchild          add_to_ref_init_set(loc_no);
1628151378Snetchild          vcts = out1;
1629151378Snetchild        } else {
1630151378Snetchild          // It wasn't a ref-uninit conflict. So must be a
1631151378Snetchild          // ref-val or ref-pc conflict. Split the variable.
1632151378Snetchild          record_refval_conflict(loc_no);
1633151378Snetchild          vcts = out1;
1634151378Snetchild        }
1635151378Snetchild        push(out1); // recover...
1636151378Snetchild      } else {
1637151378Snetchild        push(vcts); // preserve reference.
1638151378Snetchild      }
1639151378Snetchild      // Otherwise it is a conflict, but one that verification would
1640151378Snetchild      // have caught if illegal. In particular, it can't be a topCTS
1641151378Snetchild      // resulting from mergeing two difference pcCTS's since the verifier
1642151378Snetchild      // would have rejected any use of such a merge.
1643151378Snetchild    } else {
1644151378Snetchild      push(out1); // handle val/init conflict
1645151378Snetchild    }
1646151378Snetchild    loc_no++;
1647151378Snetchild  }
1648151378Snetchild}
1649151378Snetchild
1650151378Snetchildvoid GenerateOopMap::ppdupswap(int poplen, const char *out) {
1651151378Snetchild  CellTypeState actual[5];
1652151378Snetchild  assert(poplen < 5, "this must be less than length of actual vector");
1653151378Snetchild
1654151378Snetchild  // pop all arguments
1655151378Snetchild  for(int i = 0; i < poplen; i++) actual[i] = pop();
1656151378Snetchild
1657151378Snetchild  // put them back
1658151378Snetchild  char push_ch = *out++;
1659151378Snetchild  while (push_ch != '\0') {
1660151378Snetchild    int idx = push_ch - '1';
1661151378Snetchild    assert(idx >= 0 && idx < poplen, "wrong arguments");
1662151378Snetchild    push(actual[idx]);
1663151378Snetchild    push_ch = *out++;
1664151378Snetchild  }
1665151378Snetchild}
1666151378Snetchild
1667151378Snetchildvoid GenerateOopMap::ppop1(CellTypeState out) {
1668151378Snetchild  CellTypeState actual = pop();
1669151378Snetchild  check_type(out, actual);
1670151378Snetchild}
1671151378Snetchild
1672151378Snetchildvoid GenerateOopMap::ppop(CellTypeState *out) {
1673151378Snetchild  while (!(*out).is_bottom()) {
1674151378Snetchild    ppop1(*out++);
1675151378Snetchild  }
1676151378Snetchild}
1677151378Snetchild
1678151378Snetchildvoid GenerateOopMap::ppush1(CellTypeState in) {
1679151378Snetchild  assert(in.is_reference() | in.is_value(), "sanity check");
1680151378Snetchild  push(in);
1681151378Snetchild}
1682151378Snetchild
1683151378Snetchildvoid GenerateOopMap::ppush(CellTypeState *in) {
1684151378Snetchild  while (!(*in).is_bottom()) {
1685151378Snetchild    ppush1(*in++);
1686151378Snetchild  }
1687151378Snetchild}
1688151378Snetchild
1689151378Snetchildvoid GenerateOopMap::pp(CellTypeState *in, CellTypeState *out) {
1690151378Snetchild  ppop(in);
1691151378Snetchild  ppush(out);
1692151378Snetchild}
1693151378Snetchild
1694151378Snetchildvoid GenerateOopMap::pp_new_ref(CellTypeState *in, int bci) {
1695151378Snetchild  ppop(in);
1696151378Snetchild  ppush1(CellTypeState::make_line_ref(bci));
1697151378Snetchild}
1698151378Snetchild
1699151378Snetchildvoid GenerateOopMap::ppop_any(int poplen) {
1700151378Snetchild  if (_stack_top >= poplen) {
1701151378Snetchild    _stack_top -= poplen;
1702151378Snetchild  } else {
1703151378Snetchild    verify_error("stack underflow");
1704151378Snetchild  }
1705151378Snetchild}
1706151378Snetchild
1707151378Snetchild// Replace all occurences of the state 'match' with the state 'replace'
1708151378Snetchild// in our current state vector.
1709151378Snetchildvoid GenerateOopMap::replace_all_CTS_matches(CellTypeState match,
1710151378Snetchild                                             CellTypeState replace) {
1711151378Snetchild  int i;
1712151378Snetchild  int len = _max_locals + _stack_top;
1713151378Snetchild  bool change = false;
1714151378Snetchild
1715151378Snetchild  for (i = len - 1; i >= 0; i--) {
1716151378Snetchild    if (match.equal(_state[i])) {
1717151378Snetchild      _state[i] = replace;
1718151378Snetchild    }
1719151378Snetchild  }
1720151378Snetchild
1721151378Snetchild  if (_monitor_top > 0) {
1722151378Snetchild    int base = _max_locals + _max_stack;
1723151378Snetchild    len = base + _monitor_top;
1724151378Snetchild    for (i = len - 1; i >= base; i--) {
1725151378Snetchild      if (match.equal(_state[i])) {
1726151378Snetchild        _state[i] = replace;
1727151378Snetchild      }
1728151378Snetchild    }
1729151378Snetchild  }
1730151378Snetchild}
1731151378Snetchild
1732151378Snetchildvoid GenerateOopMap::do_checkcast() {
1733151378Snetchild  CellTypeState actual = pop();
1734151378Snetchild  check_type(refCTS, actual);
1735151378Snetchild  push(actual);
1736151378Snetchild}
1737151378Snetchild
1738151378Snetchildvoid GenerateOopMap::do_monitorenter(int bci) {
1739151378Snetchild  CellTypeState actual = pop();
1740151378Snetchild  if (_monitor_top == bad_monitors) {
1741151378Snetchild    return;
1742151378Snetchild  }
1743151378Snetchild
1744151378Snetchild  // Bail out when we get repeated locks on an identical monitor.  This case
1745151378Snetchild  // isn't too hard to handle and can be made to work if supporting nested
1746151378Snetchild  // redundant synchronized statements becomes a priority.
1747151378Snetchild  //
1748151378Snetchild  // See also "Note" in do_monitorexit(), below.
1749151378Snetchild  if (actual.is_lock_reference()) {
1750151378Snetchild    _monitor_top = bad_monitors;
1751151378Snetchild    _monitor_safe = false;
1752151378Snetchild
1753151378Snetchild    if (TraceMonitorMismatch) {
1754151378Snetchild      report_monitor_mismatch("nested redundant lock -- bailout...");
1755151378Snetchild    }
1756151378Snetchild    return;
1757151378Snetchild  }
1758151378Snetchild
1759151378Snetchild  CellTypeState lock = CellTypeState::make_lock_ref(bci);
1760151378Snetchild  check_type(refCTS, actual);
1761151378Snetchild  if (!actual.is_info_top()) {
1762151378Snetchild    replace_all_CTS_matches(actual, lock);
1763151378Snetchild    monitor_push(lock);
1764151378Snetchild  }
1765151378Snetchild}
1766151378Snetchild
1767151378Snetchildvoid GenerateOopMap::do_monitorexit(int bci) {
1768151378Snetchild  CellTypeState actual = pop();
1769151378Snetchild  if (_monitor_top == bad_monitors) {
1770151378Snetchild    return;
1771151378Snetchild  }
1772151378Snetchild  check_type(refCTS, actual);
1773151378Snetchild  CellTypeState expected = monitor_pop();
1774151378Snetchild  if (!actual.is_lock_reference() || !expected.equal(actual)) {
1775151378Snetchild    // The monitor we are exiting is not verifiably the one
1776151378Snetchild    // on the top of our monitor stack.  This causes a monitor
1777151378Snetchild    // mismatch.
1778151378Snetchild    _monitor_top = bad_monitors;
1779151378Snetchild    _monitor_safe = false;
1780151378Snetchild
1781151378Snetchild    // We need to mark this basic block as changed so that
1782151378Snetchild    // this monitorexit will be visited again.  We need to
1783151378Snetchild    // do this to ensure that we have accounted for the
1784151378Snetchild    // possibility that this bytecode will throw an
1785151378Snetchild    // exception.
1786151378Snetchild    BasicBlock* bb = get_basic_block_containing(bci);
1787151378Snetchild    bb->set_changed(true);
1788151378Snetchild    bb->_monitor_top = bad_monitors;
1789151378Snetchild
1790151378Snetchild    if (TraceMonitorMismatch) {
1791151378Snetchild      report_monitor_mismatch("improper monitor pair");
1792151378Snetchild    }
1793151378Snetchild  } else {
1794151378Snetchild    // This code is a fix for the case where we have repeated
1795151378Snetchild    // locking of the same object in straightline code.  We clear
1796151378Snetchild    // out the lock when it is popped from the monitor stack
1797151378Snetchild    // and replace it with an unobtrusive reference value that can
1798151378Snetchild    // be locked again.
1799151378Snetchild    //
1800151378Snetchild    // Note: when generateOopMap is fixed to properly handle repeated,
1801151378Snetchild    //       nested, redundant locks on the same object, then this
1802151378Snetchild    //       fix will need to be removed at that time.
1803151378Snetchild    replace_all_CTS_matches(actual, CellTypeState::make_line_ref(bci));
1804151378Snetchild  }
1805151378Snetchild}
1806151378Snetchild
1807151378Snetchildvoid GenerateOopMap::do_return_monitor_check() {
1808151378Snetchild  if (_monitor_top > 0) {
1809151378Snetchild    // The monitor stack must be empty when we leave the method
1810151378Snetchild    // for the monitors to be properly matched.
1811151378Snetchild    _monitor_safe = false;
1812151378Snetchild
1813151378Snetchild    // Since there are no successors to the *return bytecode, it
1814151378Snetchild    // isn't necessary to set _monitor_top to bad_monitors.
1815151378Snetchild
1816151378Snetchild    if (TraceMonitorMismatch) {
1817151378Snetchild      report_monitor_mismatch("non-empty monitor stack at return");
1818151378Snetchild    }
1819151378Snetchild  }
1820151378Snetchild}
1821151378Snetchild
1822151378Snetchildvoid GenerateOopMap::do_jsr(int targ_bci) {
1823151378Snetchild  push(CellTypeState::make_addr(targ_bci));
1824151378Snetchild}
1825151378Snetchild
1826151378Snetchild
1827151378Snetchild
1828151378Snetchildvoid GenerateOopMap::do_ldc(int idx, int bci) {
1829151378Snetchild  constantPoolOop cp = method()->constants();
1830151378Snetchild  constantTag tag    = cp->tag_at(idx);
1831151378Snetchild
1832151378Snetchild  CellTypeState cts = (tag.is_string() || tag.is_unresolved_string() ||
1833151378Snetchild                       tag.is_klass()  || tag.is_unresolved_klass())
1834151378Snetchild                    ? CellTypeState::make_line_ref(bci) : valCTS;
1835151378Snetchild  ppush1(cts);
1836151378Snetchild}
1837151378Snetchild
1838151378Snetchildvoid GenerateOopMap::do_multianewarray(int dims, int bci) {
1839151378Snetchild  assert(dims >= 1, "sanity check");
1840151378Snetchild  for(int i = dims -1; i >=0; i--) {
1841151378Snetchild    ppop1(valCTS);
1842151378Snetchild  }
1843151378Snetchild  ppush1(CellTypeState::make_line_ref(bci));
1844151378Snetchild}
1845151378Snetchild
1846151378Snetchildvoid GenerateOopMap::do_astore(int idx) {
1847151378Snetchild  CellTypeState r_or_p = pop();
1848151378Snetchild  if (!r_or_p.is_address() && !r_or_p.is_reference()) {
1849151378Snetchild    // We actually expected ref or pc, but we only report that we expected a ref. It does not
1850151378Snetchild    // really matter (at least for now)
1851151378Snetchild    verify_error("wrong type on stack (found: %c, expected: {pr})", r_or_p.to_char());
1852151378Snetchild    return;
1853151378Snetchild  }
1854151378Snetchild  set_var(idx, r_or_p);
1855151378Snetchild}
1856151378Snetchild
1857151378Snetchild// Copies bottom/zero terminated CTS string from "src" into "dst".
1858151378Snetchild//   Does NOT terminate with a bottom. Returns the number of cells copied.
1859151378Snetchildint GenerateOopMap::copy_cts(CellTypeState *dst, CellTypeState *src) {
1860151378Snetchild  int idx = 0;
1861151378Snetchild  while (!src[idx].is_bottom()) {
1862151378Snetchild    dst[idx] = src[idx];
1863151378Snetchild    idx++;
1864151378Snetchild  }
1865151378Snetchild  return idx;
1866151378Snetchild}
1867151378Snetchild
1868151378Snetchildvoid GenerateOopMap::do_field(int is_get, int is_static, int idx, int bci) {
1869151378Snetchild  // Dig up signature for field in constant pool
1870151378Snetchild  constantPoolOop cp     = method()->constants();
1871151378Snetchild  int nameAndTypeIdx     = cp->name_and_type_ref_index_at(idx);
1872151378Snetchild  int signatureIdx       = cp->signature_ref_index_at(nameAndTypeIdx);
1873151378Snetchild  symbolOop signature    = cp->symbol_at(signatureIdx);
1874151378Snetchild
1875151378Snetchild  // Parse signature (espcially simple for fields)
1876151378Snetchild  assert(signature->utf8_length() > 0, "field signatures cannot have zero length");
1877151378Snetchild  // The signature is UFT8 encoded, but the first char is always ASCII for signatures.
1878151378Snetchild  char sigch = (char)*(signature->base());
1879151378Snetchild  CellTypeState temp[4];
1880151378Snetchild  CellTypeState *eff  = sigchar_to_effect(sigch, bci, temp);
1881151378Snetchild
1882151378Snetchild  CellTypeState in[4];
1883151378Snetchild  CellTypeState *out;
1884151378Snetchild  int i =  0;
1885151378Snetchild
1886151378Snetchild  if (is_get) {
1887151378Snetchild    out = eff;
1888151378Snetchild  } else {
1889151378Snetchild    out = epsilonCTS;
1890151378Snetchild    i   = copy_cts(in, eff);
1891151378Snetchild  }
1892151378Snetchild  if (!is_static) in[i++] = CellTypeState::ref;
1893151378Snetchild  in[i] = CellTypeState::bottom;
1894151378Snetchild  assert(i<=3, "sanity check");
1895151378Snetchild  pp(in, out);
1896151378Snetchild}
1897151378Snetchild
1898151378Snetchildvoid GenerateOopMap::do_method(int is_static, int is_interface, int idx, int bci) {
1899151378Snetchild  // Dig up signature for field in constant pool
1900151378Snetchild  constantPoolOop cp    = _method->constants();
1901151378Snetchild  int nameAndTypeIdx    = cp->name_and_type_ref_index_at(idx);
1902151378Snetchild  int signatureIdx      = cp->signature_ref_index_at(nameAndTypeIdx);
1903151378Snetchild  symbolOop signature   = cp->symbol_at(signatureIdx);
1904151378Snetchild
1905151378Snetchild  // Parse method signature
1906151378Snetchild  CellTypeState out[4];
1907151378Snetchild  CellTypeState in[MAXARGSIZE+1];   // Includes result
1908151378Snetchild  ComputeCallStack cse(signature);
1909151378Snetchild
1910151378Snetchild  // Compute return type
1911151378Snetchild  int res_length=  cse.compute_for_returntype(out);
1912151378Snetchild
1913151378Snetchild  // Temporary hack.
1914151378Snetchild  if (out[0].equal(CellTypeState::ref) && out[1].equal(CellTypeState::bottom)) {
1915151378Snetchild    out[0] = CellTypeState::make_line_ref(bci);
1916151378Snetchild  }
1917151378Snetchild
1918151378Snetchild  assert(res_length<=4, "max value should be vv");
1919151378Snetchild
1920151378Snetchild  // Compute arguments
1921151378Snetchild  int arg_length = cse.compute_for_parameters(is_static != 0, in);
1922151378Snetchild  assert(arg_length<=MAXARGSIZE, "too many locals");
1923151378Snetchild
1924151378Snetchild  // Pop arguments
1925151378Snetchild  for (int i = arg_length - 1; i >= 0; i--) ppop1(in[i]);// Do args in reverse order.
1926151378Snetchild
1927151378Snetchild  // Report results
1928151378Snetchild  if (_report_result_for_send == true) {
1929151378Snetchild     fill_stackmap_for_opcodes(_itr_send, vars(), stack(), _stack_top);
1930151378Snetchild     _report_result_for_send = false;
1931151378Snetchild  }
1932151378Snetchild
1933151378Snetchild  // Push return address
1934151378Snetchild  ppush(out);
1935151378Snetchild}
1936151378Snetchild
1937151378Snetchild// This is used to parse the signature for fields, since they are very simple...
1938151378SnetchildCellTypeState *GenerateOopMap::sigchar_to_effect(char sigch, int bci, CellTypeState *out) {
1939151378Snetchild  // Object and array
1940151378Snetchild  if (sigch=='L' || sigch=='[') {
1941151378Snetchild    out[0] = CellTypeState::make_line_ref(bci);
1942151378Snetchild    out[1] = CellTypeState::bottom;
1943151378Snetchild    return out;
1944151378Snetchild  }
1945151378Snetchild  if (sigch == 'J' || sigch == 'D' ) return vvCTS;  // Long and Double
1946151378Snetchild  if (sigch == 'V' ) return epsilonCTS;             // Void
1947151378Snetchild  return vCTS;                                      // Otherwise
1948151378Snetchild}
1949151378Snetchild
1950151378Snetchildlong GenerateOopMap::_total_byte_count = 0;
1951151378SnetchildelapsedTimer GenerateOopMap::_total_oopmap_time;
1952151378Snetchild
1953151378Snetchild// This function assumes "bcs" is at a "ret" instruction and that the vars
1954151378Snetchild// state is valid for that instruction. Furthermore, the ret instruction
1955151378Snetchild// must be the last instruction in "bb" (we store information about the
1956151378Snetchild// "ret" in "bb").
1957151378Snetchildvoid GenerateOopMap::ret_jump_targets_do(BytecodeStream *bcs, jmpFct_t jmpFct, int varNo, int *data) {
1958151378Snetchild  CellTypeState ra = vars()[varNo];
1959151378Snetchild  if (!ra.is_good_address()) {
1960151378Snetchild    verify_error("ret returns from two jsr subroutines?");
1961151378Snetchild    return;
1962151378Snetchild  }
1963151378Snetchild  int target = ra.get_info();
1964151378Snetchild
1965151378Snetchild  RetTableEntry* rtEnt = _rt.find_jsrs_for_target(target);
1966151378Snetchild  int bci = bcs->bci();
1967151378Snetchild  for (int i = 0; i < rtEnt->nof_jsrs(); i++) {
1968151378Snetchild    int target_bci = rtEnt->jsrs(i);
1969151378Snetchild    // Make sure a jrtRet does not set the changed bit for dead basicblock.
1970151378Snetchild    BasicBlock* jsr_bb    = get_basic_block_containing(target_bci - 1);
1971151378Snetchild    debug_only(BasicBlock* target_bb = &jsr_bb[1];)
1972151378Snetchild    assert(target_bb  == get_basic_block_at(target_bci), "wrong calc. of successor basicblock");
1973151378Snetchild    bool alive = jsr_bb->is_alive();
1974151378Snetchild    if (TraceNewOopMapGeneration) {
1975151378Snetchild      tty->print("pc = %d, ret -> %d alive: %s\n", bci, target_bci, alive ? "true" : "false");
1976151378Snetchild    }
1977151378Snetchild    if (alive) jmpFct(this, target_bci, data);
1978151378Snetchild  }
1979151378Snetchild}
1980151378Snetchild
1981151378Snetchild//
1982151378Snetchild// Debug method
1983151378Snetchild//
1984151378Snetchildchar* GenerateOopMap::state_vec_to_string(CellTypeState* vec, int len) {
1985151378Snetchild#ifdef ASSERT
1986151378Snetchild  int checklen = MAX3(_max_locals, _max_stack, _max_monitors) + 1;
1987151378Snetchild  assert(len < checklen, "state_vec_buf overflow");
1988151378Snetchild#endif
1989151378Snetchild  for (int i = 0; i < len; i++) _state_vec_buf[i] = vec[i].to_char();
1990151378Snetchild  _state_vec_buf[len] = 0;
1991151378Snetchild  return _state_vec_buf;
1992151378Snetchild}
1993151378Snetchild
1994151378Snetchildvoid GenerateOopMap::print_time() {
1995151378Snetchild  tty->print_cr ("Accumulated oopmap times:");
1996151378Snetchild  tty->print_cr ("---------------------------");
1997151378Snetchild  tty->print_cr ("  Total : %3.3f sec.", GenerateOopMap::_total_oopmap_time.seconds());
1998151378Snetchild  tty->print_cr ("  (%3.0f bytecodes per sec) ",
1999151378Snetchild  GenerateOopMap::_total_byte_count / GenerateOopMap::_total_oopmap_time.seconds());
2000151378Snetchild}
2001151378Snetchild
2002151378Snetchild//
2003151378Snetchild//  ============ Main Entry Point ===========
2004151378Snetchild//
2005151378SnetchildGenerateOopMap::GenerateOopMap(methodHandle method) {
2006151378Snetchild  // We have to initialize all variables here, that can be queried direcly
2007151378Snetchild  _method = method;
2008151378Snetchild  _max_locals=0;
2009151378Snetchild  _init_vars = NULL;
2010151378Snetchild
2011151378Snetchild#ifndef PRODUCT
2012151378Snetchild  // If we are doing a detailed trace, include the regular trace information.
2013151378Snetchild  if (TraceNewOopMapGenerationDetailed) {
2014151378Snetchild    TraceNewOopMapGeneration = true;
2015151378Snetchild  }
2016151378Snetchild#endif
2017151378Snetchild}
2018151378Snetchild
2019151378Snetchildvoid GenerateOopMap::compute_map(TRAPS) {
2020151378Snetchild#ifndef PRODUCT
2021151378Snetchild  if (TimeOopMap2) {
2022151378Snetchild    method()->print_short_name(tty);
2023151378Snetchild    tty->print("  ");
2024151378Snetchild  }
2025151378Snetchild  if (TimeOopMap) {
2026151378Snetchild    _total_byte_count += method()->code_size();
2027151378Snetchild  }
2028151378Snetchild#endif
2029151378Snetchild  TraceTime t_single("oopmap time", TimeOopMap2);
2030151378Snetchild  TraceTime t_all(NULL, &_total_oopmap_time, TimeOopMap);
2031151378Snetchild
2032151378Snetchild  // Initialize values
2033151378Snetchild  _got_error      = false;
2034151378Snetchild  _conflict       = false;
2035151378Snetchild  _max_locals     = method()->max_locals();
2036151378Snetchild  _max_stack      = method()->max_stack();
2037151378Snetchild  _has_exceptions = (method()->exception_table()->length() > 0);
2038151378Snetchild  _nof_refval_conflicts = 0;
2039151378Snetchild  _init_vars      = new GrowableArray<intptr_t>(5);  // There are seldom more than 5 init_vars
2040151378Snetchild  _report_result  = false;
2041151378Snetchild  _report_result_for_send = false;
2042151378Snetchild  _new_var_map    = NULL;
2043151378Snetchild  _ret_adr_tos    = new GrowableArray<intptr_t>(5);  // 5 seems like a good number;
2044151378Snetchild  _did_rewriting  = false;
2045151378Snetchild  _did_relocation = false;
2046151378Snetchild
2047151378Snetchild  if (TraceNewOopMapGeneration) {
2048151378Snetchild    tty->print("Method name: %s\n", method()->name()->as_C_string());
2049151378Snetchild    if (Verbose) {
2050151378Snetchild      _method->print_codes();
2051151378Snetchild      tty->print_cr("Exception table:");
2052151378Snetchild      typeArrayOop excps = method()->exception_table();
2053151378Snetchild      for(int i = 0; i < excps->length(); i += 4) {
2054151378Snetchild        tty->print_cr("[%d - %d] -> %d", excps->int_at(i + 0), excps->int_at(i + 1), excps->int_at(i + 2));
2055151378Snetchild      }
2056151378Snetchild    }
2057151378Snetchild  }
2058151378Snetchild
2059151378Snetchild  // if no code - do nothing
2060151378Snetchild  // compiler needs info
2061151378Snetchild  if (method()->code_size() == 0 || _max_locals + method()->max_stack() == 0) {
2062151378Snetchild    fill_stackmap_prolog(0);
2063151378Snetchild    fill_stackmap_epilog();
2064151378Snetchild    return;
2065151378Snetchild  }
2066151378Snetchild  // Step 1: Compute all jump targets and their return value
2067151378Snetchild  if (!_got_error)
2068151378Snetchild    _rt.compute_ret_table(_method);
2069151378Snetchild
2070151378Snetchild  // Step 2: Find all basic blocks and count GC points
2071151378Snetchild  if (!_got_error)
2072151378Snetchild    mark_bbheaders_and_count_gc_points();
2073151378Snetchild
2074151378Snetchild  // Step 3: Calculate stack maps
2075151378Snetchild  if (!_got_error)
2076151378Snetchild    do_interpretation();
2077151378Snetchild
2078151378Snetchild  // Step 4:Return results
2079151378Snetchild  if (!_got_error && report_results())
2080151378Snetchild     report_result();
2081151378Snetchild
2082151378Snetchild  if (_got_error) {
2083151378Snetchild    THROW_HANDLE(_exception);
2084151378Snetchild  }
2085151378Snetchild}
2086151378Snetchild
2087151378Snetchild// Error handling methods
2088151378Snetchild// These methods create an exception for the current thread which is thrown
2089151378Snetchild// at the bottom of the call stack, when it returns to compute_map().  The
2090151378Snetchild// _got_error flag controls execution.  NOT TODO: The VM exception propagation
2091151378Snetchild// mechanism using TRAPS/CHECKs could be used here instead but it would need
2092151378Snetchild// to be added as a parameter to every function and checked for every call.
2093151378Snetchild// The tons of extra code it would generate didn't seem worth the change.
2094151378Snetchild//
2095151378Snetchildvoid GenerateOopMap::error_work(const char *format, va_list ap) {
2096151378Snetchild  _got_error = true;
2097151378Snetchild  char msg_buffer[512];
2098151378Snetchild  vsnprintf(msg_buffer, sizeof(msg_buffer), format, ap);
2099151378Snetchild  // Append method name
2100151378Snetchild  char msg_buffer2[512];
2101151378Snetchild  jio_snprintf(msg_buffer2, sizeof(msg_buffer2), "%s in method %s", msg_buffer, method()->name()->as_C_string());
2102151378Snetchild  _exception = Exceptions::new_exception(Thread::current(),
2103151378Snetchild                vmSymbols::java_lang_LinkageError(), msg_buffer2);
2104151378Snetchild}
2105151378Snetchild
2106151378Snetchildvoid GenerateOopMap::report_error(const char *format, ...) {
2107151378Snetchild  va_list ap;
2108151378Snetchild  va_start(ap, format);
2109151378Snetchild  error_work(format, ap);
2110151378Snetchild}
2111151378Snetchild
2112151378Snetchildvoid GenerateOopMap::verify_error(const char *format, ...) {
2113151378Snetchild  // We do not distinguish between different types of errors for verification
2114151378Snetchild  // errors.  Let the verifier give a better message.
2115151378Snetchild  const char *msg = "Illegal class file encountered. Try running with -Xverify:all";
2116151378Snetchild  error_work(msg, NULL);
2117151378Snetchild}
2118151378Snetchild
2119151378Snetchild//
2120151378Snetchild// Report result opcodes
2121151378Snetchild//
2122151378Snetchildvoid GenerateOopMap::report_result() {
2123151378Snetchild
2124151378Snetchild  if (TraceNewOopMapGeneration) tty->print_cr("Report result pass");
2125151378Snetchild
2126151378Snetchild  // We now want to report the result of the parse
2127151378Snetchild  _report_result = true;
2128151378Snetchild
2129151378Snetchild  // Prolog code
2130151378Snetchild  fill_stackmap_prolog(_gc_points);
2131151378Snetchild
2132151378Snetchild   // Mark everything changed, then do one interpretation pass.
2133151378Snetchild  for (int i = 0; i<_bb_count; i++) {
2134151378Snetchild    if (_basic_blocks[i].is_reachable()) {
2135151378Snetchild      _basic_blocks[i].set_changed(true);
2136151378Snetchild      interp_bb(&_basic_blocks[i]);
2137151378Snetchild    }
2138151378Snetchild  }
2139151378Snetchild
2140151378Snetchild  // Note: Since we are skipping dead-code when we are reporting results, then
2141151378Snetchild  // the no. of encountered gc-points might be fewer than the previously number
2142151378Snetchild  // we have counted. (dead-code is a pain - it should be removed before we get here)
2143151378Snetchild  fill_stackmap_epilog();
2144151378Snetchild
2145151378Snetchild  // Report initvars
2146151378Snetchild  fill_init_vars(_init_vars);
2147151378Snetchild
2148151378Snetchild  _report_result = false;
2149151378Snetchild}
2150151378Snetchild
2151151378Snetchildvoid GenerateOopMap::result_for_basicblock(int bci) {
2152151378Snetchild if (TraceNewOopMapGeneration) tty->print_cr("Report result pass for basicblock");
2153151378Snetchild
2154151378Snetchild  // We now want to report the result of the parse
2155151378Snetchild  _report_result = true;
2156151378Snetchild
2157151378Snetchild  // Find basicblock and report results
2158151378Snetchild  BasicBlock* bb = get_basic_block_containing(bci);
2159151378Snetchild  assert(bb->is_reachable(), "getting result from unreachable basicblock");
2160151378Snetchild  bb->set_changed(true);
2161151378Snetchild  interp_bb(bb);
2162151378Snetchild}
2163151378Snetchild
2164151378Snetchild//
2165151378Snetchild// Conflict handling code
2166151378Snetchild//
2167151378Snetchild
2168151378Snetchildvoid GenerateOopMap::record_refval_conflict(int varNo) {
2169151378Snetchild  assert(varNo>=0 && varNo< _max_locals, "index out of range");
2170151378Snetchild
2171151378Snetchild  if (TraceOopMapRewrites) {
2172151378Snetchild     tty->print("### Conflict detected (local no: %d)\n", varNo);
2173151378Snetchild  }
2174151378Snetchild
2175151378Snetchild  if (!_new_var_map) {
2176151378Snetchild    _new_var_map = NEW_RESOURCE_ARRAY(int, _max_locals);
2177151378Snetchild    for (int k = 0; k < _max_locals; k++)  _new_var_map[k] = k;
2178151378Snetchild  }
2179151378Snetchild
2180151378Snetchild  if ( _new_var_map[varNo] == varNo) {
2181151378Snetchild    // Check if max. number of locals has been reached
2182151378Snetchild    if (_max_locals + _nof_refval_conflicts >= MAX_LOCAL_VARS) {
2183151378Snetchild      report_error("Rewriting exceeded local variable limit");
2184151378Snetchild      return;
2185151378Snetchild    }
2186151378Snetchild    _new_var_map[varNo] = _max_locals + _nof_refval_conflicts;
2187151378Snetchild    _nof_refval_conflicts++;
2188151378Snetchild  }
2189151378Snetchild}
2190151378Snetchild
2191151378Snetchildvoid GenerateOopMap::rewrite_refval_conflicts()
2192151378Snetchild{
2193151378Snetchild  // We can get here two ways: Either a rewrite conflict was detected, or
2194151378Snetchild  // an uninitialize reference was detected. In the second case, we do not
2195151378Snetchild  // do any rewriting, we just want to recompute the reference set with the
2196151378Snetchild  // new information
2197151378Snetchild
2198151378Snetchild  int nof_conflicts = 0;              // Used for debugging only
2199151378Snetchild
2200151378Snetchild  if ( _nof_refval_conflicts == 0 )
2201151378Snetchild     return;
2202151378Snetchild
2203151378Snetchild  // Check if rewrites are allowed in this parse.
2204151378Snetchild  if (!allow_rewrites() && !IgnoreRewrites) {
2205151378Snetchild    fatal("Rewriting method not allowed at this stage");
2206151378Snetchild  }
2207151378Snetchild
2208151378Snetchild
2209151378Snetchild  // This following flag is to tempoary supress rewrites. The locals that might conflict will
2210151378Snetchild  // all be set to contain values. This is UNSAFE - however, until the rewriting has been completely
2211151378Snetchild  // tested it is nice to have.
2212151378Snetchild  if (IgnoreRewrites) {
2213151378Snetchild    if (Verbose) {
2214151378Snetchild       tty->print("rewrites suppressed for local no. ");
2215151378Snetchild       for (int l = 0; l < _max_locals; l++) {
2216151378Snetchild         if (_new_var_map[l] != l) {
2217151378Snetchild           tty->print("%d ", l);
2218151378Snetchild           vars()[l] = CellTypeState::value;
2219151378Snetchild         }
2220151378Snetchild       }
2221151378Snetchild       tty->cr();
2222151378Snetchild    }
2223151378Snetchild
2224151378Snetchild    // That was that...
2225151378Snetchild    _new_var_map = NULL;
2226151378Snetchild    _nof_refval_conflicts = 0;
2227151378Snetchild    _conflict = false;
2228151378Snetchild
2229151378Snetchild    return;
2230151378Snetchild  }
2231151378Snetchild
2232151378Snetchild  // Tracing flag
2233151378Snetchild  _did_rewriting = true;
2234151378Snetchild
2235151378Snetchild  if (TraceOopMapRewrites) {
2236151378Snetchild    tty->print_cr("ref/value conflict for method %s - bytecodes are getting rewritten", method()->name()->as_C_string());
2237151378Snetchild    method()->print();
2238151378Snetchild    method()->print_codes();
2239151378Snetchild  }
2240151378Snetchild
2241151378Snetchild  assert(_new_var_map!=NULL, "nothing to rewrite");
2242151378Snetchild  assert(_conflict==true, "We should not be here");
2243151378Snetchild
2244151378Snetchild  compute_ret_adr_at_TOS();
2245151378Snetchild  if (!_got_error) {
2246151378Snetchild    for (int k = 0; k < _max_locals && !_got_error; k++) {
2247151378Snetchild      if (_new_var_map[k] != k) {
2248151378Snetchild        if (TraceOopMapRewrites) {
2249151378Snetchild          tty->print_cr("Rewriting: %d -> %d", k, _new_var_map[k]);
2250151378Snetchild        }
2251151378Snetchild        rewrite_refval_conflict(k, _new_var_map[k]);
2252151378Snetchild        if (_got_error) return;
2253151378Snetchild        nof_conflicts++;
2254151378Snetchild      }
2255151378Snetchild    }
2256151378Snetchild  }
2257151378Snetchild
2258151378Snetchild  assert(nof_conflicts == _nof_refval_conflicts, "sanity check");
2259151378Snetchild
2260151378Snetchild  // Adjust the number of locals
2261151378Snetchild  method()->set_max_locals(_max_locals+_nof_refval_conflicts);
2262151378Snetchild  _max_locals += _nof_refval_conflicts;
2263151378Snetchild
2264151378Snetchild  // That was that...
2265151378Snetchild  _new_var_map = NULL;
2266151378Snetchild  _nof_refval_conflicts = 0;
2267151378Snetchild}
2268151378Snetchild
2269151378Snetchildvoid GenerateOopMap::rewrite_refval_conflict(int from, int to) {
2270151378Snetchild  bool startOver;
2271151378Snetchild  do {
2272151378Snetchild    // Make sure that the BytecodeStream is constructed in the loop, since
2273151378Snetchild    // during rewriting a new method oop is going to be used, and the next time
2274151378Snetchild    // around we want to use that.
2275151378Snetchild    BytecodeStream bcs(_method);
2276151378Snetchild    startOver = false;
2277151378Snetchild
2278151378Snetchild    while( bcs.next() >=0 && !startOver && !_got_error) {
2279151378Snetchild      startOver = rewrite_refval_conflict_inst(&bcs, from, to);
2280151378Snetchild    }
2281151378Snetchild  } while (startOver && !_got_error);
2282151378Snetchild}
2283151378Snetchild
2284151378Snetchild/* If the current instruction is one that uses local variable "from"
2285151378Snetchild   in a ref way, change it to use "to". There's a subtle reason why we
2286151378Snetchild   renumber the ref uses and not the non-ref uses: non-ref uses may be
2287151378Snetchild   2 slots wide (double, long) which would necessitate keeping track of
2288151378Snetchild   whether we should add one or two variables to the method. If the change
2289151378Snetchild   affected the width of some instruction, returns "TRUE"; otherwise, returns "FALSE".
2290151378Snetchild   Another reason for moving ref's value is for solving (addr, ref) conflicts, which
2291151378Snetchild   both uses aload/astore methods.
2292151378Snetchild*/
2293151378Snetchildbool GenerateOopMap::rewrite_refval_conflict_inst(BytecodeStream *itr, int from, int to) {
2294151378Snetchild  Bytecodes::Code bc = itr->code();
2295151378Snetchild  int index;
2296151378Snetchild  int bci = itr->bci();
2297151378Snetchild
2298151378Snetchild  if (is_aload(itr, &index) && index == from) {
2299151378Snetchild    if (TraceOopMapRewrites) {
2300151378Snetchild      tty->print_cr("Rewriting aload at bci: %d", bci);
2301151378Snetchild    }
2302151378Snetchild    return rewrite_load_or_store(itr, Bytecodes::_aload, Bytecodes::_aload_0, to);
2303151378Snetchild  }
2304151378Snetchild
2305151378Snetchild  if (is_astore(itr, &index) && index == from) {
2306151378Snetchild    if (!stack_top_holds_ret_addr(bci)) {
2307151378Snetchild      if (TraceOopMapRewrites) {
2308151378Snetchild        tty->print_cr("Rewriting astore at bci: %d", bci);
2309151378Snetchild      }
2310151378Snetchild      return rewrite_load_or_store(itr, Bytecodes::_astore, Bytecodes::_astore_0, to);
2311151378Snetchild    } else {
2312151378Snetchild      if (TraceOopMapRewrites) {
2313151378Snetchild        tty->print_cr("Supress rewriting of astore at bci: %d", bci);
2314151378Snetchild      }
2315151378Snetchild    }
2316151378Snetchild  }
2317151378Snetchild
2318151378Snetchild  return false;
2319151378Snetchild}
2320151378Snetchild
2321151378Snetchild// The argument to this method is:
2322151378Snetchild// bc : Current bytecode
2323151378Snetchild// bcN : either _aload or _astore
2324151378Snetchild// bc0 : either _aload_0 or _astore_0
2325151378Snetchildbool GenerateOopMap::rewrite_load_or_store(BytecodeStream *bcs, Bytecodes::Code bcN, Bytecodes::Code bc0, unsigned int varNo) {
2326151378Snetchild  assert(bcN == Bytecodes::_astore   || bcN == Bytecodes::_aload,   "wrong argument (bcN)");
2327151378Snetchild  assert(bc0 == Bytecodes::_astore_0 || bc0 == Bytecodes::_aload_0, "wrong argument (bc0)");
2328151378Snetchild  int ilen = Bytecodes::length_at(bcs->bcp());
2329151378Snetchild  int newIlen;
2330151378Snetchild
2331151378Snetchild  if (ilen == 4) {
2332151378Snetchild    // Original instruction was wide; keep it wide for simplicity
2333151378Snetchild    newIlen = 4;
2334151378Snetchild  } else if (varNo < 4)
2335151378Snetchild     newIlen = 1;
2336151378Snetchild  else if (varNo >= 256)
2337151378Snetchild     newIlen = 4;
2338151378Snetchild  else
2339151378Snetchild     newIlen = 2;
2340151378Snetchild
2341151378Snetchild  // If we need to relocate in order to patch the byte, we
2342151378Snetchild  // do the patching in a temp. buffer, that is passed to the reloc.
2343151378Snetchild  // The patching of the bytecode stream is then done by the Relocator.
2344151378Snetchild  // This is neccesary, since relocating the instruction at a certain bci, might
2345151378Snetchild  // also relocate that instruction, e.g., if a _goto before it gets widen to a _goto_w.
2346151378Snetchild  // Hence, we do not know which bci to patch after relocation.
2347151378Snetchild
2348151378Snetchild  assert(newIlen <= 4, "sanity check");
2349151378Snetchild  u_char inst_buffer[4]; // Max. instruction size is 4.
2350151378Snetchild  address bcp;
2351151378Snetchild
2352151378Snetchild  if (newIlen != ilen) {
2353151378Snetchild    // Relocation needed do patching in temp. buffer
2354151378Snetchild    bcp = (address)inst_buffer;
2355151378Snetchild  } else {
2356151378Snetchild    bcp = _method->bcp_from(bcs->bci());
2357151378Snetchild  }
2358151378Snetchild
2359151378Snetchild  // Patch either directly in methodOop or in temp. buffer
2360151378Snetchild  if (newIlen == 1) {
2361151378Snetchild    assert(varNo < 4, "varNo too large");
2362151378Snetchild    *bcp = bc0 + varNo;
2363151378Snetchild  } else if (newIlen == 2) {
2364151378Snetchild    assert(varNo < 256, "2-byte index needed!");
2365151378Snetchild    *(bcp + 0) = bcN;
2366151378Snetchild    *(bcp + 1) = varNo;
2367151378Snetchild  } else {
2368151378Snetchild    assert(newIlen == 4, "Wrong instruction length");
2369151378Snetchild    *(bcp + 0) = Bytecodes::_wide;
2370151378Snetchild    *(bcp + 1) = bcN;
2371151378Snetchild    Bytes::put_Java_u2(bcp+2, varNo);
2372151378Snetchild  }
2373151378Snetchild
2374151378Snetchild  if (newIlen != ilen) {
2375151378Snetchild    expand_current_instr(bcs->bci(), ilen, newIlen, inst_buffer);
2376151378Snetchild  }
2377151378Snetchild
2378151378Snetchild
2379151378Snetchild  return (newIlen != ilen);
2380151378Snetchild}
2381151378Snetchild
2382151378Snetchildclass RelocCallback : public RelocatorListener {
2383151378Snetchild private:
2384151378Snetchild  GenerateOopMap* _gom;
2385151378Snetchild public:
2386151378Snetchild   RelocCallback(GenerateOopMap* gom) { _gom = gom; };
2387151378Snetchild
2388151378Snetchild  // Callback method
2389151378Snetchild  virtual void relocated(int bci, int delta, int new_code_length) {
2390151378Snetchild    _gom->update_basic_blocks  (bci, delta, new_code_length);
2391151378Snetchild    _gom->update_ret_adr_at_TOS(bci, delta);
2392151378Snetchild    _gom->_rt.update_ret_table (bci, delta);
2393151378Snetchild  }
2394151378Snetchild};
2395151378Snetchild
2396151378Snetchild// Returns true if expanding was succesful. Otherwise, reports an error and
2397151378Snetchild// returns false.
2398151378Snetchildvoid GenerateOopMap::expand_current_instr(int bci, int ilen, int newIlen, u_char inst_buffer[]) {
2399151378Snetchild  Thread *THREAD = Thread::current();  // Could really have TRAPS argument.
2400151378Snetchild  RelocCallback rcb(this);
2401151378Snetchild  Relocator rc(_method, &rcb);
2402151378Snetchild  methodHandle m= rc.insert_space_at(bci, newIlen, inst_buffer, THREAD);
2403151378Snetchild  if (m.is_null() || HAS_PENDING_EXCEPTION) {
2404151378Snetchild    report_error("could not rewrite method - exception occurred or bytecode buffer overflow");
2405151378Snetchild    return;
2406151378Snetchild  }
2407151378Snetchild
2408151378Snetchild  // Relocator returns a new method oop.
2409151378Snetchild  _did_relocation = true;
2410151378Snetchild  _method = m;
2411151378Snetchild}
2412151378Snetchild
2413151378Snetchild
2414151378Snetchildbool GenerateOopMap::is_astore(BytecodeStream *itr, int *index) {
2415151378Snetchild  Bytecodes::Code bc = itr->code();
2416151378Snetchild  switch(bc) {
2417151378Snetchild    case Bytecodes::_astore_0:
2418151378Snetchild    case Bytecodes::_astore_1:
2419151378Snetchild    case Bytecodes::_astore_2:
2420151378Snetchild    case Bytecodes::_astore_3:
2421151378Snetchild      *index = bc - Bytecodes::_astore_0;
2422151378Snetchild      return true;
2423151378Snetchild    case Bytecodes::_astore:
2424151378Snetchild      *index = itr->get_index();
2425151378Snetchild      return true;
2426151378Snetchild  }
2427151378Snetchild  return false;
2428151378Snetchild}
2429151378Snetchild
2430153939Snetchildbool GenerateOopMap::is_aload(BytecodeStream *itr, int *index) {
2431153939Snetchild  Bytecodes::Code bc = itr->code();
2432153939Snetchild  switch(bc) {
2433153939Snetchild    case Bytecodes::_aload_0:
2434153939Snetchild    case Bytecodes::_aload_1:
2435153939Snetchild    case Bytecodes::_aload_2:
2436153939Snetchild    case Bytecodes::_aload_3:
2437153939Snetchild      *index = bc - Bytecodes::_aload_0;
2438153939Snetchild      return true;
2439153939Snetchild
2440153939Snetchild    case Bytecodes::_aload:
2441153939Snetchild      *index = itr->get_index();
2442153939Snetchild      return true;
2443153939Snetchild  }
2444153939Snetchild  return false;
2445153939Snetchild}
2446153939Snetchild
2447153939Snetchild
2448153939Snetchild// Return true iff the top of the operand stack holds a return address at
2449151378Snetchild// the current instruction
2450151378Snetchildbool GenerateOopMap::stack_top_holds_ret_addr(int bci) {
2451151378Snetchild  for(int i = 0; i < _ret_adr_tos->length(); i++) {
2452151378Snetchild    if (_ret_adr_tos->at(i) == bci)
2453151378Snetchild      return true;
2454151378Snetchild  }
2455151378Snetchild
2456151378Snetchild  return false;
2457151378Snetchild}
2458151378Snetchild
2459151378Snetchildvoid GenerateOopMap::compute_ret_adr_at_TOS() {
2460151378Snetchild  assert(_ret_adr_tos != NULL, "must be initialized");
2461151378Snetchild  _ret_adr_tos->clear();
2462151378Snetchild
2463151378Snetchild  for (int i = 0; i < bb_count(); i++) {
2464151378Snetchild    BasicBlock* bb = &_basic_blocks[i];
2465151378Snetchild
2466151378Snetchild    // Make sure to only check basicblocks that are reachable
2467151378Snetchild    if (bb->is_reachable()) {
2468151378Snetchild
2469151378Snetchild      // For each Basic block we check all instructions
2470151378Snetchild      BytecodeStream bcs(_method);
2471151378Snetchild      bcs.set_interval(bb->_bci, next_bb_start_pc(bb));
2472151378Snetchild
2473151378Snetchild      restore_state(bb);
2474151378Snetchild
2475151378Snetchild      while (bcs.next()>=0 && !_got_error) {
2476151378Snetchild        // TDT: should this be is_good_address() ?
2477151378Snetchild        if (_stack_top > 0 && stack()[_stack_top-1].is_address()) {
2478151378Snetchild          _ret_adr_tos->append(bcs.bci());
2479151378Snetchild          if (TraceNewOopMapGeneration) {
2480151378Snetchild            tty->print_cr("Ret_adr TOS at bci: %d", bcs.bci());
2481151378Snetchild          }
2482151378Snetchild        }
2483151378Snetchild        interp1(&bcs);
2484151378Snetchild      }
2485151378Snetchild    }
2486151378Snetchild  }
2487151378Snetchild}
2488151378Snetchild
2489151378Snetchildvoid GenerateOopMap::update_ret_adr_at_TOS(int bci, int delta) {
2490151378Snetchild  for(int i = 0; i < _ret_adr_tos->length(); i++) {
2491151378Snetchild    int v = _ret_adr_tos->at(i);
2492151378Snetchild    if (v > bci)  _ret_adr_tos->at_put(i, v + delta);
2493151378Snetchild  }
2494151378Snetchild}
2495151378Snetchild
2496151378Snetchild// ===================================================================
2497151378Snetchild
2498151378Snetchild#ifndef PRODUCT
2499151378Snetchildint ResolveOopMapConflicts::_nof_invocations  = 0;
2500151378Snetchildint ResolveOopMapConflicts::_nof_rewrites     = 0;
2501151378Snetchildint ResolveOopMapConflicts::_nof_relocations  = 0;
2502151378Snetchild#endif
2503151378Snetchild
2504151378SnetchildmethodHandle ResolveOopMapConflicts::do_potential_rewrite(TRAPS) {
2505151378Snetchild  compute_map(CHECK_(methodHandle()));
2506151378Snetchild
2507151378Snetchild#ifndef PRODUCT
2508151378Snetchild  // Tracking and statistics
2509151378Snetchild  if (PrintRewrites) {
2510151378Snetchild    _nof_invocations++;
2511151378Snetchild    if (did_rewriting()) {
2512151378Snetchild      _nof_rewrites++;
2513151378Snetchild      if (did_relocation()) _nof_relocations++;
2514151378Snetchild      tty->print("Method was rewritten %s: ", (did_relocation()) ? "and relocated" : "");
2515151378Snetchild      method()->print_value(); tty->cr();
2516151378Snetchild      tty->print_cr("Cand.: %d rewrts: %d (%d%%) reloc.: %d (%d%%)",
2517151378Snetchild          _nof_invocations,
2518153939Snetchild          _nof_rewrites,    (_nof_rewrites    * 100) / _nof_invocations,
2519153939Snetchild          _nof_relocations, (_nof_relocations * 100) / _nof_invocations);
2520153939Snetchild    }
2521153939Snetchild  }
2522153939Snetchild#endif
2523153939Snetchild  return methodHandle(THREAD, method());
2524153939Snetchild}
2525153939Snetchild