Movatterモバイル変換


[0]ホーム

URL:


JEP 416: Reimplement Core Reflection with Method Handles

OwnerMandy Chung
TypeFeature
ScopeJDK
StatusClosed / Delivered
Release18
Componentcore-libs / java.lang:reflect
Discussioncore dash libs dash dev at openjdk dot java dot net
EffortM
DurationM
Reviewed byAlan Bateman, John Rose
Endorsed byJohn Rose
Created2021/04/26 22:41
Updated2024/03/07 18:49
Issue8266010

Summary

Reimplementjava.lang.reflect.Method,Constructor, andField on top ofjava.lang.invoke method handles. Making method handles the underlyingmechanism for reflection will reduce the maintenance and development cost ofboth thejava.lang.reflect andjava.lang.invoke APIs.

Non-Goals

It is not a goal to make any change to thejava.lang.reflect API. This issolely an implementation change.

Motivation

Core reflection has two internal mechanisms for invoking methods andconstructors. For fast startup, it uses native methods in the HotSpot VM forthe first few invocations of a specific reflective method or constructor object.For better peak performance, after a number of invocations it generates bytecodefor the reflective operation and uses that in subsequent invocations.

For field access, core reflection uses the internalsun.misc.Unsafe API.

With thejava.lang.invoke method-handle API introduced in Java 7, thereare altogether three different internal mechanisms for reflective operations:

When we updatejava.lang.reflect andjava.lang.invoke to support newlanguage features, such as those envisioned inProject Valhalla, wemust modify all three code paths, which is costly. In addition, the currentimplementation relies on special treatment by the VM of the generated bytecode,which is wrapped in subclasses ofjdk.internal.reflect.MagicAccessorImpl:

Description

Reimplementjava.lang.reflect on top of method handles as the commonunderlying reflective mechanism of the platform by replacing thebytecode-generating implementations ofMethod::invoke,Constructor::newInstance,Field::get, andField::set.

The new implementation performs direct invocations of the method handlesfor specific reflective objects.We use the VM's native reflection mechanism only during early VM startup,before the method-handle mechanism is initialized. That happens soon afterSystem::initPhase1 and beforeSystem::initPhase2, after which we switch to using methodhandles exclusively. This benefitsProject Loom by reducing the use ofnative stack frames.

For optimal performance,Method,Constructor, andField instancesshould be held instatic final fields so that they can beconstant-folded by the JIT. When that is done, microbenchmarks show thatthe performance of the new implementation is significantly faster thanthe old implementation, by 43–57%.

WhenMethod,Constructor, andField instances are held innon-constant fields (e.g., in a non-final field or an array element),microbenchmarks show some performance degradation. The performance offield accesses is significantly slower than the old implementation, by51–77%, whenField instances cannot be constant-folded.

This degradation may, however, not have much effect on the performance ofreal-world applications. We ran several serialization anddeserialization benchmarks using real-world libraries and found nodegradation in

We will continue to explore opportunities to improve performance, forexample by refining the bytecode shapes for field access to enableconcreteMethodHandles andVarHandles to be reliably optimized by theJIT regardless of whether the receiver is constant.

The new implementation will reduce the cost of upgrading reflectionsupport for new language features and, further, will allow us to simplifythe HotSpot VM by removing the special treatment ofMagicAccessorImplsubclasses.

Alternatives

Alternative 1: Do nothing

Retain the existing core reflection implementation to avoid any compatibilityrisk. The dynamic bytecode generated for core reflection would remain at classfile version 49, and the VM would continue to treat such bytecode specially.

We reject this alternative because

Alternative 2: Upgrade to a new bytecode library

Replace the bytecode writer used by core reflection to use a new bytecodelibrary that evolves together with the class-file format, but otherwise retainthe existing core reflection implementation and continue to treatdynamically-generated reflection bytecode specially.

This alternative has lower compatibility risk than what we propose above, but itis still a sizeable amount of work and it still has the first and lastdisadvantages of the first alternative.

Testing

Comprehensive testing will ensure that the implementation is robust andcompatible with existing behavior. Performance testing will ensure that thereare no unexpected significant performance regressions compared to the currentimplementation. We will encourage developers using early-access builds to testas many libraries and frameworks as possible in order to help us identify anybehavior or performance regressions.

Baseline

