Re: RFR: 8269384: Determine native byte order for StringUTF16 via ByteOrder

2021-06-28 Thread Yi Yang
On Fri, 25 Jun 2021 13:40:54 GMT, Yi Yang  wrote:

> Prefer using ByteOrder to compute byte order for StringUTF16 to determining 
> byte order by native method StringUTF16.isBigEndian.

Thanks for the detailed clarification!

The purpose of this PR is to skip the native call and use ByteOrder. Now I'm 
convinced that we should not change the initialization order casually, this 
will break some "future code" and make UnsafeConstants unable to use String.

-

PR: https://git.openjdk.java.net/jdk/pull/4596


Re: RFR: 8269384: Determine native byte order for StringUTF16 via ByteOrder

2021-06-28 Thread David Holmes
On Mon, 28 Jun 2021 03:25:09 GMT, Yi Yang  wrote:

>> Prefer using ByteOrder to compute byte order for StringUTF16 to determining 
>> byte order by native method StringUTF16.isBigEndian.
>
> Hi Aleksey, do you have a concrete issue/discussion about bootstrapping 
> problems? I don't see it because I can build JDK and passes tier1 tests w/o 
> problems. But I admit this may cause potential problems. In order to reduce 
> potential risks, how about changing the class initialization orders, i.e. 
> initialize UUnsafeConstants_klas earlier, which seems reasonable:
> 
> 
> void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
>   TraceTime timer("Initialize java.lang classes", TRACETIME_LOG(Info, 
> startuptime));
> 
>   if (EagerXrunInit && Arguments::init_libraries_at_startup()) {
> create_vm_init_libraries();
>   }
> 
> +#ifdef ASSERT
> +  InstanceKlass *k = vmClasses::UnsafeConstants_klass();
> +  assert(k->is_not_initialized(), "UnsafeConstants should not already be 
> initialized");
> +#endif
> +
> +  // initialize the hardware-specific constants needed by Unsafe
> +  initialize_class(vmSymbols::jdk_internal_misc_UnsafeConstants(), CHECK);
> +  jdk_internal_misc_UnsafeConstants::set_unsafe_constants();
> 
>   initialize_class(vmSymbols::java_lang_String(), CHECK);
> 
>   // Inject CompactStrings value after the static initializers for String ran.
>   java_lang_String::set_compact_strings(CompactStrings);
>   ...

@kelthuzadx , if you want to discuss initialization order changes please take 
this to hotspot-runtime-dev. Simply building okay and running a few tests can 
never validate a change in VM initialization order - there are a lot of 
subtleties involved, platform differences, affect of different flags, etc etc. 
Thanks @adinn for the details on this specific proposal - I agree that we 
neither want to make UnsafeConstants unable to use String, nor expose it for 
use by String.

Backing up a step what is the motivation for change here? Is there something 
wrong with the way String currently does this? Or is it just that it seemed on 
the surface that you could skip the native call and "just use Byteorder"?

-

PR: https://git.openjdk.java.net/jdk/pull/4596


Re: RFR: 8269384: Determine native byte order for StringUTF16 via ByteOrder

2021-06-28 Thread Andrew Dinn
On Fri, 25 Jun 2021 13:40:54 GMT, Yi Yang  wrote:

> Prefer using ByteOrder to compute byte order for StringUTF16 to determining 
> byte order by native method StringUTF16.isBigEndian.

Hi Yi Yang,

This is more complex than it seems. The general policy is not to change boot 
order if at all possible and for good reason. there are many ways it can cause 
unexpected consequences.

Regarding this specific case, UnsafeConstants exists in order to allow class 
Unsafe to define a few final fields derived from runtime environment/hardware 
parameters provided as final static *primitive* fields of UnsafeConstants. The 
relevant fields in UnsafeConstants are injected by the JVM after they have been 
initialized to dummy values by the class's  method. So, the purpose of 
the class is simply to pre-cache these runtime/hardware values as Java state, 
avoiding the need for Unsafe to call out to the JVM using native code. Before 
UnsafeConstants was defined these constants used to be retrieved using native 
callouts.

What you are asking for is to make String use the same pre-cache as Unsafe i.e. 
to expand the set of classes which depend on UnsafeConstants to include String. 
While that might work as currently defined it is not clear that it will always 
continue to work in the future. That's because String is a rather special case, 
much like a primitive class. Instances of String are created to represent 
literal terms in the language. Note that these String terms are themselves 
*constants*.

UnsafeConstants is not meant to have any other uses except to cache the 
runtime-specific/hardware constants used by Unsafe. So, it ought not to depend 
on other classes. However, it is also important that no other classes depend on 
it and that includes String. Now imagine someone were to update UnsafeConstants 
to include an injected String constant -- say, the current setting for LC_LANG, 
or the processor CPU name or some other legitimate text value derived form the 
runtime or hardware. Your change would cause a problem because initialization 
of UnsafeConstants would require String already to be initialized.

Of course, neither of those examples is a likely candidate for inclusion in 
UnsafeConstants but it is hard to say whether other more realistic cases might 
arise in future.

-

PR: https://git.openjdk.java.net/jdk/pull/4596


Re: RFR: 8269384: Determine native byte order for StringUTF16 via ByteOrder

2021-06-27 Thread Yi Yang
On Fri, 25 Jun 2021 13:40:54 GMT, Yi Yang  wrote:

> Prefer using ByteOrder to compute byte order for StringUTF16 to determining 
> byte order by native method StringUTF16.isBigEndian.

Hi Aleksey, do you have a concrete issue/discussion about bootstrapping 
problems? I don't see it because I can build JDK and passes tier1 tests w/o 
problems. But I admit this may cause potential problems. In order to reduce 
potential risks, how about changing the class initialization orders, i.e. 
initialize UUnsafeConstants_klas earlier, which seems reasonable:


void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) {
  TraceTime timer("Initialize java.lang classes", TRACETIME_LOG(Info, 
startuptime));

  if (EagerXrunInit && Arguments::init_libraries_at_startup()) {
create_vm_init_libraries();
  }

+#ifdef ASSERT
+  InstanceKlass *k = vmClasses::UnsafeConstants_klass();
+  assert(k->is_not_initialized(), "UnsafeConstants should not already be 
initialized");
+#endif
+
+  // initialize the hardware-specific constants needed by Unsafe
+  initialize_class(vmSymbols::jdk_internal_misc_UnsafeConstants(), CHECK);
+  jdk_internal_misc_UnsafeConstants::set_unsafe_constants();

  initialize_class(vmSymbols::java_lang_String(), CHECK);

  // Inject CompactStrings value after the static initializers for String ran.
  java_lang_String::set_compact_strings(CompactStrings);
  ...

-

PR: https://git.openjdk.java.net/jdk/pull/4596


Re: RFR: 8269384: Determine native byte order for StringUTF16 via ByteOrder

2021-06-25 Thread Aleksey Shipilev
On Fri, 25 Jun 2021 13:40:54 GMT, Yi Yang  wrote:

> Prefer using ByteOrder to compute byte order for StringUTF16 to determining 
> byte order by native method StringUTF16.isBigEndian.

Adding new dependencies in `String` quite probably risks bootstrapping issues. 
There is a reason why `String` calls into its own native methods for this.

-

PR: https://git.openjdk.java.net/jdk/pull/4596