ciStreams.hpp 14.1 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31 32 33
#ifndef SHARE_VM_CI_CISTREAMS_HPP
#define SHARE_VM_CI_CISTREAMS_HPP

#include "ci/ciClassList.hpp"
#include "ci/ciExceptionHandler.hpp"
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciMethod.hpp"
#include "interpreter/bytecode.hpp"

D
duke 已提交
34 35 36 37 38 39 40 41 42
// ciBytecodeStream
//
// The class is used to iterate over the bytecodes of a method.
// It hides the details of constant pool structure/access by
// providing accessors for constant pool items.  It returns only pure
// Java bytecodes; VM-internal _fast bytecodes are translated back to
// their original form during iteration.
class ciBytecodeStream : StackObj {
private:
43 44
  // Handling for the weird bytecodes
  Bytecodes::Code next_wide_or_table(Bytecodes::Code); // Handle _wide & complicated inline table
D
duke 已提交
45 46 47 48 49 50

  static Bytecodes::Code check_java(Bytecodes::Code c) {
    assert(Bytecodes::is_java_code(c), "should not return _fast bytecodes");
    return c;
  }

51 52 53 54 55
  static Bytecodes::Code check_defined(Bytecodes::Code c) {
    assert(Bytecodes::is_defined(c), "");
    return c;
  }

D
duke 已提交
56 57 58 59 60 61 62 63 64 65
  ciMethod* _method;           // the method
  ciInstanceKlass* _holder;
  address _bc_start;            // Start of current bytecode for table
  address _was_wide;            // Address past last wide bytecode
  jint* _table_base;            // Aligned start of last table or switch

  address _start;                  // Start of bytecodes
  address _end;                    // Past end of bytecodes
  address _pc;                     // Current PC
  Bytecodes::Code _bc;             // Current bytecode
66
  Bytecodes::Code _raw_bc;         // Current bytecode, raw form
D
duke 已提交
67 68 69

  void reset( address base, unsigned int size ) {
    _bc_start =_was_wide = 0;
70 71
    _start = _pc = base; _end = base + size;
  }
D
duke 已提交
72

73 74 75 76 77 78
  void assert_wide(bool require_wide) const {
    if (require_wide)
         { assert(is_wide(),  "must be a wide instruction"); }
    else { assert(!is_wide(), "must not be a wide instruction"); }
  }

79 80
  Bytecode bytecode() const { return Bytecode(this, _bc_start); }
  Bytecode next_bytecode() const { return Bytecode(this, _pc); }
81

D
duke 已提交
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
public:
  // End-Of-Bytecodes
  static Bytecodes::Code EOBC() {
    return Bytecodes::_illegal;
  }

  ciBytecodeStream(ciMethod* m) {
    reset_to_method(m);
  }

  ciBytecodeStream() {
    reset_to_method(NULL);
  }

  ciMethod* method() const { return _method; }

  void reset_to_method(ciMethod* m) {
    _method = m;
    if (m == NULL) {
      _holder = NULL;
      reset(NULL, 0);
    } else {
      _holder = m->holder();
      reset(m->code(), m->code_size());
    }
  }

  void reset_to_bci( int bci );

  // Force the iterator to report a certain bci.
  void force_bci(int bci);

  void set_max_bci( int max ) {
    _end = _start + max;
  }

118
  address cur_bcp() const       { return _bc_start; }  // Returns bcp to current instruction
119
  int next_bci() const          { return _pc - _start; }
D
duke 已提交
120
  int cur_bci() const           { return _bc_start - _start; }
121
  int instruction_size() const  { return _pc - _bc_start; }
D
duke 已提交
122 123

  Bytecodes::Code cur_bc() const{ return check_java(_bc); }
124
  Bytecodes::Code cur_bc_raw() const { return check_defined(_raw_bc); }
D
duke 已提交
125 126 127 128 129
  Bytecodes::Code next_bc()     { return Bytecodes::java_code((Bytecodes::Code)* _pc); }

