Skip to content

Commit 36c150b

Browse files
committed
8255489: Unify the parsing of @lambda-proxy and @lambda-form-invokers tags in a classlist
Reviewed-by: iklam, minqi
1 parent 0f48603 commit 36c150b

File tree

9 files changed

+65
-34
lines changed

9 files changed

+65
-34
lines changed

src/hotspot/share/classfile/classListParser.cpp

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,6 @@ bool ClassListParser::parse_one_line() {
115115
_line_len = len;
116116
}
117117

118-
// Check if the line is output TRACE_RESOLVE
119-
if (strncmp(_line, LambdaFormInvokers::lambda_form_invoker_tag(),
120-
strlen(LambdaFormInvokers::lambda_form_invoker_tag())) == 0) {
121-
LambdaFormInvokers::append(os::strdup((const char*)_line, mtInternal));
122-
continue;
123-
}
124-
125118
// valid line
126119
break;
127120
}
@@ -133,6 +126,7 @@ bool ClassListParser::parse_one_line() {
133126
_source = NULL;
134127
_interfaces_specified = false;
135128
_indy_items->clear();
129+
_lambda_form_line = false;
136130

137131
if (_line[0] == '@') {
138132
return parse_at_tags();
@@ -185,8 +179,8 @@ bool ClassListParser::parse_one_line() {
185179
return true;
186180
}
187181

188-
void ClassListParser::split_tokens_by_whitespace() {
189-
int start = 0;
182+
void ClassListParser::split_tokens_by_whitespace(int offset) {
183+
int start = offset;
190184
int end;
191185
bool done = false;
192186
while (!done) {
@@ -203,19 +197,40 @@ void ClassListParser::split_tokens_by_whitespace() {
203197
}
204198
}
205199

200+
int ClassListParser::split_at_tag_from_line() {
201+
_token = _line;
202+
char* ptr;
203+
if ((ptr = strchr(_line, ' ')) == NULL) {
204+
error("Too few items following the @ tag \"%s\" line #%d", _line, _line_no);
205+
return 0;
206+
}
207+
*ptr++ = '\0';
208+
while (*ptr == ' ' || *ptr == '\t') ptr++;
209+
return (int)(ptr - _line);
210+
}
211+
206212
bool ClassListParser::parse_at_tags() {
207213
assert(_line[0] == '@', "must be");
208-
split_tokens_by_whitespace();
209-
if (strcmp(_indy_items->at(0), LAMBDA_PROXY_TAG) == 0) {
210-
if (_indy_items->length() < 3) {
211-
error("Line with @ tag has too few items \"%s\" line #%d", _line, _line_no);
214+
int offset;
215+
if ((offset = split_at_tag_from_line()) == 0) {
216+
return false;
217+
}
218+
219+
if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) {
220+
split_tokens_by_whitespace(offset);
221+
if (_indy_items->length() < 2) {
222+
error("Line with @ tag has too few items \"%s\" line #%d", _token, _line_no);
212223
return false;
213224
}
214225
// set the class name
215-
_class_name = _indy_items->at(1);
226+
_class_name = _indy_items->at(0);
227+
return true;
228+
} else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) {
229+
LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal));
230+
_lambda_form_line = true;
216231
return true;
217232
} else {
218-
error("Invalid @ tag at the beginning of line \"%s\" line #%d", _line, _line_no);
233+
error("Invalid @ tag at the beginning of line \"%s\" line #%d", _token, _line_no);
219234
return false;
220235
}
221236
}
@@ -432,7 +447,7 @@ bool ClassListParser::is_matching_cp_entry(constantPoolHandle &pool, int cp_inde
432447
CDSIndyInfo cii;
433448
populate_cds_indy_info(pool, cp_index, &cii, THREAD);
434449
GrowableArray<const char*>* items = cii.items();
435-
int indy_info_offset = 2;
450+
int indy_info_offset = 1;
436451
if (_indy_items->length() - indy_info_offset != items->length()) {
437452
return false;
438453
}

src/hotspot/share/classfile/classListParser.hpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@
3030
#include "utilities/growableArray.hpp"
3131
#include "utilities/hashtable.inline.hpp"
3232

33-
#define LAMBDA_PROXY_TAG "@lambda-proxy:"
33+
#define LAMBDA_PROXY_TAG "@lambda-proxy"
34+
#define LAMBDA_FORM_TAG "@lambda-form-invoker"
3435

3536
class ID2KlassTable : public KVHashtable<int, InstanceKlass*, mtInternal> {
3637
public:
@@ -99,6 +100,7 @@ class ClassListParser : public StackObj {
99100
GrowableArray<int>* _interfaces;
100101
bool _interfaces_specified;
101102
const char* _source;
103+
bool _lambda_form_line;
102104

103105
bool parse_int_option(const char* option_name, int* value);
104106
bool parse_uint_option(const char* option_name, int* value);
@@ -120,7 +122,8 @@ class ClassListParser : public StackObj {
120122
return _instance;
121123
}
122124
bool parse_one_line();
123-
void split_tokens_by_whitespace();
125+
void split_tokens_by_whitespace(int offset);
126+
int split_at_tag_from_line();
124127
bool parse_at_tags();
125128
char* _token;
126129
void error(const char* msg, ...);
@@ -162,6 +165,8 @@ class ClassListParser : public StackObj {
162165

163166
bool is_loading_from_source();
164167

168+
bool lambda_form_line() { return _lambda_form_line; }
169+
165170
// Look up the super or interface of the current class being loaded
166171
// (in this->load_current_class()).
167172
InstanceKlass* lookup_super_for_current_class(Symbol* super_name);

src/hotspot/share/classfile/lambdaFormInvokers.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,7 @@ void LambdaFormInvokers::regenerate_holder_classes(TRAPS) {
6666
int len = _lambdaform_lines->length();
6767
objArrayHandle list_lines = oopFactory::new_objArray_handle(SystemDictionary::String_klass(), len, CHECK);
6868
for (int i = 0; i < len; i++) {
69-
char* record = _lambdaform_lines->at(i);
70-
record += strlen(lambda_form_invoker_tag()) + 1; // skip the @lambda_form_invoker prefix
71-
Handle h_line = java_lang_String::create_from_str(record, CHECK);
69+
Handle h_line = java_lang_String::create_from_str(_lambdaform_lines->at(i), CHECK);
7270
list_lines->obj_at_put(i, h_line());
7371
}
7472

src/hotspot/share/classfile/lambdaFormInvokers.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,5 @@ class LambdaFormInvokers : public AllStatic {
4242
static GrowableArray<char*>* lambdaform_lines() {
4343
return _lambdaform_lines;
4444
}
45-
46-
static const char* lambda_form_invoker_tag() {
47-
return "@lambda-form-invoker";
48-
}
4945
};
5046
#endif // SHARE_MEMORY_LAMBDAFORMINVOKERS_HPP

src/hotspot/share/memory/metaspaceShared.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,9 @@ int MetaspaceShared::preload_classes(const char* class_list_path, TRAPS) {
10961096
int class_count = 0;
10971097

10981098
while (parser.parse_one_line()) {
1099+
if (parser.lambda_form_line()) {
1100+
continue;
1101+
}
10991102
Klass* klass = parser.load_current_class(THREAD);
11001103
if (HAS_PENDING_EXCEPTION) {
11011104
if (klass == NULL &&

src/hotspot/share/prims/jvm.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,14 @@
2525
#include "precompiled.hpp"
2626
#include "jvm.h"
2727
#include "classfile/classFileStream.hpp"
28+
#include "classfile/classListParser.hpp"
2829
#include "classfile/classListWriter.hpp"
2930
#include "classfile/classLoader.hpp"
3031
#include "classfile/classLoaderData.hpp"
3132
#include "classfile/classLoaderData.inline.hpp"
3233
#include "classfile/classLoadInfo.hpp"
3334
#include "classfile/javaAssertions.hpp"
3435
#include "classfile/javaClasses.inline.hpp"
35-
#include "classfile/lambdaFormInvokers.hpp"
3636
#include "classfile/moduleEntry.hpp"
3737
#include "classfile/modules.hpp"
3838
#include "classfile/packageEntry.hpp"
@@ -3883,7 +3883,7 @@ JVM_ENTRY(void, JVM_LogLambdaFormInvoker(JNIEnv *env, jstring line))
38833883
Handle h_line (THREAD, JNIHandles::resolve_non_null(line));
38843884
char* c_line = java_lang_String::as_utf8_string(h_line());
38853885
ClassListWriter w;
3886-
w.stream()->print_cr("%s %s", LambdaFormInvokers::lambda_form_invoker_tag(), c_line);
3886+
w.stream()->print_cr("%s %s", LAMBDA_FORM_TAG, c_line);
38873887
}
38883888
#endif // INCLUDE_CDS
38893889
JVM_END

test/hotspot/jtreg/runtime/cds/appcds/BadBSM.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public static void main(String[] args) throws Exception {
4242

4343
OutputAnalyzer out = TestCommon.dump(appJar,
4444
TestCommon.list("WrongBSM",
45-
"@lambda-proxy: WrongBSM 7"));
45+
"@lambda-proxy WrongBSM 7"));
4646
out.shouldHaveExitValue(0);
4747
out.shouldContain( "is_supported_invokedynamic check failed for cp_index 7");
4848
}

test/hotspot/jtreg/runtime/cds/appcds/DumpClassListWithLF.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,5 +105,12 @@ appJar, classlist(
105105
"Hello",
106106
"@lambda-form-invoker [SPECIES_RESOLVE] java.lang.invoke.BoundMethodHandle$Species_L L"),
107107
"Incorrect number of items in the line: 3");
108+
// 10. The line with incorrect (less) number of items.
109+
dumpShouldFail(
110+
"TESTCASE 10: With incorrect @lambda-form-invoker tag",
111+
appJar, classlist(
112+
"Hello",
113+
"@lambda-form-invoker-xxx [LF_RESOLVE] java.lang.invoke.DirectMethodHandle$Holder invokeStatic"),
114+
"Invalid @ tag at the beginning of line \"@lambda-form-invoker-xxx\" line #2");
108115
}
109116
}

test/hotspot/jtreg/runtime/cds/appcds/LambdaProxyClasslist.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,35 +43,42 @@ public static void main(String[] args) throws Exception {
4343
// 1. No error with a correct @lambda-proxy entry.
4444
OutputAnalyzer out = TestCommon.dump(appJar,
4545
TestCommon.list("LambHello",
46-
"@lambda-proxy: LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V"));
46+
"@lambda-proxy LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V"));
4747
out.shouldHaveExitValue(0);
4848

4949
// 2. Error if the @lambda-proxy entry is too short.
5050
out = TestCommon.dump(appJar,
5151
TestCommon.list("LambHello",
52-
"@lambda-proxy: LambHello"));
52+
"@lambda-proxy LambHello"));
5353
out.shouldContain("An error has occurred while processing class list file")
54-
.shouldContain("Line with @ tag has too few items \"@lambda-proxy:\" line #2")
54+
.shouldContain("Line with @ tag has too few items \"@lambda-proxy\" line #2")
5555
.shouldContain("class list format error")
5656
.shouldHaveExitValue(1);
5757

5858
// 3. Warning message if there's an incorrect signature in the @lambda-proxy entry.
5959
out = TestCommon.dump(appJar,
6060
TestCommon.list("LambHello",
61-
"@lambda-proxy: LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()Z"));
61+
"@lambda-proxy LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()Z"));
6262
out.shouldContain("[warning][cds] No invoke dynamic constant pool entry can be found for class LambHello. The classlist is probably out-of-date.")
6363
.shouldHaveExitValue(0);
6464

6565
// 4. More blank spaces in between items should be fine.
6666
out = TestCommon.dump(appJar,
6767
TestCommon.list("LambHello",
68-
"@lambda-proxy: LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V"));
68+
"@lambda-proxy LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V"));
6969
out.shouldHaveExitValue(0);
7070

7171
// 5. Trailing spaces at the end of the @lambda-proxy line should be fine.
7272
out = TestCommon.dump(appJar,
7373
TestCommon.list("LambHello",
74-
"@lambda-proxy: LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V "));
74+
"@lambda-proxy LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V "));
7575
out.shouldHaveExitValue(0);
76+
77+
// 6. Error on invalid @lambda-proxy tag
78+
out = TestCommon.dump(appJar,
79+
TestCommon.list("LambHello",
80+
"@lambda-proxy: LambHello run ()Ljava/lang/Runnable; ()V REF_invokeStatic LambHello lambda$doTest$0 ()V ()V"));
81+
out.shouldContain("Invalid @ tag at the beginning of line \"@lambda-proxy:\" line #2")
82+
.shouldHaveExitValue(1);
7683
}
7784
}

0 commit comments

Comments
 (0)