/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*
* 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.
*
*/
#include "interpreter/bytecode.hpp"
#include "memory/allocation.hpp"
#include "oops/methodOop.hpp"
#ifdef TARGET_ARCH_x86
# include "bytes_x86.hpp"
#endif
#ifdef TARGET_ARCH_sparc
# include "bytes_sparc.hpp"
#endif
#ifdef TARGET_ARCH_zero
# include "bytes_zero.hpp"
#endif
#ifdef TARGET_ARCH_arm
# include "bytes_arm.hpp"
#endif
#ifdef TARGET_ARCH_ppc
# include "bytes_ppc.hpp"
#endif
// A BytecodeStream is used for fast iteration over the bytecodes
// of a methodOop.
//
// Usage:
//
// BytecodeStream s(method);
// Bytecodes::Code c;
// while ((c = s.next()) >= 0) {
// ...
// }
// A RawBytecodeStream is a simple version of BytecodeStream.
// It is used ONLY when we know the bytecodes haven't been rewritten
// yet, such as in the rewriter or the verifier.
// Here is the common base class for both RawBytecodeStream and BytecodeStream:
protected:
// stream buffer
// reading position
// last bytecode read
bool _is_wide;
// Construction
_is_raw = false;
}
public:
// Iteration control
// iterate over the interval [beg_bci, end_bci)
// setup of iteration pointers
}
}
// Stream attributes
// State changes
void set_next_bci(int bci) { assert(0 <= bci && bci <= method()->code_size(), "illegal bci"); _next_bci = bci; }
// Bytecode-specific attributes
// One-byte indices.
protected:
};
public:
// Construction
_is_raw = true;
}
public:
// Iteration
// Use raw_next() rather than next() for faster method reference
// set reading position
// set next bytecode position
_is_wide = false;
_next_bci += l;
return code;
} else {
return raw_next_special(code);
}
}
// Unsigned indices, widening, with no swapping of bytes
// Get an unsigned 2-byte index, with no swapping of bytes.
private:
return Bytes::get_Java_u2(p);
}
};
// In BytecodeStream, non-java bytecodes will be translated into the
// corresponding java bytecodes.
public:
// Construction
// Iteration
// set reading position
if (is_last_bytecode()) {
// indicate end of bytecode stream
} else {
// get bytecode
// set next bytecode position
//
// note that we cannot advance before having the
// tty bytecode otherwise the stepping is wrong!
// (carefull: length_for(...) must be used first!)
_next_bci += l;
// set attributes
_is_wide = false;
// check for special (uncommon) cases
_is_wide = true;
}
}
return _code;
}
// Unsigned indices, widening
int get_index() const { return is_wide() ? bytecode().get_index_u2(raw_code(), true) : get_index_u1(); }
// Get an unsigned 2-byte index, swapping the bytes if necessary.
int get_index_u2() const { assert_raw_stream(false);
// Get an unsigned 2-byte index in native order.
int get_index_u2_cpcache() const { assert_raw_stream(false);
int get_index_u4() const { assert_raw_stream(false);
};
#endif // SHARE_VM_INTERPRETER_BYTECODESTREAM_HPP