RFR(L): 8215559: [lworld] Scalarize calls with a value type receiver

Tobias Hartmann tobias.hartmann at oracle.com
Tue Feb 5 14:43:04 UTC 2019


Hi,

please review the following patch that enables scalarization of value type receivers:
https://bugs.openjdk.java.net/browse/JDK-8215559
http://cr.openjdk.java.net/~thartmann/8215559/webrev.00/

Given a non-static method in class MyValue with receiver v1 and signature (MyValue v2, int i1, int
i2, int i3, int i4, int i5) where MyValue has four integer fields f1 - f4, the following nmethod
entry points and corresponding c2i adapters are now defined:

(1) Value Entry Point
- Used by method handle linkTo* calls from compiled code where all value types are passed as oop
- Extends the stack, unpacks all value type arguments, moves other arguments to their expected
stack/register locations and jumps to the normal entry point

Signature: (v1, v2, i1, i2, i3, i4, i5)
Adapter: c2iVE
Register/stack layout:
  rsi: v1
  rdx: v2
  rcx: i1
   r8: i2
   r9: i3
  rdi: i4
 0x20: ...    <- sp of caller
 0x18  i5
 0x10: return_address
 0x08: rbp
 0x00: locals

(2) Value Entry Point RO (*R*eceiver *O*nly)
- Used by interface calls from compiled code where the receiver is always passed as oop
- Extends the stack, unpacks only the value type receiver, moves other arguments to their expected
stack/register locations and jumps to the normal entry point

Signature: (v1, v2.f1, v2.f2, v2.f3, v2.f4, i1, i2, i3, i4, i5)
Adapter: c2iVROE
Register/stack layout:
  rsi: v1
  rdx: v2.f1
  rcx: v2.f2
   r8: v2.f3
   r9: v2.f4
  rdi: i1
 0x38: ...    <- sp of caller
 0x30: i5
 0x28: i4
 0x20: i3
 0x18: i2
 0x10: return_address
 0x08: rbp
 0x00: locals

(3) Normal Entry Point
- Used by scalarized calls from compiled code (all value type arguments are passed as fields)
- Expects all arguments in scalarized form and has reserved argument entries to account for return
addresses when called through (1) or (2)

Signature: (v1.f1, v1.f2, v1.f3, v1.f4, v2.f1, v2.f2, v2.f3, v2.f4, i1, i2, [RESERVED], i3, i4,
[RESERVED], i5)
Adapter: c2i
Register/stack layout:
  rsi: v1.f1
  rdx: v1.f2
  rcx: v1.f3
   r8: v1.f4
   r9: v2.f1
  rdi: v2.f2
 0x68: ...    <- sp of caller
 0x60: i5
 0x58: [RESERVED] <- might contain return address from Value Entry Point (1)
 0x50: i4
 0x48: i3
 0x40: [RESERVED] <- might contain return address from Value Entry Point RO (2)
 0x38: i2
 0x30: i1
 0x28: v2.f4
 0x20: v2.f3
 0x18: return_address
 0x10: rbp
 0x08: sp_inc = 0x58 (1), 0x40 (2) or 0x18 (3)
 0x00: locals

Like before, the special 'sp_inc' value is used at returns to repair the stack that has been
extended by the value type entry points. The difference is that we now need two 'Reserved' entries
in the extended signature because the return address is at a different location depending on if we
call through (1) or (2).

The complete entry point layout of the example method then looks like this:

-> Value Entry Point RO
   - Verify class and then fall through
-> Verified Value Entry Point RO
   - Extend stack, unpack receiver, move other arguments into expected locations
   - Jump to verified entry point
-> Verified Value Entry Point
   - Extend stack, unpack all value type arguments and move other arguments into expected locations
   - Jump to verified entry point
-> Entry Point
   - Verify class and then fall through
-> Verified Entry Point
   - Scalarized code

This patch also contains significant refactoring of related code (for example, methods in
valuetypenode.cpp).

Open issues that will be addresses by follow up changes:
- If the method holder does not implement any interfaces, the method can't be called through an
interface and we don't need the additional entry point(s)
- If the only value type in the argument list is the receiver, we don't need the RO entry point but
can use the value type entry point

Please let me know if some changes require more detailed explanation.

Thanks,
Tobias


More information about the valhalla-dev mailing list