On Fri, 13 Nov 2020 19:23:54 GMT, Jorn Vernee <jver...@openjdk.org> wrote:
>>> Also (as mentioned offline), while it's possible with the current API to >>> provide an `Object[]` as class data, and then load elements of that array >>> into CP entries using downstream condys (e.g. by creating an array access >>> var handle and then using that), I think it would be good to add a >>> `getArrayElement` BSM for doing that to `ConstantBootstraps` to make this >>> (seemingly) common case easier (maybe also a `getField` for loading >>> instance fields). This would help to address the case where multiple live >>> constants need to be injected. >> >> I am uncomfortable with adding `ConstantBootstraps::getArrayElement` because >> an array is modifiable and _not_ true constant. A final instance field can >> be modified via reflection and therefore it's not trusted as a constant >> either. > >> > Also (as mentioned offline), while it's possible with the current API to >> > provide an `Object[]` as class data, and then load elements of that array >> > into CP entries using downstream condys (e.g. by creating an array access >> > var handle and then using that), I think it would be good to add a >> > `getArrayElement` BSM for doing that to `ConstantBootstraps` to make this >> > (seemingly) common case easier (maybe also a `getField` for loading >> > instance fields). This would help to address the case where multiple live >> > constants need to be injected. >> >> I am uncomfortable with adding `ConstantBootstraps::getArrayElement` because >> an array is modifiable and _not_ true constant. A final instance field can >> be modified via reflection and therefore it's not trusted as a constant >> either. > > I guess it would be similar to doing something like: > > private static final Object[] arr = getArray(); > private static final Object o = arr[0]; > > Setting `arr[0] = new Object();` would not affect `o` after it has been > initialized. The difference being that a constant for the array element would > be resolved (more) lazily, so it would be possible to resolve the array, then > modify it, and then resolve the constant that loads the element, which would > see the updated value as well. > > However, we can already store an array in the constant pool today, and modify > it if we want, even though, as you say, it is mutable. In that sense > getArrayElement doesn't introduce anything new. > > Mutating the array is probably a bad idea though, so maybe we want to push > users away from using arrays? To prevent inadvertent modification, maybe an > immutable `List` should be used in place of a plain array. In that case, > would you feel differently about added a `getListElement` BSM, that gets an > element from an (immutable) List instead? > > Another idea is to rely on records, since they can not be mutated with > reflection at all. i.e. we add a getRecordComponent BSM instead, so a class > data Object can be a record, and then the BSM can be used to extract > individual components. > > WDYT? Sorry, this is unrelated to this RFR, I will start a separate discussion thread elsewhere. ------------- PR: https://git.openjdk.java.net/jdk/pull/1171