Skip to content

Commit

Permalink
[GR-51106] Represent field offsets as a FieldOffsetNode during static…
Browse files Browse the repository at this point in the history
… analysis.

PullRequest: graal/16477
  • Loading branch information
Christian Wimmer committed Jan 21, 2024
2 parents d91a572 + 97c7336 commit d9b8d30
Show file tree
Hide file tree
Showing 25 changed files with 613 additions and 657 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2024, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package jdk.graal.compiler.nodes.extended;

import jdk.graal.compiler.nodes.ConstantNode;
import jdk.graal.compiler.nodes.ValueNodeInterface;
import jdk.vm.ci.meta.ResolvedJavaField;

/**
* Interface that can be implemented by nodes that compute the offset of a field, but cannot expose
* the offset as a {@link ConstantNode} yet. The provided field can be used by the compiler to
* convert low-level memory access nodes to high-level field access nodes.
*/
public interface FieldOffsetProvider extends ValueNodeInterface {

/** The field whose offset this node is computing. */
ResolvedJavaField getField();
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

import java.nio.ByteOrder;

import org.graalvm.word.LocationIdentity;

import jdk.graal.compiler.core.common.memory.MemoryOrderMode;
import jdk.graal.compiler.core.common.type.Stamp;
import jdk.graal.compiler.graph.Node;
Expand All @@ -43,8 +45,6 @@
import jdk.graal.compiler.nodes.spi.Canonicalizable;
import jdk.graal.compiler.nodes.spi.CanonicalizerTool;
import jdk.graal.compiler.nodes.type.StampTool;
import org.graalvm.word.LocationIdentity;

import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
Expand Down Expand Up @@ -112,29 +112,31 @@ public MemoryOrderMode getMemoryOrder() {
@Override
public Node canonical(CanonicalizerTool tool) {
if (isCanonicalizable()) {
if (offset().isConstant()) {
long constantOffset = offset().asJavaConstant().asLong();

// Try to canonicalize to a field access.
ResolvedJavaType receiverType = StampTool.typeOrNull(object());
if (receiverType != null) {
ResolvedJavaField field = getStaticFieldUnsafeAccess(tool.getConstantReflection());
// Try to canonicalize to a field access.
ResolvedJavaType receiverType = StampTool.typeOrNull(object(), tool.getMetaAccess());
if (receiverType != null) {
ResolvedJavaField field = null;
if (offset().isConstant()) {
field = getStaticFieldUnsafeAccess(tool.getConstantReflection());
if (field == null) {
long constantOffset = offset().asJavaConstant().asLong();
field = receiverType.findInstanceFieldWithOffset(constantOffset, accessKind());
}
} else if (offset() instanceof FieldOffsetProvider fieldOffsetProvider) {
field = fieldOffsetProvider.getField();
}

// No need for checking that the receiver is non-null. The field access
// includes the null check and if a field is found, the offset is so small that
// this is never a valid access of an arbitrary address.
if ((field != null && field.getJavaKind() == this.accessKind() &&
!field.isInternal() /* Ensure this is a true java field. */)) {
return cloneAsFieldAccess(field);
}
// No need for checking that the receiver is non-null. The field access
// includes the null check and if a field is found, the offset is so small that
// this is never a valid access of an arbitrary address.
if ((field != null && field.getJavaKind() == this.accessKind() &&
!field.isInternal() /* Ensure this is a true java field. */)) {
return cloneAsFieldAccess(field);
}
}

if (getLocationIdentity().isAny()) {
// If we have a vague one, try to build a better location identity.
ResolvedJavaType receiverType = StampTool.typeOrNull(object());
if (receiverType != null && receiverType.isArray()) {
/*
* This code might assign a wrong location identity in case the offset is
Expand Down
3 changes: 3 additions & 0 deletions substratevm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

This changelog summarizes major changes to GraalVM Native Image.

## GraalVM for JDK 23 (Internal Version 24.1.0)
* (GR-51106) Fields that are accessed via a `VarHandle` or `MethodHandle` are no longer marked as "unsafe accessed" when the `VarHandle`/`MethodHandle` can be fully intrinsified.

## GraalVM for JDK 22 (Internal Version 24.0.0)
* (GR-48304) Red Hat added support for the JFR event ThreadAllocationStatistics.
* (GR-48343) Red Hat added support for the JFR events AllocationRequiringGC and SystemGC.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ public AnalysisType lookup(JavaType type) {
}

public AnalysisType getObjectType() {
return metaAccess.lookupJavaType(Object.class);
return universe.objectType();
}

public AnalysisType getObjectArrayType() {
Expand Down
Loading

0 comments on commit d9b8d30

Please sign in to comment.