001package Torello.Browser;
002
003import java.util.*;
004import javax.json.*;
005import javax.json.stream.*;
006import java.io.*;
007
008import java.lang.reflect.Method;
009import java.lang.reflect.Parameter;
010import java.util.function.Function;
011
012import Torello.Java.Additional.*;
013import Torello.Java.JSON.*;
014
015import static Torello.Java.JSON.JFlag.*;
016
017import Torello.Java.StrCmpr;
018import Torello.JavaDoc.StaticFunctional;
019import Torello.JavaDoc.JDHeaderBackgroundImg;
020import Torello.JavaDoc.Excuse;
021
022/**
023 * <SPAN CLASS=COPIEDJDK><B><CODE>[No Description Provided by Google]</CODE></B></SPAN>
024 * 
025 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE>
026 */
027@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION})
028@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE")
029public class Memory
030{
031    // ********************************************************************************************
032    // ********************************************************************************************
033    // Class Header Stuff
034    // ********************************************************************************************
035    // ********************************************************************************************
036
037
038    // No Pubic Constructors
039    private Memory () { }
040
041    // These two Vector's are used by all the "Methods" exported by this class.  java.lang.reflect
042    // is used to generate the JSON String's.  It saves thousands of lines of Auto-Generated Code.
043    private static final Map<String, Vector<String>>    parameterNames = new HashMap<>();
044    private static final Map<String, Vector<Class<?>>>  parameterTypes = new HashMap<>();
045
046    // Some Methods do not take any parameters - for instance all the "enable()" and "disable()"
047    // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now,
048    // offically, two empty-vectors.  One for String's, and the other for Classes.
049
050    private static final Vector<String>     EMPTY_VEC_STR = new Vector<>();
051    private static final Vector<Class<?>>   EMPTY_VEC_CLASS = new Vector<>();
052
053    static
054    {
055        for (Method m : Memory.class.getMethods())
056        {
057            // This doesn't work!  The parameter names are all "arg0" ... "argN"
058            // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter!
059            //
060            // Vector<String> parameterNamesList = new Vector<>(); -- NOPE!
061
062            Vector<Class<?>> parameterTypesList = new Vector<>();
063        
064            for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType());
065
066            parameterTypes.put(
067                m.getName(),
068                (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS
069            );
070        }
071    }
072
073    static
074    {
075        Vector<String> v = null;
076
077        parameterNames.put("getDOMCounters", EMPTY_VEC_STR);
078
079        parameterNames.put("prepareForLeakDetection", EMPTY_VEC_STR);
080
081        parameterNames.put("forciblyPurgeJavaScriptMemory", EMPTY_VEC_STR);
082
083        v = new Vector<String>(1);
084        parameterNames.put("setPressureNotificationsSuppressed", v);
085        Collections.addAll(v, new String[]
086        { "suppressed", });
087
088        v = new Vector<String>(1);
089        parameterNames.put("simulatePressureNotification", v);
090        Collections.addAll(v, new String[]
091        { "level", });
092
093        v = new Vector<String>(2);
094        parameterNames.put("startSampling", v);
095        Collections.addAll(v, new String[]
096        { "samplingInterval", "suppressRandomness", });
097
098        parameterNames.put("stopSampling", EMPTY_VEC_STR);
099
100        parameterNames.put("getAllTimeSamplingProfile", EMPTY_VEC_STR);
101
102        parameterNames.put("getBrowserSamplingProfile", EMPTY_VEC_STR);
103
104        parameterNames.put("getSamplingProfile", EMPTY_VEC_STR);
105    }
106
107
108    // ********************************************************************************************
109    // ********************************************************************************************
110    // Types - Static Inner Classes
111    // ********************************************************************************************
112    // ********************************************************************************************
113
114    /** Memory pressure level. */
115    public static final String[] PressureLevel =
116    { "moderate", "critical", };
117    
118    /** Heap profile sample. */
119    public static class SamplingProfileNode
120        extends BaseType
121        implements java.io.Serializable
122    {
123        /** For Object Serialization.  java.io.Serializable */
124        protected static final long serialVersionUID = 1;
125        
126        public boolean[] optionals()
127        { return new boolean[] { false, false, false, }; }
128        
129        /** Size of the sampled allocation. */
130        public final Number size;
131        
132        /** Total bytes attributed to this sample. */
133        public final Number total;
134        
135        /** Execution stack at the point of allocation. */
136        public final String[] stack;
137        
138        /**
139         * Constructor
140         *
141         * @param size Size of the sampled allocation.
142         * 
143         * @param total Total bytes attributed to this sample.
144         * 
145         * @param stack Execution stack at the point of allocation.
146         */
147        public SamplingProfileNode(Number size, Number total, String[] stack)
148        {
149            // Exception-Check(s) to ensure that if any parameters which are not declared as
150            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
151            
152            if (size == null)  THROWS.throwNPE("size");
153            if (total == null) THROWS.throwNPE("total");
154            if (stack == null) THROWS.throwNPE("stack");
155            
156            this.size   = size;
157            this.total  = total;
158            this.stack  = stack;
159        }
160        
161        /**
162         * JSON Object Constructor
163         * @param jo A Json-Object having data about an instance of {@code 'SamplingProfileNode'}.
164         */
165        public SamplingProfileNode (JsonObject jo)
166        {
167            this.size   = ReadNumberJSON.get(jo, "size", false, true);
168            this.total  = ReadNumberJSON.get(jo, "total", false, true);
169            this.stack = (jo.getJsonArray("stack") == null)
170                ? null
171                : RJArrIntoStream.strArr(jo.getJsonArray("stack"), null, 0).toArray(String[]::new);
172        
173        }
174        
175        
176        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
177        public boolean equals(Object other)
178        {
179            if (this == other)                       return true;
180            if (other == null)                       return false;
181            if (other.getClass() != this.getClass()) return false;
182        
183            SamplingProfileNode o = (SamplingProfileNode) other;
184        
185            return
186                    Objects.equals(this.size, o.size)
187                &&  Objects.equals(this.total, o.total)
188                &&  Arrays.deepEquals(this.stack, o.stack);
189        }
190        
191        /** Generates a Hash-Code for {@code 'this'} instance */
192        public int hashCode()
193        {
194            return
195                    Objects.hashCode(this.size)
196                +   Objects.hashCode(this.total)
197                +   Arrays.deepHashCode(this.stack);
198        }
199    }
200    
201    /** Array of heap profile samples. */
202    public static class SamplingProfile
203        extends BaseType
204        implements java.io.Serializable
205    {
206        /** For Object Serialization.  java.io.Serializable */
207        protected static final long serialVersionUID = 1;
208        
209        public boolean[] optionals()
210        { return new boolean[] { false, false, }; }
211        
212        /** <CODE>[No Description Provided by Google]</CODE> */
213        public final Memory.SamplingProfileNode[] samples;
214        
215        /** <CODE>[No Description Provided by Google]</CODE> */
216        public final Memory.Module[] modules;
217        
218        /**
219         * Constructor
220         *
221         * @param samples -
222         * 
223         * @param modules -
224         */
225        public SamplingProfile(Memory.SamplingProfileNode[] samples, Memory.Module[] modules)
226        {
227            // Exception-Check(s) to ensure that if any parameters which are not declared as
228            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
229            
230            if (samples == null) THROWS.throwNPE("samples");
231            if (modules == null) THROWS.throwNPE("modules");
232            
233            this.samples  = samples;
234            this.modules  = modules;
235        }
236        
237        /**
238         * JSON Object Constructor
239         * @param jo A Json-Object having data about an instance of {@code 'SamplingProfile'}.
240         */
241        public SamplingProfile (JsonObject jo)
242        {
243            this.samples = (jo.getJsonArray("samples") == null)
244                ? null
245                : RJArrIntoStream.objArr(jo.getJsonArray("samples"), null, 0, Memory.SamplingProfileNode.class).toArray(Memory.SamplingProfileNode[]::new);
246        
247            this.modules = (jo.getJsonArray("modules") == null)
248                ? null
249                : RJArrIntoStream.objArr(jo.getJsonArray("modules"), null, 0, Memory.Module.class).toArray(Memory.Module[]::new);
250        
251        }
252        
253        
254        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
255        public boolean equals(Object other)
256        {
257            if (this == other)                       return true;
258            if (other == null)                       return false;
259            if (other.getClass() != this.getClass()) return false;
260        
261            SamplingProfile o = (SamplingProfile) other;
262        
263            return
264                    Arrays.deepEquals(this.samples, o.samples)
265                &&  Arrays.deepEquals(this.modules, o.modules);
266        }
267        
268        /** Generates a Hash-Code for {@code 'this'} instance */
269        public int hashCode()
270        {
271            return
272                    Arrays.deepHashCode(this.samples)
273                +   Arrays.deepHashCode(this.modules);
274        }
275    }
276    
277    /** Executable module information */
278    public static class Module
279        extends BaseType
280        implements java.io.Serializable
281    {
282        /** For Object Serialization.  java.io.Serializable */
283        protected static final long serialVersionUID = 1;
284        
285        public boolean[] optionals()
286        { return new boolean[] { false, false, false, false, }; }
287        
288        /** Name of the module. */
289        public final String name;
290        
291        /** UUID of the module. */
292        public final String uuid;
293        
294        /**
295         * Base address where the module is loaded into memory. Encoded as a decimal
296         * or hexadecimal (0x prefixed) string.
297         */
298        public final String baseAddress;
299        
300        /** Size of the module in bytes. */
301        public final Number size;
302        
303        /**
304         * Constructor
305         *
306         * @param name Name of the module.
307         * 
308         * @param uuid UUID of the module.
309         * 
310         * @param baseAddress 
311         * Base address where the module is loaded into memory. Encoded as a decimal
312         * or hexadecimal (0x prefixed) string.
313         * 
314         * @param size Size of the module in bytes.
315         */
316        public Module(String name, String uuid, String baseAddress, Number size)
317        {
318            // Exception-Check(s) to ensure that if any parameters which are not declared as
319            // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
320            
321            if (name == null)        THROWS.throwNPE("name");
322            if (uuid == null)        THROWS.throwNPE("uuid");
323            if (baseAddress == null) THROWS.throwNPE("baseAddress");
324            if (size == null)        THROWS.throwNPE("size");
325            
326            this.name         = name;
327            this.uuid         = uuid;
328            this.baseAddress  = baseAddress;
329            this.size         = size;
330        }
331        
332        /**
333         * JSON Object Constructor
334         * @param jo A Json-Object having data about an instance of {@code 'Module'}.
335         */
336        public Module (JsonObject jo)
337        {
338            this.name         = ReadJSON.getString(jo, "name", false, true);
339            this.uuid         = ReadJSON.getString(jo, "uuid", false, true);
340            this.baseAddress  = ReadJSON.getString(jo, "baseAddress", false, true);
341            this.size         = ReadNumberJSON.get(jo, "size", false, true);
342        }
343        
344        
345        /** Checks whether {@code 'this'} equals an input Java-{@code Object} */
346        public boolean equals(Object other)
347        {
348            if (this == other)                       return true;
349            if (other == null)                       return false;
350            if (other.getClass() != this.getClass()) return false;
351        
352            Module o = (Module) other;
353        
354            return
355                    Objects.equals(this.name, o.name)
356                &&  Objects.equals(this.uuid, o.uuid)
357                &&  Objects.equals(this.baseAddress, o.baseAddress)
358                &&  Objects.equals(this.size, o.size);
359        }
360        
361        /** Generates a Hash-Code for {@code 'this'} instance */
362        public int hashCode()
363        {
364            return
365                    Objects.hashCode(this.name)
366                +   Objects.hashCode(this.uuid)
367                +   Objects.hashCode(this.baseAddress)
368                +   Objects.hashCode(this.size);
369        }
370    }
371    
372    
373    // Counter for keeping the WebSocket Request ID's distinct.
374    private static int counter = 1;
375    
376    /**
377     * <CODE>[No Description Provided by Google]</CODE>
378     * 
379     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
380     * {@link Ret3}&gt;</CODE>
381     *
382     * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 
383     * {@link Script#exec()}), and a {@link Promise} returned.
384     *
385     * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B>
386     * (using {@link Promise#await()}), the {@code Ret3} will subsequently
387     * be returned from that call.
388     * 
389     * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated
390     * in an instance of <B>{@link Ret3}</B>
391     *
392     * <BR /><BR /><UL CLASS=JDUL>
393     * <LI><CODE><B>Ret3.a:</B> Integer (<B>documents</B>)</CODE>
394     *     <BR />-
395     *     <BR /><BR /></LI>
396     * <LI><CODE><B>Ret3.b:</B> Integer (<B>nodes</B>)</CODE>
397     *     <BR />-
398     *     <BR /><BR /></LI>
399     * <LI><CODE><B>Ret3.c:</B> Integer (<B>jsEventListeners</B>)</CODE>
400     *     <BR />-
401     *     </LI>
402     * </UL>
403     */
404    public static Script<String, JsonObject, Ret3<Integer, Integer, Integer>> getDOMCounters()
405    {
406        final int          webSocketID = 29000000 + counter++;
407        final boolean[]    optionals   = new boolean[0];
408        
409        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
410        String requestJSON = WriteJSON.get(
411            parameterTypes.get("getDOMCounters"),
412            parameterNames.get("getDOMCounters"),
413            optionals, webSocketID,
414            "Memory.getDOMCounters"
415        );
416        
417        // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret3'
418        Function<JsonObject, Ret3<Integer, Integer, Integer>> 
419            responseProcessor = (JsonObject jo) -> new Ret3<>(
420                ReadBoxedJSON.getInteger(jo, "documents", true),
421                ReadBoxedJSON.getInteger(jo, "nodes", true),
422                ReadBoxedJSON.getInteger(jo, "jsEventListeners", true)
423            );
424        
425        return new Script<>(webSocketID, requestJSON, responseProcessor);
426    }
427    
428    /**
429     * <CODE>[No Description Provided by Google]</CODE>
430     * 
431     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
432     * {@link Ret0}&gt;</CODE>
433     *
434     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
435     * browser receives the invocation-request.
436     *
437     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
438     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
439     * {@code >} to ensure the Browser Function has run to completion.
440     */
441    public static Script<String, JsonObject, Ret0> prepareForLeakDetection()
442    {
443        final int          webSocketID = 29001000 + counter++;
444        final boolean[]    optionals   = new boolean[0];
445        
446        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
447        String requestJSON = WriteJSON.get(
448            parameterTypes.get("prepareForLeakDetection"),
449            parameterNames.get("prepareForLeakDetection"),
450            optionals, webSocketID,
451            "Memory.prepareForLeakDetection"
452        );
453        
454        // This Remote Command does not have a Return-Value.
455        return new Script<>
456            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
457    }
458    
459    /**
460     * Simulate OomIntervention by purging V8 memory.
461     * 
462     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
463     * {@link Ret0}&gt;</CODE>
464     *
465     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
466     * browser receives the invocation-request.
467     *
468     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
469     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
470     * {@code >} to ensure the Browser Function has run to completion.
471     */
472    public static Script<String, JsonObject, Ret0> forciblyPurgeJavaScriptMemory()
473    {
474        final int          webSocketID = 29002000 + counter++;
475        final boolean[]    optionals   = new boolean[0];
476        
477        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
478        String requestJSON = WriteJSON.get(
479            parameterTypes.get("forciblyPurgeJavaScriptMemory"),
480            parameterNames.get("forciblyPurgeJavaScriptMemory"),
481            optionals, webSocketID,
482            "Memory.forciblyPurgeJavaScriptMemory"
483        );
484        
485        // This Remote Command does not have a Return-Value.
486        return new Script<>
487            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
488    }
489    
490    /**
491     * Enable/disable suppressing memory pressure notifications in all processes.
492     * 
493     * @param suppressed If true, memory pressure notifications will be suppressed.
494     * 
495     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
496     * {@link Ret0}&gt;</CODE>
497     *
498     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
499     * browser receives the invocation-request.
500     *
501     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
502     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
503     * {@code >} to ensure the Browser Function has run to completion.
504     */
505    public static Script<String, JsonObject, Ret0> setPressureNotificationsSuppressed
506        (boolean suppressed)
507    {
508        final int       webSocketID = 29003000 + counter++;
509        final boolean[] optionals   = { false, };
510        
511        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
512        String requestJSON = WriteJSON.get(
513            parameterTypes.get("setPressureNotificationsSuppressed"),
514            parameterNames.get("setPressureNotificationsSuppressed"),
515            optionals, webSocketID,
516            "Memory.setPressureNotificationsSuppressed",
517            suppressed
518        );
519        
520        // This Remote Command does not have a Return-Value.
521        return new Script<>
522            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
523    }
524    
525    /**
526     * Simulate a memory pressure notification in all processes.
527     * 
528     * @param level Memory pressure level of the notification.
529     * 
530     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
531     * {@link Ret0}&gt;</CODE>
532     *
533     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
534     * browser receives the invocation-request.
535     *
536     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
537     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
538     * {@code >} to ensure the Browser Function has run to completion.
539     */
540    public static Script<String, JsonObject, Ret0> simulatePressureNotification(String level)
541    {
542        // Exception-Check(s) to ensure that if any parameters which are not declared as
543        // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw.
544        
545        if (level == null) THROWS.throwNPE("level");
546        
547        // Exception-Check(s) to ensure that if any parameters which must adhere to a
548        // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw.
549        
550        THROWS.checkIAE("level", level, "Memory.PressureLevel", Memory.PressureLevel);
551        
552        final int       webSocketID = 29004000 + counter++;
553        final boolean[] optionals   = { false, };
554        
555        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
556        String requestJSON = WriteJSON.get(
557            parameterTypes.get("simulatePressureNotification"),
558            parameterNames.get("simulatePressureNotification"),
559            optionals, webSocketID,
560            "Memory.simulatePressureNotification",
561            level
562        );
563        
564        // This Remote Command does not have a Return-Value.
565        return new Script<>
566            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
567    }
568    
569    /**
570     * Start collecting native memory profile.
571     * 
572     * @param samplingInterval Average number of bytes between samples.
573     * <BR /><B>OPTIONAL</B>
574     * 
575     * @param suppressRandomness Do not randomize intervals between samples.
576     * <BR /><B>OPTIONAL</B>
577     * 
578     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
579     * {@link Ret0}&gt;</CODE>
580     *
581     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
582     * browser receives the invocation-request.
583     *
584     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
585     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
586     * {@code >} to ensure the Browser Function has run to completion.
587     */
588    public static Script<String, JsonObject, Ret0> startSampling
589        (Integer samplingInterval, Boolean suppressRandomness)
590    {
591        final int       webSocketID = 29005000 + counter++;
592        final boolean[] optionals   = { true, true, };
593        
594        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
595        String requestJSON = WriteJSON.get(
596            parameterTypes.get("startSampling"),
597            parameterNames.get("startSampling"),
598            optionals, webSocketID,
599            "Memory.startSampling",
600            samplingInterval, suppressRandomness
601        );
602        
603        // This Remote Command does not have a Return-Value.
604        return new Script<>
605            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
606    }
607    
608    /**
609     * Stop collecting native memory profile.
610     * 
611     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
612     * {@link Ret0}&gt;</CODE>
613     *
614     * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the
615     * browser receives the invocation-request.
616     *
617     * <BR /><BR />This Browser-Function <I>does not have</I> a return-value.  You may choose to
618     * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0}
619     * {@code >} to ensure the Browser Function has run to completion.
620     */
621    public static Script<String, JsonObject, Ret0> stopSampling()
622    {
623        final int          webSocketID = 29006000 + counter++;
624        final boolean[]    optionals   = new boolean[0];
625        
626        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
627        String requestJSON = WriteJSON.get(
628            parameterTypes.get("stopSampling"),
629            parameterNames.get("stopSampling"),
630            optionals, webSocketID,
631            "Memory.stopSampling"
632        );
633        
634        // This Remote Command does not have a Return-Value.
635        return new Script<>
636            (webSocketID, requestJSON, VOID_RETURN.NoReturnValues);
637    }
638    
639    /**
640     * Retrieve native memory allocations profile
641     * collected since renderer process startup.
642     * 
643     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
644     * {@link Memory.SamplingProfile}&gt;</CODE>
645     * 
646     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
647     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
648     * {@link Memory.SamplingProfile}&gt;</CODE> will be returned.
649     *
650     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
651     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
652      * may be retrieved.</I>
653     *
654     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
655     * <BR /><BR /><UL CLASS=JDUL>
656     * <LI><CODE>{@link Memory.SamplingProfile} (<B>profile</B></CODE>)
657     *     <BR />-
658     * </LI>
659     * </UL> */
660    public static Script<String, JsonObject, Memory.SamplingProfile> getAllTimeSamplingProfile()
661    {
662        final int          webSocketID = 29007000 + counter++;
663        final boolean[]    optionals   = new boolean[0];
664        
665        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
666        String requestJSON = WriteJSON.get(
667            parameterTypes.get("getAllTimeSamplingProfile"),
668            parameterNames.get("getAllTimeSamplingProfile"),
669            optionals, webSocketID,
670            "Memory.getAllTimeSamplingProfile"
671        );
672        
673        // 'JSON Binding' ... Converts Browser Response-JSON to 'Memory.SamplingProfile'
674        Function<JsonObject, Memory.SamplingProfile> responseProcessor = (JsonObject jo) ->
675            ReadJSON.getObject(jo, "profile", Memory.SamplingProfile.class, false, true);
676        
677        return new Script<>(webSocketID, requestJSON, responseProcessor);
678    }
679    
680    /**
681     * Retrieve native memory allocations profile
682     * collected since browser process startup.
683     * 
684     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
685     * {@link Memory.SamplingProfile}&gt;</CODE>
686     * 
687     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
688     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
689     * {@link Memory.SamplingProfile}&gt;</CODE> will be returned.
690     *
691     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
692     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
693      * may be retrieved.</I>
694     *
695     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
696     * <BR /><BR /><UL CLASS=JDUL>
697     * <LI><CODE>{@link Memory.SamplingProfile} (<B>profile</B></CODE>)
698     *     <BR />-
699     * </LI>
700     * </UL> */
701    public static Script<String, JsonObject, Memory.SamplingProfile> getBrowserSamplingProfile()
702    {
703        final int          webSocketID = 29008000 + counter++;
704        final boolean[]    optionals   = new boolean[0];
705        
706        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
707        String requestJSON = WriteJSON.get(
708            parameterTypes.get("getBrowserSamplingProfile"),
709            parameterNames.get("getBrowserSamplingProfile"),
710            optionals, webSocketID,
711            "Memory.getBrowserSamplingProfile"
712        );
713        
714        // 'JSON Binding' ... Converts Browser Response-JSON to 'Memory.SamplingProfile'
715        Function<JsonObject, Memory.SamplingProfile> responseProcessor = (JsonObject jo) ->
716            ReadJSON.getObject(jo, "profile", Memory.SamplingProfile.class, false, true);
717        
718        return new Script<>(webSocketID, requestJSON, responseProcessor);
719    }
720    
721    /**
722     * Retrieve native memory allocations profile collected since last
723     * <CODE>startSampling</CODE> call.
724     * 
725     * @return An instance of <CODE>{@link Script}&lt;String, {@link JsonObject},
726     * {@link Memory.SamplingProfile}&gt;</CODE>
727     * 
728     * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using
729     * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE>&lt;JsonObject,
730     * {@link Memory.SamplingProfile}&gt;</CODE> will be returned.
731     *
732     * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>,
733     * using {@link Promise#await()}, <I>and the returned result of this Browser Function may
734      * may be retrieved.</I>
735     *
736     * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B>
737     * <BR /><BR /><UL CLASS=JDUL>
738     * <LI><CODE>{@link Memory.SamplingProfile} (<B>profile</B></CODE>)
739     *     <BR />-
740     * </LI>
741     * </UL> */
742    public static Script<String, JsonObject, Memory.SamplingProfile> getSamplingProfile()
743    {
744        final int          webSocketID = 29009000 + counter++;
745        final boolean[]    optionals   = new boolean[0];
746        
747        // Convert Method Parameters into JSON.  Build the JSON Request-Object (as a String)
748        String requestJSON = WriteJSON.get(
749            parameterTypes.get("getSamplingProfile"),
750            parameterNames.get("getSamplingProfile"),
751            optionals, webSocketID,
752            "Memory.getSamplingProfile"
753        );
754        
755        // 'JSON Binding' ... Converts Browser Response-JSON to 'Memory.SamplingProfile'
756        Function<JsonObject, Memory.SamplingProfile> responseProcessor = (JsonObject jo) ->
757            ReadJSON.getObject(jo, "profile", Memory.SamplingProfile.class, false, true);
758        
759        return new Script<>(webSocketID, requestJSON, responseProcessor);
760    }
761    
762}