mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8335922: Incorrect @Stable usage of LambdaForm$Name.index
Reviewed-by: jvernee, shade
This commit is contained in:
parent
96e4a1876a
commit
aabec4a947
1 changed files with 23 additions and 47 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -395,7 +395,7 @@ class LambdaForm {
|
||||||
Name[] names = arguments(isVoid ? 0 : 1, mt);
|
Name[] names = arguments(isVoid ? 0 : 1, mt);
|
||||||
if (!isVoid) {
|
if (!isVoid) {
|
||||||
Name zero = new Name(constantZero(basicType(mt.returnType())));
|
Name zero = new Name(constantZero(basicType(mt.returnType())));
|
||||||
names[arity] = zero.newIndex(arity);
|
names[arity] = zero.withIndex(arity);
|
||||||
}
|
}
|
||||||
assert(namesOK(arity, names));
|
assert(namesOK(arity, names));
|
||||||
return names;
|
return names;
|
||||||
|
@ -495,28 +495,18 @@ class LambdaForm {
|
||||||
* @return true if we can interpret
|
* @return true if we can interpret
|
||||||
*/
|
*/
|
||||||
private static boolean normalizeNames(int arity, Name[] names) {
|
private static boolean normalizeNames(int arity, Name[] names) {
|
||||||
Name[] oldNames = null;
|
Name[] oldNames = names.clone();
|
||||||
int maxOutArity = 0;
|
int maxOutArity = 0;
|
||||||
int changesStart = 0;
|
|
||||||
for (int i = 0; i < names.length; i++) {
|
for (int i = 0; i < names.length; i++) {
|
||||||
Name n = names[i];
|
Name n = names[i];
|
||||||
if (!n.initIndex(i)) {
|
names[i] = n.withIndex(i);
|
||||||
if (oldNames == null) {
|
|
||||||
oldNames = names.clone();
|
|
||||||
changesStart = i;
|
|
||||||
}
|
|
||||||
names[i] = n.cloneWithIndex(i);
|
|
||||||
}
|
|
||||||
if (n.arguments != null && maxOutArity < n.arguments.length)
|
if (n.arguments != null && maxOutArity < n.arguments.length)
|
||||||
maxOutArity = n.arguments.length;
|
maxOutArity = n.arguments.length;
|
||||||
}
|
}
|
||||||
if (oldNames != null) {
|
if (oldNames != null) {
|
||||||
int startFixing = arity;
|
for (int i = Math.max(1, arity); i < names.length; i++) {
|
||||||
if (startFixing <= changesStart)
|
Name fixed = names[i].replaceNames(oldNames, names, 0, i);
|
||||||
startFixing = changesStart+1;
|
names[i] = fixed.withIndex(i);
|
||||||
for (int i = startFixing; i < names.length; i++) {
|
|
||||||
Name fixed = names[i].replaceNames(oldNames, names, changesStart, i);
|
|
||||||
names[i] = fixed.newIndex(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int maxInterned = Math.min(arity, INTERNED_ARGUMENT_LIMIT);
|
int maxInterned = Math.min(arity, INTERNED_ARGUMENT_LIMIT);
|
||||||
|
@ -1339,30 +1329,24 @@ class LambdaForm {
|
||||||
|
|
||||||
static final class Name {
|
static final class Name {
|
||||||
final BasicType type;
|
final BasicType type;
|
||||||
@Stable short index;
|
final short index;
|
||||||
final NamedFunction function;
|
final NamedFunction function;
|
||||||
final Object constraint; // additional type information, if not null
|
final Object constraint; // additional type information, if not null
|
||||||
@Stable final Object[] arguments;
|
@Stable final Object[] arguments;
|
||||||
|
|
||||||
private static final Object[] EMPTY_ARGS = new Object[0];
|
private static final Object[] EMPTY_ARGS = new Object[0];
|
||||||
|
|
||||||
private Name(int index, BasicType type, NamedFunction function, Object[] arguments) {
|
private Name(int index, BasicType type, NamedFunction function, Object[] arguments, Object constraint) {
|
||||||
this.index = (short)index;
|
this.index = (short)index;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.function = function;
|
this.function = function;
|
||||||
this.arguments = arguments;
|
this.arguments = arguments;
|
||||||
this.constraint = null;
|
|
||||||
assert(this.index == index && typesMatch(function, this.arguments));
|
|
||||||
}
|
|
||||||
private Name(Name that, Object constraint) {
|
|
||||||
this.index = that.index;
|
|
||||||
this.type = that.type;
|
|
||||||
this.function = that.function;
|
|
||||||
this.arguments = that.arguments;
|
|
||||||
this.constraint = constraint;
|
this.constraint = constraint;
|
||||||
|
assert(this.index == index && typesMatch(function, arguments));
|
||||||
assert(constraint == null || isParam()); // only params have constraints
|
assert(constraint == null || isParam()); // only params have constraints
|
||||||
assert(constraint == null || constraint instanceof ClassSpecializer.SpeciesData || constraint instanceof Class);
|
assert(constraint == null || constraint instanceof ClassSpecializer.SpeciesData || constraint instanceof Class);
|
||||||
}
|
}
|
||||||
|
|
||||||
Name(MethodHandle function, Object... arguments) {
|
Name(MethodHandle function, Object... arguments) {
|
||||||
this(new NamedFunction(function), arguments);
|
this(new NamedFunction(function), arguments);
|
||||||
}
|
}
|
||||||
|
@ -1374,49 +1358,41 @@ class LambdaForm {
|
||||||
this(new NamedFunction(function), arguments);
|
this(new NamedFunction(function), arguments);
|
||||||
}
|
}
|
||||||
Name(NamedFunction function) {
|
Name(NamedFunction function) {
|
||||||
this(-1, function.returnType(), function, EMPTY_ARGS);
|
this(-1, function.returnType(), function, EMPTY_ARGS, null);
|
||||||
}
|
}
|
||||||
Name(NamedFunction function, Object arg) {
|
Name(NamedFunction function, Object arg) {
|
||||||
this(-1, function.returnType(), function, new Object[] { arg });
|
this(-1, function.returnType(), function, new Object[] { arg }, null);
|
||||||
}
|
}
|
||||||
Name(NamedFunction function, Object arg0, Object arg1) {
|
Name(NamedFunction function, Object arg0, Object arg1) {
|
||||||
this(-1, function.returnType(), function, new Object[] { arg0, arg1 });
|
this(-1, function.returnType(), function, new Object[] { arg0, arg1 }, null);
|
||||||
}
|
}
|
||||||
Name(NamedFunction function, Object... arguments) {
|
Name(NamedFunction function, Object... arguments) {
|
||||||
this(-1, function.returnType(), function, Arrays.copyOf(arguments, arguments.length, Object[].class));
|
this(-1, function.returnType(), function, Arrays.copyOf(arguments, arguments.length, Object[].class), null);
|
||||||
}
|
}
|
||||||
/** Create a raw parameter of the given type, with an expected index. */
|
/** Create a raw parameter of the given type, with an expected index. */
|
||||||
Name(int index, BasicType type) {
|
Name(int index, BasicType type) {
|
||||||
this(index, type, null, null);
|
this(index, type, null, null, null);
|
||||||
}
|
}
|
||||||
/** Create a raw parameter of the given type. */
|
/** Create a raw parameter of the given type. */
|
||||||
Name(BasicType type) { this(-1, type); }
|
Name(BasicType type) { this(-1, type); }
|
||||||
|
|
||||||
BasicType type() { return type; }
|
BasicType type() { return type; }
|
||||||
int index() { return index; }
|
int index() { return index; }
|
||||||
boolean initIndex(int i) {
|
|
||||||
if (index != i) {
|
|
||||||
if (index != -1) return false;
|
|
||||||
index = (short)i;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
char typeChar() {
|
char typeChar() {
|
||||||
return type.btChar;
|
return type.btChar;
|
||||||
}
|
}
|
||||||
|
|
||||||
Name newIndex(int i) {
|
Name withIndex(int i) {
|
||||||
if (initIndex(i)) return this;
|
if (i == this.index) return this;
|
||||||
return cloneWithIndex(i);
|
return new Name(i, type, function, arguments, constraint);
|
||||||
}
|
|
||||||
Name cloneWithIndex(int i) {
|
|
||||||
Object[] newArguments = (arguments == null) ? null : arguments.clone();
|
|
||||||
return new Name(i, type, function, newArguments).withConstraint(constraint);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Name withConstraint(Object constraint) {
|
Name withConstraint(Object constraint) {
|
||||||
if (constraint == this.constraint) return this;
|
if (constraint == this.constraint) return this;
|
||||||
return new Name(this, constraint);
|
return new Name(index, type, function, arguments, constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
Name replaceName(Name oldName, Name newName) { // FIXME: use replaceNames uniformly
|
Name replaceName(Name oldName, Name newName) { // FIXME: use replaceNames uniformly
|
||||||
if (oldName == newName) return this;
|
if (oldName == newName) return this;
|
||||||
@SuppressWarnings("LocalVariableHidesMemberVariable")
|
@SuppressWarnings("LocalVariableHidesMemberVariable")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue