8306851: Move Method access flags
Reviewed-by: cjplummer, dholmes, dnsimon, matsaave, fparain
This commit is contained in:
parent
a6b4f25bd5
commit
316d303c1d
@ -84,8 +84,8 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) :
|
||||
_code_size = h_m->code_size();
|
||||
_handler_count = h_m->exception_table_length();
|
||||
_size_of_parameters = h_m->size_of_parameters();
|
||||
_uses_monitors = h_m->access_flags().has_monitor_bytecodes();
|
||||
_balanced_monitors = !_uses_monitors || h_m->access_flags().is_monitor_matching();
|
||||
_uses_monitors = h_m->has_monitor_bytecodes();
|
||||
_balanced_monitors = !_uses_monitors || h_m->guaranteed_monitor_matching();
|
||||
_is_c1_compilable = !h_m->is_not_c1_compilable();
|
||||
_is_c2_compilable = !h_m->is_not_c2_compilable();
|
||||
_can_be_parsed = true;
|
||||
|
@ -1978,27 +1978,27 @@ ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector() {
|
||||
|
||||
void MethodAnnotationCollector::apply_to(const methodHandle& m) {
|
||||
if (has_annotation(_method_CallerSensitive))
|
||||
m->set_caller_sensitive(true);
|
||||
m->set_caller_sensitive();
|
||||
if (has_annotation(_method_ForceInline))
|
||||
m->set_force_inline(true);
|
||||
m->set_force_inline();
|
||||
if (has_annotation(_method_DontInline))
|
||||
m->set_dont_inline(true);
|
||||
m->set_dont_inline();
|
||||
if (has_annotation(_method_ChangesCurrentThread))
|
||||
m->set_changes_current_thread(true);
|
||||
m->set_changes_current_thread();
|
||||
if (has_annotation(_method_JvmtiMountTransition))
|
||||
m->set_jvmti_mount_transition(true);
|
||||
m->set_jvmti_mount_transition();
|
||||
if (has_annotation(_method_InjectedProfile))
|
||||
m->set_has_injected_profile(true);
|
||||
m->set_has_injected_profile();
|
||||
if (has_annotation(_method_LambdaForm_Compiled) && m->intrinsic_id() == vmIntrinsics::_none)
|
||||
m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm);
|
||||
if (has_annotation(_method_Hidden))
|
||||
m->set_hidden(true);
|
||||
m->set_is_hidden();
|
||||
if (has_annotation(_method_Scoped))
|
||||
m->set_scoped(true);
|
||||
m->set_scoped();
|
||||
if (has_annotation(_method_IntrinsicCandidate) && !m->is_synthetic())
|
||||
m->set_intrinsic_candidate(true);
|
||||
m->set_intrinsic_candidate();
|
||||
if (has_annotation(_jdk_internal_vm_annotation_ReservedStackAccess))
|
||||
m->set_has_reserved_stack_access(true);
|
||||
m->set_has_reserved_stack_access();
|
||||
}
|
||||
|
||||
void ClassFileParser::ClassAnnotationCollector::apply_to(InstanceKlass* ik) {
|
||||
@ -2739,7 +2739,7 @@ Method* ClassFileParser::parse_method(const ClassFileStream* const cfs,
|
||||
parsed_annotations.apply_to(methodHandle(THREAD, m));
|
||||
|
||||
if (is_hidden()) { // Mark methods in hidden classes as 'hidden'.
|
||||
m->set_hidden(true);
|
||||
m->set_is_hidden();
|
||||
}
|
||||
|
||||
// Copy annotations
|
||||
|
@ -476,7 +476,7 @@ ExceptionMessageBuilder::ExceptionMessageBuilder(Method* method, int bci) :
|
||||
_stacks->at_put(0, new SimulatedOperandStack());
|
||||
|
||||
// And initialize the start of all exception handlers.
|
||||
if (const_method->has_exception_handler()) {
|
||||
if (const_method->has_exception_table()) {
|
||||
ExceptionTableElement *et = const_method->exception_table_start();
|
||||
for (int i = 0; i < const_method->exception_table_length(); ++i) {
|
||||
u2 index = et[i].handler_pc;
|
||||
|
@ -473,7 +473,7 @@ void Rewriter::scan_method(Thread* thread, Method* method, bool reverse, bool* i
|
||||
}
|
||||
}
|
||||
|
||||
// Update access flags
|
||||
// Update flags
|
||||
if (has_monitor_bytecodes) {
|
||||
method->set_has_monitor_bytecodes();
|
||||
}
|
||||
@ -482,8 +482,6 @@ void Rewriter::scan_method(Thread* thread, Method* method, bool reverse, bool* i
|
||||
// have to be rewritten, so we run the oopMapGenerator on the method
|
||||
if (nof_jsrs > 0) {
|
||||
method->set_has_jsrs();
|
||||
// Second pass will revisit this method.
|
||||
assert(method->has_jsrs(), "didn't we just set this?");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -926,8 +926,8 @@ C2V_END
|
||||
|
||||
C2V_VMENTRY(void, setNotInlinableOrCompilable,(JNIEnv* env, jobject, ARGUMENT_PAIR(method)))
|
||||
methodHandle method(THREAD, UNPACK_PAIR(Method, method));
|
||||
method->set_not_c1_compilable();
|
||||
method->set_not_c2_compilable();
|
||||
method->set_is_not_c1_compilable();
|
||||
method->set_is_not_c2_compilable();
|
||||
method->set_dont_inline(true);
|
||||
C2V_END
|
||||
|
||||
|
@ -129,7 +129,7 @@
|
||||
nonstatic_field(ConstantPool, _source_file_name_index, u2) \
|
||||
\
|
||||
nonstatic_field(ConstMethod, _constants, ConstantPool*) \
|
||||
nonstatic_field(ConstMethod, _flags, u2) \
|
||||
nonstatic_field(ConstMethod, _flags._flags, u4) \
|
||||
nonstatic_field(ConstMethod, _code_size, u2) \
|
||||
nonstatic_field(ConstMethod, _name_index, u2) \
|
||||
nonstatic_field(ConstMethod, _signature_index, u2) \
|
||||
@ -228,7 +228,7 @@
|
||||
nonstatic_field(Method, _access_flags, AccessFlags) \
|
||||
nonstatic_field(Method, _vtable_index, int) \
|
||||
nonstatic_field(Method, _intrinsic_id, u2) \
|
||||
nonstatic_field(Method, _flags, u2) \
|
||||
nonstatic_field(Method, _flags._status, u4) \
|
||||
volatile_nonstatic_field(Method, _code, CompiledMethod*) \
|
||||
volatile_nonstatic_field(Method, _from_compiled_entry, address) \
|
||||
\
|
||||
@ -416,8 +416,6 @@
|
||||
declare_constant(JVMCINMethodData::SPECULATION_LENGTH_BITS) \
|
||||
\
|
||||
declare_constant(JVM_ACC_WRITTEN_FLAGS) \
|
||||
declare_constant(JVM_ACC_MONITOR_MATCH) \
|
||||
declare_constant(JVM_ACC_HAS_MONITOR_BYTECODES) \
|
||||
declare_constant(JVM_ACC_HAS_FINALIZER) \
|
||||
declare_constant(JVM_ACC_IS_CLONEABLE_FAST) \
|
||||
declare_constant(JVM_ACC_IS_HIDDEN_CLASS) \
|
||||
@ -582,11 +580,16 @@
|
||||
declare_constant(ConstantPool::CPCACHE_INDEX_TAG) \
|
||||
declare_constant(ConstantPool::_has_dynamic_constant) \
|
||||
\
|
||||
declare_constant(ConstMethod::_has_linenumber_table) \
|
||||
declare_constant(ConstMethod::_has_localvariable_table) \
|
||||
declare_constant(ConstMethod::_has_exception_table) \
|
||||
declare_constant(ConstMethod::_has_method_annotations) \
|
||||
declare_constant(ConstMethod::_has_parameter_annotations) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_linenumber_table) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_localvariable_table) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_exception_table) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_method_annotations) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_parameter_annotations) \
|
||||
declare_constant(ConstMethodFlags::_misc_caller_sensitive) \
|
||||
declare_constant(ConstMethodFlags::_misc_is_hidden) \
|
||||
declare_constant(ConstMethodFlags::_misc_intrinsic_candidate) \
|
||||
declare_constant(ConstMethodFlags::_misc_reserved_stack_access) \
|
||||
declare_constant(ConstMethodFlags::_misc_changes_current_thread) \
|
||||
\
|
||||
declare_constant(CounterData::count_off) \
|
||||
\
|
||||
@ -683,13 +686,8 @@
|
||||
\
|
||||
declare_constant(markWord::no_hash) \
|
||||
\
|
||||
declare_constant(Method::_caller_sensitive) \
|
||||
declare_constant(Method::_force_inline) \
|
||||
declare_constant(Method::_dont_inline) \
|
||||
declare_constant(Method::_hidden) \
|
||||
declare_constant(Method::_intrinsic_candidate) \
|
||||
declare_constant(Method::_reserved_stack_access) \
|
||||
declare_constant(Method::_changes_current_thread) \
|
||||
declare_constant(MethodFlags::_misc_force_inline) \
|
||||
declare_constant(MethodFlags::_misc_dont_inline) \
|
||||
\
|
||||
declare_constant(Method::nonvirtual_vtable_index) \
|
||||
declare_constant(Method::invalid_vtable_index) \
|
||||
|
@ -199,7 +199,7 @@ u2* ConstMethod::checked_exceptions_length_addr() const {
|
||||
}
|
||||
|
||||
u2* ConstMethod::exception_table_length_addr() const {
|
||||
assert(has_exception_handler(), "called only if table is present");
|
||||
assert(has_exception_table(), "called only if table is present");
|
||||
if (has_checked_exceptions()) {
|
||||
// If checked_exception present, locate immediately before them.
|
||||
return (u2*) checked_exceptions_start() - 1;
|
||||
@ -217,7 +217,7 @@ u2* ConstMethod::exception_table_length_addr() const {
|
||||
|
||||
u2* ConstMethod::localvariable_table_length_addr() const {
|
||||
assert(has_localvariable_table(), "called only if table is present");
|
||||
if (has_exception_handler()) {
|
||||
if (has_exception_table()) {
|
||||
// If exception_table present, locate immediately before them.
|
||||
return (u2*) exception_table_start() - 1;
|
||||
} else {
|
||||
@ -239,30 +239,29 @@ u2* ConstMethod::localvariable_table_length_addr() const {
|
||||
|
||||
// Update the flags to indicate the presence of these optional fields.
|
||||
void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) {
|
||||
_flags = 0;
|
||||
if (sizes->compressed_linenumber_size() > 0)
|
||||
_flags |= _has_linenumber_table;
|
||||
set_has_linenumber_table();
|
||||
if (sizes->generic_signature_index() != 0)
|
||||
_flags |= _has_generic_signature;
|
||||
set_has_generic_signature();
|
||||
if (sizes->method_parameters_length() >= 0)
|
||||
_flags |= _has_method_parameters;
|
||||
set_has_method_parameters();
|
||||
if (sizes->checked_exceptions_length() > 0)
|
||||
_flags |= _has_checked_exceptions;
|
||||
set_has_checked_exceptions();
|
||||
if (sizes->exception_table_length() > 0)
|
||||
_flags |= _has_exception_table;
|
||||
set_has_exception_table();
|
||||
if (sizes->localvariable_table_length() > 0)
|
||||
_flags |= _has_localvariable_table;
|
||||
set_has_localvariable_table();
|
||||
|
||||
// annotations, they are all pointer sized embedded objects so don't have
|
||||
// a length embedded also.
|
||||
if (sizes->method_annotations_length() > 0)
|
||||
_flags |= _has_method_annotations;
|
||||
set_has_method_annotations();
|
||||
if (sizes->parameter_annotations_length() > 0)
|
||||
_flags |= _has_parameter_annotations;
|
||||
set_has_parameter_annotations();
|
||||
if (sizes->type_annotations_length() > 0)
|
||||
_flags |= _has_type_annotations;
|
||||
set_has_type_annotations();
|
||||
if (sizes->default_annotations_length() > 0)
|
||||
_flags |= _has_default_annotations;
|
||||
set_has_default_annotations();
|
||||
|
||||
// This code is extremely brittle and should possibly be revised.
|
||||
// The *_length_addr functions walk backwards through the
|
||||
@ -329,7 +328,7 @@ LocalVariableTableElement* ConstMethod::localvariable_table_start() const {
|
||||
}
|
||||
|
||||
int ConstMethod::exception_table_length() const {
|
||||
return has_exception_handler() ? *(exception_table_length_addr()) : 0;
|
||||
return has_exception_table() ? *(exception_table_length_addr()) : 0;
|
||||
}
|
||||
|
||||
ExceptionTableElement* ConstMethod::exception_table_start() const {
|
||||
@ -431,13 +430,14 @@ void ConstMethod::print_on(outputStream* st) const {
|
||||
ResourceMark rm;
|
||||
st->print_cr("%s", internal_name());
|
||||
Method* m = method();
|
||||
st->print(" - method: " PTR_FORMAT " ", p2i(m));
|
||||
st->print(" - method: " PTR_FORMAT " ", p2i(m));
|
||||
if (m != nullptr) {
|
||||
m->print_value_on(st);
|
||||
}
|
||||
st->cr();
|
||||
st->print(" - flags: 0x%x ", _flags.as_int()); _flags.print_on(st); st->cr();
|
||||
if (has_stackmap_table()) {
|
||||
st->print(" - stackmap data: ");
|
||||
st->print(" - stackmap data: ");
|
||||
stackmap_data()->print_value_on(st);
|
||||
st->cr();
|
||||
}
|
||||
@ -484,7 +484,7 @@ void ConstMethod::verify_on(outputStream* st) {
|
||||
u2* addr = checked_exceptions_length_addr();
|
||||
guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
|
||||
}
|
||||
if (has_exception_handler()) {
|
||||
if (has_exception_table()) {
|
||||
u2* addr = exception_table_length_addr();
|
||||
guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
|
||||
}
|
||||
@ -496,7 +496,7 @@ void ConstMethod::verify_on(outputStream* st) {
|
||||
u2* uncompressed_table_start;
|
||||
if (has_localvariable_table()) {
|
||||
uncompressed_table_start = (u2*) localvariable_table_start();
|
||||
} else if (has_exception_handler()) {
|
||||
} else if (has_exception_table()) {
|
||||
uncompressed_table_start = (u2*) exception_table_start();
|
||||
} else if (has_checked_exceptions()) {
|
||||
uncompressed_table_start = (u2*) checked_exceptions_start();
|
||||
|
@ -25,6 +25,7 @@
|
||||
#ifndef SHARE_OOPS_CONSTMETHOD_HPP
|
||||
#define SHARE_OOPS_CONSTMETHOD_HPP
|
||||
|
||||
#include "oops/constMethodFlags.hpp"
|
||||
#include "oops/oop.hpp"
|
||||
#include "utilities/align.hpp"
|
||||
|
||||
@ -173,19 +174,6 @@ public:
|
||||
typedef enum { NORMAL, OVERPASS } MethodType;
|
||||
|
||||
private:
|
||||
enum {
|
||||
_has_linenumber_table = 0x0001,
|
||||
_has_checked_exceptions = 0x0002,
|
||||
_has_localvariable_table = 0x0004,
|
||||
_has_exception_table = 0x0008,
|
||||
_has_generic_signature = 0x0010,
|
||||
_has_method_parameters = 0x0020,
|
||||
_is_overpass = 0x0040,
|
||||
_has_method_annotations = 0x0080,
|
||||
_has_parameter_annotations = 0x0100,
|
||||
_has_type_annotations = 0x0200,
|
||||
_has_default_annotations = 0x0400
|
||||
};
|
||||
|
||||
// Bit vector of signature
|
||||
// Callers interpret 0=not initialized yet and
|
||||
@ -204,7 +192,7 @@ private:
|
||||
Array<u1>* _stackmap_data;
|
||||
|
||||
int _constMethod_size;
|
||||
u2 _flags;
|
||||
ConstMethodFlags _flags; // for sizing
|
||||
u1 _result_type; // BasicType of result
|
||||
|
||||
// Size of Java bytecodes allocated immediately after Method*.
|
||||
@ -236,33 +224,20 @@ public:
|
||||
// Inlined tables
|
||||
void set_inlined_tables_length(InlineTableSizes* sizes);
|
||||
|
||||
bool has_generic_signature() const
|
||||
{ return (_flags & _has_generic_signature) != 0; }
|
||||
|
||||
bool has_linenumber_table() const
|
||||
{ return (_flags & _has_linenumber_table) != 0; }
|
||||
|
||||
bool has_checked_exceptions() const
|
||||
{ return (_flags & _has_checked_exceptions) != 0; }
|
||||
|
||||
bool has_localvariable_table() const
|
||||
{ return (_flags & _has_localvariable_table) != 0; }
|
||||
|
||||
bool has_exception_handler() const
|
||||
{ return (_flags & _has_exception_table) != 0; }
|
||||
|
||||
bool has_method_parameters() const
|
||||
{ return (_flags & _has_method_parameters) != 0; }
|
||||
// Create getters and setters for the flag values.
|
||||
#define CM_FLAGS_GET_SET(name, ignore) \
|
||||
bool name() const { return _flags.name(); } \
|
||||
void set_##name() { _flags.set_##name(); }
|
||||
CM_FLAGS_DO(CM_FLAGS_GET_SET)
|
||||
#undef CM_FLAGS_GET_SET
|
||||
|
||||
MethodType method_type() const {
|
||||
return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS;
|
||||
return (_flags.is_overpass()) ? OVERPASS : NORMAL;
|
||||
}
|
||||
|
||||
void set_method_type(MethodType mt) {
|
||||
if (mt == NORMAL) {
|
||||
_flags &= ~(_is_overpass);
|
||||
} else {
|
||||
_flags |= _is_overpass;
|
||||
if (mt != NORMAL) {
|
||||
set_is_overpass();
|
||||
}
|
||||
}
|
||||
|
||||
@ -382,20 +357,6 @@ public:
|
||||
int method_parameters_length() const;
|
||||
MethodParametersElement* method_parameters_start() const;
|
||||
|
||||
// method annotations
|
||||
bool has_method_annotations() const
|
||||
{ return (_flags & _has_method_annotations) != 0; }
|
||||
|
||||
bool has_parameter_annotations() const
|
||||
{ return (_flags & _has_parameter_annotations) != 0; }
|
||||
|
||||
bool has_type_annotations() const
|
||||
{ return (_flags & _has_type_annotations) != 0; }
|
||||
|
||||
bool has_default_annotations() const
|
||||
{ return (_flags & _has_default_annotations) != 0; }
|
||||
|
||||
|
||||
AnnotationArray** method_annotations_addr() const;
|
||||
AnnotationArray* method_annotations() const {
|
||||
return has_method_annotations() ? *(method_annotations_addr()) : nullptr;
|
||||
|
35
src/hotspot/share/oops/constMethodFlags.cpp
Normal file
35
src/hotspot/share/oops/constMethodFlags.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "oops/constMethodFlags.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
void ConstMethodFlags::print_on(outputStream* st) const {
|
||||
#define CM_PRINT(name, ignore) \
|
||||
if (name()) st->print(" " #name " ");
|
||||
CM_FLAGS_DO(CM_PRINT)
|
||||
#undef CM_PRINT
|
||||
}
|
89
src/hotspot/share/oops/constMethodFlags.hpp
Normal file
89
src/hotspot/share/oops/constMethodFlags.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_OOPS_CONSTMETHODFLAGS_HPP
|
||||
#define SHARE_OOPS_CONSTMETHODFLAGS_HPP
|
||||
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
class outputStream;
|
||||
|
||||
// The ConstMethodFlags class contains the parse-time flags associated with
|
||||
// a Method, and its associated accessors.
|
||||
// These flags are JVM internal and not part of the AccessFlags classfile specification.
|
||||
|
||||
class ConstMethodFlags {
|
||||
friend class VMStructs;
|
||||
friend class JVMCIVMStructs;
|
||||
|
||||
#define CM_FLAGS_DO(flag) \
|
||||
flag(has_linenumber_table , 1 << 0) \
|
||||
flag(has_checked_exceptions , 1 << 1) \
|
||||
flag(has_localvariable_table , 1 << 2) \
|
||||
flag(has_exception_table , 1 << 3) \
|
||||
flag(has_generic_signature , 1 << 4) \
|
||||
flag(has_method_parameters , 1 << 5) \
|
||||
flag(is_overpass , 1 << 6) \
|
||||
flag(has_method_annotations , 1 << 7) \
|
||||
flag(has_parameter_annotations , 1 << 8) \
|
||||
flag(has_type_annotations , 1 << 9) \
|
||||
flag(has_default_annotations , 1 << 10) \
|
||||
flag(caller_sensitive , 1 << 11) \
|
||||
flag(is_hidden , 1 << 12) \
|
||||
flag(has_injected_profile , 1 << 13) \
|
||||
flag(intrinsic_candidate , 1 << 14) \
|
||||
flag(reserved_stack_access , 1 << 15) \
|
||||
flag(is_scoped , 1 << 16) \
|
||||
flag(changes_current_thread , 1 << 17) \
|
||||
flag(jvmti_mount_transition , 1 << 18) \
|
||||
/* end of list */
|
||||
|
||||
#define CM_FLAGS_ENUM_NAME(name, value) _misc_##name = value,
|
||||
enum {
|
||||
CM_FLAGS_DO(CM_FLAGS_ENUM_NAME)
|
||||
};
|
||||
#undef CM_FLAGS_ENUM_NAME
|
||||
|
||||
// These flags are write-once before the class is published and then read-only so don't require atomic updates.
|
||||
u4 _flags;
|
||||
|
||||
public:
|
||||
|
||||
ConstMethodFlags() : _flags(0) {}
|
||||
|
||||
// Create getters and setters for the flag values.
|
||||
#define CM_FLAGS_GET_SET(name, ignore) \
|
||||
bool name() const { return (_flags & _misc_##name) != 0; } \
|
||||
void set_##name() { \
|
||||
_flags |= _misc_##name; \
|
||||
}
|
||||
CM_FLAGS_DO(CM_FLAGS_GET_SET)
|
||||
#undef CM_FLAGS_GET_SET
|
||||
|
||||
int as_int() const { return _flags; }
|
||||
void print_on(outputStream* st) const;
|
||||
};
|
||||
|
||||
#endif // SHARE_OOPS_CONSTMETHODFLAGS_HPP
|
@ -3477,6 +3477,7 @@ void InstanceKlass::print_on(outputStream* st) const {
|
||||
st->print(BULLET"instance size: %d", size_helper()); st->cr();
|
||||
st->print(BULLET"klass size: %d", size()); st->cr();
|
||||
st->print(BULLET"access: "); access_flags().print_on(st); st->cr();
|
||||
st->print(BULLET"flags: "); _misc_flags.print_on(st); st->cr();
|
||||
st->print(BULLET"state: "); st->print_cr("%s", init_state_name());
|
||||
st->print(BULLET"name: "); name()->print_value_on(st); st->cr();
|
||||
st->print(BULLET"super: "); Metadata::print_value_on_maybe_null(st, super()); st->cr();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 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
|
||||
@ -29,6 +29,7 @@
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
// This can be removed for the atomic bitset functions, when available.
|
||||
void InstanceKlassFlags::atomic_set_bits(u1 bits) {
|
||||
@ -51,6 +52,15 @@ void InstanceKlassFlags::atomic_clear_bits(u1 bits) {
|
||||
} while(f != old_status);
|
||||
}
|
||||
|
||||
void InstanceKlassFlags::print_on(outputStream* st) const {
|
||||
#define IK_FLAGS_PRINT(name, ignore) \
|
||||
if (name()) st->print(" ##name ");
|
||||
IK_FLAGS_DO(IK_FLAGS_PRINT)
|
||||
IK_STATUS_DO(IK_FLAGS_PRINT)
|
||||
#undef IK_FLAGS_PRINT
|
||||
st->cr();
|
||||
}
|
||||
|
||||
#if INCLUDE_CDS
|
||||
void InstanceKlassFlags::set_shared_class_loader_type(s2 loader_type) {
|
||||
switch (loader_type) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2023, 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
|
||||
@ -66,7 +66,8 @@ class InstanceKlassFlags {
|
||||
status(has_resolved_methods , 1 << 1) /* True if the klass has resolved MethodHandle methods */ \
|
||||
status(has_been_redefined , 1 << 2) /* class has been redefined */ \
|
||||
status(is_scratch_class , 1 << 3) /* class is the redefined scratch class */ \
|
||||
status(is_marked_dependent , 1 << 4) /* class is the redefined scratch class */
|
||||
status(is_marked_dependent , 1 << 4) /* class is the redefined scratch class */ \
|
||||
/* end of list */
|
||||
|
||||
#define IK_STATUS_ENUM_NAME(name, value) _misc_##name = value,
|
||||
enum {
|
||||
@ -89,18 +90,14 @@ class InstanceKlassFlags {
|
||||
InstanceKlassFlags() : _flags(0), _status(0) {}
|
||||
|
||||
// Create getters and setters for the flag values.
|
||||
#define IK_FLAGS_GET(name, ignore) \
|
||||
bool name() const { return (_flags & _misc_##name) != 0; }
|
||||
IK_FLAGS_DO(IK_FLAGS_GET)
|
||||
#undef IK_FLAGS_GET
|
||||
|
||||
#define IK_FLAGS_SET(name, ignore) \
|
||||
#define IK_FLAGS_GET_SET(name, ignore) \
|
||||
bool name() const { return (_flags & _misc_##name) != 0; } \
|
||||
void set_##name(bool b) { \
|
||||
assert_is_safe(name()); \
|
||||
if (b) _flags |= _misc_##name; \
|
||||
}
|
||||
IK_FLAGS_DO(IK_FLAGS_SET)
|
||||
#undef IK_FLAGS_SET
|
||||
IK_FLAGS_DO(IK_FLAGS_GET_SET)
|
||||
#undef IK_FLAGS_GET_SET
|
||||
|
||||
bool is_shared_unregistered_class() const {
|
||||
return (_flags & shared_loader_type_bits()) == 0;
|
||||
@ -112,12 +109,8 @@ class InstanceKlassFlags {
|
||||
void assert_is_safe(bool set) NOT_DEBUG_RETURN;
|
||||
|
||||
// Create getters and setters for the status values.
|
||||
#define IK_STATUS_GET(name, ignore) \
|
||||
bool name() const { return (_status & _misc_##name) != 0; }
|
||||
IK_STATUS_DO(IK_STATUS_GET)
|
||||
#undef IK_STATUS_GET
|
||||
|
||||
#define IK_STATUS_SET(name, ignore) \
|
||||
#define IK_STATUS_GET_SET(name, ignore) \
|
||||
bool name() const { return (_status & _misc_##name) != 0; } \
|
||||
void set_##name(bool b) { \
|
||||
if (b) { \
|
||||
atomic_set_bits(_misc_##name); \
|
||||
@ -125,11 +118,12 @@ class InstanceKlassFlags {
|
||||
atomic_clear_bits(_misc_##name); \
|
||||
} \
|
||||
}
|
||||
IK_STATUS_DO(IK_STATUS_SET)
|
||||
#undef IK_STATUS_SET
|
||||
IK_STATUS_DO(IK_STATUS_GET_SET)
|
||||
#undef IK_STATUS_GET_SET
|
||||
|
||||
void atomic_set_bits(u1 bits);
|
||||
void atomic_clear_bits(u1 bits);
|
||||
void print_on(outputStream* st) const;
|
||||
};
|
||||
|
||||
#endif // SHARE_OOPS_INSTANCEKLASSFLAGS_HPP
|
||||
|
@ -102,11 +102,6 @@ Method::Method(ConstMethod* xconst, AccessFlags access_flags, Symbol* name) {
|
||||
set_constMethod(xconst);
|
||||
set_access_flags(access_flags);
|
||||
set_intrinsic_id(vmIntrinsics::_none);
|
||||
set_force_inline(false);
|
||||
set_hidden(false);
|
||||
set_dont_inline(false);
|
||||
set_changes_current_thread(false);
|
||||
set_has_injected_profile(false);
|
||||
set_method_data(nullptr);
|
||||
clear_method_counters();
|
||||
set_vtable_index(Method::garbage_vtable_index);
|
||||
@ -736,24 +731,27 @@ bool Method::compute_has_loops_flag() {
|
||||
case Bytecodes::_if_acmpne:
|
||||
case Bytecodes::_goto:
|
||||
case Bytecodes::_jsr:
|
||||
if (bcs.dest() < bcs.next_bci()) _access_flags.set_has_loops();
|
||||
if (bcs.dest() < bcs.next_bci()) {
|
||||
return set_has_loops();
|
||||
}
|
||||
break;
|
||||
|
||||
case Bytecodes::_goto_w:
|
||||
case Bytecodes::_jsr_w:
|
||||
if (bcs.dest_w() < bcs.next_bci()) _access_flags.set_has_loops();
|
||||
if (bcs.dest_w() < bcs.next_bci()) {
|
||||
return set_has_loops();
|
||||
}
|
||||
break;
|
||||
|
||||
case Bytecodes::_lookupswitch: {
|
||||
Bytecode_lookupswitch lookupswitch(this, bcs.bcp());
|
||||
if (lookupswitch.default_offset() < 0) {
|
||||
_access_flags.set_has_loops();
|
||||
return set_has_loops();
|
||||
} else {
|
||||
for (int i = 0; i < lookupswitch.number_of_pairs(); ++i) {
|
||||
LookupswitchPair pair = lookupswitch.pair_at(i);
|
||||
if (pair.offset() < 0) {
|
||||
_access_flags.set_has_loops();
|
||||
break;
|
||||
return set_has_loops();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -762,11 +760,11 @@ bool Method::compute_has_loops_flag() {
|
||||
case Bytecodes::_tableswitch: {
|
||||
Bytecode_tableswitch tableswitch(this, bcs.bcp());
|
||||
if (tableswitch.default_offset() < 0) {
|
||||
_access_flags.set_has_loops();
|
||||
return set_has_loops();
|
||||
} else {
|
||||
for (int i = 0; i < tableswitch.length(); ++i) {
|
||||
if (tableswitch.dest_offset_at(i) < 0) {
|
||||
_access_flags.set_has_loops();
|
||||
return set_has_loops();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -776,8 +774,9 @@ bool Method::compute_has_loops_flag() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
_access_flags.set_loops_flag_init();
|
||||
return _access_flags.has_loops();
|
||||
|
||||
_flags.set_has_loops_flag_init(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Method::is_final_method(AccessFlags class_access_flags) const {
|
||||
@ -1108,13 +1107,13 @@ void Method::set_not_compilable(const char* reason, int comp_level, bool report)
|
||||
}
|
||||
print_made_not_compilable(comp_level, /*is_osr*/ false, report, reason);
|
||||
if (comp_level == CompLevel_all) {
|
||||
set_not_c1_compilable();
|
||||
set_not_c2_compilable();
|
||||
set_is_not_c1_compilable();
|
||||
set_is_not_c2_compilable();
|
||||
} else {
|
||||
if (is_c1_compile(comp_level))
|
||||
set_not_c1_compilable();
|
||||
set_is_not_c1_compilable();
|
||||
if (is_c2_compile(comp_level))
|
||||
set_not_c2_compilable();
|
||||
set_is_not_c2_compilable();
|
||||
}
|
||||
assert(!CompilationPolicy::can_be_compiled(methodHandle(Thread::current(), this), comp_level), "sanity check");
|
||||
}
|
||||
@ -1134,13 +1133,13 @@ bool Method::is_not_osr_compilable(int comp_level) const {
|
||||
void Method::set_not_osr_compilable(const char* reason, int comp_level, bool report) {
|
||||
print_made_not_compilable(comp_level, /*is_osr*/ true, report, reason);
|
||||
if (comp_level == CompLevel_all) {
|
||||
set_not_c1_osr_compilable();
|
||||
set_not_c2_osr_compilable();
|
||||
set_is_not_c1_osr_compilable();
|
||||
set_is_not_c2_osr_compilable();
|
||||
} else {
|
||||
if (is_c1_compile(comp_level))
|
||||
set_not_c1_osr_compilable();
|
||||
set_is_not_c1_osr_compilable();
|
||||
if (is_c2_compile(comp_level))
|
||||
set_not_c2_osr_compilable();
|
||||
set_is_not_c2_osr_compilable();
|
||||
}
|
||||
assert(!CompilationPolicy::can_be_osr_compiled(methodHandle(Thread::current(), this), comp_level), "sanity check");
|
||||
}
|
||||
@ -1663,7 +1662,7 @@ void Method::init_intrinsic_id(vmSymbolID klass_id) {
|
||||
set_intrinsic_id(id);
|
||||
if (id == vmIntrinsics::_Class_cast) {
|
||||
// Even if the intrinsic is rejected, we want to inline this simple method.
|
||||
set_force_inline(true);
|
||||
set_force_inline();
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -2241,8 +2240,8 @@ void Method::set_on_stack(const bool value) {
|
||||
// on stack means some method referring to it is also on the stack.
|
||||
constants()->set_on_stack(value);
|
||||
|
||||
bool already_set = on_stack();
|
||||
_access_flags.set_on_stack(value);
|
||||
bool already_set = on_stack_flag();
|
||||
set_on_stack_flag(value);
|
||||
if (value && !already_set) {
|
||||
MetadataOnStackMark::record(this);
|
||||
}
|
||||
@ -2304,6 +2303,7 @@ void Method::print_on(outputStream* st) const {
|
||||
st->print (" - constants: " PTR_FORMAT " ", p2i(constants()));
|
||||
constants()->print_value_on(st); st->cr();
|
||||
st->print (" - access: 0x%x ", access_flags().as_int()); access_flags().print_on(st); st->cr();
|
||||
st->print (" - flags: 0x%x ", _flags.as_int()); _flags.print_on(st); st->cr();
|
||||
st->print (" - name: "); name()->print_value_on(st); st->cr();
|
||||
st->print (" - signature: "); signature()->print_value_on(st); st->cr();
|
||||
st->print_cr(" - max stack: %d", max_stack());
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "oops/annotations.hpp"
|
||||
#include "oops/constantPool.hpp"
|
||||
#include "oops/methodCounters.hpp"
|
||||
#include "oops/methodFlags.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
#include "oops/oop.hpp"
|
||||
#include "oops/typeArrayOop.hpp"
|
||||
@ -79,23 +80,9 @@ class Method : public Metadata {
|
||||
AdapterHandlerEntry* _adapter;
|
||||
AccessFlags _access_flags; // Access flags
|
||||
int _vtable_index; // vtable index of this method (see VtableIndexFlag)
|
||||
// note: can have vtables with >2**16 elements (because of inheritance)
|
||||
u2 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none)
|
||||
MethodFlags _flags;
|
||||
|
||||
// Flags
|
||||
enum Flags {
|
||||
_caller_sensitive = 1 << 0,
|
||||
_force_inline = 1 << 1,
|
||||
_dont_inline = 1 << 2,
|
||||
_hidden = 1 << 3,
|
||||
_has_injected_profile = 1 << 4,
|
||||
_intrinsic_candidate = 1 << 5,
|
||||
_reserved_stack_access = 1 << 6,
|
||||
_scoped = 1 << 7,
|
||||
_changes_current_thread = 1 << 8,
|
||||
_jvmti_mount_transition = 1 << 9,
|
||||
};
|
||||
mutable u2 _flags;
|
||||
u2 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none)
|
||||
|
||||
JFR_ONLY(DEFINE_TRACE_FLAG;)
|
||||
|
||||
@ -332,7 +319,7 @@ class Method : public Metadata {
|
||||
|
||||
// exception handler table
|
||||
bool has_exception_handler() const
|
||||
{ return constMethod()->has_exception_handler(); }
|
||||
{ return constMethod()->has_exception_table(); }
|
||||
int exception_table_length() const
|
||||
{ return constMethod()->exception_table_length(); }
|
||||
ExceptionTableElement* exception_table_start() const
|
||||
@ -602,31 +589,35 @@ public:
|
||||
// true if method can omit stack trace in throw in compiled code.
|
||||
bool can_omit_stack_trace();
|
||||
|
||||
// Flags getting and setting.
|
||||
#define M_STATUS_GET_SET(name, ignore) \
|
||||
bool name() const { return _flags.name(); } \
|
||||
void set_##name(bool x) { _flags.set_##name(x); } \
|
||||
void set_##name() { _flags.set_##name(true); }
|
||||
M_STATUS_DO(M_STATUS_GET_SET)
|
||||
#undef M_STATUS_GET_SET
|
||||
|
||||
// returns true if the method has any backward branches.
|
||||
bool has_loops() {
|
||||
return access_flags().loops_flag_init() ? access_flags().has_loops() : compute_has_loops_flag();
|
||||
return has_loops_flag_init() ? has_loops_flag() : compute_has_loops_flag();
|
||||
};
|
||||
|
||||
bool compute_has_loops_flag();
|
||||
|
||||
bool has_jsrs() {
|
||||
return access_flags().has_jsrs();
|
||||
};
|
||||
void set_has_jsrs() {
|
||||
_access_flags.set_has_jsrs();
|
||||
bool set_has_loops() {
|
||||
// set both the flags and that it's been initialized.
|
||||
set_has_loops_flag();
|
||||
set_has_loops_flag_init();
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns true if the method has any monitors.
|
||||
bool has_monitors() const { return is_synchronized() || access_flags().has_monitor_bytecodes(); }
|
||||
bool has_monitor_bytecodes() const { return access_flags().has_monitor_bytecodes(); }
|
||||
|
||||
void set_has_monitor_bytecodes() { _access_flags.set_has_monitor_bytecodes(); }
|
||||
bool has_monitors() const { return is_synchronized() || has_monitor_bytecodes(); }
|
||||
|
||||
// monitor matching. This returns a conservative estimate of whether the monitorenter/monitorexit bytecodes
|
||||
// propererly nest in the method. It might return false, even though they actually nest properly, since the info.
|
||||
// properly nest in the method. It might return false, even though they actually nest properly, since the info.
|
||||
// has not been computed yet.
|
||||
bool guaranteed_monitor_matching() const { return access_flags().is_monitor_matching(); }
|
||||
void set_guaranteed_monitor_matching() { _access_flags.set_monitor_matching(); }
|
||||
bool guaranteed_monitor_matching() const { return monitor_matching(); }
|
||||
void set_guaranteed_monitor_matching() { set_monitor_matching(); }
|
||||
|
||||
// returns true if the method is an accessor function (setter/getter).
|
||||
bool is_accessor() const;
|
||||
@ -745,14 +736,7 @@ public:
|
||||
static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize
|
||||
|
||||
// RedefineClasses() support:
|
||||
bool is_old() const { return access_flags().is_old(); }
|
||||
void set_is_old() { _access_flags.set_is_old(); }
|
||||
bool is_obsolete() const { return access_flags().is_obsolete(); }
|
||||
void set_is_obsolete() { _access_flags.set_is_obsolete(); }
|
||||
bool is_deleted() const { return access_flags().is_deleted(); }
|
||||
void set_is_deleted() { _access_flags.set_is_deleted(); }
|
||||
|
||||
bool on_stack() const { return access_flags().on_stack(); }
|
||||
bool on_stack() const { return on_stack_flag(); }
|
||||
void set_on_stack(const bool value);
|
||||
|
||||
void record_gc_epoch();
|
||||
@ -760,10 +744,6 @@ public:
|
||||
// see the definition in Method*.cpp for the gory details
|
||||
bool should_not_be_cached() const;
|
||||
|
||||
// JVMTI Native method prefixing support:
|
||||
bool is_prefixed_native() const { return access_flags().is_prefixed_native(); }
|
||||
void set_is_prefixed_native() { _access_flags.set_is_prefixed_native(); }
|
||||
|
||||
// Rewriting support
|
||||
static methodHandle clone_with_new_data(const methodHandle& m, u_char* new_code, int new_code_length,
|
||||
u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS);
|
||||
@ -820,78 +800,29 @@ public:
|
||||
void init_intrinsic_id(vmSymbolID klass_id); // updates from _none if a match
|
||||
static vmSymbolID klass_id_for_intrinsics(const Klass* holder);
|
||||
|
||||
bool caller_sensitive() {
|
||||
return (_flags & _caller_sensitive) != 0;
|
||||
}
|
||||
void set_caller_sensitive(bool x) {
|
||||
_flags = x ? (_flags | _caller_sensitive) : (_flags & ~_caller_sensitive);
|
||||
}
|
||||
bool caller_sensitive() const { return constMethod()->caller_sensitive(); }
|
||||
void set_caller_sensitive() { constMethod()->set_caller_sensitive(); }
|
||||
|
||||
bool force_inline() {
|
||||
return (_flags & _force_inline) != 0;
|
||||
}
|
||||
void set_force_inline(bool x) {
|
||||
_flags = x ? (_flags | _force_inline) : (_flags & ~_force_inline);
|
||||
}
|
||||
bool changes_current_thread() const { return constMethod()->changes_current_thread(); }
|
||||
void set_changes_current_thread() { constMethod()->set_changes_current_thread(); }
|
||||
|
||||
bool dont_inline() {
|
||||
return (_flags & _dont_inline) != 0;
|
||||
}
|
||||
void set_dont_inline(bool x) {
|
||||
_flags = x ? (_flags | _dont_inline) : (_flags & ~_dont_inline);
|
||||
}
|
||||
bool jvmti_mount_transition() const { return constMethod()->jvmti_mount_transition(); }
|
||||
void set_jvmti_mount_transition() { constMethod()->set_jvmti_mount_transition(); }
|
||||
|
||||
bool changes_current_thread() {
|
||||
return (_flags & _changes_current_thread) != 0;
|
||||
}
|
||||
void set_changes_current_thread(bool x) {
|
||||
_flags = x ? (_flags | _changes_current_thread) : (_flags & ~_changes_current_thread);
|
||||
}
|
||||
bool is_hidden() const { return constMethod()->is_hidden(); }
|
||||
void set_is_hidden() { constMethod()->set_is_hidden(); }
|
||||
|
||||
bool jvmti_mount_transition() {
|
||||
return (_flags & _jvmti_mount_transition) != 0;
|
||||
}
|
||||
void set_jvmti_mount_transition(bool x) {
|
||||
_flags = x ? (_flags | _jvmti_mount_transition) : (_flags & ~_jvmti_mount_transition);
|
||||
}
|
||||
bool is_scoped() const { return constMethod()->is_scoped(); }
|
||||
void set_scoped() { constMethod()->set_is_scoped(); }
|
||||
|
||||
bool is_hidden() const {
|
||||
return (_flags & _hidden) != 0;
|
||||
}
|
||||
bool intrinsic_candidate() const { return constMethod()->intrinsic_candidate(); }
|
||||
void set_intrinsic_candidate() { constMethod()->set_intrinsic_candidate(); }
|
||||
|
||||
void set_hidden(bool x) {
|
||||
_flags = x ? (_flags | _hidden) : (_flags & ~_hidden);
|
||||
}
|
||||
bool has_injected_profile() const { return constMethod()->has_injected_profile(); }
|
||||
void set_has_injected_profile() { constMethod()->set_has_injected_profile(); }
|
||||
|
||||
bool is_scoped() const {
|
||||
return (_flags & _scoped) != 0;
|
||||
}
|
||||
|
||||
void set_scoped(bool x) {
|
||||
_flags = x ? (_flags | _scoped) : (_flags & ~_scoped);
|
||||
}
|
||||
|
||||
bool intrinsic_candidate() {
|
||||
return (_flags & _intrinsic_candidate) != 0;
|
||||
}
|
||||
void set_intrinsic_candidate(bool x) {
|
||||
_flags = x ? (_flags | _intrinsic_candidate) : (_flags & ~_intrinsic_candidate);
|
||||
}
|
||||
|
||||
bool has_injected_profile() {
|
||||
return (_flags & _has_injected_profile) != 0;
|
||||
}
|
||||
void set_has_injected_profile(bool x) {
|
||||
_flags = x ? (_flags | _has_injected_profile) : (_flags & ~_has_injected_profile);
|
||||
}
|
||||
|
||||
bool has_reserved_stack_access() {
|
||||
return (_flags & _reserved_stack_access) != 0;
|
||||
}
|
||||
|
||||
void set_has_reserved_stack_access(bool x) {
|
||||
_flags = x ? (_flags | _reserved_stack_access) : (_flags & ~_reserved_stack_access);
|
||||
}
|
||||
bool has_reserved_stack_access() const { return constMethod()->reserved_stack_access(); }
|
||||
void set_has_reserved_stack_access() { constMethod()->set_reserved_stack_access(); }
|
||||
|
||||
JFR_ONLY(DEFINE_TRACE_FLAG_ACCESSOR;)
|
||||
|
||||
@ -939,24 +870,17 @@ public:
|
||||
return _method_counters;
|
||||
}
|
||||
|
||||
bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); }
|
||||
void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); }
|
||||
void clear_not_c1_compilable() { _access_flags.clear_not_c1_compilable(); }
|
||||
bool is_not_c2_compilable() const { return access_flags().is_not_c2_compilable(); }
|
||||
void set_not_c2_compilable() { _access_flags.set_not_c2_compilable(); }
|
||||
void clear_not_c2_compilable() { _access_flags.clear_not_c2_compilable(); }
|
||||
void clear_is_not_c1_compilable() { set_is_not_c1_compilable(false); }
|
||||
void clear_is_not_c2_compilable() { set_is_not_c2_compilable(false); }
|
||||
void clear_is_not_c2_osr_compilable() { set_is_not_c2_osr_compilable(false); }
|
||||
|
||||
bool is_not_c1_osr_compilable() const { return is_not_c1_compilable(); } // don't waste an accessFlags bit
|
||||
void set_not_c1_osr_compilable() { set_not_c1_compilable(); } // don't waste an accessFlags bit
|
||||
void clear_not_c1_osr_compilable() { clear_not_c1_compilable(); } // don't waste an accessFlags bit
|
||||
bool is_not_c2_osr_compilable() const { return access_flags().is_not_c2_osr_compilable(); }
|
||||
void set_not_c2_osr_compilable() { _access_flags.set_not_c2_osr_compilable(); }
|
||||
void clear_not_c2_osr_compilable() { _access_flags.clear_not_c2_osr_compilable(); }
|
||||
// not_c1_osr_compilable == not_c1_compilable
|
||||
bool is_not_c1_osr_compilable() const { return is_not_c1_compilable(); }
|
||||
void set_is_not_c1_osr_compilable() { set_is_not_c1_compilable(); }
|
||||
void clear_is_not_c1_osr_compilable() { clear_is_not_c1_compilable(); }
|
||||
|
||||
// Background compilation support
|
||||
bool queued_for_compilation() const { return access_flags().queued_for_compilation(); }
|
||||
void set_queued_for_compilation() { _access_flags.set_queued_for_compilation(); }
|
||||
void clear_queued_for_compilation() { _access_flags.clear_queued_for_compilation(); }
|
||||
void clear_queued_for_compilation() { set_queued_for_compilation(false); }
|
||||
|
||||
// Resolve all classes in signature, return 'true' if successful
|
||||
static bool load_signature_classes(const methodHandle& m, TRAPS);
|
||||
|
56
src/hotspot/share/oops/methodFlags.cpp
Normal file
56
src/hotspot/share/oops/methodFlags.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "oops/methodFlags.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "utilities/ostream.hpp"
|
||||
|
||||
// This can be removed for the atomic bitset functions, when available.
|
||||
void MethodFlags::atomic_set_bits(u4 bits) {
|
||||
// Atomically update the status with the bits given
|
||||
u4 old_status, new_status, f;
|
||||
do {
|
||||
old_status = _status;
|
||||
new_status = old_status | bits;
|
||||
f = Atomic::cmpxchg(&_status, old_status, new_status);
|
||||
} while(f != old_status);
|
||||
}
|
||||
|
||||
void MethodFlags::atomic_clear_bits(u4 bits) {
|
||||
// Atomically update the status with the bits given
|
||||
u4 old_status, new_status, f;
|
||||
do {
|
||||
old_status = _status;
|
||||
new_status = old_status & ~bits;
|
||||
f = Atomic::cmpxchg(&_status, old_status, new_status);
|
||||
} while(f != old_status);
|
||||
}
|
||||
|
||||
void MethodFlags::print_on(outputStream* st) const {
|
||||
#define M_PRINT(name, ignore) \
|
||||
if (name()) st->print(" " #name " ");
|
||||
M_STATUS_DO(M_PRINT)
|
||||
#undef M_PRINT
|
||||
}
|
94
src/hotspot/share/oops/methodFlags.hpp
Normal file
94
src/hotspot/share/oops/methodFlags.hpp
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2023, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_OOPS_METHODFLAGS_HPP
|
||||
#define SHARE_OOPS_METHODFLAGS_HPP
|
||||
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/macros.hpp"
|
||||
|
||||
class outputStream;
|
||||
|
||||
// The MethodFlags class contains the writeable flags aka. status associated with
|
||||
// an Method, and their associated accessors.
|
||||
// _status are set at runtime and require atomic access.
|
||||
// These flags are JVM internal and not part of the AccessFlags classfile specification.
|
||||
|
||||
class MethodFlags {
|
||||
friend class VMStructs;
|
||||
friend class JVMCIVMStructs;
|
||||
/* end of list */
|
||||
|
||||
#define M_STATUS_DO(status) \
|
||||
status(has_monitor_bytecodes , 1 << 0) /* Method contains monitorenter/monitorexit bytecodes */ \
|
||||
status(has_jsrs , 1 << 1) \
|
||||
status(is_old , 1 << 2) /* RedefineClasses() has replaced this method */ \
|
||||
status(is_obsolete , 1 << 3) /* RedefineClasses() has made method obsolete */ \
|
||||
status(is_deleted , 1 << 4) /* RedefineClasses() has deleted this method */ \
|
||||
status(is_prefixed_native , 1 << 5) /* JVMTI has prefixed this native method */ \
|
||||
status(monitor_matching , 1 << 6) /* True if we know that monitorenter/monitorexit bytecodes match */ \
|
||||
status(queued_for_compilation , 1 << 7) \
|
||||
status(is_not_c2_compilable , 1 << 8) \
|
||||
status(is_not_c1_compilable , 1 << 9) \
|
||||
status(is_not_c2_osr_compilable , 1 << 10) \
|
||||
status(force_inline , 1 << 11) /* Annotations but also set/reset at runtime */ \
|
||||
status(dont_inline , 1 << 12) \
|
||||
status(has_loops_flag , 1 << 13) /* Method has loops */ \
|
||||
status(has_loops_flag_init , 1 << 14) /* The loop flag has been initialized */ \
|
||||
status(on_stack_flag , 1 << 15) /* RedefineClasses support to keep Metadata from being cleaned */ \
|
||||
/* end of list */
|
||||
|
||||
#define M_STATUS_ENUM_NAME(name, value) _misc_##name = value,
|
||||
enum {
|
||||
M_STATUS_DO(M_STATUS_ENUM_NAME)
|
||||
};
|
||||
#undef M_STATUS_ENUM_NAME
|
||||
|
||||
// These flags are written during execution so require atomic stores
|
||||
u4 _status;
|
||||
|
||||
public:
|
||||
|
||||
MethodFlags() : _status(0) {}
|
||||
|
||||
// Create getters and setters for the status values.
|
||||
#define M_STATUS_GET_SET(name, ignore) \
|
||||
bool name() const { return (_status & _misc_##name) != 0; } \
|
||||
void set_##name(bool b) { \
|
||||
if (b) { \
|
||||
atomic_set_bits(_misc_##name); \
|
||||
} else { \
|
||||
atomic_clear_bits(_misc_##name); \
|
||||
} \
|
||||
}
|
||||
M_STATUS_DO(M_STATUS_GET_SET)
|
||||
#undef M_STATUS_GET_SET
|
||||
|
||||
int as_int() const { return _status; }
|
||||
void atomic_set_bits(u4 bits);
|
||||
void atomic_clear_bits(u4 bits);
|
||||
void print_on(outputStream* st) const;
|
||||
};
|
||||
|
||||
#endif // SHARE_OOPS_METHODFLAGS_HPP
|
@ -1206,9 +1206,9 @@ WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
|
||||
mdo->clean_method_data(/*always_clean*/true);
|
||||
}
|
||||
|
||||
mh->clear_not_c1_compilable();
|
||||
mh->clear_not_c2_compilable();
|
||||
mh->clear_not_c2_osr_compilable();
|
||||
mh->clear_is_not_c1_compilable();
|
||||
mh->clear_is_not_c2_compilable();
|
||||
mh->clear_is_not_c2_osr_compilable();
|
||||
NOT_PRODUCT(mh->set_compiled_invocation_count(0));
|
||||
if (mcs != nullptr) {
|
||||
mcs->clear_counters();
|
||||
|
@ -299,7 +299,6 @@
|
||||
nonstatic_field(Method, _access_flags, AccessFlags) \
|
||||
nonstatic_field(Method, _vtable_index, int) \
|
||||
nonstatic_field(Method, _intrinsic_id, u2) \
|
||||
nonstatic_field(Method, _flags, u2) \
|
||||
volatile_nonstatic_field(Method, _code, CompiledMethod*) \
|
||||
nonstatic_field(Method, _i2i_entry, address) \
|
||||
volatile_nonstatic_field(Method, _from_compiled_entry, address) \
|
||||
@ -308,7 +307,7 @@
|
||||
nonstatic_field(ConstMethod, _constants, ConstantPool*) \
|
||||
nonstatic_field(ConstMethod, _stackmap_data, Array<u1>*) \
|
||||
nonstatic_field(ConstMethod, _constMethod_size, int) \
|
||||
nonstatic_field(ConstMethod, _flags, u2) \
|
||||
nonstatic_field(ConstMethod, _flags._flags, u4) \
|
||||
nonstatic_field(ConstMethod, _code_size, u2) \
|
||||
nonstatic_field(ConstMethod, _name_index, u2) \
|
||||
nonstatic_field(ConstMethod, _signature_index, u2) \
|
||||
@ -2085,16 +2084,6 @@
|
||||
/************************************************************/ \
|
||||
\
|
||||
declare_constant(JVM_ACC_WRITTEN_FLAGS) \
|
||||
declare_constant(JVM_ACC_MONITOR_MATCH) \
|
||||
declare_constant(JVM_ACC_HAS_MONITOR_BYTECODES) \
|
||||
declare_constant(JVM_ACC_HAS_LOOPS) \
|
||||
declare_constant(JVM_ACC_LOOPS_FLAG_INIT) \
|
||||
declare_constant(JVM_ACC_QUEUED) \
|
||||
declare_constant(JVM_ACC_NOT_C2_OSR_COMPILABLE) \
|
||||
declare_constant(JVM_ACC_HAS_JSRS) \
|
||||
declare_constant(JVM_ACC_IS_OLD) \
|
||||
declare_constant(JVM_ACC_IS_OBSOLETE) \
|
||||
declare_constant(JVM_ACC_IS_PREFIXED_NATIVE) \
|
||||
declare_constant(JVM_ACC_HAS_FINALIZER) \
|
||||
declare_constant(JVM_ACC_IS_CLONEABLE_FAST) \
|
||||
\
|
||||
@ -2178,30 +2167,23 @@
|
||||
declare_constant(Klass::_lh_array_tag_type_value) \
|
||||
declare_constant(Klass::_lh_array_tag_obj_value) \
|
||||
\
|
||||
declare_constant(Method::nonvirtual_vtable_index) \
|
||||
declare_constant(Method::extra_stack_entries_for_jsr292) \
|
||||
\
|
||||
/********************************/ \
|
||||
/* ConstMethod anon-enum */ \
|
||||
/********************************/ \
|
||||
\
|
||||
declare_constant(Method::_caller_sensitive) \
|
||||
declare_constant(Method::_force_inline) \
|
||||
declare_constant(Method::_dont_inline) \
|
||||
declare_constant(Method::_hidden) \
|
||||
declare_constant(Method::_changes_current_thread) \
|
||||
\
|
||||
declare_constant(Method::nonvirtual_vtable_index) \
|
||||
\
|
||||
declare_constant(Method::extra_stack_entries_for_jsr292) \
|
||||
\
|
||||
declare_constant(ConstMethod::_has_linenumber_table) \
|
||||
declare_constant(ConstMethod::_has_checked_exceptions) \
|
||||
declare_constant(ConstMethod::_has_localvariable_table) \
|
||||
declare_constant(ConstMethod::_has_exception_table) \
|
||||
declare_constant(ConstMethod::_has_generic_signature) \
|
||||
declare_constant(ConstMethod::_has_method_parameters) \
|
||||
declare_constant(ConstMethod::_has_method_annotations) \
|
||||
declare_constant(ConstMethod::_has_parameter_annotations) \
|
||||
declare_constant(ConstMethod::_has_default_annotations) \
|
||||
declare_constant(ConstMethod::_has_type_annotations) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_linenumber_table) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_checked_exceptions) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_localvariable_table) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_exception_table) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_generic_signature) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_method_parameters) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_method_annotations) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_parameter_annotations) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_default_annotations) \
|
||||
declare_constant(ConstMethodFlags::_misc_has_type_annotations) \
|
||||
\
|
||||
/**************/ \
|
||||
/* DataLayout */ \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2023, 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
|
||||
@ -27,27 +27,6 @@
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "utilities/accessFlags.hpp"
|
||||
|
||||
void AccessFlags::atomic_set_bits(jint bits) {
|
||||
// Atomically update the flags with the bits given
|
||||
jint old_flags, new_flags, f;
|
||||
do {
|
||||
old_flags = _flags;
|
||||
new_flags = old_flags | bits;
|
||||
f = Atomic::cmpxchg(&_flags, old_flags, new_flags);
|
||||
} while(f != old_flags);
|
||||
}
|
||||
|
||||
void AccessFlags::atomic_clear_bits(jint bits) {
|
||||
// Atomically update the flags with the bits given
|
||||
jint old_flags, new_flags, f;
|
||||
do {
|
||||
old_flags = _flags;
|
||||
new_flags = old_flags & ~bits;
|
||||
f = Atomic::cmpxchg(&_flags, old_flags, new_flags);
|
||||
} while(f != old_flags);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(PRODUCT) || INCLUDE_JVMTI
|
||||
|
||||
void AccessFlags::print_on(outputStream* st) const {
|
||||
@ -63,9 +42,6 @@ void AccessFlags::print_on(outputStream* st) const {
|
||||
if (is_interface ()) st->print("interface " );
|
||||
if (is_abstract ()) st->print("abstract " );
|
||||
if (is_synthetic ()) st->print("synthetic " );
|
||||
if (is_old ()) st->print("{old} " );
|
||||
if (is_obsolete ()) st->print("{obsolete} " );
|
||||
if (on_stack ()) st->print("{on_stack} " );
|
||||
}
|
||||
|
||||
#endif // !PRODUCT || INCLUDE_JVMTI
|
||||
|
@ -42,22 +42,6 @@ enum {
|
||||
// flags actually put in .class file
|
||||
JVM_ACC_WRITTEN_FLAGS = 0x00007FFF,
|
||||
|
||||
// Method* flags
|
||||
JVM_ACC_MONITOR_MATCH = 0x10000000, // True if we know that monitorenter/monitorexit bytecodes match
|
||||
JVM_ACC_HAS_MONITOR_BYTECODES = 0x20000000, // Method contains monitorenter/monitorexit bytecodes
|
||||
JVM_ACC_HAS_LOOPS = 0x40000000, // Method has loops
|
||||
JVM_ACC_LOOPS_FLAG_INIT = (int)0x80000000,// The loop flag has been initialized
|
||||
JVM_ACC_QUEUED = 0x01000000, // Queued for compilation
|
||||
JVM_ACC_NOT_C2_COMPILABLE = 0x02000000,
|
||||
JVM_ACC_NOT_C1_COMPILABLE = 0x04000000,
|
||||
JVM_ACC_NOT_C2_OSR_COMPILABLE = 0x08000000,
|
||||
JVM_ACC_HAS_JSRS = 0x00800000,
|
||||
JVM_ACC_IS_OLD = 0x00010000, // RedefineClasses() has replaced this method
|
||||
JVM_ACC_IS_OBSOLETE = 0x00020000, // RedefineClasses() has made method obsolete
|
||||
JVM_ACC_IS_PREFIXED_NATIVE = 0x00040000, // JVMTI has prefixed this native method
|
||||
JVM_ACC_ON_STACK = 0x00080000, // RedefineClasses() was used on the stack
|
||||
JVM_ACC_IS_DELETED = 0x00008000, // RedefineClasses() has deleted this method
|
||||
|
||||
// Klass* flags
|
||||
JVM_ACC_HAS_FINALIZER = 0x40000000, // True if klass has a non-empty finalize() method
|
||||
JVM_ACC_IS_CLONEABLE_FAST = (int)0x80000000,// True if klass implements the Cloneable interface and can be optimized in generated code
|
||||
@ -92,29 +76,12 @@ class AccessFlags {
|
||||
// Attribute flags
|
||||
bool is_synthetic () const { return (_flags & JVM_ACC_SYNTHETIC ) != 0; }
|
||||
|
||||
// Method* flags
|
||||
bool is_monitor_matching () const { return (_flags & JVM_ACC_MONITOR_MATCH ) != 0; }
|
||||
bool has_monitor_bytecodes () const { return (_flags & JVM_ACC_HAS_MONITOR_BYTECODES ) != 0; }
|
||||
bool has_loops () const { return (_flags & JVM_ACC_HAS_LOOPS ) != 0; }
|
||||
bool loops_flag_init () const { return (_flags & JVM_ACC_LOOPS_FLAG_INIT ) != 0; }
|
||||
bool queued_for_compilation () const { return (_flags & JVM_ACC_QUEUED ) != 0; }
|
||||
bool is_not_c1_compilable () const { return (_flags & JVM_ACC_NOT_C1_COMPILABLE ) != 0; }
|
||||
bool is_not_c2_compilable () const { return (_flags & JVM_ACC_NOT_C2_COMPILABLE ) != 0; }
|
||||
bool is_not_c2_osr_compilable() const { return (_flags & JVM_ACC_NOT_C2_OSR_COMPILABLE ) != 0; }
|
||||
bool has_jsrs () const { return (_flags & JVM_ACC_HAS_JSRS ) != 0; }
|
||||
bool is_old () const { return (_flags & JVM_ACC_IS_OLD ) != 0; }
|
||||
bool is_obsolete () const { return (_flags & JVM_ACC_IS_OBSOLETE ) != 0; }
|
||||
bool is_deleted () const { return (_flags & JVM_ACC_IS_DELETED ) != 0; }
|
||||
bool is_prefixed_native () const { return (_flags & JVM_ACC_IS_PREFIXED_NATIVE ) != 0; }
|
||||
|
||||
// Klass* flags
|
||||
bool has_finalizer () const { return (_flags & JVM_ACC_HAS_FINALIZER ) != 0; }
|
||||
bool is_cloneable_fast () const { return (_flags & JVM_ACC_IS_CLONEABLE_FAST ) != 0; }
|
||||
bool is_hidden_class () const { return (_flags & JVM_ACC_IS_HIDDEN_CLASS ) != 0; }
|
||||
bool is_value_based_class () const { return (_flags & JVM_ACC_IS_VALUE_BASED_CLASS ) != 0; }
|
||||
|
||||
bool on_stack() const { return (_flags & JVM_ACC_ON_STACK) != 0; }
|
||||
|
||||
// get .class file flags
|
||||
jint get_flags () const { return (_flags & JVM_ACC_WRITTEN_FLAGS); }
|
||||
|
||||
@ -125,55 +92,23 @@ class AccessFlags {
|
||||
}
|
||||
void set_flags(jint flags) { _flags = (flags & JVM_ACC_WRITTEN_FLAGS); }
|
||||
|
||||
void set_queued_for_compilation() { atomic_set_bits(JVM_ACC_QUEUED); }
|
||||
void clear_queued_for_compilation() { atomic_clear_bits(JVM_ACC_QUEUED); }
|
||||
|
||||
// Atomic update of flags
|
||||
void atomic_set_bits(jint bits);
|
||||
void atomic_clear_bits(jint bits);
|
||||
|
||||
private:
|
||||
friend class Method;
|
||||
friend class Klass;
|
||||
friend class ClassFileParser;
|
||||
// the functions below should only be called on the _access_flags inst var directly,
|
||||
// otherwise they are just changing a copy of the flags
|
||||
|
||||
// attribute flags
|
||||
void set_is_synthetic() { atomic_set_bits(JVM_ACC_SYNTHETIC); }
|
||||
void set_is_synthetic() { _flags |= JVM_ACC_SYNTHETIC; }
|
||||
|
||||
// Method* flags
|
||||
void set_monitor_matching() { atomic_set_bits(JVM_ACC_MONITOR_MATCH); }
|
||||
void set_has_monitor_bytecodes() { atomic_set_bits(JVM_ACC_HAS_MONITOR_BYTECODES); }
|
||||
void set_has_loops() { atomic_set_bits(JVM_ACC_HAS_LOOPS); }
|
||||
void set_loops_flag_init() { atomic_set_bits(JVM_ACC_LOOPS_FLAG_INIT); }
|
||||
void set_not_c1_compilable() { atomic_set_bits(JVM_ACC_NOT_C1_COMPILABLE); }
|
||||
void set_not_c2_compilable() { atomic_set_bits(JVM_ACC_NOT_C2_COMPILABLE); }
|
||||
void set_not_c2_osr_compilable() { atomic_set_bits(JVM_ACC_NOT_C2_OSR_COMPILABLE); }
|
||||
void set_has_jsrs() { atomic_set_bits(JVM_ACC_HAS_JSRS); }
|
||||
void set_is_old() { atomic_set_bits(JVM_ACC_IS_OLD); }
|
||||
void set_is_obsolete() { atomic_set_bits(JVM_ACC_IS_OBSOLETE); }
|
||||
void set_is_deleted() { atomic_set_bits(JVM_ACC_IS_DELETED); }
|
||||
void set_is_prefixed_native() { atomic_set_bits(JVM_ACC_IS_PREFIXED_NATIVE); }
|
||||
|
||||
void clear_not_c1_compilable() { atomic_clear_bits(JVM_ACC_NOT_C1_COMPILABLE); }
|
||||
void clear_not_c2_compilable() { atomic_clear_bits(JVM_ACC_NOT_C2_COMPILABLE); }
|
||||
void clear_not_c2_osr_compilable() { atomic_clear_bits(JVM_ACC_NOT_C2_OSR_COMPILABLE); }
|
||||
// Klass* flags
|
||||
void set_has_finalizer() { atomic_set_bits(JVM_ACC_HAS_FINALIZER); }
|
||||
void set_is_cloneable_fast() { atomic_set_bits(JVM_ACC_IS_CLONEABLE_FAST); }
|
||||
void set_is_hidden_class() { atomic_set_bits(JVM_ACC_IS_HIDDEN_CLASS); }
|
||||
void set_is_value_based_class() { atomic_set_bits(JVM_ACC_IS_VALUE_BASED_CLASS); }
|
||||
// These are set at classfile parsing time so do not require atomic access.
|
||||
void set_has_finalizer() { _flags |= JVM_ACC_HAS_FINALIZER; }
|
||||
void set_is_cloneable_fast() { _flags |= JVM_ACC_IS_CLONEABLE_FAST; }
|
||||
void set_is_hidden_class() { _flags |= JVM_ACC_IS_HIDDEN_CLASS; }
|
||||
void set_is_value_based_class() { _flags |= JVM_ACC_IS_VALUE_BASED_CLASS; }
|
||||
|
||||
public:
|
||||
void set_on_stack(const bool value)
|
||||
{
|
||||
if (value) {
|
||||
atomic_set_bits(JVM_ACC_ON_STACK);
|
||||
} else {
|
||||
atomic_clear_bits(JVM_ACC_ON_STACK);
|
||||
}
|
||||
}
|
||||
// Conversion
|
||||
jshort as_short() const { return (jshort)_flags; }
|
||||
jint as_int() const { return _flags; }
|
||||
|
@ -56,17 +56,6 @@ public class AccessFlags implements /* imports */ ClassConstants {
|
||||
|
||||
public long getValue () { return flags; }
|
||||
|
||||
// Hotspot internal flags
|
||||
// Method* flags
|
||||
public boolean isMonitorMatching () { return (flags & JVM_ACC_MONITOR_MATCH ) != 0; }
|
||||
public boolean hasMonitorBytecodes () { return (flags & JVM_ACC_HAS_MONITOR_BYTECODES ) != 0; }
|
||||
public boolean hasLoops () { return (flags & JVM_ACC_HAS_LOOPS ) != 0; }
|
||||
public boolean loopsFlagInit () { return (flags & JVM_ACC_LOOPS_FLAG_INIT ) != 0; }
|
||||
public boolean queuedForCompilation() { return (flags & JVM_ACC_QUEUED ) != 0; }
|
||||
public boolean isNotOsrCompilable () { return (flags & JVM_ACC_NOT_OSR_COMPILABLE ) != 0; }
|
||||
public boolean hasJsrs () { return (flags & JVM_ACC_HAS_JSRS ) != 0; }
|
||||
public boolean isObsolete () { return (flags & JVM_ACC_IS_OBSOLETE ) != 0; }
|
||||
|
||||
// Klass* flags
|
||||
public boolean hasFinalizer () { return (flags & JVM_ACC_HAS_FINALIZER ) != 0; }
|
||||
public boolean isCloneable () { return (flags & JVM_ACC_IS_CLONEABLE ) != 0; }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2023, 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
|
||||
@ -63,19 +63,19 @@ public class ConstMethod extends Metadata {
|
||||
Type type = db.lookupType("ConstMethod");
|
||||
constants = new MetadataField(type.getAddressField("_constants"), 0);
|
||||
constMethodSize = new CIntField(type.getCIntegerField("_constMethod_size"), 0);
|
||||
flags = new CIntField(type.getCIntegerField("_flags"), 0);
|
||||
flags = new CIntField(type.getCIntegerField("_flags._flags"), 0);
|
||||
|
||||
// enum constants for flags
|
||||
HAS_LINENUMBER_TABLE = db.lookupIntConstant("ConstMethod::_has_linenumber_table").intValue();
|
||||
HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("ConstMethod::_has_checked_exceptions").intValue();
|
||||
HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("ConstMethod::_has_localvariable_table").intValue();
|
||||
HAS_EXCEPTION_TABLE = db.lookupIntConstant("ConstMethod::_has_exception_table").intValue();
|
||||
HAS_GENERIC_SIGNATURE = db.lookupIntConstant("ConstMethod::_has_generic_signature").intValue();
|
||||
HAS_METHOD_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_method_annotations").intValue();
|
||||
HAS_PARAMETER_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_parameter_annotations").intValue();
|
||||
HAS_METHOD_PARAMETERS = db.lookupIntConstant("ConstMethod::_has_method_parameters").intValue();
|
||||
HAS_DEFAULT_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_default_annotations").intValue();
|
||||
HAS_TYPE_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_type_annotations").intValue();
|
||||
HAS_LINENUMBER_TABLE = db.lookupIntConstant("ConstMethodFlags::_misc_has_linenumber_table").intValue();
|
||||
HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("ConstMethodFlags::_misc_has_checked_exceptions").intValue();
|
||||
HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("ConstMethodFlags::_misc_has_localvariable_table").intValue();
|
||||
HAS_EXCEPTION_TABLE = db.lookupIntConstant("ConstMethodFlags::_misc_has_exception_table").intValue();
|
||||
HAS_GENERIC_SIGNATURE = db.lookupIntConstant("ConstMethodFlags::_misc_has_generic_signature").intValue();
|
||||
HAS_METHOD_ANNOTATIONS = db.lookupIntConstant("ConstMethodFlags::_misc_has_method_annotations").intValue();
|
||||
HAS_PARAMETER_ANNOTATIONS = db.lookupIntConstant("ConstMethodFlags::_misc_has_parameter_annotations").intValue();
|
||||
HAS_METHOD_PARAMETERS = db.lookupIntConstant("ConstMethodFlags::_misc_has_method_parameters").intValue();
|
||||
HAS_DEFAULT_ANNOTATIONS = db.lookupIntConstant("ConstMethodFlags::_misc_has_default_annotations").intValue();
|
||||
HAS_TYPE_ANNOTATIONS = db.lookupIntConstant("ConstMethodFlags::_misc_has_type_annotations").intValue();
|
||||
|
||||
// Size of Java bytecodes allocated immediately after ConstMethod*.
|
||||
codeSize = new CIntField(type.getCIntegerField("_code_size"), 0);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2023, 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
|
||||
@ -252,10 +252,6 @@ public class Method extends Metadata {
|
||||
return isStatic() && getName().equals(classInitializerName());
|
||||
}
|
||||
|
||||
public boolean isObsolete() {
|
||||
return getAccessFlagsObj().isObsolete();
|
||||
}
|
||||
|
||||
public OopMapCacheEntry getMaskFor(int bci) {
|
||||
OopMapCacheEntry entry = new OopMapCacheEntry();
|
||||
entry.fill(this, bci);
|
||||
|
@ -103,25 +103,6 @@ public interface ClassConstants
|
||||
// flags actually put in .class file
|
||||
public static final long JVM_ACC_WRITTEN_FLAGS = 0x00007FFF;
|
||||
|
||||
// Method* flags
|
||||
// monitorenter/monitorexit bytecodes match
|
||||
public static final long JVM_ACC_MONITOR_MATCH = 0x10000000;
|
||||
// Method contains monitorenter/monitorexit bytecodes
|
||||
public static final long JVM_ACC_HAS_MONITOR_BYTECODES = 0x20000000;
|
||||
// Method has loops
|
||||
public static final long JVM_ACC_HAS_LOOPS = 0x40000000;
|
||||
// The loop flag has been initialized
|
||||
public static final long JVM_ACC_LOOPS_FLAG_INIT = (int)0x80000000;
|
||||
// Queued for compilation
|
||||
public static final long JVM_ACC_QUEUED = 0x01000000;
|
||||
// TEMPORARY: currently on stack replacement compilation is not built into the
|
||||
// invocation counter machinery. Until it is, we will keep track of methods which
|
||||
// cannot be on stack replaced in the access flags.
|
||||
public static final long JVM_ACC_NOT_OSR_COMPILABLE = 0x08000000;
|
||||
public static final long JVM_ACC_HAS_JSRS = 0x00800000;
|
||||
// RedefineClasses() has made method obsolete
|
||||
public static final long JVM_ACC_IS_OBSOLETE = 0x00010000;
|
||||
|
||||
// Klass* flags
|
||||
// True if klass has a non-empty finalize() method
|
||||
public static final long JVM_ACC_HAS_FINALIZER = 0x40000000;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2023, 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
|
||||
@ -317,7 +317,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
|
||||
*/
|
||||
@Override
|
||||
public boolean isCallerSensitive() {
|
||||
return (getFlags() & config().methodFlagsCallerSensitive) != 0;
|
||||
return (getConstMethodFlags() & config().constMethodFlagsCallerSensitive) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -337,7 +337,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
|
||||
*/
|
||||
@Override
|
||||
public boolean hasReservedStackAccess() {
|
||||
return (getFlags() & config().methodFlagsReservedStackAccess) != 0;
|
||||
return (getConstMethodFlags() & config().constMethodFlagsReservedStackAccess) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -737,7 +737,7 @@ final class HotSpotResolvedJavaMethodImpl extends HotSpotMethod implements HotSp
|
||||
|
||||
@Override
|
||||
public boolean isIntrinsicCandidate() {
|
||||
return (getFlags() & config().methodFlagsIntrinsicCandidate) != 0;
|
||||
return (getConstMethodFlags() & config().constMethodFlagsIntrinsicCandidate) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,17 +149,14 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||
final int methodAccessFlagsOffset = getFieldOffset("Method::_access_flags", Integer.class, "AccessFlags");
|
||||
final int methodConstMethodOffset = getFieldOffset("Method::_constMethod", Integer.class, "ConstMethod*");
|
||||
final int methodIntrinsicIdOffset = getFieldOffset("Method::_intrinsic_id", Integer.class, "u2");
|
||||
final int methodFlagsOffset = getFieldOffset("Method::_flags", Integer.class, "u2");
|
||||
final int methodFlagsOffset = getFieldOffset("Method::_flags._status", Integer.class, "u4");
|
||||
final int methodVtableIndexOffset = getFieldOffset("Method::_vtable_index", Integer.class, "int");
|
||||
|
||||
final int methodDataOffset = getFieldOffset("Method::_method_data", Integer.class, "MethodData*");
|
||||
final int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, "CompiledMethod*");
|
||||
|
||||
final int methodFlagsCallerSensitive = getConstant("Method::_caller_sensitive", Integer.class);
|
||||
final int methodFlagsForceInline = getConstant("Method::_force_inline", Integer.class);
|
||||
final int methodFlagsIntrinsicCandidate = getConstant("Method::_intrinsic_candidate", Integer.class);
|
||||
final int methodFlagsDontInline = getConstant("Method::_dont_inline", Integer.class);
|
||||
final int methodFlagsReservedStackAccess = getConstant("Method::_reserved_stack_access", Integer.class);
|
||||
final int methodFlagsForceInline = getConstant("MethodFlags::_misc_force_inline", Integer.class);
|
||||
final int methodFlagsDontInline = getConstant("MethodFlags::_misc_dont_inline", Integer.class);
|
||||
final int nonvirtualVtableIndex = getConstant("Method::nonvirtual_vtable_index", Integer.class);
|
||||
final int invalidVtableIndex = getConstant("Method::invalid_vtable_index", Integer.class);
|
||||
|
||||
@ -190,7 +187,7 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||
final int extraStackEntries = getFieldValue("CompilerToVM::Data::Method_extra_stack_entries", Integer.class, "int");
|
||||
|
||||
final int constMethodConstantsOffset = getFieldOffset("ConstMethod::_constants", Integer.class, "ConstantPool*");
|
||||
final int constMethodFlagsOffset = getFieldOffset("ConstMethod::_flags", Integer.class, "u2");
|
||||
final int constMethodFlagsOffset = getFieldOffset("ConstMethod::_flags._flags", Integer.class, "u4");
|
||||
final int constMethodCodeSizeOffset = getFieldOffset("ConstMethod::_code_size", Integer.class, "u2");
|
||||
final int constMethodNameIndexOffset = getFieldOffset("ConstMethod::_name_index", Integer.class, "u2");
|
||||
final int constMethodSignatureIndexOffset = getFieldOffset("ConstMethod::_signature_index", Integer.class, "u2");
|
||||
@ -198,11 +195,14 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
|
||||
final int constMethodMaxStackOffset = getFieldOffset("ConstMethod::_max_stack", Integer.class, "u2");
|
||||
final int methodMaxLocalsOffset = getFieldOffset("ConstMethod::_max_locals", Integer.class, "u2");
|
||||
|
||||
final int constMethodHasLineNumberTable = getConstant("ConstMethod::_has_linenumber_table", Integer.class);
|
||||
final int constMethodHasLocalVariableTable = getConstant("ConstMethod::_has_localvariable_table", Integer.class);
|
||||
final int constMethodHasMethodAnnotations = getConstant("ConstMethod::_has_method_annotations", Integer.class);
|
||||
final int constMethodHasParameterAnnotations = getConstant("ConstMethod::_has_parameter_annotations", Integer.class);
|
||||
final int constMethodHasExceptionTable = getConstant("ConstMethod::_has_exception_table", Integer.class);
|
||||
final int constMethodFlagsReservedStackAccess = getConstant("ConstMethodFlags::_misc_reserved_stack_access", Integer.class);
|
||||
final int constMethodFlagsCallerSensitive = getConstant("ConstMethodFlags::_misc_caller_sensitive", Integer.class);
|
||||
final int constMethodFlagsIntrinsicCandidate = getConstant("ConstMethodFlags::_misc_intrinsic_candidate", Integer.class);
|
||||
final int constMethodHasLineNumberTable = getConstant("ConstMethodFlags::_misc_has_linenumber_table", Integer.class);
|
||||
final int constMethodHasLocalVariableTable = getConstant("ConstMethodFlags::_misc_has_localvariable_table", Integer.class);
|
||||
final int constMethodHasMethodAnnotations = getConstant("ConstMethodFlags::_misc_has_method_annotations", Integer.class);
|
||||
final int constMethodHasParameterAnnotations = getConstant("ConstMethodFlags::_misc_has_parameter_annotations", Integer.class);
|
||||
final int constMethodHasExceptionTable = getConstant("ConstMethodFlags::_misc_has_exception_table", Integer.class);
|
||||
|
||||
final int exceptionTableElementSize = getFieldValue("CompilerToVM::Data::sizeof_ExceptionTableElement", Integer.class, "int");
|
||||
final int exceptionTableElementStartPcOffset = getFieldOffset("ExceptionTableElement::start_pc", Integer.class, "u2");
|
||||
|
Loading…
Reference in New Issue
Block a user