Skip to content

[DRAFT] [lworld] Test scalarization and call conventions for different value class shapes #1522

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: lworld
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c7eca00
8344942: Template-Based Testing Framework
eme64 Jun 4, 2025
2e25844
8358600: Template-Framework Library: Template for TestFramework test …
eme64 Jun 12, 2025
469fc37
8358772: Template-Framework Library: Primitive Types
eme64 Jun 13, 2025
68e4a60
8352869: Verify.checkEQ: extension for NaN, VectorAPI and arbitrary O…
eme64 May 6, 2025
f3fb29d
Basic type parameterized template value class test
galderz Jul 30, 2025
a4597e6
Separate IRNode definitions from test template
galderz Jul 31, 2025
a24c686
Test with all primitive types
galderz Jul 31, 2025
e3ee7ad
Change structure to make it easier to add multiple types
galderz Aug 4, 2025
edce035
Product a type with multiple fields
galderz Aug 4, 2025
b144b05
Add a hash method computed from the fields of the type
galderz Aug 5, 2025
102cd6e
Take advantage of $ substitution to avoid tracking ids
galderz Aug 5, 2025
7d104a3
Basic test with multiple fields of boolean
galderz Aug 5, 2025
ce1352b
Avoid using FieldConstant on uni field test
galderz Aug 6, 2025
8f45b11
Test value class within value class failing but reason unknown
galderz Aug 6, 2025
80cf340
Comment failing IR test combination
galderz Aug 6, 2025
897827c
Merge branch 'valhalla.lworld' into topic.template-101
galderz Aug 12, 2025
153d5b8
Add a multi type that works just about
galderz Aug 13, 2025
d8b4ffa
Remove hardcoded MyTimeInstant references
galderz Aug 13, 2025
dd069ec
Discovered bug in int[] box
galderz Aug 14, 2025
f7dc66a
Added ForceInline to make sure constructor gets inlined
galderz Aug 15, 2025
8adfff6
Comment print inlining flag usage
galderz Aug 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2025, 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.
*
* 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 compiler.lib.template_framework;

record AddNameToken(Name name) implements Token {}
51 changes: 51 additions & 0 deletions test/hotspot/jtreg/compiler/lib/template_framework/Code.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright (c) 2025, 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.
*
* 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 compiler.lib.template_framework;

import java.util.List;

/**
* This class collects code, i.e. {@link String}s or {@link List}s of {@link String}s.
* All the {@link String}s are later collected in a {@link StringBuilder}. If we used a {@link StringBuilder}
* directly to collect the {@link String}s, we could not as easily insert code at an "earlier" position, i.e.
* reaching out to a {@link Hook#anchor}.
*/
sealed interface Code permits Code.Token, Code.CodeList {

record Token(String s) implements Code {
@Override
public void renderTo(StringBuilder builder) {
builder.append(s);
}
}

record CodeList(List<Code> list) implements Code {
@Override
public void renderTo(StringBuilder builder) {
list.forEach(code -> code.renderTo(builder));
}
}

void renderTo(StringBuilder builder);
}
156 changes: 156 additions & 0 deletions test/hotspot/jtreg/compiler/lib/template_framework/CodeFrame.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* Copyright (c) 2025, 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.
*
* 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 compiler.lib.template_framework;

import java.util.HashMap;
import java.util.Map;
import java.util.ArrayList;
import java.util.List;

/**
* The {@link CodeFrame} represents a frame (i.e. scope) of code, appending {@link Code} to the {@code 'codeList'}
* as {@link Token}s are rendered, and adding names to the {@link NameSet}s with {@link Template#addStructuralName}/
* {@link Template#addDataName}. {@link Hook}s can be added to a frame, which allows code to be inserted at that
* location later. When a {@link Hook} is {@link Hook#anchor}ed, it separates the Template into an outer and inner
* {@link CodeFrame}, ensuring that names that are added inside the inner frame are only available inside that frame.
*
* <p>
* On the other hand, each {@link TemplateFrame} represents the frame (or scope) of exactly one use of a
* Template.
*
* <p>
* For simple Template nesting, the {@link CodeFrame}s and {@link TemplateFrame}s overlap exactly.
* However, when using {@link Hook#insert}, we simply nest {@link TemplateFrame}s, going further "in",
* but we jump to an outer {@link CodeFrame}, ensuring that we insert {@link Code} at the outer frame,
* and operating on the names of the outer frame. Once the {@link Hook#insert}ion is complete, we jump
* back to the caller {@link TemplateFrame} and {@link CodeFrame}.
*/
class CodeFrame {
public final CodeFrame parent;
private final List<Code> codeList = new ArrayList<>();
private final Map<Hook, Code.CodeList> hookCodeLists = new HashMap<>();

/**
* The {@link NameSet} is used for variable and fields etc.
*/
private final NameSet names;

private CodeFrame(CodeFrame parent, boolean isTransparentForNames) {
this.parent = parent;
if (parent == null) {
// NameSet without any parent.
this.names = new NameSet(null);
} else if (isTransparentForNames) {
// We use the same NameSet as the parent - makes it transparent.
this.names = parent.names;
} else {
// New NameSet, to make sure we have a nested scope for the names.
this.names = new NameSet(parent.names);
}
}

/**
* Creates a base frame, which has no {@link #parent}.
*/
public static CodeFrame makeBase() {
return new CodeFrame(null, false);
}

/**
* Creates a normal frame, which has a {@link #parent} and which defines an inner
* {@link NameSet}, for the names that are generated inside this frame. Once this
* frame is exited, the name from inside this frame are not available anymore.
*/
public static CodeFrame make(CodeFrame parent) {
return new CodeFrame(parent, false);
}

/**
* Creates a special frame, which has a {@link #parent} but uses the {@link NameSet}
* from the parent frame, allowing {@link Template#addDataName}/
* {@link Template#addStructuralName} to persist in the outer frame when the current frame
* is exited. This is necessary for {@link Hook#insert}, where we would possibly want to
* make field or variable definitions during the insertion that are not just local to the
* insertion but affect the {@link CodeFrame} that we {@link Hook#anchor} earlier and are
* now {@link Hook#insert}ing into.
*/
public static CodeFrame makeTransparentForNames(CodeFrame parent) {
return new CodeFrame(parent, true);
}

void addString(String s) {
codeList.add(new Code.Token(s));
}

void addCode(Code code) {
codeList.add(code);
}

void addHook(Hook hook) {
if (hasHook(hook)) {
// This should never happen, as we add a dedicated CodeFrame for each hook.
throw new RuntimeException("Internal error: Duplicate Hook in CodeFrame: " + hook.name());
}
hookCodeLists.put(hook, new Code.CodeList(new ArrayList<>()));
}

private boolean hasHook(Hook hook) {
return hookCodeLists.containsKey(hook);
}

CodeFrame codeFrameForHook(Hook hook) {
CodeFrame current = this;
while (current != null) {
if (current.hasHook(hook)) {
return current;
}
current = current.parent;
}
return null;
}

void addName(Name name) {
names.add(name);
}

Name sampleName(NameSet.Predicate predicate) {
return names.sample(predicate);
}

int countNames(NameSet.Predicate predicate) {
return names.count(predicate);
}

boolean hasAnyNames(NameSet.Predicate predicate) {
return names.hasAny(predicate);
}

List<Name> listNames(NameSet.Predicate predicate) {
return names.toList(predicate);
}

Code getCode() {
return new Code.CodeList(codeList);
}
}
Loading