8306851: Move Method access flags

Reviewed-by: cjplummer, dholmes, dnsimon, matsaave, fparain
This commit is contained in:
Coleen Phillimore 2023-05-01 11:33:22 +00:00
parent a6b4f25bd5
commit 316d303c1d
27 changed files with 483 additions and 464 deletions

View file

@ -84,8 +84,8 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) :
_code_size = h_m->code_size(); _code_size = h_m->code_size();
_handler_count = h_m->exception_table_length(); _handler_count = h_m->exception_table_length();
_size_of_parameters = h_m->size_of_parameters(); _size_of_parameters = h_m->size_of_parameters();
_uses_monitors = h_m->access_flags().has_monitor_bytecodes(); _uses_monitors = h_m->has_monitor_bytecodes();
_balanced_monitors = !_uses_monitors || h_m->access_flags().is_monitor_matching(); _balanced_monitors = !_uses_monitors || h_m->guaranteed_monitor_matching();
_is_c1_compilable = !h_m->is_not_c1_compilable(); _is_c1_compilable = !h_m->is_not_c1_compilable();
_is_c2_compilable = !h_m->is_not_c2_compilable(); _is_c2_compilable = !h_m->is_not_c2_compilable();
_can_be_parsed = true; _can_be_parsed = true;

View file

@ -1978,27 +1978,27 @@ ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector() {
void MethodAnnotationCollector::apply_to(const methodHandle& m) { void MethodAnnotationCollector::apply_to(const methodHandle& m) {
if (has_annotation(_method_CallerSensitive)) if (has_annotation(_method_CallerSensitive))
m->set_caller_sensitive(true); m->set_caller_sensitive();
if (has_annotation(_method_ForceInline)) if (has_annotation(_method_ForceInline))
m->set_force_inline(true); m->set_force_inline();
if (has_annotation(_method_DontInline)) if (has_annotation(_method_DontInline))
m->set_dont_inline(true); m->set_dont_inline();
if (has_annotation(_method_ChangesCurrentThread)) if (has_annotation(_method_ChangesCurrentThread))
m->set_changes_current_thread(true); m->set_changes_current_thread();
if (has_annotation(_method_JvmtiMountTransition)) if (has_annotation(_method_JvmtiMountTransition))
m->set_jvmti_mount_transition(true); m->set_jvmti_mount_transition();
if (has_annotation(_method_InjectedProfile)) 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) if (has_annotation(_method_LambdaForm_Compiled) && m->intrinsic_id() == vmIntrinsics::_none)
m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm); m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm);
if (has_annotation(_method_Hidden)) if (has_annotation(_method_Hidden))
m->set_hidden(true); m->set_is_hidden();
if (has_annotation(_method_Scoped)) if (has_annotation(_method_Scoped))
m->set_scoped(true); m->set_scoped();
if (has_annotation(_method_IntrinsicCandidate) && !m->is_synthetic()) 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)) 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) { 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)); parsed_annotations.apply_to(methodHandle(THREAD, m));
if (is_hidden()) { // Mark methods in hidden classes as 'hidden'. if (is_hidden()) { // Mark methods in hidden classes as 'hidden'.
m->set_hidden(true); m->set_is_hidden();
} }
// Copy annotations // Copy annotations

View file

