[10] RFR 8186046 Minimal ConstantDynamic support

Paul Sandoz paul.sandoz at oracle.com
Fri Nov 3 21:28:54 UTC 2017


> On 3 Nov 2017, at 11:14, Karen Kinnear <karen.kinnear at oracle.com> wrote:
> 
> Thank you so much for doing this jointly.
> 
> Couple of questions/comments:
> 1. thank you for making UseBootstrapCallInfo diagnostic
> 
> 2. org/objectweb/asmClassReader.java
> why hardcoded 17 instead of ClassWriter.CONDY?
> 

I chose to make the absolute minimal amount of changes to our internal ASM to reduce possible conflicts as i anticipate that a new version of ASM with condy support will eventually be rolled in.


> 3. java/lang/invoke/package-info.java 128-134
> Error handling could be clearer.
> My understanding is that if a LinkageError or subclass is thrown, this will be rethrown
> for all subsequent attempts. Other errors, e.g. VMError may retry resolution
> 
> Also: after line 165: rules do not enable the JVM to share call sites.
> Is it worth noting anywhere that the Constant_Dynamic resolution is shared?
> 
> 4. SD::find_java_mirror_for_type
> lines 2679+
>   ConDy should not be supporting CONSTANT_Class(“;” + FD)
>   IIRC that is temporary for MVT but not part of ConDy’s spec, nor part of what
>   should be checked in for 18.3


Yes, i deleted lines 2678 to 2687

TempNewSymbol type_buf;
if (type->utf8_length() > 1 && type->byte_at(0) == ';') {
  // Strip the quote, which may have come from CONSTANT_Class[";"+FD].
  // (This logic corresponds to the use of "FieldType::is_obj"
  // in resolve_or_null.  A field type can be unwrapped to a class
  // type and vice versa.)
  type = SymbolTable::new_symbol(type->as_C_string() + 1,
                                 type->utf8_length() - 1, CHECK_(empty));
  type_buf = type;  // will free later
}


> also line 2731 - remove comment about “Foo;”
> 

Removed.


> 5. constantTag.hpp
> ofBasicType: case T_OBJECT return constantTag(JVM_CONSTANT_String) ?
> why not JVM_CONSTANT_CLASS?
> 

We would have to ask John on that, i am guessing it does not matter much since round tripping is ok and it is the more benign of the mapping. I do find this sits awkwardly though, perhaps there is a more general cleanup that can follow in this regard?


> 6. SD::find_java_mirror_for_type
> You have resolve_or_null/fail doing CHECK_(empty) which should
> check for a NULL constant_type_klass. This is followed by an explicit if
> (constant_type_klass == NULL) — is that needed?
> 

Can SD:resolve_or_null return a null value when HAS_PENDING_EXCEPTION=false?

I see other usages that suggest this to be the case. Where as for resolve_or_fail:

Klass* SystemDictionary::resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS) {
  Klass* klass = resolve_or_null(class_name, class_loader, protection_domain, THREAD);
  if (HAS_PENDING_EXCEPTION || klass == NULL) {
    // can return a null klass
    klass = handle_resolution_exception(class_name, throw_error, klass, THREAD);
  }
  return klass;
}


It suggests we can change the code from:

if (failure_mode == SignatureStream::ReturnNull) {
  constant_type_klass = resolve_or_null(type, class_loader, protection_domain,
                                        CHECK_(empty));
} else {
  bool throw_error = (failure_mode == SignatureStream::NCDFError);
  constant_type_klass = resolve_or_fail(type, class_loader, protection_domain,
                                        throw_error, CHECK_(empty));
}
if (constant_type_klass == NULL) {
  return Handle();  // report failure this way
}

to

if (failure_mode == SignatureStream::ReturnNull) {
  constant_type_klass = resolve_or_null(type, class_loader, protection_domain,
                                        CHECK_(empty));
  if (constant_type_klass == NULL) {
    return Handle();  // report failure this way
  }
} else {
  bool throw_error = (failure_mode == SignatureStream::NCDFError);
  constant_type_klass = resolve_or_fail(type, class_loader, protection_domain,
                                        throw_error, CHECK_(empty));
}

?


> 7. reflection.cpp
> get_mirror_from_signature
> Looks like potential for side effects. Odd to set mirror_oop inside if (log_is_enabled)
> Is the intent to assert that k->java_mirror() == mirror_oop?
> Or is the issue that we have a make drop here and the potential for a safe point?
> If so, make a handle and extract it on return?
> 
> — Or better yet - don’t make any changes to reflection.cpp - not necessary
> 

Lois, John?

My recollection was John was attempting to tunnel things through a single method find_java_mirror_for_type, but i agree the setting of mirror_oop is odd.



> 8. BootstrapMethodInvoker
> Could you possibly add a comment that the default today is vmIsPushing and IsPullModeBSM is false?
> Or find a slightly different naming to make that clearer?

boolean pullMode = isPullModeBSM(bootstrapMethod);  // default value is false
boolean vmIsPushing = !staticArgumentsPulled(info); // default value is true

?


> 
> 9. test/jdk/java/lang/invoke/common/test/java/lang/invoke/lib/InstructionHelper.java
> How would I write an ldc CONSTANT_Dynamic which referred to a bootstrap method that
> was not ACC_STATIC?

https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.23

See the note under bootstrap_method_ref. The kind of method handle is constrained because of the arguments that are pushed on the stack before invocation. I believe it’s possible to have a constructor, but the declaring class would need to be a subtype of CallSite in the case of indy, and a subtype of the constant value type in the case of condy.


> Or was not ACC_PUBLIC?

That’s dependent on the accessibility between the lookup class the the BSM declaring class.


> Or was 
> Or did I read the invoke dynamic method incorrectly?
> 

By default, and for convenience, the InstructionHelper assumes the BSM is declared by the lookup class. I recently modified that to support the BSM being declared on another class, to test the minimal set of BSMs for condy (separate issue [1]). Note it’s always possible to use the bytecode API more directly.

So we can easily add more -ve tests for non-accessible or non-static BSMs.

Paul.

[1] http://cr.openjdk.java.net/~psandoz/jdk10/JDK-8187742-condy-bootstraps/webrev/



More information about the core-libs-dev mailing list