Path: blob/master/runtime/compiler/ilgen/J9ByteCodeIterator.hpp
6000 views
/*******************************************************************************1* Copyright (c) 2000, 2020 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122#ifndef J9BYTECODEITERATOR_INCL23#define J9BYTECODEITERATOR_INCL2425#include "env/jittypes.h"26#include "il/LabelSymbol.hpp"27#include "il/MethodSymbol.hpp"28#include "il/RegisterMappedSymbol.hpp"29#include "il/ResolvedMethodSymbol.hpp"30#include "il/StaticSymbol.hpp"31#include "il/Symbol.hpp"32#include "ilgen/ByteCodeIterator.hpp"33#include "infra/Link.hpp"34#include "env/j9method.h"35#include "env/VMJ9.h"36#include "ilgen/J9ByteCode.hpp"3738class TR_J9ByteCodeIterator : public TR_ByteCodeIterator<TR_J9ByteCode, TR_ResolvedJ9Method>39{40typedef TR_ByteCodeIterator<TR_J9ByteCode, TR_ResolvedJ9Method> Base;4142public:43TR_ALLOC(TR_Memory::ByteCodeIterator);4445enum TR_ByteCodeFlags46{47SizeMask = 0x07,48Branch = 0x08,49ToHandler = 0x10,50Absolute = 0x20,51TwoByteOffset = 0x40,52FourByteOffset = 0x80,5354TwoByteRelativeBranch = (Branch | TwoByteOffset),55FourByteRelativeBranch = (Branch | FourByteOffset),56TwoByteAbsoluteBranch = (Branch | Absolute | TwoByteOffset),57FourByteAbsoluteBranch = (Branch | Absolute | FourByteOffset),58TwoByteRelativeToHandler = (ToHandler | TwoByteOffset),59FourByteRelativeToHandler = (ToHandler | FourByteOffset),60TwoByteAbsoluteToHandler = (ToHandler | Absolute | TwoByteOffset),61FourByteAbsoluteToHandler = (ToHandler | Absolute | FourByteOffset),6263};6465TR_J9ByteCodeIterator(TR::ResolvedMethodSymbol *methodSymbol, TR::Compilation *comp)66: Base(methodSymbol, static_cast<TR_ResolvedJ9Method*>(methodSymbol->getResolvedMethod()), comp)67{}6869TR_J9ByteCodeIterator(TR::ResolvedMethodSymbol *methodSymbol, TR_ResolvedJ9Method *method, TR_J9VMBase * fe, TR::Compilation * comp) :70Base(methodSymbol, method, comp)71{72initialize(method, fe);73}7475void initialize(TR_ResolvedJ9Method *, TR_J9VMBase *);7677int32_t defaultTargetIndex() { return (int32_t)(_bcIndex + 1 + ((4 - ((intptr_t)&_code[_bcIndex+1] & 3)) & 3)); }7879bool isThisChanged();8081int32_t findFloatingPointInstruction();8283int32_t nextSwitchValue(int32_t & bcIndex);8485static int32_t size(TR_J9ByteCode bc)86{87return _byteCodeFlags[bc] & SizeMask;88}8990TR_J9ByteCode first()91{92_bcIndex = 0;93return current();94}9596TR_J9ByteCode next()97{98int32_t size = _byteCodeFlags[_bc] & SizeMask;99if (size)100_bcIndex += size;101else102stepOverVariableSizeBC();103return current();104}105106int32_t currentByteCodeIndex()107{108return _bcIndex;109}110111TR_J9ByteCode current()112{113_bc = (_bcIndex >= _maxByteCodeIndex ? J9BCunknown : convertOpCodeToByteCodeEnum(_code[_bcIndex]));114TR_ASSERT_FATAL(_bcIndex >= _maxByteCodeIndex || _bc != J9BCunknown, "Unknown bytecode to JIT %d \n", _code[_bcIndex]);115return _bc;116}117118static TR_J9ByteCode convertOpCodeToByteCodeEnum(uint8_t opcode)119{120return _opCodeToByteCodeEnum[opcode];121}122uint32_t estimatedCodeSize() { return estimatedCodeSize(current()); }123static uint32_t estimatedCodeSize(TR_J9ByteCode bc) { return _estimatedCodeSize[bc]; }124125126bool isBranch() { return (_byteCodeFlags[_bc] & Branch) != 0; }127int32_t relativeBranch() { TR_ASSERT((_byteCodeFlags[_bc] & Absolute) == 0, "assertion failure"); return (_byteCodeFlags[_bc] & TwoByteOffset) ? next2BytesSigned() : next4BytesSigned(); }128int32_t absoluteBranch() { TR_ASSERT((_byteCodeFlags[_bc] & Absolute) != 0, "assertion failure"); return (_byteCodeFlags[_bc] & TwoByteOffset) ? next2Bytes() : next4Bytes(); }129int32_t branchDestination(int32_t base) { TR_ASSERT((_byteCodeFlags[_bc] & Branch) != 0, "assertion failure"); return ((_byteCodeFlags[_bc] & Absolute) != 0) ? absoluteBranch() : base + relativeBranch(); }130131uint8_t nextByte(int32_t o = 1) { return _code[_bcIndex + o]; }132int8_t nextByteSigned(int32_t o = 1) { return nextByte(o); }133134#if defined(NETWORK_ORDER_BYTECODE)135uint16_t next2Bytes(int32_t o = 1) { return nextByte(o) << 8 | nextByte(o + 1); }136uint32_t next4Bytes(int32_t o = 1) { return nextByte(o) << 24 | nextByte(o + 1) << 16 |137nextByte(o + 2) << 8 |138nextByte(o + 3); }139int16_t next2BytesSigned(int32_t o = 1) { return next2Bytes(o); }140int32_t next4BytesSigned(int32_t o = 1) { return next4Bytes(o); }141#else142uint16_t next2Bytes(int32_t o = 1) { return *((uint16_t*)&_code[_bcIndex + o]); }143uint32_t next4Bytes(int32_t o = 1) { return *((uint32_t*)&_code[_bcIndex + o]); }144int16_t next2BytesSigned(int32_t o = 1) { return next2Bytes(o); }145int32_t next4BytesSigned(int32_t o = 1) { return next4Bytes(o); }146#endif147148protected:149void stepOverVariableSizeBC();150151void printFirst(int32_t i);152void printCPIndex(int32_t i);153void printConstant(int32_t i);154void printConstant(double d);155void printFirstAndConstant(int32_t i, int32_t j);156void printJumpIndex(int32_t offset);157158void printByteCodePrologue();159void printByteCode();160void printByteCodeEpilogue();161162TR_J9VMBase *fe() { return _fe; }163//TR_ResolvedJ9Method *method() { return _method; }164//TR_ResolvedJ9Method * _method;165TR_J9VMBase * _fe;166const uint8_t * _code;167TR_J9ByteCode _bc; // TODO: remove this field, Replace uses with call to current()168169static const uint8_t _byteCodeFlags[];170static const TR_J9ByteCode _opCodeToByteCodeEnum[256];171static const uint8_t _estimatedCodeSize[];172173static TR::ILOpCodes _lcmpOps[];174static TR::ILOpCodes _fcmplOps[];175static TR::ILOpCodes _fcmpgOps[];176static TR::ILOpCodes _dcmplOps[];177static TR::ILOpCodes _dcmpgOps[];178};179180#endif181182183184