001package Torello.Browser.JavaScriptAPI; 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.Browser.BrowserEvent; 013import Torello.Browser.BrowserAPI.*; 014import Torello.Browser.helper.*; 015 016import Torello.Java.Additional.*; 017import Torello.Java.JSON.*; 018 019import static Torello.Java.JSON.JFlag.*; 020 021import Torello.Java.StrCmpr; 022import Torello.JavaDoc.StaticFunctional; 023import Torello.JavaDoc.JDHeaderBackgroundImg; 024import Torello.JavaDoc.Excuse; 025 026/** 027 * <SPAN CLASS=COPIEDJDK><B><CODE>[No Description Provided by Google]</CODE></B></SPAN> 028 * 029 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE> 030 */ 031@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION}) 032@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE") 033public class Profiler 034{ 035 // ******************************************************************************************** 036 // ******************************************************************************************** 037 // Class Header Stuff 038 // ******************************************************************************************** 039 // ******************************************************************************************** 040 041 042 // No Pubic Constructors 043 private Profiler () { } 044 045 // These two Vector's are used by all the "Methods" exported by this class. java.lang.reflect 046 // is used to generate the JSON String's. It saves thousands of lines of Auto-Generated Code. 047 private static final Map<String, Vector<String>> parameterNames = new HashMap<>(); 048 private static final Map<String, Vector<Class<?>>> parameterTypes = new HashMap<>(); 049 050 // Some Methods do not take any parameters - for instance all the "enable()" and "disable()" 051 // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now, 052 // offically, two empty-vectors. One for String's, and the other for Classes. 053 054 private static final Vector<String> EMPTY_VEC_STR = new Vector<>(); 055 private static final Vector<Class<?>> EMPTY_VEC_CLASS = new Vector<>(); 056 057 static 058 { 059 for (Method m : Profiler.class.getMethods()) 060 { 061 // This doesn't work! The parameter names are all "arg0" ... "argN" 062 // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter! 063 // 064 // Vector<String> parameterNamesList = new Vector<>(); -- NOPE! 065 066 Vector<Class<?>> parameterTypesList = new Vector<>(); 067 068 for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType()); 069 070 parameterTypes.put( 071 m.getName(), 072 (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS 073 ); 074 } 075 } 076 077 static 078 { 079 Vector<String> v = null; 080 081 parameterNames.put("disable", EMPTY_VEC_STR); 082 083 parameterNames.put("enable", EMPTY_VEC_STR); 084 085 parameterNames.put("getBestEffortCoverage", EMPTY_VEC_STR); 086 087 v = new Vector<String>(1); 088 parameterNames.put("setSamplingInterval", v); 089 Collections.addAll(v, new String[] 090 { "interval", }); 091 092 parameterNames.put("start", EMPTY_VEC_STR); 093 094 v = new Vector<String>(3); 095 parameterNames.put("startPreciseCoverage", v); 096 Collections.addAll(v, new String[] 097 { "callCount", "detailed", "allowTriggeredUpdates", }); 098 099 parameterNames.put("stop", EMPTY_VEC_STR); 100 101 parameterNames.put("stopPreciseCoverage", EMPTY_VEC_STR); 102 103 parameterNames.put("takePreciseCoverage", EMPTY_VEC_STR); 104 } 105 106 107 // ******************************************************************************************** 108 // ******************************************************************************************** 109 // Types - Static Inner Classes 110 // ******************************************************************************************** 111 // ******************************************************************************************** 112 113 /** Profile node. Holds callsite information, execution statistics and child nodes. */ 114 public static class ProfileNode 115 extends BaseType 116 implements java.io.Serializable 117 { 118 /** For Object Serialization. java.io.Serializable */ 119 protected static final long serialVersionUID = 1; 120 121 public boolean[] optionals() 122 { return new boolean[] { false, false, true, true, true, true, }; } 123 124 /** Unique id of the node. */ 125 public final int id; 126 127 /** Function location. */ 128 public final RunTime.CallFrame callFrame; 129 130 /** 131 * Number of samples where this node was on top of the call stack. 132 * <BR /><B CLASS=Opt>OPTIONAL</B> 133 */ 134 public final Integer hitCount; 135 136 /** 137 * Child node ids. 138 * <BR /><B CLASS=Opt>OPTIONAL</B> 139 */ 140 public final int[] children; 141 142 /** 143 * The reason of being not optimized. The function may be deoptimized or marked as don't 144 * optimize. 145 * <BR /><B CLASS=Opt>OPTIONAL</B> 146 */ 147 public final String deoptReason; 148 149 /** 150 * An array of source position ticks. 151 * <BR /><B CLASS=Opt>OPTIONAL</B> 152 */ 153 public final Profiler.PositionTickInfo[] positionTicks; 154 155 /** 156 * Constructor 157 * 158 * @param id Unique id of the node. 159 * 160 * @param callFrame Function location. 161 * 162 * @param hitCount Number of samples where this node was on top of the call stack. 163 * <BR /><B CLASS=Opt>OPTIONAL</B> 164 * 165 * @param children Child node ids. 166 * <BR /><B CLASS=Opt>OPTIONAL</B> 167 * 168 * @param deoptReason 169 * The reason of being not optimized. The function may be deoptimized or marked as don't 170 * optimize. 171 * <BR /><B CLASS=Opt>OPTIONAL</B> 172 * 173 * @param positionTicks An array of source position ticks. 174 * <BR /><B CLASS=Opt>OPTIONAL</B> 175 */ 176 public ProfileNode( 177 int id, RunTime.CallFrame callFrame, Integer hitCount, int[] children, 178 String deoptReason, Profiler.PositionTickInfo[] positionTicks 179 ) 180 { 181 // Exception-Check(s) to ensure that if any parameters which are not declared as 182 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 183 184 if (callFrame == null) THROWS.throwNPE("callFrame"); 185 186 this.id = id; 187 this.callFrame = callFrame; 188 this.hitCount = hitCount; 189 this.children = children; 190 this.deoptReason = deoptReason; 191 this.positionTicks = positionTicks; 192 } 193 194 /** 195 * JSON Object Constructor 196 * @param jo A Json-Object having data about an instance of {@code 'ProfileNode'}. 197 */ 198 public ProfileNode (JsonObject jo) 199 { 200 this.id = ReadPrimJSON.getInt(jo, "id"); 201 this.callFrame = ReadJSON.getObject(jo, "callFrame", RunTime.CallFrame.class, false, true); 202 this.hitCount = ReadBoxedJSON.getInteger(jo, "hitCount", true); 203 this.children = (jo.getJsonArray("children") == null) 204 ? null 205 : RJArrIntoPrimArray.intArr(jo.getJsonArray("children"), -1, 0, null); 206 207 this.deoptReason = ReadJSON.getString(jo, "deoptReason", true, false); 208 this.positionTicks = (jo.getJsonArray("positionTicks") == null) 209 ? null 210 : RJArrIntoStream.objArr(jo.getJsonArray("positionTicks"), null, 0, Profiler.PositionTickInfo.class).toArray(Profiler.PositionTickInfo[]::new); 211 212 } 213 214 215 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 216 public boolean equals(Object other) 217 { 218 if (this == other) return true; 219 if (other == null) return false; 220 if (other.getClass() != this.getClass()) return false; 221 222 ProfileNode o = (ProfileNode) other; 223 224 return 225 (this.id == o.id) 226 && Objects.equals(this.callFrame, o.callFrame) 227 && Objects.equals(this.hitCount, o.hitCount) 228 && Arrays.equals(this.children, o.children) 229 && Objects.equals(this.deoptReason, o.deoptReason) 230 && Arrays.deepEquals(this.positionTicks, o.positionTicks); 231 } 232 233 /** Generates a Hash-Code for {@code 'this'} instance */ 234 public int hashCode() 235 { 236 return 237 this.id 238 + this.callFrame.hashCode() 239 + Objects.hashCode(this.hitCount) 240 + Arrays.hashCode(this.children) 241 + Objects.hashCode(this.deoptReason) 242 + Arrays.deepHashCode(this.positionTicks); 243 } 244 } 245 246 /** Profile. */ 247 public static class Profile 248 extends BaseType 249 implements java.io.Serializable 250 { 251 /** For Object Serialization. java.io.Serializable */ 252 protected static final long serialVersionUID = 1; 253 254 public boolean[] optionals() 255 { return new boolean[] { false, false, false, true, true, }; } 256 257 /** The list of profile nodes. First item is the root node. */ 258 public final Profiler.ProfileNode[] nodes; 259 260 /** Profiling start timestamp in microseconds. */ 261 public final Number startTime; 262 263 /** Profiling end timestamp in microseconds. */ 264 public final Number endTime; 265 266 /** 267 * Ids of samples top nodes. 268 * <BR /><B CLASS=Opt>OPTIONAL</B> 269 */ 270 public final int[] samples; 271 272 /** 273 * Time intervals between adjacent samples in microseconds. The first delta is relative to the 274 * profile startTime. 275 * <BR /><B CLASS=Opt>OPTIONAL</B> 276 */ 277 public final int[] timeDeltas; 278 279 /** 280 * Constructor 281 * 282 * @param nodes The list of profile nodes. First item is the root node. 283 * 284 * @param startTime Profiling start timestamp in microseconds. 285 * 286 * @param endTime Profiling end timestamp in microseconds. 287 * 288 * @param samples Ids of samples top nodes. 289 * <BR /><B CLASS=Opt>OPTIONAL</B> 290 * 291 * @param timeDeltas 292 * Time intervals between adjacent samples in microseconds. The first delta is relative to the 293 * profile startTime. 294 * <BR /><B CLASS=Opt>OPTIONAL</B> 295 */ 296 public Profile( 297 Profiler.ProfileNode[] nodes, Number startTime, Number endTime, int[] samples, 298 int[] timeDeltas 299 ) 300 { 301 // Exception-Check(s) to ensure that if any parameters which are not declared as 302 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 303 304 if (nodes == null) THROWS.throwNPE("nodes"); 305 if (startTime == null) THROWS.throwNPE("startTime"); 306 if (endTime == null) THROWS.throwNPE("endTime"); 307 308 this.nodes = nodes; 309 this.startTime = startTime; 310 this.endTime = endTime; 311 this.samples = samples; 312 this.timeDeltas = timeDeltas; 313 } 314 315 /** 316 * JSON Object Constructor 317 * @param jo A Json-Object having data about an instance of {@code 'Profile'}. 318 */ 319 public Profile (JsonObject jo) 320 { 321 this.nodes = (jo.getJsonArray("nodes") == null) 322 ? null 323 : RJArrIntoStream.objArr(jo.getJsonArray("nodes"), null, 0, Profiler.ProfileNode.class).toArray(Profiler.ProfileNode[]::new); 324 325 this.startTime = ReadNumberJSON.get(jo, "startTime", false, true); 326 this.endTime = ReadNumberJSON.get(jo, "endTime", false, true); 327 this.samples = (jo.getJsonArray("samples") == null) 328 ? null 329 : RJArrIntoPrimArray.intArr(jo.getJsonArray("samples"), -1, 0, null); 330 331 this.timeDeltas = (jo.getJsonArray("timeDeltas") == null) 332 ? null 333 : RJArrIntoPrimArray.intArr(jo.getJsonArray("timeDeltas"), -1, 0, null); 334 335 } 336 337 338 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 339 public boolean equals(Object other) 340 { 341 if (this == other) return true; 342 if (other == null) return false; 343 if (other.getClass() != this.getClass()) return false; 344 345 Profile o = (Profile) other; 346 347 return 348 Arrays.deepEquals(this.nodes, o.nodes) 349 && Objects.equals(this.startTime, o.startTime) 350 && Objects.equals(this.endTime, o.endTime) 351 && Arrays.equals(this.samples, o.samples) 352 && Arrays.equals(this.timeDeltas, o.timeDeltas); 353 } 354 355 /** Generates a Hash-Code for {@code 'this'} instance */ 356 public int hashCode() 357 { 358 return 359 Arrays.deepHashCode(this.nodes) 360 + Objects.hashCode(this.startTime) 361 + Objects.hashCode(this.endTime) 362 + Arrays.hashCode(this.samples) 363 + Arrays.hashCode(this.timeDeltas); 364 } 365 } 366 367 /** Specifies a number of samples attributed to a certain source position. */ 368 public static class PositionTickInfo 369 extends BaseType 370 implements java.io.Serializable 371 { 372 /** For Object Serialization. java.io.Serializable */ 373 protected static final long serialVersionUID = 1; 374 375 public boolean[] optionals() 376 { return new boolean[] { false, false, }; } 377 378 /** Source line number (1-based). */ 379 public final int line; 380 381 /** Number of samples attributed to the source line. */ 382 public final int ticks; 383 384 /** 385 * Constructor 386 * 387 * @param line Source line number (1-based). 388 * 389 * @param ticks Number of samples attributed to the source line. 390 */ 391 public PositionTickInfo(int line, int ticks) 392 { 393 this.line = line; 394 this.ticks = ticks; 395 } 396 397 /** 398 * JSON Object Constructor 399 * @param jo A Json-Object having data about an instance of {@code 'PositionTickInfo'}. 400 */ 401 public PositionTickInfo (JsonObject jo) 402 { 403 this.line = ReadPrimJSON.getInt(jo, "line"); 404 this.ticks = ReadPrimJSON.getInt(jo, "ticks"); 405 } 406 407 408 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 409 public boolean equals(Object other) 410 { 411 if (this == other) return true; 412 if (other == null) return false; 413 if (other.getClass() != this.getClass()) return false; 414 415 PositionTickInfo o = (PositionTickInfo) other; 416 417 return 418 (this.line == o.line) 419 && (this.ticks == o.ticks); 420 } 421 422 /** Generates a Hash-Code for {@code 'this'} instance */ 423 public int hashCode() 424 { 425 return 426 this.line 427 + this.ticks; 428 } 429 } 430 431 /** Coverage data for a source range. */ 432 public static class CoverageRange 433 extends BaseType 434 implements java.io.Serializable 435 { 436 /** For Object Serialization. java.io.Serializable */ 437 protected static final long serialVersionUID = 1; 438 439 public boolean[] optionals() 440 { return new boolean[] { false, false, false, }; } 441 442 /** JavaScript script source offset for the range start. */ 443 public final int startOffset; 444 445 /** JavaScript script source offset for the range end. */ 446 public final int endOffset; 447 448 /** Collected execution count of the source range. */ 449 public final int count; 450 451 /** 452 * Constructor 453 * 454 * @param startOffset JavaScript script source offset for the range start. 455 * 456 * @param endOffset JavaScript script source offset for the range end. 457 * 458 * @param count Collected execution count of the source range. 459 */ 460 public CoverageRange(int startOffset, int endOffset, int count) 461 { 462 this.startOffset = startOffset; 463 this.endOffset = endOffset; 464 this.count = count; 465 } 466 467 /** 468 * JSON Object Constructor 469 * @param jo A Json-Object having data about an instance of {@code 'CoverageRange'}. 470 */ 471 public CoverageRange (JsonObject jo) 472 { 473 this.startOffset = ReadPrimJSON.getInt(jo, "startOffset"); 474 this.endOffset = ReadPrimJSON.getInt(jo, "endOffset"); 475 this.count = ReadPrimJSON.getInt(jo, "count"); 476 } 477 478 479 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 480 public boolean equals(Object other) 481 { 482 if (this == other) return true; 483 if (other == null) return false; 484 if (other.getClass() != this.getClass()) return false; 485 486 CoverageRange o = (CoverageRange) other; 487 488 return 489 (this.startOffset == o.startOffset) 490 && (this.endOffset == o.endOffset) 491 && (this.count == o.count); 492 } 493 494 /** Generates a Hash-Code for {@code 'this'} instance */ 495 public int hashCode() 496 { 497 return 498 this.startOffset 499 + this.endOffset 500 + this.count; 501 } 502 } 503 504 /** Coverage data for a JavaScript function. */ 505 public static class FunctionCoverage 506 extends BaseType 507 implements java.io.Serializable 508 { 509 /** For Object Serialization. java.io.Serializable */ 510 protected static final long serialVersionUID = 1; 511 512 public boolean[] optionals() 513 { return new boolean[] { false, false, false, }; } 514 515 /** JavaScript function name. */ 516 public final String functionName; 517 518 /** Source ranges inside the function with coverage data. */ 519 public final Profiler.CoverageRange[] ranges; 520 521 /** Whether coverage data for this function has block granularity. */ 522 public final boolean isBlockCoverage; 523 524 /** 525 * Constructor 526 * 527 * @param functionName JavaScript function name. 528 * 529 * @param ranges Source ranges inside the function with coverage data. 530 * 531 * @param isBlockCoverage Whether coverage data for this function has block granularity. 532 */ 533 public FunctionCoverage 534 (String functionName, Profiler.CoverageRange[] ranges, boolean isBlockCoverage) 535 { 536 // Exception-Check(s) to ensure that if any parameters which are not declared as 537 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 538 539 if (functionName == null) THROWS.throwNPE("functionName"); 540 if (ranges == null) THROWS.throwNPE("ranges"); 541 542 this.functionName = functionName; 543 this.ranges = ranges; 544 this.isBlockCoverage = isBlockCoverage; 545 } 546 547 /** 548 * JSON Object Constructor 549 * @param jo A Json-Object having data about an instance of {@code 'FunctionCoverage'}. 550 */ 551 public FunctionCoverage (JsonObject jo) 552 { 553 this.functionName = ReadJSON.getString(jo, "functionName", false, true); 554 this.ranges = (jo.getJsonArray("ranges") == null) 555 ? null 556 : RJArrIntoStream.objArr(jo.getJsonArray("ranges"), null, 0, Profiler.CoverageRange.class).toArray(Profiler.CoverageRange[]::new); 557 558 this.isBlockCoverage = ReadPrimJSON.getBoolean(jo, "isBlockCoverage"); 559 } 560 561 562 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 563 public boolean equals(Object other) 564 { 565 if (this == other) return true; 566 if (other == null) return false; 567 if (other.getClass() != this.getClass()) return false; 568 569 FunctionCoverage o = (FunctionCoverage) other; 570 571 return 572 Objects.equals(this.functionName, o.functionName) 573 && Arrays.deepEquals(this.ranges, o.ranges) 574 && (this.isBlockCoverage == o.isBlockCoverage); 575 } 576 577 /** Generates a Hash-Code for {@code 'this'} instance */ 578 public int hashCode() 579 { 580 return 581 Objects.hashCode(this.functionName) 582 + Arrays.deepHashCode(this.ranges) 583 + (this.isBlockCoverage ? 1 : 0); 584 } 585 } 586 587 /** Coverage data for a JavaScript script. */ 588 public static class ScriptCoverage 589 extends BaseType 590 implements java.io.Serializable 591 { 592 /** For Object Serialization. java.io.Serializable */ 593 protected static final long serialVersionUID = 1; 594 595 public boolean[] optionals() 596 { return new boolean[] { false, false, false, }; } 597 598 /** JavaScript script id. */ 599 public final String scriptId; 600 601 /** JavaScript script name or url. */ 602 public final String url; 603 604 /** Functions contained in the script that has coverage data. */ 605 public final Profiler.FunctionCoverage[] functions; 606 607 /** 608 * Constructor 609 * 610 * @param scriptId JavaScript script id. 611 * 612 * @param url JavaScript script name or url. 613 * 614 * @param functions Functions contained in the script that has coverage data. 615 */ 616 public ScriptCoverage 617 (String scriptId, String url, Profiler.FunctionCoverage[] functions) 618 { 619 // Exception-Check(s) to ensure that if any parameters which are not declared as 620 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 621 622 if (scriptId == null) THROWS.throwNPE("scriptId"); 623 if (url == null) THROWS.throwNPE("url"); 624 if (functions == null) THROWS.throwNPE("functions"); 625 626 this.scriptId = scriptId; 627 this.url = url; 628 this.functions = functions; 629 } 630 631 /** 632 * JSON Object Constructor 633 * @param jo A Json-Object having data about an instance of {@code 'ScriptCoverage'}. 634 */ 635 public ScriptCoverage (JsonObject jo) 636 { 637 this.scriptId = ReadJSON.getString(jo, "scriptId", false, true); 638 this.url = ReadJSON.getString(jo, "url", false, true); 639 this.functions = (jo.getJsonArray("functions") == null) 640 ? null 641 : RJArrIntoStream.objArr(jo.getJsonArray("functions"), null, 0, Profiler.FunctionCoverage.class).toArray(Profiler.FunctionCoverage[]::new); 642 643 } 644 645 646 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 647 public boolean equals(Object other) 648 { 649 if (this == other) return true; 650 if (other == null) return false; 651 if (other.getClass() != this.getClass()) return false; 652 653 ScriptCoverage o = (ScriptCoverage) other; 654 655 return 656 Objects.equals(this.scriptId, o.scriptId) 657 && Objects.equals(this.url, o.url) 658 && Arrays.deepEquals(this.functions, o.functions); 659 } 660 661 /** Generates a Hash-Code for {@code 'this'} instance */ 662 public int hashCode() 663 { 664 return 665 Objects.hashCode(this.scriptId) 666 + Objects.hashCode(this.url) 667 + Arrays.deepHashCode(this.functions); 668 } 669 } 670 671 /** <CODE>[No Description Provided by Google]</CODE> */ 672 public static class consoleProfileFinished 673 extends BrowserEvent 674 implements java.io.Serializable 675 { 676 /** For Object Serialization. java.io.Serializable */ 677 protected static final long serialVersionUID = 1; 678 679 public boolean[] optionals() 680 { return new boolean[] { false, false, false, true, }; } 681 682 /** <CODE>[No Description Provided by Google]</CODE> */ 683 public final String id; 684 685 /** Location of console.profileEnd(). */ 686 public final Debugger.Location location; 687 688 /** <CODE>[No Description Provided by Google]</CODE> */ 689 public final Profiler.Profile profile; 690 691 /** 692 * Profile title passed as an argument to console.profile(). 693 * <BR /><B CLASS=Opt>OPTIONAL</B> 694 */ 695 public final String title; 696 697 /** 698 * Constructor 699 * 700 * @param id - 701 * 702 * @param location Location of console.profileEnd(). 703 * 704 * @param profile - 705 * 706 * @param title Profile title passed as an argument to console.profile(). 707 * <BR /><B CLASS=Opt>OPTIONAL</B> 708 */ 709 public consoleProfileFinished 710 (String id, Debugger.Location location, Profiler.Profile profile, String title) 711 { 712 super("Profiler", "consoleProfileFinished", 4); 713 714 // Exception-Check(s) to ensure that if any parameters which are not declared as 715 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 716 717 if (id == null) THROWS.throwNPE("id"); 718 if (location == null) THROWS.throwNPE("location"); 719 if (profile == null) THROWS.throwNPE("profile"); 720 721 this.id = id; 722 this.location = location; 723 this.profile = profile; 724 this.title = title; 725 } 726 727 /** 728 * JSON Object Constructor 729 * @param jo A Json-Object having data about an instance of {@code 'consoleProfileFinished'}. 730 */ 731 public consoleProfileFinished (JsonObject jo) 732 { 733 super("Profiler", "consoleProfileFinished", 4); 734 735 this.id = ReadJSON.getString(jo, "id", false, true); 736 this.location = ReadJSON.getObject(jo, "location", Debugger.Location.class, false, true); 737 this.profile = ReadJSON.getObject(jo, "profile", Profiler.Profile.class, false, true); 738 this.title = ReadJSON.getString(jo, "title", true, false); 739 } 740 741 742 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 743 public boolean equals(Object other) 744 { 745 if (this == other) return true; 746 if (other == null) return false; 747 if (other.getClass() != this.getClass()) return false; 748 749 consoleProfileFinished o = (consoleProfileFinished) other; 750 751 return 752 Objects.equals(this.id, o.id) 753 && Objects.equals(this.location, o.location) 754 && Objects.equals(this.profile, o.profile) 755 && Objects.equals(this.title, o.title); 756 } 757 758 /** Generates a Hash-Code for {@code 'this'} instance */ 759 public int hashCode() 760 { 761 return 762 Objects.hashCode(this.id) 763 + this.location.hashCode() 764 + this.profile.hashCode() 765 + Objects.hashCode(this.title); 766 } 767 } 768 769 /** Sent when new profile recording is started using console.profile() call. */ 770 public static class consoleProfileStarted 771 extends BrowserEvent 772 implements java.io.Serializable 773 { 774 /** For Object Serialization. java.io.Serializable */ 775 protected static final long serialVersionUID = 1; 776 777 public boolean[] optionals() 778 { return new boolean[] { false, false, true, }; } 779 780 /** <CODE>[No Description Provided by Google]</CODE> */ 781 public final String id; 782 783 /** Location of console.profile(). */ 784 public final Debugger.Location location; 785 786 /** 787 * Profile title passed as an argument to console.profile(). 788 * <BR /><B CLASS=Opt>OPTIONAL</B> 789 */ 790 public final String title; 791 792 /** 793 * Constructor 794 * 795 * @param id - 796 * 797 * @param location Location of console.profile(). 798 * 799 * @param title Profile title passed as an argument to console.profile(). 800 * <BR /><B CLASS=Opt>OPTIONAL</B> 801 */ 802 public consoleProfileStarted(String id, Debugger.Location location, String title) 803 { 804 super("Profiler", "consoleProfileStarted", 3); 805 806 // Exception-Check(s) to ensure that if any parameters which are not declared as 807 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 808 809 if (id == null) THROWS.throwNPE("id"); 810 if (location == null) THROWS.throwNPE("location"); 811 812 this.id = id; 813 this.location = location; 814 this.title = title; 815 } 816 817 /** 818 * JSON Object Constructor 819 * @param jo A Json-Object having data about an instance of {@code 'consoleProfileStarted'}. 820 */ 821 public consoleProfileStarted (JsonObject jo) 822 { 823 super("Profiler", "consoleProfileStarted", 3); 824 825 this.id = ReadJSON.getString(jo, "id", false, true); 826 this.location = ReadJSON.getObject(jo, "location", Debugger.Location.class, false, true); 827 this.title = ReadJSON.getString(jo, "title", true, false); 828 } 829 830 831 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 832 public boolean equals(Object other) 833 { 834 if (this == other) return true; 835 if (other == null) return false; 836 if (other.getClass() != this.getClass()) return false; 837 838 consoleProfileStarted o = (consoleProfileStarted) other; 839 840 return 841 Objects.equals(this.id, o.id) 842 && Objects.equals(this.location, o.location) 843 && Objects.equals(this.title, o.title); 844 } 845 846 /** Generates a Hash-Code for {@code 'this'} instance */ 847 public int hashCode() 848 { 849 return 850 Objects.hashCode(this.id) 851 + this.location.hashCode() 852 + Objects.hashCode(this.title); 853 } 854 } 855 856 /** 857 * Reports coverage delta since the last poll (either from an event like this, or from 858 * {@code takePreciseCoverage} for the current isolate. May only be sent if precise code 859 * coverage has been started. This event can be trigged by the embedder to, for example, 860 * trigger collection of coverage data immediately at a certain point in time. 861 * <BR /><B CLASS=Exp>EXPERIMENTAL</B> 862 */ 863 public static class preciseCoverageDeltaUpdate 864 extends BrowserEvent 865 implements java.io.Serializable 866 { 867 /** For Object Serialization. java.io.Serializable */ 868 protected static final long serialVersionUID = 1; 869 870 public boolean[] optionals() 871 { return new boolean[] { false, false, false, }; } 872 873 /** Monotonically increasing time (in seconds) when the coverage update was taken in the backend. */ 874 public final Number timestamp; 875 876 /** Identifier for distinguishing coverage events. */ 877 public final String occasion; 878 879 /** Coverage data for the current isolate. */ 880 public final Profiler.ScriptCoverage[] result; 881 882 /** 883 * Constructor 884 * 885 * @param timestamp Monotonically increasing time (in seconds) when the coverage update was taken in the backend. 886 * 887 * @param occasion Identifier for distinguishing coverage events. 888 * 889 * @param result Coverage data for the current isolate. 890 */ 891 public preciseCoverageDeltaUpdate 892 (Number timestamp, String occasion, Profiler.ScriptCoverage[] result) 893 { 894 super("Profiler", "preciseCoverageDeltaUpdate", 3); 895 896 // Exception-Check(s) to ensure that if any parameters which are not declared as 897 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 898 899 if (timestamp == null) THROWS.throwNPE("timestamp"); 900 if (occasion == null) THROWS.throwNPE("occasion"); 901 if (result == null) THROWS.throwNPE("result"); 902 903 this.timestamp = timestamp; 904 this.occasion = occasion; 905 this.result = result; 906 } 907 908 /** 909 * JSON Object Constructor 910 * @param jo A Json-Object having data about an instance of {@code 'preciseCoverageDeltaUpdate'}. 911 */ 912 public preciseCoverageDeltaUpdate (JsonObject jo) 913 { 914 super("Profiler", "preciseCoverageDeltaUpdate", 3); 915 916 this.timestamp = ReadNumberJSON.get(jo, "timestamp", false, true); 917 this.occasion = ReadJSON.getString(jo, "occasion", false, true); 918 this.result = (jo.getJsonArray("result") == null) 919 ? null 920 : RJArrIntoStream.objArr(jo.getJsonArray("result"), null, 0, Profiler.ScriptCoverage.class).toArray(Profiler.ScriptCoverage[]::new); 921 922 } 923 924 925 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 926 public boolean equals(Object other) 927 { 928 if (this == other) return true; 929 if (other == null) return false; 930 if (other.getClass() != this.getClass()) return false; 931 932 preciseCoverageDeltaUpdate o = (preciseCoverageDeltaUpdate) other; 933 934 return 935 Objects.equals(this.timestamp, o.timestamp) 936 && Objects.equals(this.occasion, o.occasion) 937 && Arrays.deepEquals(this.result, o.result); 938 } 939 940 /** Generates a Hash-Code for {@code 'this'} instance */ 941 public int hashCode() 942 { 943 return 944 Objects.hashCode(this.timestamp) 945 + Objects.hashCode(this.occasion) 946 + Arrays.deepHashCode(this.result); 947 } 948 } 949 950 951 // Counter for keeping the WebSocket Request ID's distinct. 952 private static int counter = 1; 953 954 /** 955 * <CODE>[No Description Provided by Google]</CODE> 956 * 957 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 958 * {@link Ret0}></CODE> 959 * 960 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 961 * browser receives the invocation-request. 962 * 963 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 964 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 965 * {@code >} to ensure the Browser Function has run to completion. 966 */ 967 public static Script<String, JsonObject, Ret0> disable() 968 { 969 final int webSocketID = 4000000 + counter++; 970 final boolean[] optionals = new boolean[0]; 971 972 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 973 String requestJSON = WriteJSON.get( 974 parameterTypes.get("disable"), 975 parameterNames.get("disable"), 976 optionals, webSocketID, 977 "Profiler.disable" 978 ); 979 980 // This Remote Command does not have a Return-Value. 981 return new Script<> 982 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 983 } 984 985 /** 986 * <CODE>[No Description Provided by Google]</CODE> 987 * 988 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 989 * {@link Ret0}></CODE> 990 * 991 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 992 * browser receives the invocation-request. 993 * 994 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 995 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 996 * {@code >} to ensure the Browser Function has run to completion. 997 */ 998 public static Script<String, JsonObject, Ret0> enable() 999 { 1000 final int webSocketID = 4001000 + counter++; 1001 final boolean[] optionals = new boolean[0]; 1002 1003 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1004 String requestJSON = WriteJSON.get( 1005 parameterTypes.get("enable"), 1006 parameterNames.get("enable"), 1007 optionals, webSocketID, 1008 "Profiler.enable" 1009 ); 1010 1011 // This Remote Command does not have a Return-Value. 1012 return new Script<> 1013 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1014 } 1015 1016 /** 1017 * Collect coverage data for the current isolate. The coverage data may be incomplete due to 1018 * garbage collection. 1019 * 1020 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1021 * {@link Profiler.ScriptCoverage}[]></CODE> 1022 * 1023 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 1024 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 1025 * {@link Profiler.ScriptCoverage}[]></CODE> will be returned. 1026 * 1027 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 1028 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 1029 * may be retrieved.</I> 1030 * 1031 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 1032 * <BR /><BR /><UL CLASS=JDUL> 1033 * <LI><CODE>{@link Profiler.ScriptCoverage}[] (<B>result</B></CODE>) 1034 * <BR />Coverage data for the current isolate. 1035 * </LI> 1036 * </UL> */ 1037 public static Script<String, JsonObject, Profiler.ScriptCoverage[]> getBestEffortCoverage() 1038 { 1039 final int webSocketID = 4002000 + counter++; 1040 final boolean[] optionals = new boolean[0]; 1041 1042 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1043 String requestJSON = WriteJSON.get( 1044 parameterTypes.get("getBestEffortCoverage"), 1045 parameterNames.get("getBestEffortCoverage"), 1046 optionals, webSocketID, 1047 "Profiler.getBestEffortCoverage" 1048 ); 1049 1050 // 'JSON Binding' ... Converts Browser Response-JSON to 'Profiler.ScriptCoverage[]' 1051 Function<JsonObject, Profiler.ScriptCoverage[]> responseProcessor = (JsonObject jo) -> 1052 (jo.getJsonArray("result") == null) 1053 ? null 1054 : RJArrIntoStream.objArr(jo.getJsonArray("result"), null, 0, Profiler.ScriptCoverage.class).toArray(Profiler.ScriptCoverage[]::new); 1055 1056 return new Script<>(webSocketID, requestJSON, responseProcessor); 1057 } 1058 1059 /** 1060 * Changes CPU profiler sampling interval. Must be called before CPU profiles recording started. 1061 * 1062 * @param interval New sampling interval in microseconds. 1063 * 1064 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1065 * {@link Ret0}></CODE> 1066 * 1067 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 1068 * browser receives the invocation-request. 1069 * 1070 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1071 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1072 * {@code >} to ensure the Browser Function has run to completion. 1073 */ 1074 public static Script<String, JsonObject, Ret0> setSamplingInterval(int interval) 1075 { 1076 final int webSocketID = 4003000 + counter++; 1077 final boolean[] optionals = { false, }; 1078 1079 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1080 String requestJSON = WriteJSON.get( 1081 parameterTypes.get("setSamplingInterval"), 1082 parameterNames.get("setSamplingInterval"), 1083 optionals, webSocketID, 1084 "Profiler.setSamplingInterval", 1085 interval 1086 ); 1087 1088 // This Remote Command does not have a Return-Value. 1089 return new Script<> 1090 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1091 } 1092 1093 /** 1094 * <CODE>[No Description Provided by Google]</CODE> 1095 * 1096 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1097 * {@link Ret0}></CODE> 1098 * 1099 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 1100 * browser receives the invocation-request. 1101 * 1102 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1103 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1104 * {@code >} to ensure the Browser Function has run to completion. 1105 */ 1106 public static Script<String, JsonObject, Ret0> start() 1107 { 1108 final int webSocketID = 4004000 + counter++; 1109 final boolean[] optionals = new boolean[0]; 1110 1111 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1112 String requestJSON = WriteJSON.get( 1113 parameterTypes.get("start"), 1114 parameterNames.get("start"), 1115 optionals, webSocketID, 1116 "Profiler.start" 1117 ); 1118 1119 // This Remote Command does not have a Return-Value. 1120 return new Script<> 1121 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1122 } 1123 1124 /** 1125 * Enable precise code coverage. Coverage data for JavaScript executed before enabling precise code 1126 * coverage may be incomplete. Enabling prevents running optimized code and resets execution 1127 * counters. 1128 * 1129 * @param callCount Collect accurate call counts beyond simple 'covered' or 'not covered'. 1130 * <BR /><B CLASS=Opt>OPTIONAL</B> 1131 * 1132 * @param detailed Collect block-based coverage. 1133 * <BR /><B CLASS=Opt>OPTIONAL</B> 1134 * 1135 * @param allowTriggeredUpdates Allow the backend to send updates on its own initiative 1136 * <BR /><B CLASS=Opt>OPTIONAL</B> 1137 * 1138 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1139 * Number></CODE> 1140 * 1141 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 1142 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 1143 * Number></CODE> will be returned. 1144 * 1145 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 1146 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 1147 * may be retrieved.</I> 1148 * 1149 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 1150 * <BR /><BR /><UL CLASS=JDUL> 1151 * <LI><CODE>Number (<B>timestamp</B></CODE>) 1152 * <BR />Monotonically increasing time (in seconds) when the coverage update was taken in the backend. 1153 * </LI> 1154 * </UL> */ 1155 public static Script<String, JsonObject, Number> startPreciseCoverage 1156 (Boolean callCount, Boolean detailed, Boolean allowTriggeredUpdates) 1157 { 1158 final int webSocketID = 4005000 + counter++; 1159 final boolean[] optionals = { true, true, true, }; 1160 1161 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1162 String requestJSON = WriteJSON.get( 1163 parameterTypes.get("startPreciseCoverage"), 1164 parameterNames.get("startPreciseCoverage"), 1165 optionals, webSocketID, 1166 "Profiler.startPreciseCoverage", 1167 callCount, detailed, allowTriggeredUpdates 1168 ); 1169 1170 // 'JSON Binding' ... Converts Browser Response-JSON to 'Number' 1171 Function<JsonObject, Number> responseProcessor = (JsonObject jo) -> 1172 ReadNumberJSON.get(jo, "timestamp", false, true); 1173 1174 return new Script<>(webSocketID, requestJSON, responseProcessor); 1175 } 1176 1177 /** 1178 * <CODE>[No Description Provided by Google]</CODE> 1179 * 1180 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1181 * {@link Profiler.Profile}></CODE> 1182 * 1183 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 1184 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 1185 * {@link Profiler.Profile}></CODE> will be returned. 1186 * 1187 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 1188 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 1189 * may be retrieved.</I> 1190 * 1191 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 1192 * <BR /><BR /><UL CLASS=JDUL> 1193 * <LI><CODE>{@link Profiler.Profile} (<B>profile</B></CODE>) 1194 * <BR />Recorded profile. 1195 * </LI> 1196 * </UL> */ 1197 public static Script<String, JsonObject, Profiler.Profile> stop() 1198 { 1199 final int webSocketID = 4006000 + counter++; 1200 final boolean[] optionals = new boolean[0]; 1201 1202 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1203 String requestJSON = WriteJSON.get( 1204 parameterTypes.get("stop"), 1205 parameterNames.get("stop"), 1206 optionals, webSocketID, 1207 "Profiler.stop" 1208 ); 1209 1210 // 'JSON Binding' ... Converts Browser Response-JSON to 'Profiler.Profile' 1211 Function<JsonObject, Profiler.Profile> responseProcessor = (JsonObject jo) -> 1212 ReadJSON.getObject(jo, "profile", Profiler.Profile.class, false, true); 1213 1214 return new Script<>(webSocketID, requestJSON, responseProcessor); 1215 } 1216 1217 /** 1218 * Disable precise code coverage. Disabling releases unnecessary execution count records and allows 1219 * executing optimized code. 1220 * 1221 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1222 * {@link Ret0}></CODE> 1223 * 1224 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 1225 * browser receives the invocation-request. 1226 * 1227 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1228 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1229 * {@code >} to ensure the Browser Function has run to completion. 1230 */ 1231 public static Script<String, JsonObject, Ret0> stopPreciseCoverage() 1232 { 1233 final int webSocketID = 4007000 + counter++; 1234 final boolean[] optionals = new boolean[0]; 1235 1236 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1237 String requestJSON = WriteJSON.get( 1238 parameterTypes.get("stopPreciseCoverage"), 1239 parameterNames.get("stopPreciseCoverage"), 1240 optionals, webSocketID, 1241 "Profiler.stopPreciseCoverage" 1242 ); 1243 1244 // This Remote Command does not have a Return-Value. 1245 return new Script<> 1246 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1247 } 1248 1249 /** 1250 * Collect coverage data for the current isolate, and resets execution counters. Precise code 1251 * coverage needs to have started. 1252 * 1253 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1254 * {@link Ret2}></CODE> 1255 * 1256 * <BR /><BR />This {@link Script} may be <B STYLE='color:red'>executed</B> (using 1257 * {@link Script#exec()}), and a {@link Promise} returned. 1258 * 1259 * <BR /><BR />When the {@code Promise} is <B STYLE='color: red'>awaited</B> 1260 * (using {@link Promise#await()}), the {@code Ret2} will subsequently 1261 * be returned from that call. 1262 * 1263 * <BR /><BR />The <B STYLE='color: red'>returned</B> values are encapsulated 1264 * in an instance of <B>{@link Ret2}</B> 1265 * 1266 * <BR /><BR /><UL CLASS=JDUL> 1267 * <LI><CODE><B>Ret2.a:</B> {@link Profiler.ScriptCoverage}[] (<B>result</B>)</CODE> 1268 * <BR />Coverage data for the current isolate. 1269 * <BR /><BR /></LI> 1270 * <LI><CODE><B>Ret2.b:</B> Number (<B>timestamp</B>)</CODE> 1271 * <BR />Monotonically increasing time (in seconds) when the coverage update was taken in the backend. 1272 * </LI> 1273 * </UL> 1274 */ 1275 public static Script<String, JsonObject, Ret2<Profiler.ScriptCoverage[], Number>> takePreciseCoverage() 1276 { 1277 final int webSocketID = 4008000 + counter++; 1278 final boolean[] optionals = new boolean[0]; 1279 1280 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1281 String requestJSON = WriteJSON.get( 1282 parameterTypes.get("takePreciseCoverage"), 1283 parameterNames.get("takePreciseCoverage"), 1284 optionals, webSocketID, 1285 "Profiler.takePreciseCoverage" 1286 ); 1287 1288 // 'JSON Binding' ... Converts Browser Response-JSON into Java-Type 'Ret2' 1289 Function<JsonObject, Ret2<Profiler.ScriptCoverage[], Number>> 1290 responseProcessor = (JsonObject jo) -> new Ret2<>( 1291 (jo.getJsonArray("result") == null) 1292 ? null 1293 : RJArrIntoStream.objArr(jo.getJsonArray("result"), null, 0, Profiler.ScriptCoverage.class).toArray(Profiler.ScriptCoverage[]::new), 1294 ReadNumberJSON.get(jo, "timestamp", false, true) 1295 ); 1296 1297 return new Script<>(webSocketID, requestJSON, responseProcessor); 1298 } 1299 1300}