Path: blob/master/src/hotspot/share/interpreter/abstractInterpreter.hpp
40949 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_INTERPRETER_ABSTRACTINTERPRETER_HPP25#define SHARE_INTERPRETER_ABSTRACTINTERPRETER_HPP2627#include "asm/macroAssembler.hpp"28#include "classfile/vmIntrinsics.hpp"29#include "code/stubs.hpp"30#include "interpreter/bytecodes.hpp"31#include "oops/method.hpp"32#include "runtime/frame.hpp"33#include "runtime/thread.hpp"34#include "runtime/vmThread.hpp"3536// This file contains the platform-independent parts37// of the abstract interpreter and the abstract interpreter generator.3839// Organization of the interpreter(s). There exists two different interpreters in hotpot40// an assembly language version (aka template interpreter) and a high level language version41// (aka c++ interpreter). Th division of labor is as follows:4243// Template Interpreter Zero Interpreter Functionality44//45// templateTable* bytecodeInterpreter* actual interpretation of bytecodes46//47// templateInterpreter* zeroInterpreter* generation of assembly code that creates48// and manages interpreter runtime frames.49//5051class InterpreterMacroAssembler;5253class AbstractInterpreter: AllStatic {54friend class VMStructs;55friend class ZeroInterpreterGenerator;56friend class TemplateInterpreterGenerator;57public:58enum MethodKind {59zerolocals, // method needs locals initialization60zerolocals_synchronized, // method needs locals initialization & is synchronized61native, // native method62native_synchronized, // native method & is synchronized63empty, // empty method (code: _return)64getter, // getter method65setter, // setter method66abstract, // abstract method (throws an AbstractMethodException)67method_handle_invoke_FIRST, // java.lang.invoke.MethodHandles::invokeExact, etc.68method_handle_invoke_LAST = (method_handle_invoke_FIRST69+ (static_cast<int>(vmIntrinsics::LAST_MH_SIG_POLY)70- static_cast<int>(vmIntrinsics::FIRST_MH_SIG_POLY))),71java_lang_math_sin, // implementation of java.lang.Math.sin (x)72java_lang_math_cos, // implementation of java.lang.Math.cos (x)73java_lang_math_tan, // implementation of java.lang.Math.tan (x)74java_lang_math_abs, // implementation of java.lang.Math.abs (x)75java_lang_math_sqrt, // implementation of java.lang.Math.sqrt (x)76java_lang_math_log, // implementation of java.lang.Math.log (x)77java_lang_math_log10, // implementation of java.lang.Math.log10 (x)78java_lang_math_pow, // implementation of java.lang.Math.pow (x,y)79java_lang_math_exp, // implementation of java.lang.Math.exp (x)80java_lang_math_fmaF, // implementation of java.lang.Math.fma (x, y, z)81java_lang_math_fmaD, // implementation of java.lang.Math.fma (x, y, z)82java_lang_ref_reference_get, // implementation of java.lang.ref.Reference.get()83java_util_zip_CRC32_update, // implementation of java.util.zip.CRC32.update()84java_util_zip_CRC32_updateBytes, // implementation of java.util.zip.CRC32.updateBytes()85java_util_zip_CRC32_updateByteBuffer, // implementation of java.util.zip.CRC32.updateByteBuffer()86java_util_zip_CRC32C_updateBytes, // implementation of java.util.zip.CRC32C.updateBytes(crc, b[], off, end)87java_util_zip_CRC32C_updateDirectByteBuffer, // implementation of java.util.zip.CRC32C.updateDirectByteBuffer(crc, address, off, end)88java_lang_Float_intBitsToFloat, // implementation of java.lang.Float.intBitsToFloat()89java_lang_Float_floatToRawIntBits, // implementation of java.lang.Float.floatToRawIntBits()90java_lang_Double_longBitsToDouble, // implementation of java.lang.Double.longBitsToDouble()91java_lang_Double_doubleToRawLongBits, // implementation of java.lang.Double.doubleToRawLongBits()92number_of_method_entries,93invalid = -194};9596// Conversion from the part of the above enum to vmIntrinsics::_invokeExact, etc.97static vmIntrinsics::ID method_handle_intrinsic(MethodKind kind) {98if (kind >= method_handle_invoke_FIRST && kind <= method_handle_invoke_LAST)99return vmIntrinsics::ID_from(static_cast<int>(vmIntrinsics::FIRST_MH_SIG_POLY) + (kind - method_handle_invoke_FIRST));100else101return vmIntrinsics::_none;102}103104enum SomeConstants {105number_of_result_handlers = 10 // number of result handlers for native calls106};107108protected:109static StubQueue* _code; // the interpreter code (codelets)110111static bool _notice_safepoints; // true if safepoints are activated112113static address _native_entry_begin; // Region for native entry code114static address _native_entry_end;115116// method entry points117static address _entry_table[number_of_method_entries]; // entry points for a given method118static address _native_abi_to_tosca[number_of_result_handlers]; // for native method result handlers119static address _slow_signature_handler; // the native method generic (slow) signature handler120121static address _rethrow_exception_entry; // rethrows an activation in previous frame122123friend class AbstractInterpreterGenerator;124friend class InterpreterMacroAssembler;125126public:127// Initialization/debugging128static void initialize();129static StubQueue* code() { return _code; }130131132// Method activation133static MethodKind method_kind(const methodHandle& m);134static address entry_for_kind(MethodKind k) { assert(0 <= k && k < number_of_method_entries, "illegal kind"); return _entry_table[k]; }135static address entry_for_method(const methodHandle& m) { return entry_for_kind(method_kind(m)); }136137// used for bootstrapping method handles:138static void set_entry_for_kind(MethodKind k, address e);139140static void print_method_kind(MethodKind kind) PRODUCT_RETURN;141142// These should never be compiled since the interpreter will prefer143// the compiled version to the intrinsic version.144static bool can_be_compiled(const methodHandle& m) {145switch (m->intrinsic_id()) {146case vmIntrinsics::_dsin : // fall thru147case vmIntrinsics::_dcos : // fall thru148case vmIntrinsics::_dtan : // fall thru149case vmIntrinsics::_dabs : // fall thru150case vmIntrinsics::_dsqrt : // fall thru151case vmIntrinsics::_dlog : // fall thru152case vmIntrinsics::_dlog10: // fall thru153case vmIntrinsics::_dpow : // fall thru154case vmIntrinsics::_dexp : // fall thru155case vmIntrinsics::_fmaD : // fall thru156case vmIntrinsics::_fmaF : // fall thru157return false;158default:159return true;160}161}162163// Runtime support164165// length = invoke bytecode length (to advance to next bytecode)166static address deopt_entry(TosState state, int length) { ShouldNotReachHere(); return NULL; }167static address return_entry(TosState state, int length, Bytecodes::Code code) { ShouldNotReachHere(); return NULL; }168169static address rethrow_exception_entry() { return _rethrow_exception_entry; }170171// Activation size in words for a method that is just being called.172// Parameters haven't been pushed so count them too.173static int size_top_interpreter_activation(Method* method);174175// Deoptimization support176// Compute the entry address for continuation after177static address deopt_continue_after_entry(Method* method,178address bcp,179int callee_parameters,180bool is_top_frame);181// Compute the entry address for reexecution182static address deopt_reexecute_entry(Method* method, address bcp);183// Deoptimization should reexecute this bytecode184static bool bytecode_should_reexecute(Bytecodes::Code code);185186// deoptimization support187static int size_activation(int max_stack,188int temps,189int extra_args,190int monitors,191int callee_params,192int callee_locals,193bool is_top_frame);194195static void layout_activation(Method* method,196int temps,197int popframe_args,198int monitors,199int caller_actual_parameters,200int callee_params,201int callee_locals,202frame* caller,203frame* interpreter_frame,204bool is_top_frame,205bool is_bottom_frame);206207// Runtime support208static bool is_not_reached(const methodHandle& method, int bci);209// Safepoint support210static void notice_safepoints() { ShouldNotReachHere(); } // stops the thread when reaching a safepoint211static void ignore_safepoints() { ShouldNotReachHere(); } // ignores safepoints212213// Support for native calls214static address slow_signature_handler() { return _slow_signature_handler; }215static address result_handler(BasicType type) { return _native_abi_to_tosca[BasicType_as_index(type)]; }216static int BasicType_as_index(BasicType type); // computes index into result_handler_by_index table217static bool in_native_entry(address pc) { return _native_entry_begin <= pc && pc < _native_entry_end; }218// Debugging/printing219static void print(); // prints the interpreter code220221public:222// Interpreter helpers223const static int stackElementWords = 1;224const static int stackElementSize = stackElementWords * wordSize;225const static int logStackElementSize = LogBytesPerWord;226227static int expr_index_at(int i) {228return stackElementWords * i;229}230231static int expr_offset_in_bytes(int i) {232#if !defined(ZERO) && (defined(PPC) || defined(S390))233return stackElementSize * i + wordSize; // both point to one word past TOS234#else235return stackElementSize * i;236#endif237}238239static int local_index_at(int i) {240assert(i <= 0, "local direction already negated");241return stackElementWords * i;242}243244#if !defined(ZERO) && (defined(IA32) || defined(AMD64))245static Address::ScaleFactor stackElementScale() {246return NOT_LP64(Address::times_4) LP64_ONLY(Address::times_8);247}248#endif249250// Local values relative to locals[n]251static int local_offset_in_bytes(int n) {252return ((frame::interpreter_frame_expression_stack_direction() * n) * stackElementSize);253}254255// access to stacked values according to type:256static oop* oop_addr_in_slot(intptr_t* slot_addr) {257return (oop*) slot_addr;258}259static jint* int_addr_in_slot(intptr_t* slot_addr) {260if ((int) sizeof(jint) < wordSize && !Endian::is_Java_byte_ordering_different())261// big-endian LP64262return (jint*)(slot_addr + 1) - 1;263else264return (jint*) slot_addr;265}266static jlong long_in_slot(intptr_t* slot_addr) {267if (sizeof(intptr_t) >= sizeof(jlong)) {268return *(jlong*) slot_addr;269} else {270return Bytes::get_native_u8((address)slot_addr);271}272}273static void set_long_in_slot(intptr_t* slot_addr, jlong value) {274if (sizeof(intptr_t) >= sizeof(jlong)) {275*(jlong*) slot_addr = value;276} else {277Bytes::put_native_u8((address)slot_addr, value);278}279}280281static void initialize_method_handle_entries();282};283284//------------------------------------------------------------------------------------------------------------------------285// The interpreter generator.286287class Template;288class AbstractInterpreterGenerator: public StackObj {289protected:290InterpreterMacroAssembler* _masm;291292public:293AbstractInterpreterGenerator(StubQueue* _code);294};295296#endif // SHARE_INTERPRETER_ABSTRACTINTERPRETER_HPP297298299