Benchmark                                     Mode  Cnt   Score  Error  UnitsReflectionSpeedBenchmark.constructorConst     avgt   10  68.049 ± 0.872  ns/opReflectionSpeedBenchmark.constructorPoly      avgt   10  94.132 ± 1.805  ns/opReflectionSpeedBenchmark.constructorVar       avgt   10  64.543 ± 0.799  ns/opReflectionSpeedBenchmark.instanceFieldConst   avgt   10  35.361 ± 0.492  ns/opReflectionSpeedBenchmark.instanceFieldPoly    avgt   10  67.089 ± 3.288  ns/opReflectionSpeedBenchmark.instanceFieldVar     avgt   10  35.745 ± 0.554  ns/opReflectionSpeedBenchmark.instanceMethodConst  avgt   10  77.925 ± 2.026  ns/opReflectionSpeedBenchmark.instanceMethodPoly   avgt   10  96.094 ± 2.269  ns/opReflectionSpeedBenchmark.instanceMethodVar    avgt   10  80.002 ± 4.267  ns/opReflectionSpeedBenchmark.staticFieldConst     avgt   10  33.442 ± 2.659  ns/opReflectionSpeedBenchmark.staticFieldPoly      avgt   10  51.918 ± 1.522  ns/opReflectionSpeedBenchmark.staticFieldVar       avgt   10  33.967 ± 0.451  ns/opReflectionSpeedBenchmark.staticMethodConst    avgt   10  75.380 ± 1.660  ns/opReflectionSpeedBenchmark.staticMethodPoly     avgt   10  93.553 ± 1.037  ns/opReflectionSpeedBenchmark.staticMethodVar      avgt   10  76.728 ± 1.614  ns/op

New implementation

Benchmark                                     Mode  Cnt    Score   Error  UnitsReflectionSpeedBenchmark.constructorConst     avgt   10   32.392 ± 0.473  ns/opReflectionSpeedBenchmark.constructorPoly      avgt   10  113.947 ± 1.205  ns/opReflectionSpeedBenchmark.constructorVar       avgt   10   76.885 ± 1.128  ns/opReflectionSpeedBenchmark.instanceFieldConst   avgt   10   18.569 ± 0.161  ns/opReflectionSpeedBenchmark.instanceFieldPoly    avgt   10   98.671 ± 2.015  ns/opReflectionSpeedBenchmark.instanceFieldVar     avgt   10   54.193 ± 3.510  ns/opReflectionSpeedBenchmark.instanceMethodConst  avgt   10   33.421 ± 0.406  ns/opReflectionSpeedBenchmark.instanceMethodPoly   avgt   10  109.129 ± 1.959  ns/opReflectionSpeedBenchmark.instanceMethodVar    avgt   10   90.420 ± 2.187  ns/opReflectionSpeedBenchmark.staticFieldConst     avgt   10   19.080 ± 0.179  ns/opReflectionSpeedBenchmark.staticFieldPoly      avgt   10   92.130 ± 2.729  ns/opReflectionSpeedBenchmark.staticFieldVar       avgt   10   53.899 ± 1.051  ns/opReflectionSpeedBenchmark.staticMethodConst    avgt   10   35.907 ± 0.456  ns/opReflectionSpeedBenchmark.staticMethodPoly     avgt   10  102.895 ± 1.604  ns/opReflectionSpeedBenchmark.staticMethodVar      avgt   10   82.123 ± 0.629  ns/op

Risks and Assumptions

Code that depends upon highly implementation-specific and undocumented aspectsof the existing implementation may be impacted. To mitigate this compatibilityrisk, as a workaround you can enable the old implementation via-Djdk.reflect.useDirectMethodHandle=false.

OpenJDK logo
Installing
Contributing
Sponsoring
Developers' Guide
Vulnerabilities
JDK GA/EA Builds
Mailing lists
Wiki ·IRC
Mastodon
Bluesky
Bylaws ·Census
Legal
Workshop
JEP Process
Source code
GitHub
Mercurial
Tools
Git
jtreg harness
Groups
(overview)
Adoption
Build
Client Libraries
Compatibility & Specification Review
Compiler
Conformance
Core Libraries
Governing Board
HotSpot
IDE Tooling & Support
Internationalization
JMX
Members
Networking
Porters
Quality
Security
Serviceability
Vulnerability
Web
Projects
(overview,archive)
Amber
Babylon
CRaC
Code Tools
Coin
Common VM Interface
Developers' Guide
Device I/O
Duke
Galahad
Graal
IcedTea
JDK 8 Updates
JDK 9
JDK (…,24,25,26)
JDK Updates
JMC
Jigsaw
Kona
Lanai
Leyden
Lilliput
Locale Enhancement
Loom
Memory Model Update
Metropolis
Multi-Language VM
Nashorn
New I/O
OpenJFX
Panama
Penrose
Port: AArch32
Port: AArch64
Port: BSD
Port: Haiku
Port: Mac OS X
Port: MIPS
Port: Mobile
Port: PowerPC/AIX
Port: RISC-V
Port: s390x
SCTP
Shenandoah
Skara
Sumatra
Tsan
Valhalla
Verona
VisualVM
Wakefield
Zero
ZGC
Oracle logo
© 2025 Oracle Corporation and/or its affiliates
Terms of Use · License:GPLv2 ·Privacy ·Trademarks

[8]ページ先頭

©2009-2025 Movatter.jp