  // Return current ByteCode and increment PC to next bytecode, skipping all
  // intermediate constants.  Returns EOBC at end.
  // Expected usage:
130 131
  //     ciBytecodeStream iter(m);
  //     while (iter.next() != ciBytecodeStream::EOBC()) { ... }
D
duke 已提交
132 133 134 135 136 137
  Bytecodes::Code next() {
    _bc_start = _pc;                        // Capture start of bc
    if( _pc >= _end ) return EOBC();        // End-Of-Bytecodes

    // Fetch Java bytecode
    // All rewritten bytecodes maintain the size of original bytecode.
138
    _bc = Bytecodes::java_code(_raw_bc = (Bytecodes::Code)*_pc);
D
duke 已提交
139
    int csize = Bytecodes::length_for(_bc); // Expected size
140 141 142
    _pc += csize;                           // Bump PC past bytecode
    if (csize == 0) {
      _bc = next_wide_or_table(_bc);
D
duke 已提交
143 144 145 146
    }
    return check_java(_bc);
  }

147
  bool is_wide() const { return ( _pc == _was_wide ); }
D
duke 已提交
148

149
  // Does this instruction contain an index which refes into the CP cache?
150
  bool has_cache_index() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); }
151

152 153
  bool has_optional_appendix() { return Bytecodes::has_optional_appendix(cur_bc_raw()); }

154
  int get_index_u1() const {
155
    return bytecode().get_index_u1(cur_bc_raw());
156 157
  }

158
  int get_index_u1_cpcache() const {
159
    return bytecode().get_index_u1_cpcache(cur_bc_raw());
160 161
  }

D
duke 已提交
162 163 164
  // Get a byte index following this bytecode.
  // If prefixed with a wide bytecode, get a wide index.
  int get_index() const {
165
    assert(!has_cache_index(), "else use cpcache variant");
D
duke 已提交
166
    return (_pc == _was_wide)   // was widened?
167 168
      ? get_index_u2(true)      // yes, return wide index
      : get_index_u1();         // no, return narrow index
D
duke 已提交
169 170
  }

171 172
  // Get 2-byte index (byte swapping depending on which bytecode)
  int get_index_u2(bool is_wide = false) const {
173
    return bytecode().get_index_u2(cur_bc_raw(), is_wide);
D
duke 已提交
174 175
  }

176 177
  // Get 2-byte index in native byte order.  (Rewriter::rewrite makes these.)
  int get_index_u2_cpcache() const {
178
    return bytecode().get_index_u2_cpcache(cur_bc_raw());
179 180 181
  }

  // Get 4-byte index, for invokedynamic.
182
  int get_index_u4() const {
183
    return bytecode().get_index_u4(cur_bc_raw());
184 185
  }

186
  bool has_index_u4() const {
187
    return bytecode().has_index_u4(cur_bc_raw());
188
  }
D
duke 已提交
189 190 191 192 193

  // Get dimensions byte (multinewarray)
  int get_dimensions() const { return *(unsigned char*)(_pc-1); }

  // Sign-extended index byte/short, no widening
194 195
  int get_constant_u1()                     const { return bytecode().get_constant_u1(instruction_size()-1, cur_bc_raw()); }
  int get_constant_u2(bool is_wide = false) const { return bytecode().get_constant_u2(instruction_size()-2, cur_bc_raw(), is_wide); }
D
duke 已提交
196 197 198

  // Get a byte signed constant for "iinc".  Invalid for other bytecodes.
  // If prefixed with a wide bytecode, get a wide constant
199
  int get_iinc_con() const {return (_pc==_was_wide) ? (jshort) get_constant_u2(true) : (jbyte) get_constant_u1();}
D
duke 已提交
200 201

  // 2-byte branch offset from current pc
202
  int get_dest() const {
203
    return cur_bci() + bytecode().get_offset_s2(cur_bc_raw());
D
duke 已提交
204 205 206
  }

  // 2-byte branch offset from next pc
