This is an automated email from the ASF dual-hosted git repository.

He-Pin pushed a commit to branch refactor/replace-reflection-with-methodhandles
in repository https://gitbox.apache.org/repos/asf/pekko-http.git

commit 0269df0924db824cd446ad12e0525893fb417a8d
Author: 虎鸣 <[email protected]>
AuthorDate: Mon Jul 6 16:29:58 2026 +0800

    refactor: replace java.lang.reflect with MethodHandle/VarHandle for JIT 
optimization
    
    Motivation:
    java.lang.reflect Method.invoke and Constructor.newInstance bypass JIT
    inlining, adding overhead to build-time aggregation calls and test code.
    
    Modification:
    - SbtInternalAccess: replace Method.invoke with MethodHandle.invoke via
      unreflect for Aggregation.showRun calls
    - Http2ServerSpec: replace Field.get with VarHandle.get via
      unreflectVarHandle for ManualProbe.probe field access
    - TurkishISpec: replace Constructor.newInstance with MethodHandle.invoke
      via unreflectConstructor for HttpCharsets$ instantiation
    
    Result:
    MethodHandle and VarHandle enable JIT inlining, eliminating reflection
    overhead in both build-time and test code paths.
    
    Tests:
    - sbt "http2-tests / Test / compile" - success
    - sbt "http-core / Test / compile" - success
    
    References:
    None - internal refactoring
---
 .../org/apache/pekko/http/scaladsl/model/TurkishISpec.scala    |  9 ++++++---
 .../apache/pekko/http/impl/engine/http2/Http2ServerSpec.scala  | 10 +++++++---
 project/SbtInternalAccess.scala                                |  8 +++++---
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git 
a/http-core/src/test/scala/org/apache/pekko/http/scaladsl/model/TurkishISpec.scala
 
b/http-core/src/test/scala/org/apache/pekko/http/scaladsl/model/TurkishISpec.scala
index 58d6a89f6..5ac7ec0cb 100644
--- 
a/http-core/src/test/scala/org/apache/pekko/http/scaladsl/model/TurkishISpec.scala
+++ 
b/http-core/src/test/scala/org/apache/pekko/http/scaladsl/model/TurkishISpec.scala
@@ -13,6 +13,7 @@
 
 package org.apache.pekko.http.scaladsl.model
 
+import java.lang.invoke.MethodHandles
 import java.util.Locale
 import org.apache.pekko.http.impl.util._
 import org.scalatest.matchers.should.Matchers
@@ -21,8 +22,10 @@ import org.scalatest.wordspec.AnyWordSpec
 class TurkishISpec extends AnyWordSpec with Matchers {
   "Model" should {
     "not suffer from turkish-i problem" in {
-      val charsetCons = 
Class.forName("org.apache.pekko.http.scaladsl.model.HttpCharsets$").getDeclaredConstructor()
-      charsetCons.setAccessible(true)
+      val charsetClass = 
Class.forName("org.apache.pekko.http.scaladsl.model.HttpCharsets$")
+      val charsetCtor = charsetClass.getDeclaredConstructor()
+      charsetCtor.setAccessible(true)
+      val charsetHandle = 
MethodHandles.lookup().unreflectConstructor(charsetCtor)
 
       val previousLocale = Locale.getDefault
 
@@ -34,7 +37,7 @@ class TurkishISpec extends AnyWordSpec with Matchers {
         // demonstrate difference between toRootLowerCase and 
toLowerCase(turkishLocale)
         (testString.toLowerCase should not).equal(testString.toRootLowerCase)
 
-        val newCharsets = 
charsetCons.newInstance().asInstanceOf[HttpCharsets.type]
+        val newCharsets = 
charsetHandle.invoke().asInstanceOf[HttpCharsets.type]
         newCharsets.getForKey("iso-8859-1") shouldEqual 
Some(newCharsets.`ISO-8859-1`)
       } finally {
         Locale.setDefault(previousLocale)
diff --git 
a/http2-tests/src/test/scala/org/apache/pekko/http/impl/engine/http2/Http2ServerSpec.scala
 
b/http2-tests/src/test/scala/org/apache/pekko/http/impl/engine/http2/Http2ServerSpec.scala
index 573a96335..bc2b19b7e 100644
--- 
a/http2-tests/src/test/scala/org/apache/pekko/http/impl/engine/http2/Http2ServerSpec.scala
+++ 
b/http2-tests/src/test/scala/org/apache/pekko/http/impl/engine/http2/Http2ServerSpec.scala
@@ -13,6 +13,7 @@
 
 package org.apache.pekko.http.impl.engine.http2
 
+import java.lang.invoke.MethodHandles
 import javax.net.ssl.SSLContext
 
 import scala.collection.immutable
@@ -907,10 +908,13 @@ class Http2ServerSpec extends 
Http2SpecWithMaterializer("""
           def fulfillDemandWithin(publisherProbe: TestPublisher.Probe[?], 
timeout: FiniteDuration)(
               body: => Unit): Unit = {
             // HACK to support `expectRequest` with a timeout
+            val probeHandle = {
+              val probeField = 
classOf[ManualProbe[?]].getDeclaredField("probe")
+              probeField.setAccessible(true)
+              MethodHandles.lookup().unreflectVarHandle(probeField)
+            }
             def within[T](publisherProbe: TestPublisher.Probe[?], dur: 
FiniteDuration)(t: => T): T = {
-              val field = classOf[ManualProbe[?]].getDeclaredField("probe")
-              field.setAccessible(true)
-              field.get(publisherProbe).asInstanceOf[TestProbe].within(dur)(t)
+              
probeHandle.get(publisherProbe).asInstanceOf[TestProbe].within(dur)(t)
             }
             def expectRequest(timeout: FiniteDuration): Long =
               within(publisherProbe, timeout)(publisherProbe.expectRequest())
diff --git a/project/SbtInternalAccess.scala b/project/SbtInternalAccess.scala
index bd56f21b9..1ed158b73 100644
--- a/project/SbtInternalAccess.scala
+++ b/project/SbtInternalAccess.scala
@@ -13,16 +13,18 @@
 
 package sbt {
   package object access {
+    import java.lang.invoke.MethodHandles
+
     type Aggregation = sbt.internal.Aggregation
     val Aggregation = sbt.internal.Aggregation
 
-    private val showRunMethod = {
+    private val showRunHandle = {
       val method = 
Class.forName("sbt.internal.Aggregation$").getDeclaredMethods.find(_.getName == 
"showRun").get
       method.setAccessible(true)
-      method
+      MethodHandles.lookup().unreflect(method)
     }
     def AggregationShowRun[T](complete: sbt.internal.Aggregation.Complete[T],
         show: sbt.internal.Aggregation.ShowConfig)(
-        implicit display: Show[ScopedKey[?]]): Unit = 
showRunMethod.invoke(Aggregation, complete, show, display)
+        implicit display: Show[ScopedKey[?]]): Unit = 
showRunHandle.invoke(Aggregation, complete, show, display)
   }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to