Valhalla EG notes Jan 16, 2019

Karen Kinnear karen.kinnear at
Tue Jan 29 18:55:17 UTC 2019

Attendees: Remi, Tobi, Dan H, John, Brian, Simms, Fred, Karen
Corrections welcome - thank you John for your summary notes

  Remi - write up why if we retrofit arrays for Arrays 2.0 specializable interface, 
do we need covariance?
  All: find examples where existing code assumes Class.getSuperClass() is java.lang.Object explicitly, or other pain points due to reparenting existing subclasses of Object with RefObject
  John: question about RefObject handling please?
John: val x - new Object() assert x instanceof RefObject;

ed. note - John - I don’t get the sentence above - I thought existing explicit java.lang.Objects
would stay as supers of RefObject and ValObject, or did I miss context here?

I. Array Covariance

Karen: Is it reasonable to prototype full array covariance for LW2+?
Brian: For generic specialization, if we do not have full array covariance then
we would need to move toward Arrays 2.0. The cost of not doing array
covariance is worse than the cost of doing it.
Dan H: concern with array covariance - metamorphism performance cliff?
Dan H: Also measure code cache pressure for existing code in the field
  - key to get this on larger applications, not just microenchmarks
John: prototype full covariance - get user feedback and quantify performance  costs
Brian: Could flesh out Arrays 2.0 path a bit more so we see migration costs
   with covariance, least cognitive dissonance
Dan H: Arrays 2.0 - retrofit existing arrays to implement an interface?
Brian: Yes - e.g. something like an ArrayInterface<T> specializable
Remi: if we need to retrofit existing arrays will need covariance

II. acmp
Karen: proposal - reframe as substitutability
  goal: allow existing bytecodes to work with value types - since we have to find a way to handle
  interface/java.lang.Object ==, != comparisons with dynamic value types anyway
  initial prototype - shows no significant performance loss for specjvm2008, i.e. for existing non-VT code
Dan H: Concern cost of recursion if a value type contains fields of its own type
John: yes. Also interface/Object must recurse
Brian: must do recursion based on static type
  “good cases” : if no Float/Double and no interface/Object can do bit comparison: expect mostly memcmp
   ( ed. note - and no non flattened value type fields )
Remi: concern StackOverflowError - e.g. linkedList with next field is an object
  - could always just return false
Brian: sharp edge:
   Object o1 = p1; Object o2 = p2
   if (o1 == o2) … // ouch
Karen: if concern is StackOverflowError - implementation could be done iteratively
Dan H: identityHashMap handling?
Brian: serialization uses - may need to rewrite serialization
Remi: Arrays.toString() uses 
Brian: if for values, identityHashMap also uses substitutability - all that are substitutable get lumped together
John: Need to prototype and get Google or others  to run on their stack

Brian: Spirit of L-World
goal is to explore a design from the user model - i.e. what users will expect
vs. current explorations that have mostly been from performance/cost, will need to balance these
Dan H: not sure what users will prefer - if they only want better escape analysis
and stack allocation - why are we doing value types?
Brian: flat & dense data if they can make compromises
John: need to be able to throw away identities
  - leave out, reconstruct, or redefine operations to reabstract to something more than just identity
Remi: what if .equals instead of substitutability?
Brian: author overridable, but less optimizable, recursion in java code - better SOE backtrace
Dan H: concern about safepoints in .equals
Brian: ValObject.Equals must always return same result. will need multiple prototyping rounds here
Karen: e.g. always false, substitutability, .equals

III. Spirit of L-World RefObject/ValObject
Dan H: retcon existing Objects extend RefObject - modify existing or reparent?
  what will break?
Brian: Reparent - allows generic type constraints - as part of generic specialization side explorations
Remi: Groovy 1 -> Groovy 2 migration challenges getClass.superclass() assumptions broke
John: val x - new Object() assert x instanceof RefObject;
(ed. note - see question under AIs above)
Remi: solving a type issue with a class hierarchy - could we use interfaces?
John: no - we need control over Object.wait() and Object.notify()
Brian: If we were writing a language from scratch,  we would put wait/notify on RefObject
  Let’s distinguish the model from legacy issues
John: elevate user model into the type system
  e.g. Object.wait - adhoc handling/JVMS corner case vs. final method that throws
Fred: Change the sources to retcon?
Brian: at class definition time
Remi: existing bytecodes use Object.wait)
Brian: create a final method that throws an exception, so transparent in java doc, makes sense, not magic
  RefObject - rules - e.g. only public members
  ValObject - rules - e.g. no fields
Remi: interfaces do not derive from Object
FP: JVMS: calls via interfaces call public non static methods of Object
Brian: why classes not interfaces?
  more JLS adhoc restrictions
  interfaces can not override object methods
  interfaces could be a possible fallback
  Arrays are RefObjects
FP: need to double-check JVMS array parent class
Simms: alternative (in chat) 
   ValueType extends ValObject
   existing NotValue implement Identity
John: possibly. ValObject is a class. NotValue (RefObject) is a mandatory interface for non-values
(not the way we would do this if designing from scratch)
 Better to make both classes for symmetry so concrete non-default methods can be placed in both

IV. Pattern match using ValueTypes
Brian: not yet proposed translation strategy - still exploring
see email thread instead


More information about the valhalla-spec-observers mailing list