diff a/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java b/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java
--- a/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java
@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this
@@ -23,10 +23,12 @@
  * questions.
  */
 
 package java.lang.invoke;
 
+import java.lang.reflect.code.Quotable;
+
 import java.io.Serializable;
 import java.util.Arrays;
 import java.lang.reflect.Array;
 import java.util.Objects;
 
@@ -249,10 +251,14 @@
      * Flag for alternate metafactories indicating the lambda object requires
      * additional methods that invoke the {@code implementation}
      */
     public static final int FLAG_BRIDGES = 1 << 2;
 
+    /** Flag for {@link #altMetafactory} indicating the lambda object
+     * must be a {@code Quotable} object, inspectable using code reflection. */
+    public static final int FLAG_QUOTABLE = 1 << 3;
+
     private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
     private static final MethodType[] EMPTY_MT_ARRAY = new MethodType[0];
 
     // LambdaMetafactory bootstrap methods are startup sensitive, and may be
     // special cased in java.lang.invoke.BootstrapMethodInvoker to ensure
@@ -334,11 +340,12 @@
                                              Objects.requireNonNull(interfaceMethodType),
                                              Objects.requireNonNull(implementation),
                                              Objects.requireNonNull(dynamicMethodType),
                                              false,
                                              EMPTY_CLASS_ARRAY,
-                                             EMPTY_MT_ARRAY);
+                                             EMPTY_MT_ARRAY,
+                                 null);
         mf.validateMetafactoryArgs();
         return mf.buildCallSite();
     }
 
     /**
@@ -380,10 +387,12 @@
      *                          int flags,
      *                          int altInterfaceCount,        // IF flags has MARKERS set
      *                          Class... altInterfaces,       // IF flags has MARKERS set
      *                          int altMethodCount,           // IF flags has BRIDGES set
      *                          MethodType... altMethods      // IF flags has BRIDGES set
+     *                          MethodType reflectType        // IF flags has QUOTABLE set
+     *                          MethodHandle reflectField     // IF flags has QUOTABLE set
      *                          )
      * }</pre>
      *
      * <p>Arguments that appear in the argument list for
      * {@link #metafactory(MethodHandles.Lookup, String, MethodType, MethodType, MethodHandle, MethodType)}
@@ -403,10 +412,14 @@
      *     the function object should implement, and is present if and only if
      *     the {@code FLAG_BRIDGES} flag is set.</li>
      *     <li>{@code altMethods} is a variable-length list of additional
      *     methods signatures to implement, whose length equals {@code altMethodCount},
      *     and is present if and only if the {@code FLAG_BRIDGES} flag is set.</li>
+     *     <li>{@code quotableField} is a
+     *     {@linkplain MethodHandles.Lookup#findGetter(Class, String, Class) getter} method handle
+     *     that is used to retrieve the string representation of the quotable lambda's associated
+     *     intermediate representation.</li>
      * </ul>
      *
      * <p>Each class named by {@code altInterfaces} is subject to the same
      * restrictions as {@code Rd}, the return type of {@code factoryType},
      * as described {@link LambdaMetafactory above}.  Each {@code MethodType}
@@ -417,10 +430,13 @@
      * will implement {@code Serializable}, and will have a {@code writeReplace}
      * method that returns an appropriate {@link SerializedLambda}.  The
      * {@code caller} class must have an appropriate {@code $deserializeLambda$}
      * method, as described in {@link SerializedLambda}.
      *
+     * <p>When FLAG_QUOTABLE is set in {@code flags}, the function objects
+     * will implement {@code Quotable}.
+     *
      * <p>When the target of the {@code CallSite} returned from this method is
      * invoked, the resulting function objects are instances of a class with
      * the following properties:
      * <ul>
      *     <li>The class implements the interface named by the return type
@@ -485,10 +501,11 @@
         MethodHandle implementation = extractArg(args, argIndex++, MethodHandle.class);
         MethodType dynamicMethodType = extractArg(args, argIndex++, MethodType.class);
         int flags = extractArg(args, argIndex++, Integer.class);
         Class<?>[] altInterfaces = EMPTY_CLASS_ARRAY;
         MethodType[] altMethods = EMPTY_MT_ARRAY;
+        MethodHandle quotableField = null;
         if ((flags & FLAG_MARKERS) != 0) {
             int altInterfaceCount = extractArg(args, argIndex++, Integer.class);
             if (altInterfaceCount < 0) {
                 throw new IllegalArgumentException("negative argument count");
             }
@@ -505,10 +522,15 @@
             if (altMethodCount > 0) {
                 altMethods = extractArgs(args, argIndex, MethodType.class, altMethodCount);
                 argIndex += altMethodCount;
             }
         }
+        if ((flags & FLAG_QUOTABLE) != 0) {
+            quotableField = extractArg(args, argIndex++, MethodHandle.class);
+            altInterfaces = Arrays.copyOf(altInterfaces, altInterfaces.length + 1);
+            altInterfaces[altInterfaces.length-1] = Quotable.class;
+        }
         if (argIndex < args.length) {
             throw new IllegalArgumentException("too many arguments");
         }
 
         boolean isSerializable = ((flags & FLAG_SERIALIZABLE) != 0);
@@ -529,11 +551,12 @@
                                                   interfaceMethodType,
                                                   implementation,
                                                   dynamicMethodType,
                                                   isSerializable,
                                                   altInterfaces,
-                                                  altMethods);
+                                                  altMethods,
+                                                  quotableField);
         mf.validateMetafactoryArgs();
         return mf.buildCallSite();
     }
 
     private static <T> T extractArg(Object[] args, int index, Class<T> type) {
