/* * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. * 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. * * 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. *
*/
// Some experimental projects extend the ARM back-end by implementing // what the front-end usually assumes is a single native instruction // with a sequence of instructions. // // The 'Raw' variants are the low level initial code (usually one // instruction wide but some of them were already composed // instructions). They should be used only by the back-end. // // The non-raw classes are the front-end entry point, hiding potential // back-end extensions or the actual instructions size. class NativeInstruction; class NativeCall;
// Base class exported to the front-end class NativeInstruction: public RawNativeInstruction { public: static NativeInstruction* at(address address) { return (NativeInstruction*)address;
}
public: // No need to consider indirections while parsing NativeInstruction
address next_instruction_address() const { return next_raw_instruction_address();
}
// next() is no longer defined to avoid confusion. // // The front end and most classes except for those defined in nativeInst_arm // or relocInfo_arm should only use next_instruction_address(), skipping // over composed instruction and ignoring back-end extensions. // // The back-end can use next_raw() when it knows the instruction sequence // and only wants to skip a single native instruction.
};
// ------------------------------------------------------------------- // Raw b() or bl() instructions, not used by the front-end. class RawNativeBranch: public RawNativeInstruction { public:
// ------------------------------------------------------------------- // NativeGeneralJump is for patchable internal (near) jumps // It is used directly by the front-end and must be a single instruction wide // (to support patching to other kind of instructions). class NativeGeneralJump: public RawNativeInstruction { public:
staticvoid replace_mt_safe(address instr_addr, address code_buffer) {
assert(((int)instr_addr & 3) == 0 && ((int)code_buffer & 3) == 0, "must be aligned"); // Writing a word is atomic on ARM, so no MT-safe tricks are needed
rawNativeInstruction_at(instr_addr)->set_encoding(*(int*)code_buffer);
}
};
// ------------------------------------------------------------------- class RawNativeCall: public NativeInstruction { // See IC calls in LIR_Assembler::ic_call(): ARM v5/v6 doesn't use a // single bl for IC calls.
// ------------------------------------------------------------------- // NativeMovRegMem need not be extended with indirection support. // (field access patching is handled differently in that case) class NativeMovRegMem: public NativeInstruction { public: enum arm_specific_constants {
instruction_size = 8
};
int num_bytes_to_end_of_patch() const { return instruction_size; }
// ------------------------------------------------------------------- // NativeMovConstReg is primarily for loading oops and metadata class NativeMovConstReg: public NativeInstruction { public:
intptr_t data() const; void set_data(intptr_t x, address pc = 0); bool is_pc_relative() { return !is_movw();
} void set_pc_relative_offset(address addr, address pc);
address next_instruction_address() const { // NOTE: CompiledStaticCall::set_to_interpreted() calls this but // are restricted to single-instruction ldr. No need to jump over // several instructions.
assert(is_ldr_literal(), "Should only use single-instructions load"); return next_raw_instruction_address();
}
};
class NativeCall: public RawNativeCall { public: // NativeCall::next_instruction_address() is used only to define the // range where to look for the relocation information. We need not // walk over composed instructions (as long as the relocation information // is associated to the first instruction).
address next_instruction_address() const { return next_raw_instruction_address();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.