@ -476,7 +476,7 @@ ExceptionMessageBuilder::ExceptionMessageBuilder(Method* method, int bci) :
_stacks->at_put(0, new SimulatedOperandStack()); _stacks->at_put(0, new SimulatedOperandStack());
// And initialize the start of all exception handlers. // 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(); ExceptionTableElement *et = const_method->exception_table_start();
for (int i = 0; i < const_method->exception_table_length(); ++i) { for (int i = 0; i < const_method->exception_table_length(); ++i) {
u2 index = et[i].handler_pc; u2 index = et[i].handler_pc;

View file

@ -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) { if (has_monitor_bytecodes) {
method->set_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 // have to be rewritten, so we run the oopMapGenerator on the method
if (nof_jsrs > 0) { if (nof_jsrs > 0) {
method->set_has_jsrs(); method->set_has_jsrs();
// Second pass will revisit this method.
assert(method->has_jsrs(), "didn't we just set this?");
} }
} }

View file

@ -926,8 +926,8 @@ C2V_END
C2V_VMENTRY(void, setNotInlinableOrCompilable,(JNIEnv* env, jobject, ARGUMENT_PAIR(method))) C2V_VMENTRY(void, setNotInlinableOrCompilable,(JNIEnv* env, jobject, ARGUMENT_PAIR(method)))
methodHandle method(THREAD, UNPACK_PAIR(Method, method)); methodHandle method(THREAD, UNPACK_PAIR(Method, method));
method->set_not_c1_compilable(); method->set_is_not_c1_compilable();
method->set_not_c2_compilable(); method->set_is_not_c2_compilable();
method->set_dont_inline(true); method->set_dont_inline(true);
C2V_END C2V_END

View file

@ -129,7 +129,7 @@
nonstatic_field(ConstantPool, _source_file_name_index, u2) \ nonstatic_field(ConstantPool, _source_file_name_index, u2) \
\ \
nonstatic_field(ConstMethod, _constants, ConstantPool*) \ 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, _code_size, u2) \
nonstatic_field(ConstMethod, _name_index, u2) \ nonstatic_field(ConstMethod, _name_index, u2) \
nonstatic_field(ConstMethod, _signature_index, u2) \ nonstatic_field(ConstMethod, _signature_index, u2) \
@ -228,7 +228,7 @@
nonstatic_field(Method, _access_flags, AccessFlags) \ nonstatic_field(Method, _access_flags, AccessFlags) \
nonstatic_field(Method, _vtable_index, int) \ nonstatic_field(Method, _vtable_index, int) \
nonstatic_field(Method, _intrinsic_id, u2) \ 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, _code, CompiledMethod*) \
volatile_nonstatic_field(Method, _from_compiled_entry, address) \ volatile_nonstatic_field(Method, _from_compiled_entry, address) \
\ \
@ -416,8 +416,6 @@
declare_constant(JVMCINMethodData::SPECULATION_LENGTH_BITS) \ declare_constant(JVMCINMethodData::SPECULATION_LENGTH_BITS) \
\ \
declare_constant(JVM_ACC_WRITTEN_FLAGS) \ 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_HAS_FINALIZER) \
declare_constant(JVM_ACC_IS_CLONEABLE_FAST) \ declare_constant(JVM_ACC_IS_CLONEABLE_FAST) \
declare_constant(JVM_ACC_IS_HIDDEN_CLASS) \ declare_constant(JVM_ACC_IS_HIDDEN_CLASS) \
@ -582,11 +580,16 @@
declare_constant(ConstantPool::CPCACHE_INDEX_TAG) \ declare_constant(ConstantPool::CPCACHE_INDEX_TAG) \
declare_constant(ConstantPool::_has_dynamic_constant) \ declare_constant(ConstantPool::_has_dynamic_constant) \
\ \
declare_constant(ConstMethod::_has_linenumber_table) \ declare_constant(ConstMethodFlags::_misc_has_linenumber_table) \
declare_constant(ConstMethod::_has_localvariable_table) \ declare_constant(ConstMethodFlags::_misc_has_localvariable_table) \
declare_constant(ConstMethod::_has_exception_table) \ declare_constant(ConstMethodFlags::_misc_has_exception_table) \
declare_constant(ConstMethod::_has_method_annotations) \ declare_constant(ConstMethodFlags::_misc_has_method_annotations) \
declare_constant(ConstMethod::_has_parameter_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) \ declare_constant(CounterData::count_off) \
\ \
@ -683,13 +686,8 @@
\ \
declare_constant(markWord::no_hash) \ declare_constant(markWord::no_hash) \
\ \
declare_constant(Method::_caller_sensitive) \ declare_constant(MethodFlags::_misc_force_inline) \
declare_constant(Method::_force_inline) \ declare_constant(MethodFlags::_misc_dont_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(Method::nonvirtual_vtable_index) \ declare_constant(Method::nonvirtual_vtable_index) \
declare_constant(Method::invalid_vtable_index) \ declare_constant(Method::invalid_vtable_index) \

View file

@ -199,7 +199,7 @@ u2* ConstMethod::checked_exceptions_length_addr() const {
} }
u2* ConstMethod::exception_table_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 (has_checked_exceptions()) {
// If checked_exception present, locate immediately before them. // If checked_exception present, locate immediately before them.
return (u2*) checked_exceptions_start() - 1; return (u2*) checked_exceptions_start() - 1;
@ -217,7 +217,7 @@ u2* ConstMethod::exception_table_length_addr() const {
u2* ConstMethod::localvariable_table_length_addr() const { u2* ConstMethod::localvariable_table_length_addr() const {
assert(has_localvariable_table(), "called only if table is present"); 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. // If exception_table present, locate immediately before them.
return (u2*) exception_table_start() - 1; return (u2*) exception_table_start() - 1;
} else { } else {
@ -239,30 +239,29 @@ u2* ConstMethod::localvariable_table_length_addr() const {
// Update the flags to indicate the presence of these optional fields. // Update the flags to indicate the presence of these optional fields.
void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) { void ConstMethod::set_inlined_tables_length(InlineTableSizes* sizes) {
_flags = 0;
if (sizes->compressed_linenumber_size() > 0) if (sizes->compressed_linenumber_size() > 0)
_flags |= _has_linenumber_table; set_has_linenumber_table();
if (sizes->generic_signature_index() != 0) if (sizes->generic_signature_index() != 0)
_flags |= _has_generic_signature; set_has_generic_signature();
if (sizes->method_parameters_length() >= 0) if (sizes->method_parameters_length() >= 0)
_flags |= _has_method_parameters; set_has_method_parameters();
if (sizes->checked_exceptions_length() > 0) if (sizes->checked_exceptions_length() > 0)
_flags |= _has_checked_exceptions; set_has_checked_exceptions();
if (sizes->exception_table_length() > 0) if (sizes->exception_table_length() > 0)
_flags |= _has_exception_table; set_has_exception_table();
if (sizes->localvariable_table_length() > 0) 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 // annotations, they are all pointer sized embedded objects so don't have
// a length embedded also. // a length embedded also.
if (sizes->method_annotations_length() > 0) if (sizes->method_annotations_length() > 0)
_flags |= _has_method_annotations; set_has_method_annotations();
if (sizes->parameter_annotations_length() > 0) if (sizes->parameter_annotations_length() > 0)
_flags |= _has_parameter_annotations; set_has_parameter_annotations();
if (sizes->type_annotations_length() > 0) if (sizes->type_annotations_length() > 0)
_flags |= _has_type_annotations; set_has_type_annotations();
if (sizes->default_annotations_length() > 0) if (sizes->default_annotations_length() > 0)
_flags |= _has_default_annotations; set_has_default_annotations();
// This code is extremely brittle and should possibly be revised. // This code is extremely brittle and should possibly be revised.
// The *_length_addr functions walk backwards through the // The *_length_addr functions walk backwards through the
@ -329,7 +328,7 @@ LocalVariableTableElement* ConstMethod::localvariable_table_start() const {
} }
int ConstMethod::exception_table_length() 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 { ExceptionTableElement* ConstMethod::exception_table_start() const {
@ -431,13 +430,14 @@ void ConstMethod::print_on(outputStream* st) const {
ResourceMark rm; ResourceMark rm;
st->print_cr("%s", internal_name()); st->print_cr("%s", internal_name());
Method* m = method(); Method* m = method();
st->print(" - method: " PTR_FORMAT " ", p2i(m)); st->print(" - method: " PTR_FORMAT " ", p2i(m));
if (m != nullptr) { if (m != nullptr) {
m->print_value_on(st); m->print_value_on(st);
} }
st->cr(); st->cr();
st->print(" - flags: 0x%x ", _flags.as_int()); _flags.print_on(st); st->cr();
if (has_stackmap_table()) { if (has_stackmap_table()) {
st->print(" - stackmap data: "); st->print(" - stackmap data: ");
stackmap_data()->print_value_on(st); stackmap_data()->print_value_on(st);
st->cr(); st->cr();
} }
@ -484,7 +484,7 @@ void ConstMethod::verify_on(outputStream* st) {
u2* addr = checked_exceptions_length_addr(); u2* addr = checked_exceptions_length_addr();
guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); 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(); u2* addr = exception_table_length_addr();
guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout"); 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; u2* uncompressed_table_start;
if (has_localvariable_table()) { if (has_localvariable_table()) {
uncompressed_table_start = (u2*) localvariable_table_start(); uncompressed_table_start = (u2*) localvariable_table_start();
} else if (has_exception_handler()) { } else if (has_exception_table()) {
uncompressed_table_start = (u2*) exception_table_start(); uncompressed_table_start = (u2*) exception_table_start();
} else if (has_checked_exceptions()) { } else if (has_checked_exceptions()) {
uncompressed_table_start = (u2*) checked_exceptions_start(); uncompressed_table_start = (u2*) checked_exceptions_start();

View file

@ -25,6 +25,7 @@
#ifndef SHARE_OOPS_CONSTMETHOD_HPP #ifndef SHARE_OOPS_CONSTMETHOD_HPP
#define SHARE_OOPS_CONSTMETHOD_HPP #define SHARE_OOPS_CONSTMETHOD_HPP
#include "oops/constMethodFlags.hpp"
#include "oops/oop.hpp" #include "oops/oop.hpp"
#include "utilities/align.hpp" #include "utilities/align.hpp"
@ -173,19 +174,6 @@ public:
typedef enum { NORMAL, OVERPASS } MethodType; typedef enum { NORMAL, OVERPASS } MethodType;
private: 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 // Bit vector of signature
// Callers interpret 0=not initialized yet and // Callers interpret 0=not initialized yet and
@ -204,7 +192,7 @@ private:
Array<u1>* _stackmap_data; Array<u1>* _stackmap_data;
int _constMethod_size; int _constMethod_size;
u2 _flags; ConstMethodFlags _flags; // for sizing
u1 _result_type; // BasicType of result u1 _result_type; // BasicType of result
// Size of Java bytecodes allocated immediately after Method*. // Size of Java bytecodes allocated immediately after Method*.
@ -236,33 +224,20 @@ public:
// Inlined tables // Inlined tables
void set_inlined_tables_length(InlineTableSizes* sizes); void set_inlined_tables_length(InlineTableSizes* sizes);
bool has_generic_signature() const // Create getters and setters for the flag values.
{ return (_flags & _has_generic_signature) != 0; } #define CM_FLAGS_GET_SET(name, ignore) \
bool name() const { return _flags.name(); } \
bool has_linenumber_table() const void set_##name() { _flags.set_##name(); }
{ return (_flags & _has_linenumber_table) != 0; } CM_FLAGS_DO(CM_FLAGS_GET_SET)
#undef CM_FLAGS_GET_SET
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; }
MethodType method_type() const { MethodType method_type() const {
return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS; return (_flags.is_overpass()) ? OVERPASS : NORMAL;
} }
void set_method_type(MethodType mt) { void set_method_type(MethodType mt) {
if (mt == NORMAL) { if (mt != NORMAL) {
_flags &= ~(_is_overpass); set_is_overpass();
} else {
_flags |= _is_overpass;
} }
} }
@ -382,20 +357,6 @@ public:
int method_parameters_length() const; int method_parameters_length() const;
MethodParametersElement* method_parameters_start() 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_addr() const;
AnnotationArray* method_annotations() const { AnnotationArray* method_annotations() const {
return has_method_annotations() ? *(method_annotations_addr()) : nullptr; return has_method_annotations() ? *(method_annotations_addr()) : nullptr;

View 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
}

View 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

View file

@ -3477,6 +3477,7 @@ void InstanceKlass::print_on(outputStream* st) const {
st->print(BULLET"instance size: %d", size_helper()); st->cr(); st->print(BULLET"instance size: %d", size_helper()); st->cr();
st->print(BULLET"klass size: %d", size()); 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"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"state: "); st->print_cr("%s", init_state_name());
st->print(BULLET"name: "); name()->print_value_on(st); st->cr(); 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(); st->print(BULLET"super: "); Metadata::print_value_on_maybe_null(st, super()); st->cr();

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,6 +29,7 @@
#include "runtime/atomic.hpp" #include "runtime/atomic.hpp"
#include "runtime/safepoint.hpp" #include "runtime/safepoint.hpp"
#include "utilities/macros.hpp" #include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
// This can be removed for the atomic bitset functions, when available. // This can be removed for the atomic bitset functions, when available.
void InstanceKlassFlags::atomic_set_bits(u1 bits) { void InstanceKlassFlags::atomic_set_bits(u1 bits) {
@ -51,6 +52,15 @@ void InstanceKlassFlags::atomic_clear_bits(u1 bits) {
} while(f != old_status); } 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 #if INCLUDE_CDS
void InstanceKlassFlags::set_shared_class_loader_type(s2 loader_type) { void InstanceKlassFlags::set_shared_class_loader_type(s2 loader_type) {
switch (loader_type) { switch (loader_type) {

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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_resolved_methods , 1 << 1) /* True if the klass has resolved MethodHandle methods */ \
status(has_been_redefined , 1 << 2) /* class has been redefined */ \ status(has_been_redefined , 1 << 2) /* class has been redefined */ \
status(is_scratch_class , 1 << 3) /* class is the redefined scratch class */ \ 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, #define IK_STATUS_ENUM_NAME(name, value) _misc_##name = value,
enum { enum {
@ -89,18 +90,14 @@ class InstanceKlassFlags {
InstanceKlassFlags() : _flags(0), _status(0) {} InstanceKlassFlags() : _flags(0), _status(0) {}
// Create getters and setters for the flag values. // Create getters and setters for the flag values.
#define IK_FLAGS_GET(name, ignore) \ #define IK_FLAGS_GET_SET(name, ignore) \
bool name() const { return (_flags & _misc_##name) != 0; } bool name() const { return (_flags & _misc_##name) != 0; } \
IK_FLAGS_DO(IK_FLAGS_GET)
#undef IK_FLAGS_GET
#define IK_FLAGS_SET(name, ignore) \
void set_##name(bool b) { \ void set_##name(bool b) { \
assert_is_safe(name()); \ assert_is_safe(name()); \
if (b) _flags |= _misc_##name; \ if (b) _flags |= _misc_##name; \
} }
IK_FLAGS_DO(IK_FLAGS_SET) IK_FLAGS_DO(IK_FLAGS_GET_SET)
#undef IK_FLAGS_SET #undef IK_FLAGS_GET_SET
bool is_shared_unregistered_class() const { bool is_shared_unregistered_class() const {
return (_flags & shared_loader_type_bits()) == 0; return (_flags & shared_loader_type_bits()) == 0;
@ -112,12 +109,8 @@ class InstanceKlassFlags {
void assert_is_safe(bool set) NOT_DEBUG_RETURN; void assert_is_safe(bool set) NOT_DEBUG_RETURN;
// Create getters and setters for the status values. // Create getters and setters for the status values.
#define IK_STATUS_GET(name, ignore) \ #define IK_STATUS_GET_SET(name, ignore) \
bool name() const { return (_status & _misc_##name) != 0; } bool name() const { return (_status & _misc_##name) != 0; } \
IK_STATUS_DO(IK_STATUS_GET)
#undef IK_STATUS_GET
#define IK_STATUS_SET(name, ignore) \
void set_##name(bool b) { \ void set_##name(bool b) { \
if (b) { \ if (b) { \
atomic_set_bits(_misc_##name); \ atomic_set_bits(_misc_##name); \
@ -125,11 +118,12 @@ class InstanceKlassFlags {
atomic_clear_bits(_misc_##name); \ atomic_clear_bits(_misc_##name); \
} \ } \
} }
IK_STATUS_DO(IK_STATUS_SET) IK_STATUS_DO(IK_STATUS_GET_SET)
#undef IK_STATUS_SET #undef IK_STATUS_GET_SET
void atomic_set_bits(u1 bits); void atomic_set_bits(u1 bits);
void atomic_clear_bits(u1 bits); void atomic_clear_bits(u1 bits);
void print_on(outputStream* st) const;
}; };
#endif // SHARE_OOPS_INSTANCEKLASSFLAGS_HPP #endif // SHARE_OOPS_INSTANCEKLASSFLAGS_HPP

View file

@ -102,11 +102,6 @@ Method::Method(ConstMethod* xconst, AccessFlags access_flags, Symbol* name) {
set_constMethod(xconst); set_constMethod(xconst);
set_access_flags(access_flags); set_access_flags(access_flags);
set_intrinsic_id(vmIntrinsics::_none); 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); set_method_data(nullptr);
clear_method_counters(); clear_method_counters();
set_vtable_index(Method::garbage_vtable_index); set_vtable_index(Method::garbage_vtable_index);
@ -736,24 +731,27 @@ bool Method::compute_has_loops_flag() {
case Bytecodes::_if_acmpne: case Bytecodes::_if_acmpne:
case Bytecodes::_goto: case Bytecodes::_goto:
case Bytecodes::_jsr: 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; break;
case Bytecodes::_goto_w: case Bytecodes::_goto_w:
case Bytecodes::_jsr_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; break;
case Bytecodes::_lookupswitch: { case Bytecodes::_lookupswitch: {
Bytecode_lookupswitch lookupswitch(this, bcs.bcp()); Bytecode_lookupswitch lookupswitch(this, bcs.bcp());
if (lookupswitch.default_offset() < 0) { if (lookupswitch.default_offset() < 0) {
_access_flags.set_has_loops(); return set_has_loops();
} else { } else {
for (int i = 0; i < lookupswitch.number_of_pairs(); ++i) { for (int i = 0; i < lookupswitch.number_of_pairs(); ++i) {
LookupswitchPair pair = lookupswitch.pair_at(i); LookupswitchPair pair = lookupswitch.pair_at(i);
if (pair.offset() < 0) { if (pair.offset() < 0) {
_access_flags.set_has_loops(); return set_has_loops();
break;
} }
} }
} }
@ -762,11 +760,11 @@ bool Method::compute_has_loops_flag() {
case Bytecodes::_tableswitch: { case Bytecodes::_tableswitch: {
Bytecode_tableswitch tableswitch(this, bcs.bcp()); Bytecode_tableswitch tableswitch(this, bcs.bcp());
if (tableswitch.default_offset() < 0) { if (tableswitch.default_offset() < 0) {
_access_flags.set_has_loops(); return set_has_loops();
} else { } else {
for (int i = 0; i < tableswitch.length(); ++i) { for (int i = 0; i < tableswitch.length(); ++i) {
if (tableswitch.dest_offset_at(i) < 0) { 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; 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 { 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); print_made_not_compilable(comp_level, /*is_osr*/ false, report, reason);
if (comp_level == CompLevel_all) { if (comp_level == CompLevel_all) {
set_not_c1_compilable(); set_is_not_c1_compilable();
set_not_c2_compilable(); set_is_not_c2_compilable();
} else { } else {
if (is_c1_compile(comp_level)) if (is_c1_compile(comp_level))
set_not_c1_compilable(); set_is_not_c1_compilable();
if (is_c2_compile(comp_level)) 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"); 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) { 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); print_made_not_compilable(comp_level, /*is_osr*/ true, report, reason);
if (comp_level == CompLevel_all) { if (comp_level == CompLevel_all) {
set_not_c1_osr_compilable(); set_is_not_c1_osr_compilable();
set_not_c2_osr_compilable(); set_is_not_c2_osr_compilable();
} else { } else {
if (is_c1_compile(comp_level)) if (is_c1_compile(comp_level))
set_not_c1_osr_compilable(); set_is_not_c1_osr_compilable();
if (is_c2_compile(comp_level)) 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"); 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); set_intrinsic_id(id);
if (id == vmIntrinsics::_Class_cast) { if (id == vmIntrinsics::_Class_cast) {
// Even if the intrinsic is rejected, we want to inline this simple method. // Even if the intrinsic is rejected, we want to inline this simple method.
set_force_inline(true); set_force_inline();
} }
return; 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. // on stack means some method referring to it is also on the stack.
constants()->set_on_stack(value); constants()->set_on_stack(value);
bool already_set = on_stack(); bool already_set = on_stack_flag();
_access_flags.set_on_stack(value); set_on_stack_flag(value);
if (value && !already_set) { if (value && !already_set) {
MetadataOnStackMark::record(this); MetadataOnStackMark::record(this);
} }
@ -2304,6 +2303,7 @@ void Method::print_on(outputStream* st) const {
st->print (" - constants: " PTR_FORMAT " ", p2i(constants())); st->print (" - constants: " PTR_FORMAT " ", p2i(constants()));
constants()->print_value_on(st); st->cr(); 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 (" - 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 (" - name: "); name()->print_value_on(st); st->cr();
st->print (" - signature: "); signature()->print_value_on(st); st->cr(); st->print (" - signature: "); signature()->print_value_on(st); st->cr();
st->print_cr(" - max stack: %d", max_stack()); st->print_cr(" - max stack: %d", max_stack());

View file

@ -31,6 +31,7 @@
#include "oops/annotations.hpp" #include "oops/annotations.hpp"
#include "oops/constantPool.hpp" #include "oops/constantPool.hpp"
#include "oops/methodCounters.hpp" #include "oops/methodCounters.hpp"
#include "oops/methodFlags.hpp"
#include "oops/instanceKlass.hpp" #include "oops/instanceKlass.hpp"
#include "oops/oop.hpp" #include "oops/oop.hpp"
#include "oops/typeArrayOop.hpp" #include "oops/typeArrayOop.hpp"
@ -79,23 +80,9 @@ class Method : public Metadata {
AdapterHandlerEntry* _adapter; AdapterHandlerEntry* _adapter;
AccessFlags _access_flags; // Access flags AccessFlags _access_flags; // Access flags
int _vtable_index; // vtable index of this method (see VtableIndexFlag) int _vtable_index; // vtable index of this method (see VtableIndexFlag)
// note: can have vtables with >2**16 elements (because of inheritance) MethodFlags _flags;
u2 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none)
// Flags u2 _intrinsic_id; // vmSymbols::intrinsic_id (0 == _none)
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;
JFR_ONLY(DEFINE_TRACE_FLAG;) JFR_ONLY(DEFINE_TRACE_FLAG;)
@ -332,7 +319,7 @@ class Method : public Metadata {
// exception handler table // exception handler table
bool has_exception_handler() const bool has_exception_handler() const
{ return constMethod()->has_exception_handler(); } { return constMethod()->has_exception_table(); }
int exception_table_length() const int exception_table_length() const
{ return constMethod()->exception_table_length(); } { return constMethod()->exception_table_length(); }
ExceptionTableElement* exception_table_start() const ExceptionTableElement* exception_table_start() const
@ -602,31 +589,35 @@ public:
// true if method can omit stack trace in throw in compiled code. // true if method can omit stack trace in throw in compiled code.
bool can_omit_stack_trace(); 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. // returns true if the method has any backward branches.
bool has_loops() { 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 compute_has_loops_flag();
bool set_has_loops() {
bool has_jsrs() { // set both the flags and that it's been initialized.
return access_flags().has_jsrs(); set_has_loops_flag();
}; set_has_loops_flag_init();
void set_has_jsrs() { return true;
_access_flags.set_has_jsrs();
} }
// returns true if the method has any monitors. // returns true if the method has any monitors.
bool has_monitors() const { return is_synchronized() || access_flags().has_monitor_bytecodes(); } bool has_monitors() const { return is_synchronized() || 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(); }
// monitor matching. This returns a conservative estimate of whether the monitorenter/monitorexit 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. // has not been computed yet.
bool guaranteed_monitor_matching() const { return access_flags().is_monitor_matching(); } bool guaranteed_monitor_matching() const { return monitor_matching(); }
void set_guaranteed_monitor_matching() { _access_flags.set_monitor_matching(); } void set_guaranteed_monitor_matching() { set_monitor_matching(); }
// returns true if the method is an accessor function (setter/getter). // returns true if the method is an accessor function (setter/getter).
bool is_accessor() const; bool is_accessor() const;
@ -745,14 +736,7 @@ public:
static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize
// RedefineClasses() support: // RedefineClasses() support:
bool is_old() const { return access_flags().is_old(); } bool on_stack() const { return on_stack_flag(); }
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(); }
void set_on_stack(const bool value); void set_on_stack(const bool value);
void record_gc_epoch(); void record_gc_epoch();
@ -760,10 +744,6 @@ public:
// see the definition in Method*.cpp for the gory details // see the definition in Method*.cpp for the gory details
bool should_not_be_cached() const; 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 // Rewriting support
static methodHandle clone_with_new_data(const methodHandle& m, u_char* new_code, int new_code_length, 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); 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 void init_intrinsic_id(vmSymbolID klass_id); // updates from _none if a match
static vmSymbolID klass_id_for_intrinsics(const Klass* holder); static vmSymbolID klass_id_for_intrinsics(const Klass* holder);
bool caller_sensitive() { bool caller_sensitive() const { return constMethod()->caller_sensitive(); }
return (_flags & _caller_sensitive) != 0; void set_caller_sensitive() { constMethod()->set_caller_sensitive(); }
}
void set_caller_sensitive(bool x) {
_flags = x ? (_flags | _caller_sensitive) : (_flags & ~_caller_sensitive);
}
bool force_inline() { bool changes_current_thread() const { return constMethod()->changes_current_thread(); }
return (_flags & _force_inline) != 0; void set_changes_current_thread() { constMethod()->set_changes_current_thread(); }
}
void set_force_inline(bool x) {
_flags = x ? (_flags | _force_inline) : (_flags & ~_force_inline);
}
bool dont_inline() { bool jvmti_mount_transition() const { return constMethod()->jvmti_mount_transition(); }
return (_flags & _dont_inline) != 0; void set_jvmti_mount_transition() { constMethod()->set_jvmti_mount_transition(); }
}
void set_dont_inline(bool x) {
_flags = x ? (_flags | _dont_inline) : (_flags & ~_dont_inline);
}
bool changes_current_thread() { bool is_hidden() const { return constMethod()->is_hidden(); }
return (_flags & _changes_current_thread) != 0; void set_is_hidden() { constMethod()->set_is_hidden(); }
}
void set_changes_current_thread(bool x) {
_flags = x ? (_flags | _changes_current_thread) : (_flags & ~_changes_current_thread);
}
bool jvmti_mount_transition() { bool is_scoped() const { return constMethod()->is_scoped(); }
return (_flags & _jvmti_mount_transition) != 0; void set_scoped() { constMethod()->set_is_scoped(); }
}
void set_jvmti_mount_transition(bool x) {
_flags = x ? (_flags | _jvmti_mount_transition) : (_flags & ~_jvmti_mount_transition);
}
bool is_hidden() const { bool intrinsic_candidate() const { return constMethod()->intrinsic_candidate(); }
return (_flags & _hidden) != 0; void set_intrinsic_candidate() { constMethod()->set_intrinsic_candidate(); }
}
void set_hidden(bool x) { bool has_injected_profile() const { return constMethod()->has_injected_profile(); }
_flags = x ? (_flags | _hidden) : (_flags & ~_hidden); void set_has_injected_profile() { constMethod()->set_has_injected_profile(); }
}
bool is_scoped() const { bool has_reserved_stack_access() const { return constMethod()->reserved_stack_access(); }
return (_flags & _scoped) != 0; void set_has_reserved_stack_access() { constMethod()->set_reserved_stack_access(); }
}
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);
}
JFR_ONLY(DEFINE_TRACE_FLAG_ACCESSOR;) JFR_ONLY(DEFINE_TRACE_FLAG_ACCESSOR;)
@ -939,24 +870,17 @@ public:
return _method_counters; return _method_counters;
} }
bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); } void clear_is_not_c1_compilable() { set_is_not_c1_compilable(false); }
void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); } void clear_is_not_c2_compilable() { set_is_not_c2_compilable(false); }
void clear_not_c1_compilable() { _access_flags.clear_not_c1_compilable(); } void clear_is_not_c2_osr_compilable() { set_is_not_c2_osr_compilable(false); }
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(); }
bool is_not_c1_osr_compilable() const { return is_not_c1_compilable(); } // don't waste an accessFlags bit // not_c1_osr_compilable == not_c1_compilable
void set_not_c1_osr_compilable() { set_not_c1_compilable(); } // don't waste an accessFlags bit bool is_not_c1_osr_compilable() const { return is_not_c1_compilable(); }
void clear_not_c1_osr_compilable() { clear_not_c1_compilable(); } // don't waste an accessFlags bit void set_is_not_c1_osr_compilable() { set_is_not_c1_compilable(); }
bool is_not_c2_osr_compilable() const { return access_flags().is_not_c2_osr_compilable(); } void clear_is_not_c1_osr_compilable() { clear_is_not_c1_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(); }
// Background compilation support // Background compilation support
bool queued_for_compilation() const { return access_flags().queued_for_compilation(); } void clear_queued_for_compilation() { set_queued_for_compilation(false); }
void set_queued_for_compilation() { _access_flags.set_queued_for_compilation(); }
void clear_queued_for_compilation() { _access_flags.clear_queued_for_compilation(); }
// Resolve all classes in signature, return 'true' if successful // Resolve all classes in signature, return 'true' if successful
static bool load_signature_classes(const methodHandle& m, TRAPS); static bool load_signature_classes(const methodHandle& m, TRAPS);

View 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
}

View 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

View file

@ -1206,9 +1206,9 @@ WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
mdo->clean_method_data(/*always_clean*/true); mdo->clean_method_data(/*always_clean*/true);
} }
mh->clear_not_c1_compilable(); mh->clear_is_not_c1_compilable();
mh->clear_not_c2_compilable(); mh->clear_is_not_c2_compilable();
mh->clear_not_c2_osr_compilable(); mh->clear_is_not_c2_osr_compilable();
NOT_PRODUCT(mh->set_compiled_invocation_count(0)); NOT_PRODUCT(mh->set_compiled_invocation_count(0));
if (mcs != nullptr) { if (mcs != nullptr) {
mcs->clear_counters(); mcs->clear_counters();

View file

@ -299,7 +299,6 @@
nonstatic_field(Method, _access_flags, AccessFlags) \ nonstatic_field(Method, _access_flags, AccessFlags) \
nonstatic_field(Method, _vtable_index, int) \ nonstatic_field(Method, _vtable_index, int) \
nonstatic_field(Method, _intrinsic_id, u2) \ nonstatic_field(Method, _intrinsic_id, u2) \
nonstatic_field(Method, _flags, u2) \
volatile_nonstatic_field(Method, _code, CompiledMethod*) \ volatile_nonstatic_field(Method, _code, CompiledMethod*) \
nonstatic_field(Method, _i2i_entry, address) \ nonstatic_field(Method, _i2i_entry, address) \
volatile_nonstatic_field(Method, _from_compiled_entry, address) \ volatile_nonstatic_field(Method, _from_compiled_entry, address) \
@ -308,7 +307,7 @@
nonstatic_field(ConstMethod, _constants, ConstantPool*) \ nonstatic_field(ConstMethod, _constants, ConstantPool*) \
nonstatic_field(ConstMethod, _stackmap_data, Array<u1>*) \ nonstatic_field(ConstMethod, _stackmap_data, Array<u1>*) \
nonstatic_field(ConstMethod, _constMethod_size, int) \ 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, _code_size, u2) \
nonstatic_field(ConstMethod, _name_index, u2) \ nonstatic_field(ConstMethod, _name_index, u2) \
nonstatic_field(ConstMethod, _signature_index, u2) \ nonstatic_field(ConstMethod, _signature_index, u2) \
@ -2085,16 +2084,6 @@
/************************************************************/ \ /************************************************************/ \
\ \
declare_constant(JVM_ACC_WRITTEN_FLAGS) \ 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_HAS_FINALIZER) \
declare_constant(JVM_ACC_IS_CLONEABLE_FAST) \ 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_type_value) \
declare_constant(Klass::_lh_array_tag_obj_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 */ \ /* ConstMethod anon-enum */ \
/********************************/ \ /********************************/ \
\ \
declare_constant(Method::_caller_sensitive) \ declare_constant(ConstMethodFlags::_misc_has_linenumber_table) \
declare_constant(Method::_force_inline) \ declare_constant(ConstMethodFlags::_misc_has_checked_exceptions) \
declare_constant(Method::_dont_inline) \ declare_constant(ConstMethodFlags::_misc_has_localvariable_table) \
declare_constant(Method::_hidden) \ declare_constant(ConstMethodFlags::_misc_has_exception_table) \
declare_constant(Method::_changes_current_thread) \ declare_constant(ConstMethodFlags::_misc_has_generic_signature) \
\ declare_constant(ConstMethodFlags::_misc_has_method_parameters) \
declare_constant(Method::nonvirtual_vtable_index) \ declare_constant(ConstMethodFlags::_misc_has_method_annotations) \
\ declare_constant(ConstMethodFlags::_misc_has_parameter_annotations) \
declare_constant(Method::extra_stack_entries_for_jsr292) \ declare_constant(ConstMethodFlags::_misc_has_default_annotations) \
\ declare_constant(ConstMethodFlags::_misc_has_type_annotations) \
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) \
\ \
/**************/ \ /**************/ \
/* DataLayout */ \ /* DataLayout */ \

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,27 +27,6 @@
#include "runtime/atomic.hpp" #include "runtime/atomic.hpp"
#include "utilities/accessFlags.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 #if !defined(PRODUCT) || INCLUDE_JVMTI
void AccessFlags::print_on(outputStream* st) const { 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_interface ()) st->print("interface " );
if (is_abstract ()) st->print("abstract " ); if (is_abstract ()) st->print("abstract " );
if (is_synthetic ()) st->print("synthetic " ); 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 #endif // !PRODUCT || INCLUDE_JVMTI

View file

@ -42,22 +42,6 @@ enum {
// flags actually put in .class file // flags actually put in .class file
JVM_ACC_WRITTEN_FLAGS = 0x00007FFF, 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 // Klass* flags
JVM_ACC_HAS_FINALIZER = 0x40000000, // True if klass has a non-empty finalize() method 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 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 // Attribute flags
bool is_synthetic () const { return (_flags & JVM_ACC_SYNTHETIC ) != 0; } 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 // Klass* flags
bool has_finalizer () const { return (_flags & JVM_ACC_HAS_FINALIZER ) != 0; } 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_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_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 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 // get .class file flags
jint get_flags () const { return (_flags & JVM_ACC_WRITTEN_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_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: private:
friend class Method;
friend class Klass; friend class Klass;
friend class ClassFileParser; friend class ClassFileParser;
// the functions below should only be called on the _access_flags inst var directly, // the functions below should only be called on the _access_flags inst var directly,
// otherwise they are just changing a copy of the flags // otherwise they are just changing a copy of the flags
// attribute 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 // Klass* flags
void set_has_finalizer() { atomic_set_bits(JVM_ACC_HAS_FINALIZER); } // These are set at classfile parsing time so do not require atomic access.
void set_is_cloneable_fast() { atomic_set_bits(JVM_ACC_IS_CLONEABLE_FAST); } void set_has_finalizer() { _flags |= JVM_ACC_HAS_FINALIZER; }
void set_is_hidden_class() { atomic_set_bits(JVM_ACC_IS_HIDDEN_CLASS); } void set_is_cloneable_fast() { _flags |= JVM_ACC_IS_CLONEABLE_FAST; }
void set_is_value_based_class() { atomic_set_bits(JVM_ACC_IS_VALUE_BASED_CLASS); } 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: 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 // Conversion
jshort as_short() const { return (jshort)_flags; } jshort as_short() const { return (jshort)_flags; }
jint as_int() const { return _flags; } jint as_int() const { return _flags; }

View file

@ -56,17 +56,6 @@ public class AccessFlags implements /* imports */ ClassConstants {
public long getValue () { return flags; } 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 // Klass* flags
public boolean hasFinalizer () { return (flags & JVM_ACC_HAS_FINALIZER ) != 0; } public boolean hasFinalizer () { return (flags & JVM_ACC_HAS_FINALIZER ) != 0; }
public boolean isCloneable () { return (flags & JVM_ACC_IS_CLONEABLE ) != 0; } public boolean isCloneable () { return (flags & JVM_ACC_IS_CLONEABLE ) != 0; }

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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"); Type type = db.lookupType("ConstMethod");
constants = new MetadataField(type.getAddressField("_constants"), 0); constants = new MetadataField(type.getAddressField("_constants"), 0);
constMethodSize = new CIntField(type.getCIntegerField("_constMethod_size"), 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 // enum constants for flags
HAS_LINENUMBER_TABLE = db.lookupIntConstant("ConstMethod::_has_linenumber_table").intValue(); HAS_LINENUMBER_TABLE = db.lookupIntConstant("ConstMethodFlags::_misc_has_linenumber_table").intValue();
HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("ConstMethod::_has_checked_exceptions").intValue(); HAS_CHECKED_EXCEPTIONS = db.lookupIntConstant("ConstMethodFlags::_misc_has_checked_exceptions").intValue();
HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("ConstMethod::_has_localvariable_table").intValue(); HAS_LOCALVARIABLE_TABLE = db.lookupIntConstant("ConstMethodFlags::_misc_has_localvariable_table").intValue();
HAS_EXCEPTION_TABLE = db.lookupIntConstant("ConstMethod::_has_exception_table").intValue(); HAS_EXCEPTION_TABLE = db.lookupIntConstant("ConstMethodFlags::_misc_has_exception_table").intValue();
HAS_GENERIC_SIGNATURE = db.lookupIntConstant("ConstMethod::_has_generic_signature").intValue(); HAS_GENERIC_SIGNATURE = db.lookupIntConstant("ConstMethodFlags::_misc_has_generic_signature").intValue();
HAS_METHOD_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_method_annotations").intValue(); HAS_METHOD_ANNOTATIONS = db.lookupIntConstant("ConstMethodFlags::_misc_has_method_annotations").intValue();
HAS_PARAMETER_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_parameter_annotations").intValue(); HAS_PARAMETER_ANNOTATIONS = db.lookupIntConstant("ConstMethodFlags::_misc_has_parameter_annotations").intValue();
HAS_METHOD_PARAMETERS = db.lookupIntConstant("ConstMethod::_has_method_parameters").intValue(); HAS_METHOD_PARAMETERS = db.lookupIntConstant("ConstMethodFlags::_misc_has_method_parameters").intValue();
HAS_DEFAULT_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_default_annotations").intValue(); HAS_DEFAULT_ANNOTATIONS = db.lookupIntConstant("ConstMethodFlags::_misc_has_default_annotations").intValue();
HAS_TYPE_ANNOTATIONS = db.lookupIntConstant("ConstMethod::_has_type_annotations").intValue(); HAS_TYPE_ANNOTATIONS = db.lookupIntConstant("ConstMethodFlags::_misc_has_type_annotations").intValue();
// Size of Java bytecodes allocated immediately after ConstMethod*. // Size of Java bytecodes allocated immediately after ConstMethod*.
codeSize = new CIntField(type.getCIntegerField("_code_size"), 0); codeSize = new CIntField(type.getCIntegerField("_code_size"), 0);

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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()); return isStatic() && getName().equals(classInitializerName());
} }
public boolean isObsolete() {
return getAccessFlagsObj().isObsolete();
}
public OopMapCacheEntry getMaskFor(int bci) { public OopMapCacheEntry getMaskFor(int bci) {
OopMapCacheEntry entry = new OopMapCacheEntry(); OopMapCacheEntry entry = new OopMapCacheEntry();
entry.fill(this, bci); entry.fill(this, bci);

View file

@ -103,25 +103,6 @@ public interface ClassConstants
// flags actually put in .class file // flags actually put in .class file
public static final long JVM_ACC_WRITTEN_FLAGS = 0x00007FFF; 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 // Klass* flags
// True if klass has a non-empty finalize() method // True if klass has a non-empty finalize() method
public static final long JVM_ACC_HAS_FINALIZER = 0x40000000; public static final long JVM_ACC_HAS_FINALIZER = 0x40000000;

View file

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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 @Override
public boolean isCallerSensitive() { 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 @Override
public boolean hasReservedStackAccess() { 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 @Override
public boolean isIntrinsicCandidate() { public boolean isIntrinsicCandidate() {
return (getFlags() & config().methodFlagsIntrinsicCandidate) != 0; return (getConstMethodFlags() & config().constMethodFlagsIntrinsicCandidate) != 0;
} }
/** /**

View file

@ -149,17 +149,14 @@ class HotSpotVMConfig extends HotSpotVMConfigAccess {
final int methodAccessFlagsOffset = getFieldOffset("Method::_access_flags", Integer.class, "AccessFlags"); final int methodAccessFlagsOffset = getFieldOffset("Method::_access_flags", Integer.class, "AccessFlags");
final int methodConstMethodOffset = getFieldOffset("Method::_constMethod", Integer.class, "ConstMethod*"); final int methodConstMethodOffset = getFieldOffset("Method::_constMethod", Integer.class, "ConstMethod*");
final int methodIntrinsicIdOffset = getFieldOffset("Method::_intrinsic_id", Integer.class, "u2"); 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 methodVtableIndexOffset = getFieldOffset("Method::_vtable_index", Integer.class, "int");
final int methodDataOffset = getFieldOffset("Method::_method_data", Integer.class, "MethodData*"); final int methodDataOffset = getFieldOffset("Method::_method_data", Integer.class, "MethodData*");
final int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, "CompiledMethod*"); final int methodCodeOffset = getFieldOffset("Method::_code", Integer.class, "CompiledMethod*");
final int methodFlagsCallerSensitive = getConstant("Method::_caller_sensitive", Integer.class); final int methodFlagsForceInline = getConstant("MethodFlags::_misc_force_inline", Integer.class);
final int methodFlagsForceInline = getConstant("Method::_force_inline", Integer.class); final int methodFlagsDontInline = getConstant("MethodFlags::_misc_dont_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 nonvirtualVtableIndex = getConstant("Method::nonvirtual_vtable_index", Integer.class); final int nonvirtualVtableIndex = getConstant("Method::nonvirtual_vtable_index", Integer.class);
final int invalidVtableIndex = getConstant("Method::invalid_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 extraStackEntries = getFieldValue("CompilerToVM::Data::Method_extra_stack_entries", Integer.class, "int");
final int constMethodConstantsOffset = getFieldOffset("ConstMethod::_constants", Integer.class, "ConstantPool*"); 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 constMethodCodeSizeOffset = getFieldOffset("ConstMethod::_code_size", Integer.class, "u2");
final int constMethodNameIndexOffset = getFieldOffset("ConstMethod::_name_index", Integer.class, "u2"); final int constMethodNameIndexOffset = getFieldOffset("ConstMethod::_name_index", Integer.class, "u2");
final int constMethodSignatureIndexOffset = getFieldOffset("ConstMethod::_signature_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 constMethodMaxStackOffset = getFieldOffset("ConstMethod::_max_stack", Integer.class, "u2");
final int methodMaxLocalsOffset = getFieldOffset("ConstMethod::_max_locals", 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 constMethodFlagsReservedStackAccess = getConstant("ConstMethodFlags::_misc_reserved_stack_access", Integer.class);
final int constMethodHasLocalVariableTable = getConstant("ConstMethod::_has_localvariable_table", Integer.class); final int constMethodFlagsCallerSensitive = getConstant("ConstMethodFlags::_misc_caller_sensitive", Integer.class);
final int constMethodHasMethodAnnotations = getConstant("ConstMethod::_has_method_annotations", Integer.class); final int constMethodFlagsIntrinsicCandidate = getConstant("ConstMethodFlags::_misc_intrinsic_candidate", Integer.class);
final int constMethodHasParameterAnnotations = getConstant("ConstMethod::_has_parameter_annotations", Integer.class); final int constMethodHasLineNumberTable = getConstant("ConstMethodFlags::_misc_has_linenumber_table", Integer.class);
final int constMethodHasExceptionTable = getConstant("ConstMethod::_has_exception_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 exceptionTableElementSize = getFieldValue("CompilerToVM::Data::sizeof_ExceptionTableElement", Integer.class, "int");
final int exceptionTableElementStartPcOffset = getFieldOffset("ExceptionTableElement::start_pc", Integer.class, "u2"); final int exceptionTableElementStartPcOffset = getFieldOffset("ExceptionTableElement::start_pc", Integer.class, "u2");