From ecc4be2d25d043b0436eb841746d84a1fccbcc20 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 19 May 2020 13:27:26 +0300 Subject: [PATCH] Fix class initialization optimization --- .../analysis/ClassInitializerAnalysis.java | 2 +- .../classlib/java/util/LoadOrderService.java | 20 +++++++++ .../java/util/LoadOrderServiceImpl.java | 45 +++++++++++++++++++ .../java/util/LoadOrderServiceLog.java | 23 ++++++++++ .../classlib/java/util/ServiceLoaderTest.java | 9 ++++ ....teavm.classlib.java.util.LoadOrderService | 17 +++++++ 6 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 tests/src/test/java/org/teavm/classlib/java/util/LoadOrderService.java create mode 100644 tests/src/test/java/org/teavm/classlib/java/util/LoadOrderServiceImpl.java create mode 100644 tests/src/test/java/org/teavm/classlib/java/util/LoadOrderServiceLog.java create mode 100644 tests/src/test/resources/META-INF/services/org.teavm.classlib.java.util.LoadOrderService diff --git a/core/src/main/java/org/teavm/model/analysis/ClassInitializerAnalysis.java b/core/src/main/java/org/teavm/model/analysis/ClassInitializerAnalysis.java index b4d59a89d..a036d44b2 100644 --- a/core/src/main/java/org/teavm/model/analysis/ClassInitializerAnalysis.java +++ b/core/src/main/java/org/teavm/model/analysis/ClassInitializerAnalysis.java @@ -301,7 +301,7 @@ public class ClassInitializerAnalysis implements ClassInitializerInfo { methodInfo.classesWithModifiedFields = null; } else if (calledMethod.classesWithModifiedFields != null) { for (String className : calledMethod.classesWithModifiedFields) { - if (className.equals(currentClass)) { + if (!className.equals(currentClass)) { if (methodInfo.classesWithModifiedFields == null) { methodInfo.classesWithModifiedFields = new HashSet<>(); } diff --git a/tests/src/test/java/org/teavm/classlib/java/util/LoadOrderService.java b/tests/src/test/java/org/teavm/classlib/java/util/LoadOrderService.java new file mode 100644 index 000000000..da4cb7228 --- /dev/null +++ b/tests/src/test/java/org/teavm/classlib/java/util/LoadOrderService.java @@ -0,0 +1,20 @@ +/* + * Copyright 2020 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.classlib.java.util; + +public interface LoadOrderService { + void run(); +} diff --git a/tests/src/test/java/org/teavm/classlib/java/util/LoadOrderServiceImpl.java b/tests/src/test/java/org/teavm/classlib/java/util/LoadOrderServiceImpl.java new file mode 100644 index 000000000..1edc325ab --- /dev/null +++ b/tests/src/test/java/org/teavm/classlib/java/util/LoadOrderServiceImpl.java @@ -0,0 +1,45 @@ +/* + * Copyright 2020 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.classlib.java.util; + +public class LoadOrderServiceImpl implements LoadOrderService { + static { + Log.create(); + } + + public LoadOrderServiceImpl() { + Log.run(); + } + + @Override + public void run() { + LoadOrderServiceLog.content.append("service run;"); + } + + static class Log { + static { + LoadOrderServiceLog.content.append("class init;"); + } + + static void create() { + LoadOrderServiceLog.content.append("log create;"); + } + + static void run() { + LoadOrderServiceLog.content.append("log run;"); + } + } +} diff --git a/tests/src/test/java/org/teavm/classlib/java/util/LoadOrderServiceLog.java b/tests/src/test/java/org/teavm/classlib/java/util/LoadOrderServiceLog.java new file mode 100644 index 000000000..7ff04bbda --- /dev/null +++ b/tests/src/test/java/org/teavm/classlib/java/util/LoadOrderServiceLog.java @@ -0,0 +1,23 @@ +/* + * Copyright 2020 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.classlib.java.util; + +class LoadOrderServiceLog { + private LoadOrderServiceLog() { + } + + static final StringBuilder content = new StringBuilder(); +} diff --git a/tests/src/test/java/org/teavm/classlib/java/util/ServiceLoaderTest.java b/tests/src/test/java/org/teavm/classlib/java/util/ServiceLoaderTest.java index ecb3d067b..db04e0fe2 100644 --- a/tests/src/test/java/org/teavm/classlib/java/util/ServiceLoaderTest.java +++ b/tests/src/test/java/org/teavm/classlib/java/util/ServiceLoaderTest.java @@ -43,4 +43,13 @@ public class ServiceLoaderTest { strings.sort(String::compareTo); assertEquals(Arrays.asList("A", "B"), strings); } + + @Test + public void classLoading() { + LoadOrderServiceLog.content.append("before;"); + for (LoadOrderService service : ServiceLoader.load(LoadOrderService.class)) { + service.run(); + } + assertEquals("before;class init;log create;log run;service run;", LoadOrderServiceLog.content.toString()); + } } diff --git a/tests/src/test/resources/META-INF/services/org.teavm.classlib.java.util.LoadOrderService b/tests/src/test/resources/META-INF/services/org.teavm.classlib.java.util.LoadOrderService new file mode 100644 index 000000000..d2469c336 --- /dev/null +++ b/tests/src/test/resources/META-INF/services/org.teavm.classlib.java.util.LoadOrderService @@ -0,0 +1,17 @@ +# +# Copyright 2017 Alexey Andreev. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +org.teavm.classlib.java.util.LoadOrderServiceImpl \ No newline at end of file