Skip to content

Commit

Permalink
Introduce UnsafeAccessedFieldBuildItem
Browse files Browse the repository at this point in the history
  • Loading branch information
gwenneg committed Nov 14, 2019
1 parent 8be0f98 commit 3a0599d
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.quarkus.deployment.builditem.nativeimage;

import io.quarkus.builder.item.MultiBuildItem;

public final class UnsafeAccessedFieldBuildItem extends MultiBuildItem {

final String declaringClass;
final String fieldName;

public UnsafeAccessedFieldBuildItem(String declaringClass, String fieldName) {
this.declaringClass = declaringClass;
this.fieldName = fieldName;
}

public String getDeclaringClass() {
return declaringClass;
}

public String getFieldName() {
return fieldName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
import io.quarkus.deployment.builditem.nativeimage.UnsafeAccessedFieldBuildItem;
import io.quarkus.gizmo.CatchBlockCreator;
import io.quarkus.gizmo.ClassCreator;
import io.quarkus.gizmo.ClassOutput;
Expand Down Expand Up @@ -65,7 +66,8 @@ void generateFeature(BuildProducer<GeneratedNativeImageClassBuildItem> nativeIma
List<ReflectiveMethodBuildItem> reflectiveMethods,
List<ReflectiveFieldBuildItem> reflectiveFields,
List<ReflectiveClassBuildItem> reflectiveClassBuildItems,
List<ServiceProviderBuildItem> serviceProviderBuildItems) {
List<ServiceProviderBuildItem> serviceProviderBuildItems,
List<UnsafeAccessedFieldBuildItem> unsafeAccessedFields) {
ClassCreator file = new ClassCreator(new ClassOutput() {
@Override
public void write(String s, byte[] bytes) {
Expand All @@ -80,6 +82,22 @@ public void write(String s, byte[] bytes) {
TryBlock overallCatch = beforeAn.tryBlock();
//TODO: at some point we are going to need to break this up, as if it get too big it will hit the method size limit

ResultHandle beforeAnalysisParam = beforeAn.getMethodParam(0);
for (UnsafeAccessedFieldBuildItem unsafeAccessedField : unsafeAccessedFields) {
TryBlock tc = overallCatch.tryBlock();
ResultHandle declaringClassHandle = tc.invokeStaticMethod(
ofMethod(Class.class, "forName", Class.class, String.class),
tc.load(unsafeAccessedField.getDeclaringClass()));
ResultHandle fieldHandle = tc.invokeVirtualMethod(
ofMethod(Class.class, "getDeclaredField", Field.class, String.class), declaringClassHandle,
tc.load(unsafeAccessedField.getFieldName()));
tc.invokeInterfaceMethod(
ofMethod(Feature.BeforeAnalysisAccess.class, "registerAsUnsafeAccessed", void.class, Field.class),
beforeAnalysisParam, fieldHandle);
CatchBlockCreator cc = tc.addCatch(Throwable.class);
cc.invokeVirtualMethod(ofMethod(Throwable.class, "printStackTrace", void.class), cc.getCaughtException());
}

ResultHandle initSingleton = overallCatch.invokeStaticMethod(IMAGE_SINGLETONS_LOOKUP,
overallCatch.loadClass(RuntimeClassInitializationSupport.class));
ResultHandle quarkus = overallCatch.load("Quarkus");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.netty.deployment;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

Expand All @@ -21,6 +23,7 @@
import io.quarkus.deployment.builditem.nativeimage.NativeImageSystemPropertyBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.UnsafeAccessedFieldBuildItem;
import io.quarkus.netty.BossEventLoopGroup;
import io.quarkus.netty.MainEventLoopGroup;
import io.quarkus.netty.runtime.NettyRecorder;
Expand Down Expand Up @@ -177,4 +180,12 @@ public RuntimeReinitializedClassBuildItem reinitScheduledFutureTask() {
return new RuntimeReinitializedClassBuildItem(
"io.quarkus.netty.runtime.graal.Holder_io_netty_util_concurrent_ScheduledFutureTask");
}

// TODO: Remove this when netty.version is 4.1.43.Final or greater.
@BuildStep
public List<UnsafeAccessedFieldBuildItem> unsafeAccessedFields() {
return Arrays.asList(
new UnsafeAccessedFieldBuildItem("sun.nio.ch.SelectorImpl", "selectedKeys"),
new UnsafeAccessedFieldBuildItem("sun.nio.ch.SelectorImpl", "publicSelectedKeys"));
}
}

0 comments on commit 3a0599d

Please sign in to comment.