Skip to content

Commit ccc44d4

Browse files
committed
Detecting pattern attribute
1 parent 7b693b4 commit ccc44d4

File tree

7 files changed

+89
-3
lines changed

7 files changed

+89
-3
lines changed

src/hotspot/share/classfile/classFileParser.cpp

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2341,6 +2341,11 @@ Method* ClassFileParser::parse_method(const ClassFileStream* const cfs,
23412341
const u1* annotation_default = nullptr;
23422342
int annotation_default_length = 0;
23432343

2344+
int pattern_length = 0;
2345+
const u1* pattern_runtime_visible_parameter_annotations = nullptr;
2346+
int pattern_runtime_visible_parameter_annotations_length = 0;
2347+
bool is_pattern = false;
2348+
23442349
// Parse code and exceptions attribute
23452350
u2 method_attributes_count = cfs->get_u2_fast();
23462351
while (method_attributes_count--) {
@@ -2675,7 +2680,64 @@ Method* ClassFileParser::parse_method(const ClassFileStream* const cfs,
26752680
assert(runtime_invisible_type_annotations != nullptr, "null invisible type annotations");
26762681
}
26772682
cfs->skip_u1(method_attribute_length, CHECK_NULL);
2678-
} else {
2683+
}
2684+
else if (method_attribute_name == vmSymbols::tag_pattern()) {
2685+
cfs->guarantee_more(6, CHECK_NULL); // pattern_name_index, pattern_flags, pattern_methodtype_index
2686+
2687+
const u2 pattern_name_index = cfs->get_u2_fast();
2688+
check_property(
2689+
valid_symbol_at(pattern_name_index),
2690+
"Invalid pattern attribute name index %u in class file %s",
2691+
pattern_name_index, CHECK_NULL);
2692+
const Symbol *const pattern_name = cp->symbol_at(pattern_name_index);
2693+
2694+
const u2 pattern_flags = cfs->get_u2_fast();
2695+
2696+
const u2 pattern_methodtype_index = cfs->get_u2_fast();
2697+
guarantee_property(
2698+
valid_symbol_at(pattern_methodtype_index),
2699+
"Illegal constant pool index %u for pattern method type in class file %s",
2700+
pattern_methodtype_index, CHECK_NULL);
2701+
const Symbol* const signature = cp->symbol_at(pattern_methodtype_index);
2702+
2703+
is_pattern = true;
2704+
2705+
cfs->guarantee_more(2, CHECK_NULL); // pattern_method_attributes_count
2706+
2707+
u2 pattern_method_attributes_count = cfs->get_u2_fast();
2708+
while (pattern_method_attributes_count--) {
2709+
cfs->guarantee_more(6, CHECK_NULL); // method_attribute_name_index, method_attribute_length
2710+
const u2 pattern_method_attribute_name_index = cfs->get_u2_fast();
2711+
const u4 pattern_method_attribute_length = cfs->get_u4_fast();
2712+
check_property(
2713+
valid_symbol_at(pattern_method_attribute_name_index),
2714+
"Invalid pattern method attribute name index %u in class file %s",
2715+
pattern_method_attribute_name_index, CHECK_NULL);
2716+
2717+
const Symbol *const pattern_method_attribute_name = cp->symbol_at(pattern_method_attribute_name_index);
2718+
2719+
if (pattern_method_attribute_name == vmSymbols::tag_method_parameters()) {
2720+
const int pattern_method_parameters_length = cfs->get_u1_fast();
2721+
2722+
cfs->skip_u2_fast(pattern_method_parameters_length);
2723+
cfs->skip_u2_fast(pattern_method_parameters_length);
2724+
}
2725+
else if (pattern_method_attribute_name == vmSymbols::tag_signature()) {
2726+
const int pattern_signature_data = parse_generic_signature_attribute(cfs, CHECK_NULL);
2727+
} else if (pattern_method_attribute_name == vmSymbols::tag_runtime_visible_parameter_annotations()) {
2728+
if (runtime_visible_type_annotations != nullptr) {
2729+
classfile_parse_error(
2730+
"Multiple RuntimeVisibleTypeAnnotations attributes for pattern method in class file %s",
2731+
THREAD);
2732+
return nullptr;
2733+
}
2734+
pattern_runtime_visible_parameter_annotations_length = pattern_method_attribute_length;
2735+
pattern_runtime_visible_parameter_annotations = cfs->current();
2736+
cfs->skip_u1(pattern_runtime_visible_parameter_annotations_length, CHECK_NULL);
2737+
}
2738+
}
2739+
}
2740+
else {
26792741
// Skip unknown attributes
26802742
cfs->skip_u1(method_attribute_length, CHECK_NULL);
26812743
}
@@ -2730,6 +2792,8 @@ Method* ClassFileParser::parse_method(const ClassFileStream* const cfs,
27302792
m->set_constants(_cp);
27312793
m->set_name_index(name_index);
27322794
m->set_signature_index(signature_index);
2795+
m->set_is_pattern(is_pattern);
2796+
27332797
m->constMethod()->compute_from_signature(cp->symbol_at(signature_index), access_flags.is_static());
27342798
assert(args_size < 0 || args_size == m->size_of_parameters(), "");
27352799

src/hotspot/share/classfile/vmSymbols.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ class SerializeClosure;
207207
template(tag_enclosing_method, "EnclosingMethod") \
208208
template(tag_bootstrap_methods, "BootstrapMethods") \
209209
template(tag_permitted_subclasses, "PermittedSubclasses") \
210+
template(tag_pattern, "Pattern") \
210211
\
211212
/* exception klasses: at least all exceptions thrown by the VM have entries here */ \
212213
template(java_lang_ArithmeticException, "java/lang/ArithmeticException") \

src/hotspot/share/jvmci/jvmciCompilerToVM.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2175,7 +2175,7 @@ C2V_VMENTRY_NULL(jobjectArray, getDeclaredPatternDeclarations, (JNIEnv* env, job
21752175
GrowableArray<Method*> methods_array;
21762176
for (int i = 0; i < iklass->methods()->length(); i++) {
21772177
Method* m = iklass->methods()->at(i);
2178-
if (!m->is_initializer() && !m->is_overpass()) {
2178+
if (!m->is_initializer() && !m->is_overpass() && m->is_pattern()) {
21792179
methods_array.append(m);
21802180
}
21812181
}

src/hotspot/share/oops/constMethod.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,8 @@ class ConstMethod : public MetaspaceObj {
200200
u2 _code_size;
201201
u2 _name_index; // Method name (index in constant pool)
202202
u2 _signature_index; // Method signature (index in constant pool)
203+
bool _is_pattern_flag; // Pattern method (index in constant pool)
204+
203205
u2 _method_idnum; // unique identification number for the method within the class
204206
// initially corresponds to the index into the methods array.
205207
// but this may change with redefinition
@@ -296,6 +298,10 @@ class ConstMethod : public MetaspaceObj {
296298
u2 signature_index() const { return _signature_index; }
297299
void set_signature_index(int index) { _signature_index = checked_cast<u2>(index); }
298300

301+
// pattern
302+
bool is_pattern() const { return _is_pattern_flag; }
303+
void set_is_pattern(bool b) { _is_pattern_flag = b; }
304+
299305
// generics support
300306
u2 generic_signature_index() const {
301307
if (has_generic_signature()) {

src/hotspot/share/oops/method.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ class Method : public Metadata {
148148
u2 signature_index() const { return constMethod()->signature_index(); }
149149
void set_signature_index(int index) { constMethod()->set_signature_index(index); }
150150

151+
// pattern
152+
u2 is_pattern() const { return constMethod()->is_pattern(); }
153+
void set_is_pattern(bool b) { constMethod()->set_is_pattern(b); }
154+
151155
// generics support
152156
Symbol* generic_signature() const { int idx = generic_signature_index(); return ((idx != 0) ? constants()->symbol_at(idx) : nullptr); }
153157
u2 generic_signature_index() const { return constMethod()->generic_signature_index(); }

src/hotspot/share/prims/jvm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1974,7 +1974,7 @@ static jobjectArray get_class_declared_pattern_declarations_helper(
19741974
for (int i = 0; i < methods_length; i++) {
19751975
methodHandle method(THREAD, methods->at(i));
19761976
if (select_method(method, want_constructor)) {
1977-
if (!publicOnly || method->is_public()) {
1977+
if ((!publicOnly || method->is_public()) && method->is_pattern()) {
19781978
idnums->push(method->method_idnum());
19791979
++num_methods;
19801980
}

test/jdk/java/lang/reflect/PatternDeclaration/SimplePatternDeclarationsTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class Person1 {
5454
private final String username;
5555
private boolean capitalize;
5656

57+
// 2 declared contructors
5758
public Person1(String name) {
5859
this(name, "default", false);
5960
}
@@ -64,6 +65,7 @@ public Person1(String name, String username, boolean capitalize) {
6465
this.capitalize = capitalize;
6566
}
6667

68+
// 2 declared pattern declarations
6769
public pattern Person1(String name, String username) {
6870
match Person1(this.name, this.username);
6971
}
@@ -75,4 +77,13 @@ public pattern Person1(String name) {
7577
match Person1(this.name);
7678
}
7779
}
80+
81+
// 2 methods
82+
public void test1() {
83+
84+
}
85+
86+
public int test2(int i) {
87+
return i++;
88+
}
7889
}

0 commit comments

Comments
 (0)