207 208
  int next_get_dest() const {
    assert(_pc < _end, "");
209
    return next_bci() + next_bytecode().get_offset_s2(Bytecodes::_ifeq);
D
duke 已提交
210 211 212
  }

  // 4-byte branch offset from current pc
213
  int get_far_dest() const {
214
    return cur_bci() + bytecode().get_offset_s4(cur_bc_raw());
D
duke 已提交
215 216 217 218 219 220 221 222 223 224 225 226 227
  }

  // For a lookup or switch table, return target destination
  int get_int_table( int index ) const {
    return Bytes::get_Java_u4((address)&_table_base[index]); }

  // For tableswitch - get length of offset part
  int get_tableswitch_length()  { return get_int_table(2)-get_int_table(1)+1; }

  int get_dest_table( int index ) const {
    return cur_bci() + get_int_table(index); }

  // --- Constant pool access ---
228 229 230
  int get_constant_raw_index() const;
  int get_constant_pool_index() const;
  int get_constant_cache_index() const;
D
duke 已提交
231 232 233 234 235 236 237 238 239
  int get_field_index();
  int get_method_index();

  // If this bytecode is a new, newarray, multianewarray, instanceof,
  // or checkcast, get the referenced klass.
  ciKlass* get_klass(bool& will_link);
  int get_klass_index() const;

  // If this bytecode is one of the ldc variants, get the referenced
240 241 242
  // constant.  Do not attempt to resolve it, since that would require
  // execution of Java code.  If it is not resolved, return an unloaded
  // object (ciConstant.as_object()->is_loaded() == false).
D
duke 已提交
243
  ciConstant get_constant();
244 245 246 247 248 249 250
  constantTag get_constant_pool_tag(int index) const;

  // True if the klass-using bytecode points to an unresolved klass
  bool is_unresolved_klass() const {
    constantTag tag = get_constant_pool_tag(get_klass_index());
    return tag.is_unresolved_klass();
  }
D
duke 已提交
251 252 253 254 255 256 257 258 259

  // If this bytecode is one of get_field, get_static, put_field,
  // or put_static, get the referenced field.
  ciField* get_field(bool& will_link);

  ciInstanceKlass* get_declared_field_holder();
  int      get_field_holder_index();
  int      get_field_signature_index();

260 261 262 263 264 265 266
  ciMethod*     get_method(bool& will_link, ciSignature* *declared_signature_result);
  bool          has_appendix();
  ciObject*     get_appendix();
  bool          has_method_type();
  ciMethodType* get_method_type();
  ciKlass*      get_declared_method_holder();
  int           get_method_holder_index();
267
  int           get_method_signature_index(const constantPoolHandle& cpool);
268

269 270
  // Get the resolved references arrays from the constant pool
  ciObjArray* get_resolved_references();
D
duke 已提交
271 272 273 274 275 276 277 278 279
};


// ciSignatureStream
//
// The class is used to iterate over the elements of a method signature.
class ciSignatureStream : public StackObj {
private:
  ciSignature* _sig;
280 281 282
  int          _pos;
  // holder is a method's holder
  ciKlass*     _holder;
D
duke 已提交
283
public:
284
  ciSignatureStream(ciSignature* signature, ciKlass* holder = NULL) {
D
duke 已提交
285 286
    _sig = signature;
    _pos = 0;
287
    _holder = holder;
D
duke 已提交
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
  }

  bool at_return_type() { return _pos == _sig->count(); }

  bool is_done() { return _pos > _sig->count(); }

  void next() {
    if (_pos <= _sig->count()) {
      _pos++;
    }
  }

  ciType* type() {
    if (at_return_type()) {
      return _sig->return_type();
    } else {
      return _sig->type_at(_pos);
    }
  }
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323

  // next klass in the signature
  ciKlass* next_klass() {
    ciKlass* sig_k;
    if (_holder != NULL) {
      sig_k = _holder;
      _holder = NULL;
    } else {
      while (!type()->is_klass()) {
        next();
      }
      assert(!at_return_type(), "passed end of signature");
      sig_k = type()->as_klass();
      next();
    }
    return sig_k;
  }
D
duke 已提交
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
};


// ciExceptionHandlerStream
//
// The class is used to iterate over the exception handlers of
// a method.
class ciExceptionHandlerStream : public StackObj {
private:
  // The method whose handlers we are traversing
  ciMethod* _method;

  // Our current position in the list of handlers
  int        _pos;
  int        _end;

  ciInstanceKlass*  _exception_klass;
  int        _bci;
  bool       _is_exact;

public:
  ciExceptionHandlerStream(ciMethod* method) {
    _method = method;

    // Force loading of method code and handlers.
    _method->code();

    _pos = 0;
    _end = _method->_handler_count;
    _exception_klass = NULL;
    _bci    = -1;
    _is_exact = false;
  }

  ciExceptionHandlerStream(ciMethod* method, int bci,
                           ciInstanceKlass* exception_klass = NULL,
                           bool is_exact = false) {
    _method = method;

    // Force loading of method code and handlers.
    _method->code();

    _pos = -1;
    _end = _method->_handler_count + 1; // include the rethrow handler
    _exception_klass = (exception_klass != NULL && exception_klass->is_loaded()
                          ? exception_klass
                          : NULL);
    _bci = bci;
    assert(_bci >= 0, "bci out of range");
    _is_exact = is_exact;
    next();
  }

  // These methods are currently implemented in an odd way.
  // Count the number of handlers the iterator has ever produced
  // or will ever produce.  Do not include the final rethrow handler.
  // That is, a trivial exception handler stream will have a count
  // of zero and produce just the rethrow handler.
  int count();

  // Count the number of handlers this stream will produce from now on.
  // Include the current handler, and the final rethrow handler.
  // The remaining count will be zero iff is_done() is true,
  int count_remaining();

  bool is_done() {
    return (_pos >= _end);
  }

  void next() {
    _pos++;
    if (_bci != -1) {
      // We are not iterating over all handlers...
      while (!is_done()) {
        ciExceptionHandler* handler = _method->_exception_handlers[_pos];
        if (handler->is_in_range(_bci)) {
          if (handler->is_catch_all()) {
            // Found final active catch block.
            _end = _pos+1;
            return;
          } else if (_exception_klass == NULL || !handler->catch_klass()->is_loaded()) {
            // We cannot do any type analysis here.  Must conservatively assume
            // catch block is reachable.
            return;
          } else if (_exception_klass->is_subtype_of(handler->catch_klass())) {
            // This catch clause will definitely catch the exception.
            // Final candidate.
            _end = _pos+1;
            return;
          } else if (!_is_exact &&
                     handler->catch_klass()->is_subtype_of(_exception_klass)) {
            // This catch block may be reachable.
            return;
          }
        }

        // The catch block was not pertinent.  Go on.
        _pos++;
      }
    } else {
      // This is an iteration over all handlers.
      return;
    }
  }

  ciExceptionHandler* handler() {
    return _method->_exception_handlers[_pos];
  }
};
433

434 435 436 437 438 439 440


// Implementation for declarations in bytecode.hpp
Bytecode::Bytecode(const ciBytecodeStream* stream, address bcp): _bcp(bcp != NULL ? bcp : stream->cur_bcp()), _code(Bytecodes::code_at(NULL, addr_at(0))) {}
Bytecode_lookupswitch::Bytecode_lookupswitch(const ciBytecodeStream* stream): Bytecode(stream) { verify(); }
Bytecode_tableswitch::Bytecode_tableswitch(const ciBytecodeStream* stream): Bytecode(stream) { verify(); }

441
#endif // SHARE_VM_CI_CISTREAMS_HPP