opera-devtools-mcp 0.2.4 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +104 -7
- package/build/src/McpContext.js +365 -365
- package/build/src/McpPage.js +475 -48
- package/build/src/McpResponse.js +462 -288
- package/build/src/SlimMcpResponse.js +1 -1
- package/build/src/TextSnapshot.js +101 -22
- package/build/src/ToolHandler.js +142 -20
- package/build/src/bin/check-latest-version.js +27 -1
- package/build/src/bin/chrome-devtools-cli-options.js +573 -10
- package/build/src/bin/chrome-devtools-mcp-cli-options.js +119 -32
- package/build/src/bin/chrome-devtools-mcp-main.js +50 -7
- package/build/src/bin/chrome-devtools-mcp.js +7 -4
- package/build/src/bin/chrome-devtools.js +57 -14
- package/build/src/bin/opera-devtools-cli-options.js +3 -829
- package/build/src/bin/opera-devtools-mcp-cli-options.js +3 -348
- package/build/src/bin/opera-devtools-mcp-main.js +3 -37
- package/build/src/bin/opera-devtools-mcp.js +4 -19
- package/build/src/bin/opera-devtools.js +4 -185
- package/build/src/browser.js +45 -5
- package/build/src/{PageCollector.js → collectors/PageCollector.js} +64 -133
- package/build/src/collectors/ServiceWorkerCollector.js +171 -0
- package/build/src/daemon/client.js +75 -17
- package/build/src/daemon/daemon.js +92 -30
- package/build/src/daemon/utils.js +24 -8
- package/build/src/{DevtoolsUtils.js → devtools/DevtoolsUtils.js} +94 -88
- package/build/src/devtools/McpHostBindingAdapter.js +165 -0
- package/build/src/{issue-descriptions.js → devtools/issueDescriptions.js} +8 -6
- package/build/src/formatters/ConsoleFormatter.js +44 -11
- package/build/src/formatters/HeapSnapshotFormatter.js +140 -9
- package/build/src/formatters/IssueFormatter.js +7 -7
- package/build/src/formatters/NetworkFormatter.js +10 -8
- package/build/src/index.js +101 -232
- package/build/src/opera/branding.js +34 -0
- package/build/src/opera/browserFlags.js +85 -0
- package/build/src/opera/browserLaunch.js +52 -0
- package/build/src/opera/policy.js +50 -0
- package/build/src/opera/serviceWorkerRetry.js +37 -0
- package/build/src/opera/toolHandlerHooks.js +39 -0
- package/build/src/{tools → opera/tools}/opera.js +9 -21
- package/build/src/processors/HeapSnapshotManager.js +258 -0
- package/build/src/{trace-processing/parse.js → processors/PerformanceTrace.js} +9 -9
- package/build/src/telemetry/ClearcutLogger.js +12 -119
- package/build/src/telemetry/WatchdogClient.js +5 -5
- package/build/src/telemetry/errors.js +1 -1
- package/build/src/telemetry/flagUtils.js +6 -6
- package/build/src/telemetry/{toolMetricsUtils.js → metricsRegistry.js} +4 -11
- package/build/src/telemetry/persistence.js +3 -3
- package/build/src/telemetry/transformation.js +184 -0
- package/build/src/telemetry/watchdog/ClearcutSender.js +11 -11
- package/build/src/telemetry/watchdog/main.js +6 -6
- package/build/src/third_party/THIRD_PARTY_NOTICES +232 -1061
- package/build/src/third_party/bundled-packages.json +6 -8
- package/build/src/third_party/devtools-formatter-worker.js +63 -22
- package/build/src/third_party/devtools-heap-snapshot-worker.js +809 -182
- package/build/src/third_party/index.js +69558 -74691
- package/build/src/third_party/issue-descriptions/CoepCorpNotSameOrigin.md +2 -2
- package/build/src/third_party/issue-descriptions/CoepCorpNotSameOriginAfterDefaultedToSameOriginByCoep.md +3 -3
- package/build/src/third_party/issue-descriptions/CoepCorpNotSameSite.md +2 -2
- package/build/src/third_party/issue-descriptions/CoepFrameResourceNeedsCoepHeader.md +1 -1
- package/build/src/third_party/issue-descriptions/CompatibilityModeQuirks.md +1 -1
- package/build/src/third_party/issue-descriptions/CookieAttributeValueExceedsMaxSize.md +2 -2
- package/build/src/third_party/issue-descriptions/LowTextContrast.md +1 -1
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorRead.md +1 -1
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureErrorSet.md +1 -1
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnRead.md +1 -1
- package/build/src/third_party/issue-descriptions/SameSiteNoneInsecureWarnSet.md +1 -1
- package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeRead.md +3 -3
- package/build/src/third_party/issue-descriptions/SameSiteUnspecifiedLaxAllowUnsafeSet.md +3 -3
- package/build/src/third_party/issue-descriptions/bounceTrackingMitigations.md +1 -1
- package/build/src/third_party/issue-descriptions/connectionAllowlistEmbeddingRequirementNotSatisfied.md +26 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistIFrameAttributeLoosensEmbeddingRequirement.md +19 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowConnectionAllowlistFrom.md +21 -0
- package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidAllowlistItemType.md +2 -2
- package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidHeader.md +2 -2
- package/build/src/third_party/issue-descriptions/connectionAllowlistInvalidUrlPattern.md +3 -3
- package/build/src/third_party/issue-descriptions/connectionAllowlistItemNotInnerList.md +2 -2
- package/build/src/third_party/issue-descriptions/connectionAllowlistMoreThanOneList.md +2 -2
- package/build/src/third_party/issue-descriptions/connectionAllowlistReportingEndpointNotToken.md +1 -1
- package/build/src/third_party/issue-descriptions/cookieCrossSiteRedirectDowngrade.md +3 -3
- package/build/src/third_party/issue-descriptions/cookieExcludeBlockedWithinRelatedWebsiteSet.md +1 -1
- package/build/src/third_party/issue-descriptions/cookieExcludePortMismatch.md +1 -1
- package/build/src/third_party/issue-descriptions/cookieExcludeSchemeMismatch.md +1 -1
- package/build/src/third_party/issue-descriptions/cookieExcludeThirdPartyPhaseoutSet.md +1 -1
- package/build/src/third_party/issue-descriptions/cookieWarnThirdPartyPhaseoutRead.md +1 -1
- package/build/src/third_party/issue-descriptions/corsAllowCredentialsRequired.md +1 -1
- package/build/src/third_party/issue-descriptions/corsDisabledScheme.md +2 -2
- package/build/src/third_party/issue-descriptions/corsDisallowedByMode.md +2 -2
- package/build/src/third_party/issue-descriptions/corsHeaderDisallowedByPreflightResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/corsInvalidHeaderValues.md +3 -3
- package/build/src/third_party/issue-descriptions/corsLocalNetworkAccessPermissionDenied.md +1 -1
- package/build/src/third_party/issue-descriptions/corsMethodDisallowedByPreflightResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/corsNoCorsRedirectModeNotFollow.md +1 -1
- package/build/src/third_party/issue-descriptions/corsOriginMismatch.md +3 -3
- package/build/src/third_party/issue-descriptions/corsPreflightResponseInvalid.md +2 -2
- package/build/src/third_party/issue-descriptions/corsRedirectContainsCredentials.md +3 -3
- package/build/src/third_party/issue-descriptions/corsWildcardOriginNotAllowed.md +4 -3
- package/build/src/third_party/issue-descriptions/cspEvalViolation.md +4 -4
- package/build/src/third_party/issue-descriptions/cspInlineViolation.md +2 -2
- package/build/src/third_party/issue-descriptions/cspTrustedTypesPolicyViolation.md +2 -2
- package/build/src/third_party/issue-descriptions/cspTrustedTypesSinkViolation.md +4 -4
- package/build/src/third_party/issue-descriptions/cspURLViolation.md +4 -4
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsEmptyList.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestAccountsNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsFetchFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestDnsInvalidRecord.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestEmailVerificationWellKnownNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestInvalidEmail.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestJwksInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestKeyBindingSigningFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestRpOriginIsOpaque.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenInvalidSdJwt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenMalformedSdJwt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidAudience.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidIssuedAt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidNonce.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidSdHash.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbInvalidTyp.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingAud.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingCnf.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingIat.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingNonce.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbMissingSdHash.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationKbSignatureFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmail.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidEmailVerified.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidHolderKey.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuedAt.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtInvalidIssuer.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtJwksMissingKeys.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingCnf.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingEmail.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIat.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtMissingIss.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtSignatureFailed.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestTokenVerificationSdJwtUnsupportedHeaderAlg.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestUserLoggedOut.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownAccountsEndpointCrossOrigin.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownHttpNotFound.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidContentType.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownInvalidResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownIssuanceEndpointCrossOrigin.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownListEmpty.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingAccountsEndpoint.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownMissingIssuanceEndpoint.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownNoResponse.md +1 -0
- package/build/src/third_party/issue-descriptions/emailVerificationRequestWellKnownUnsupportedSigningAlgorithm.md +1 -0
- package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsHttpNotFound.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsInvalidResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestAccountsNoResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestApprovalDeclined.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestCanceled.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorFetchingSignin.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestErrorIdToken.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenHttpNotFound.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidRequest.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenInvalidResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestIdTokenNoResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestInvalidSigninResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestHttpNotFound.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestInvalidResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestManifestNoResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthRequestTooManyRequests.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidAccountsResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestInvalidConfigOrWellKnown.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoAccountSharingPermission.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoApiPermission.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNoReturningUserFromFetchedAccounts.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotIframe.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotPotentiallyTrustworthy.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSameOrigin.md +1 -1
- package/build/src/third_party/issue-descriptions/federatedAuthUserInfoRequestNotSignedInWithIdp.md +1 -1
- package/build/src/third_party/issue-descriptions/fetchingPartitionedBlobURL.md +2 -2
- package/build/src/third_party/issue-descriptions/genericBackUINavigationWouldSkipAd.md +4 -0
- package/build/src/third_party/issue-descriptions/genericFormAriaLabelledByToNonExistingIdError.md +2 -2
- package/build/src/third_party/issue-descriptions/genericFormAutocompleteAttributeEmptyError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormDuplicateIdForInputError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormEmptyIdAndNameAttributesForInputError.md +2 -2
- package/build/src/third_party/issue-descriptions/genericFormInputAssignedAutocompleteValueToIdOrNameAttributeError.md +2 -2
- package/build/src/third_party/issue-descriptions/genericFormInputHasWrongButWellIntendedAutocompleteValueError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormInputWithNoLabelError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormLabelForMatchesNonExistingIdError.md +2 -2
- package/build/src/third_party/issue-descriptions/genericFormLabelForNameError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormLabelHasNeitherForNorNestedInputError.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormModelContextMissingToolName.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormModelContextParameterMissingName.md +1 -1
- package/build/src/third_party/issue-descriptions/genericFormModelContextRequiredParameterMissingName.md +1 -1
- package/build/src/third_party/issue-descriptions/genericNavigationEntryMarkedSkippable.md +2 -2
- package/build/src/third_party/issue-descriptions/heavyAd.md +1 -1
- package/build/src/third_party/issue-descriptions/lazyLoadImageZeroSize.md +7 -0
- package/build/src/third_party/issue-descriptions/navigatingPartitionedBlobURL.md +3 -3
- package/build/src/third_party/issue-descriptions/permissionElementActivationDisabled.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluder.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementActivationDisabledWithOccluderParent.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementFencedFrameDisallowed.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooLarge.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementFontSizeTooSmall.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementInsetBoxShadowUnsupported.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementInvalidDisplayStyle.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementInvalidSizeValue.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementInvalidType.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementInvalidTypeActivation.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementNonOpaqueColor.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementPaddingBottomUnsupported.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementPaddingRightUnsupported.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementRequestInProgress.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementSecurityChecksFailed.md +1 -1
- package/build/src/third_party/issue-descriptions/permissionElementTypeNotSupported.md +2 -2
- package/build/src/third_party/issue-descriptions/permissionElementUntrustedEvent.md +1 -1
- package/build/src/third_party/issue-descriptions/placeholderDescriptionForInvisibleIssues.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedOptGroupChild.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityDisallowedSelectChild.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentAttributesSelectDescendant.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentLegendChild.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityInteractiveContentOptionChild.md +1 -1
- package/build/src/third_party/issue-descriptions/selectElementAccessibilityNonPhrasingContentOptionChild.md +1 -1
- package/build/src/third_party/issue-descriptions/selectivePermissionsIntervention.md +3 -3
- package/build/src/third_party/issue-descriptions/sharedArrayBuffer.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorCrossOriginNoCorsRequest.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorMatchingDictionaryNotUsed.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryUseErrorUnexpectedContentDictionaryHeader.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorCossOriginNoCorsRequest.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorDisallowedBySettings.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorExpiredResponse.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorFeatureDisabled.md +2 -2
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorInvalidStructuredHeader.md +1 -1
- package/build/src/third_party/issue-descriptions/sharedDictionaryWriteErrorNavigationRequest.md +2 -2
- package/build/src/third_party/issue-descriptions/sriInvalidSignatureHeader.md +4 -4
- package/build/src/third_party/issue-descriptions/sriInvalidSignatureInputHeader.md +4 -4
- package/build/src/third_party/issue-descriptions/sriMissingSignatureHeader.md +1 -1
- package/build/src/third_party/issue-descriptions/sriMissingSignatureInputHeader.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsIncorrectLength.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsNotByteSequence.md +4 -4
- package/build/src/third_party/issue-descriptions/sriSignatureHeaderValueIsParameterized.md +4 -4
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentName.md +1 -1
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidComponentType.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidDerivedComponentParameter.md +1 -1
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidHeaderComponentParameter.md +1 -1
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderInvalidParameter.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderKeyIdLength.md +5 -5
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingLabel.md +3 -3
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderMissingRequiredParameters.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueMissingComponents.md +2 -2
- package/build/src/third_party/issue-descriptions/sriSignatureInputHeaderValueNotInnerList.md +2 -2
- package/build/src/third_party/issue-descriptions/sriValidationFailedIntegrityMismatch.md +4 -4
- package/build/src/third_party/issue-descriptions/sriValidationFailedInvalidLength.md +3 -3
- package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureExpired.md +2 -2
- package/build/src/third_party/issue-descriptions/sriValidationFailedSignatureMismatch.md +2 -2
- package/build/src/third_party/issue-descriptions/stylesheetLateImport.md +1 -1
- package/build/src/third_party/issue-descriptions/summaryElementAccessibilityInteractiveContentSummaryDescendant.md +1 -1
- package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestLength.md +2 -2
- package/build/src/third_party/issue-descriptions/unencodedDigestIncorrectDigestType.md +3 -3
- package/build/src/third_party/issue-descriptions/unencodedDigestMalformedDictionary.md +2 -2
- package/build/src/third_party/issue-descriptions/unencodedDigestUnknownAlgorithm.md +1 -1
- package/build/src/third_party/lighthouse-devtools-mcp-bundle.js +3177 -6340
- package/build/src/tools/ToolDefinition.js +2 -2
- package/build/src/tools/categories.js +3 -0
- package/build/src/tools/console.js +13 -0
- package/build/src/tools/emulation.js +30 -3
- package/build/src/tools/extensions.js +8 -1
- package/build/src/tools/input.js +246 -128
- package/build/src/tools/lighthouse.js +14 -7
- package/build/src/tools/memory.js +289 -25
- package/build/src/tools/network.js +10 -7
- package/build/src/tools/pages.js +33 -92
- package/build/src/tools/performance.js +67 -52
- package/build/src/tools/pwa.js +128 -0
- package/build/src/tools/screencast.js +35 -12
- package/build/src/tools/screenshot.js +234 -75
- package/build/src/tools/script.js +130 -45
- package/build/src/tools/slim/tools.js +3 -0
- package/build/src/tools/snapshot.js +7 -4
- package/build/src/tools/thirdPartyDeveloper.js +19 -9
- package/build/src/tools/tools.js +3 -1
- package/build/src/tools/webmcp.js +3 -1
- package/build/src/utils/WaitForHelper.js +299 -0
- package/build/src/utils/check-for-updates.js +8 -2
- package/build/src/utils/files.js +42 -3
- package/build/src/utils/logger.js +51 -0
- package/build/src/utils/polyfill.js +11 -0
- package/build/src/utils/url.js +43 -0
- package/build/src/version.js +1 -1
- package/package.json +42 -33
- package/build/src/DevToolsConnectionAdapter.js +0 -70
- package/build/src/HeapSnapshotManager.js +0 -110
- package/build/src/Mutex.js +0 -38
- package/build/src/WaitForHelper.js +0 -195
- package/build/src/bin/cliDefinitions.js +0 -616
- package/build/src/logger.js +0 -37
- package/build/src/polyfill.js +0 -8
- package/build/src/telemetry/metricUtils.js +0 -15
- package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeRead.md +0 -8
- package/build/src/third_party/issue-descriptions/SameSiteExcludeContextDowngradeSet.md +0 -8
- package/build/src/third_party/issue-descriptions/SameSiteExcludeNavigationContextDowngrade.md +0 -8
- package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeRead.md +0 -8
- package/build/src/third_party/issue-descriptions/SameSiteWarnCrossDowngradeSet.md +0 -8
- package/build/src/third_party/issue-descriptions/SameSiteWarnStrictLaxDowngradeStrict.md +0 -8
- package/build/src/third_party/issue-descriptions/arInsecureContext.md +0 -7
- package/build/src/third_party/issue-descriptions/arInvalidInfoHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arInvalidRegisterOsSourceHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arInvalidRegisterOsTriggerHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arInvalidRegisterSourceHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arInvalidRegisterTriggerHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arNavigationRegistrationUniqueScopeAlreadySet.md +0 -5
- package/build/src/third_party/issue-descriptions/arNavigationRegistrationWithoutTransientUserActivation.md +0 -6
- package/build/src/third_party/issue-descriptions/arNoRegisterOsSourceHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arNoRegisterOsTriggerHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arNoRegisterSourceHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arNoRegisterTriggerHeader.md +0 -5
- package/build/src/third_party/issue-descriptions/arNoWebOrOsSupport.md +0 -4
- package/build/src/third_party/issue-descriptions/arOsSourceIgnored.md +0 -18
- package/build/src/third_party/issue-descriptions/arOsTriggerIgnored.md +0 -19
- package/build/src/third_party/issue-descriptions/arPermissionPolicyDisabled.md +0 -8
- package/build/src/third_party/issue-descriptions/arSourceAndTriggerHeaders.md +0 -9
- package/build/src/third_party/issue-descriptions/arSourceIgnored.md +0 -13
- package/build/src/third_party/issue-descriptions/arTriggerIgnored.md +0 -12
- package/build/src/third_party/issue-descriptions/arUntrustworthyReportingOrigin.md +0 -10
- package/build/src/third_party/issue-descriptions/arWebAndOsHeaders.md +0 -11
- package/build/src/utils/string.js +0 -37
- package/build/src/utils/types.js +0 -7
|
@@ -642,10 +642,14 @@ class Diff {
|
|
|
642
642
|
removedCount = 0;
|
|
643
643
|
addedSize = 0;
|
|
644
644
|
removedSize = 0;
|
|
645
|
-
deletedIndexes = [];
|
|
646
|
-
addedIndexes = [];
|
|
647
645
|
countDelta;
|
|
648
646
|
sizeDelta;
|
|
647
|
+
addedIndexes = [];
|
|
648
|
+
addedIds = [];
|
|
649
|
+
addedSelfSizes = [];
|
|
650
|
+
deletedIndexes = [];
|
|
651
|
+
deletedIds = [];
|
|
652
|
+
deletedSelfSizes = [];
|
|
649
653
|
constructor(name) {
|
|
650
654
|
this.name = name;
|
|
651
655
|
}
|
|
@@ -2806,44 +2810,15 @@ const LAYOUT_LINES_HIGHLIGHT_COLOR = [127, 32, 210];
|
|
|
2806
2810
|
Mask: Legacy.fromRGBA([248, 249, 249, 1]),
|
|
2807
2811
|
});
|
|
2808
2812
|
|
|
2809
|
-
// Copyright 2025 The Chromium Authors
|
|
2810
|
-
class WritableDevToolsContext {
|
|
2811
|
-
#instances = new Map();
|
|
2812
|
-
get(ctor) {
|
|
2813
|
-
const instance = this.#instances.get(ctor);
|
|
2814
|
-
if (!instance) {
|
|
2815
|
-
throw new Error(`No instance for ${ctor.name}. Ensure the bootstrapper creates it.`);
|
|
2816
|
-
}
|
|
2817
|
-
return instance;
|
|
2818
|
-
}
|
|
2819
|
-
has(ctor) {
|
|
2820
|
-
return this.#instances.has(ctor);
|
|
2821
|
-
}
|
|
2822
|
-
set(ctor, instance) {
|
|
2823
|
-
this.#instances.set(ctor, instance);
|
|
2824
|
-
}
|
|
2825
|
-
delete(ctor) {
|
|
2826
|
-
this.#instances.delete(ctor);
|
|
2827
|
-
}
|
|
2828
|
-
}
|
|
2829
|
-
let gInstance = null;
|
|
2830
|
-
function globalInstance() {
|
|
2831
|
-
if (!gInstance) {
|
|
2832
|
-
gInstance = new WritableDevToolsContext();
|
|
2833
|
-
}
|
|
2834
|
-
return gInstance;
|
|
2835
|
-
}
|
|
2836
|
-
|
|
2837
2813
|
// Copyright 2026 The Chromium Authors
|
|
2838
2814
|
var ExperimentName;
|
|
2839
2815
|
(function (ExperimentName) {
|
|
2840
2816
|
ExperimentName["ALL"] = "*";
|
|
2841
|
-
ExperimentName["CAPTURE_NODE_CREATION_STACKS"] = "capture-node-creation-stacks";
|
|
2842
2817
|
ExperimentName["PROTOCOL_MONITOR"] = "protocol-monitor";
|
|
2843
2818
|
ExperimentName["INSTRUMENTATION_BREAKPOINTS"] = "instrumentation-breakpoints";
|
|
2844
|
-
ExperimentName["USE_SOURCE_MAP_SCOPES"] = "use-source-map-scopes";
|
|
2845
2819
|
ExperimentName["DURABLE_MESSAGES"] = "durable-messages";
|
|
2846
2820
|
ExperimentName["JPEG_XL"] = "jpeg-xl";
|
|
2821
|
+
ExperimentName["PLUS_BUTTON"] = "plus-button";
|
|
2847
2822
|
})(ExperimentName || (ExperimentName = {}));
|
|
2848
2823
|
|
|
2849
2824
|
// Copyright 2021 The Chromium Authors
|
|
@@ -4798,7 +4773,7 @@ function lockedLazyString(str) {
|
|
|
4798
4773
|
// Copyright 2014 The Chromium Authors
|
|
4799
4774
|
const UIStrings$2 = {
|
|
4800
4775
|
elementsPanel: 'Elements panel',
|
|
4801
|
-
stylesSidebar: '
|
|
4776
|
+
stylesSidebar: 'Styles sidebar',
|
|
4802
4777
|
changesDrawer: 'Changes drawer',
|
|
4803
4778
|
issuesView: 'Issues view',
|
|
4804
4779
|
networkPanel: 'Network panel',
|
|
@@ -4807,50 +4782,12 @@ const UIStrings$2 = {
|
|
|
4807
4782
|
sourcesPanel: 'Sources panel',
|
|
4808
4783
|
timelinePanel: 'Performance panel',
|
|
4809
4784
|
memoryInspectorPanel: 'Memory inspector panel',
|
|
4810
|
-
developerResourcesPanel: 'Developer
|
|
4785
|
+
developerResourcesPanel: 'Developer resources panel',
|
|
4811
4786
|
animationsPanel: 'Animations panel',
|
|
4787
|
+
lighthousePanel: 'Lighthouse panel',
|
|
4812
4788
|
};
|
|
4813
4789
|
const str_$2 = registerUIStrings('core/common/Revealer.ts', UIStrings$2);
|
|
4814
4790
|
const i18nLazyString$1 = getLazilyComputedLocalizedString.bind(undefined, str_$2);
|
|
4815
|
-
let revealerRegistry;
|
|
4816
|
-
class RevealerRegistry {
|
|
4817
|
-
registeredRevealers = [];
|
|
4818
|
-
static instance() {
|
|
4819
|
-
if (revealerRegistry === undefined) {
|
|
4820
|
-
revealerRegistry = new RevealerRegistry();
|
|
4821
|
-
}
|
|
4822
|
-
return revealerRegistry;
|
|
4823
|
-
}
|
|
4824
|
-
static removeInstance() {
|
|
4825
|
-
revealerRegistry = undefined;
|
|
4826
|
-
}
|
|
4827
|
-
register(registration) {
|
|
4828
|
-
this.registeredRevealers.push(registration);
|
|
4829
|
-
}
|
|
4830
|
-
async reveal(revealable, omitFocus) {
|
|
4831
|
-
const revealers = await Promise.all(this.getApplicableRegisteredRevealers(revealable).map(registration => registration.loadRevealer()));
|
|
4832
|
-
if (revealers.length < 1) {
|
|
4833
|
-
throw new Error(`No revealers found for ${revealable}`);
|
|
4834
|
-
}
|
|
4835
|
-
if (revealers.length > 1) {
|
|
4836
|
-
throw new Error(`Conflicting reveals found for ${revealable}`);
|
|
4837
|
-
}
|
|
4838
|
-
return await revealers[0].reveal(revealable, omitFocus);
|
|
4839
|
-
}
|
|
4840
|
-
getApplicableRegisteredRevealers(revealable) {
|
|
4841
|
-
return this.registeredRevealers.filter(registration => {
|
|
4842
|
-
for (const contextType of registration.contextTypes()) {
|
|
4843
|
-
if (revealable instanceof contextType) {
|
|
4844
|
-
return true;
|
|
4845
|
-
}
|
|
4846
|
-
}
|
|
4847
|
-
return false;
|
|
4848
|
-
});
|
|
4849
|
-
}
|
|
4850
|
-
}
|
|
4851
|
-
async function reveal(revealable, omitFocus = false) {
|
|
4852
|
-
await RevealerRegistry.instance().reveal(revealable, omitFocus);
|
|
4853
|
-
}
|
|
4854
4791
|
({
|
|
4855
4792
|
DEVELOPER_RESOURCES_PANEL: i18nLazyString$1(UIStrings$2.developerResourcesPanel),
|
|
4856
4793
|
ELEMENTS_PANEL: i18nLazyString$1(UIStrings$2.elementsPanel),
|
|
@@ -4864,44 +4801,10 @@ async function reveal(revealable, omitFocus = false) {
|
|
|
4864
4801
|
SOURCES_PANEL: i18nLazyString$1(UIStrings$2.sourcesPanel),
|
|
4865
4802
|
MEMORY_INSPECTOR_PANEL: i18nLazyString$1(UIStrings$2.memoryInspectorPanel),
|
|
4866
4803
|
ANIMATIONS_PANEL: i18nLazyString$1(UIStrings$2.animationsPanel),
|
|
4804
|
+
LIGHTHOUSE_PANEL: i18nLazyString$1(UIStrings$2.lighthousePanel),
|
|
4867
4805
|
});
|
|
4868
4806
|
|
|
4869
4807
|
// Copyright 2014 The Chromium Authors
|
|
4870
|
-
class Console extends ObjectWrapper {
|
|
4871
|
-
#messages = [];
|
|
4872
|
-
static instance(opts) {
|
|
4873
|
-
if (!globalInstance().has(Console) || opts?.forceNew) {
|
|
4874
|
-
globalInstance().set(Console, new Console());
|
|
4875
|
-
}
|
|
4876
|
-
return globalInstance().get(Console);
|
|
4877
|
-
}
|
|
4878
|
-
static removeInstance() {
|
|
4879
|
-
globalInstance().delete(Console);
|
|
4880
|
-
}
|
|
4881
|
-
addMessage(text, level = "info" , show = false, source) {
|
|
4882
|
-
const message = new Message(text, level, Date.now(), show, source);
|
|
4883
|
-
this.#messages.push(message);
|
|
4884
|
-
this.dispatchEventToListeners("messageAdded" , message);
|
|
4885
|
-
}
|
|
4886
|
-
log(text) {
|
|
4887
|
-
this.addMessage(text, "info" );
|
|
4888
|
-
}
|
|
4889
|
-
warn(text, source) {
|
|
4890
|
-
this.addMessage(text, "warning" , undefined, source);
|
|
4891
|
-
}
|
|
4892
|
-
error(text, show = true) {
|
|
4893
|
-
this.addMessage(text, "error" , show);
|
|
4894
|
-
}
|
|
4895
|
-
messages() {
|
|
4896
|
-
return this.#messages;
|
|
4897
|
-
}
|
|
4898
|
-
show() {
|
|
4899
|
-
void this.showPromise();
|
|
4900
|
-
}
|
|
4901
|
-
showPromise() {
|
|
4902
|
-
return reveal(this);
|
|
4903
|
-
}
|
|
4904
|
-
}
|
|
4905
4808
|
var FrontendMessageSource;
|
|
4906
4809
|
(function (FrontendMessageSource) {
|
|
4907
4810
|
FrontendMessageSource["CSS"] = "css";
|
|
@@ -4909,22 +4812,6 @@ var FrontendMessageSource;
|
|
|
4909
4812
|
FrontendMessageSource["ISSUE_PANEL"] = "issue-panel";
|
|
4910
4813
|
FrontendMessageSource["SELF_XSS"] = "self-xss";
|
|
4911
4814
|
})(FrontendMessageSource || (FrontendMessageSource = {}));
|
|
4912
|
-
class Message {
|
|
4913
|
-
text;
|
|
4914
|
-
level;
|
|
4915
|
-
timestamp;
|
|
4916
|
-
show;
|
|
4917
|
-
source;
|
|
4918
|
-
constructor(text, level, timestamp, show, source) {
|
|
4919
|
-
this.text = text;
|
|
4920
|
-
this.level = level;
|
|
4921
|
-
this.timestamp = (typeof timestamp === 'number') ? timestamp : Date.now();
|
|
4922
|
-
this.show = show;
|
|
4923
|
-
if (source) {
|
|
4924
|
-
this.source = source;
|
|
4925
|
-
}
|
|
4926
|
-
}
|
|
4927
|
-
}
|
|
4928
4815
|
|
|
4929
4816
|
// Copyright 2012 The Chromium Authors
|
|
4930
4817
|
function normalizePath(path) {
|
|
@@ -5328,7 +5215,11 @@ class ParsedURL {
|
|
|
5328
5215
|
return 'data:';
|
|
5329
5216
|
}
|
|
5330
5217
|
const scheme = this.isBlobURL() ? this.blobInnerScheme : this.scheme;
|
|
5331
|
-
|
|
5218
|
+
const domain = this.domain();
|
|
5219
|
+
if (!scheme && !domain) {
|
|
5220
|
+
return '';
|
|
5221
|
+
}
|
|
5222
|
+
return scheme + '://' + domain;
|
|
5332
5223
|
}
|
|
5333
5224
|
urlWithoutScheme() {
|
|
5334
5225
|
if (this.scheme && this.url.startsWith(this.scheme + '://')) {
|
|
@@ -5725,7 +5616,6 @@ const UIStrings = {
|
|
|
5725
5616
|
extension: 'Extension',
|
|
5726
5617
|
adorner: 'Adorner',
|
|
5727
5618
|
account: 'Account',
|
|
5728
|
-
privacy: 'Privacy',
|
|
5729
5619
|
};
|
|
5730
5620
|
const str_ = registerUIStrings('core/common/SettingRegistration.ts', UIStrings);
|
|
5731
5621
|
getLocalizedString.bind(undefined, str_);
|
|
@@ -5733,6 +5623,7 @@ getLocalizedString.bind(undefined, str_);
|
|
|
5733
5623
|
// Copyright 2011 The Chromium Authors
|
|
5734
5624
|
class HeapSnapshotWorkerProxy extends ObjectWrapper {
|
|
5735
5625
|
eventHandler;
|
|
5626
|
+
#console;
|
|
5736
5627
|
nextObjectId = 1;
|
|
5737
5628
|
nextCallId = 1;
|
|
5738
5629
|
callbacks = new Map();
|
|
@@ -5740,13 +5631,17 @@ class HeapSnapshotWorkerProxy extends ObjectWrapper {
|
|
|
5740
5631
|
worker;
|
|
5741
5632
|
interval;
|
|
5742
5633
|
workerUrl;
|
|
5743
|
-
constructor(eventHandler, workerUrl) {
|
|
5634
|
+
constructor(eventHandler, console, workerUrl) {
|
|
5744
5635
|
super();
|
|
5745
5636
|
this.eventHandler = eventHandler;
|
|
5637
|
+
this.#console = console;
|
|
5746
5638
|
this.workerUrl = workerUrl;
|
|
5747
5639
|
this.worker = HOST_RUNTIME.createWorker(workerUrl ?? import.meta.resolve('../../entrypoints/heap_snapshot_worker/heap_snapshot_worker-entrypoint.js'));
|
|
5748
5640
|
this.worker.onmessage = this.messageReceived.bind(this);
|
|
5749
5641
|
}
|
|
5642
|
+
get console() {
|
|
5643
|
+
return this.#console;
|
|
5644
|
+
}
|
|
5750
5645
|
createLoader(profileUid, snapshotReceivedCallback) {
|
|
5751
5646
|
const objectId = this.nextObjectId++;
|
|
5752
5647
|
const proxy = new HeapSnapshotLoaderProxy(this, objectId, profileUid, snapshotReceivedCallback);
|
|
@@ -5814,7 +5709,7 @@ class HeapSnapshotWorkerProxy extends ObjectWrapper {
|
|
|
5814
5709
|
return;
|
|
5815
5710
|
}
|
|
5816
5711
|
this.checkLongRunningCalls();
|
|
5817
|
-
this.interval =
|
|
5712
|
+
this.interval = globalThis.setInterval(this.checkLongRunningCalls.bind(this), 300);
|
|
5818
5713
|
}
|
|
5819
5714
|
checkLongRunningCalls() {
|
|
5820
5715
|
for (const callId of this.previousCallbacks) {
|
|
@@ -5849,8 +5744,8 @@ class HeapSnapshotWorkerProxy extends ObjectWrapper {
|
|
|
5849
5744
|
return;
|
|
5850
5745
|
}
|
|
5851
5746
|
if (data.error) {
|
|
5852
|
-
|
|
5853
|
-
|
|
5747
|
+
this.#console.error(`An error occurred when a call to method '${data.errorMethodName}' was requested`);
|
|
5748
|
+
this.#console.error(data['errorCallStack']);
|
|
5854
5749
|
this.callbacks.delete(data.callId);
|
|
5855
5750
|
return;
|
|
5856
5751
|
}
|
|
@@ -5898,7 +5793,7 @@ class HeapSnapshotLoaderProxy extends HeapSnapshotProxyObject {
|
|
|
5898
5793
|
}
|
|
5899
5794
|
async close() {
|
|
5900
5795
|
await this.callMethodPromise('close');
|
|
5901
|
-
const secondWorker = new HeapSnapshotWorkerProxy(() => { }, this.worker.workerUrl);
|
|
5796
|
+
const secondWorker = new HeapSnapshotWorkerProxy(() => { }, this.worker.console, this.worker.workerUrl);
|
|
5902
5797
|
const channel = new MessageChannel();
|
|
5903
5798
|
await secondWorker.setupForSecondaryInit(channel.port2);
|
|
5904
5799
|
const snapshotProxy = await this.callFactoryMethodPromise('buildSnapshot', HeapSnapshotProxy, [channel.port1]);
|
|
@@ -5922,9 +5817,18 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
|
|
|
5922
5817
|
interfaceDefinitions() {
|
|
5923
5818
|
return this.callMethodPromise('interfaceDefinitions');
|
|
5924
5819
|
}
|
|
5820
|
+
getNativeContextSizes() {
|
|
5821
|
+
return this.callMethodPromise('getNativeContextSizes');
|
|
5822
|
+
}
|
|
5823
|
+
getRetainedByContextSummary() {
|
|
5824
|
+
return this.callMethodPromise('getRetainedByContextSummary');
|
|
5825
|
+
}
|
|
5925
5826
|
aggregatesWithFilter(filter) {
|
|
5926
5827
|
return this.callMethodPromise('aggregatesWithFilter', filter);
|
|
5927
5828
|
}
|
|
5829
|
+
getDuplicateStrings() {
|
|
5830
|
+
return this.callMethodPromise('getDuplicateStrings');
|
|
5831
|
+
}
|
|
5928
5832
|
aggregatesForDiff(interfaceDefinitions) {
|
|
5929
5833
|
return this.callMethodPromise('aggregatesForDiff', interfaceDefinitions);
|
|
5930
5834
|
}
|
|
@@ -5934,8 +5838,14 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
|
|
|
5934
5838
|
nodeClassKey(snapshotObjectId) {
|
|
5935
5839
|
return this.callMethodPromise('nodeClassKey', snapshotObjectId);
|
|
5936
5840
|
}
|
|
5937
|
-
|
|
5938
|
-
return this.
|
|
5841
|
+
nodeIndexForId(nodeId) {
|
|
5842
|
+
return this.callMethodPromise('nodeIndexForId', nodeId);
|
|
5843
|
+
}
|
|
5844
|
+
getObjectInfo(nodeIndex) {
|
|
5845
|
+
return this.callMethodPromise('getObjectInfo', nodeIndex);
|
|
5846
|
+
}
|
|
5847
|
+
createEdgesProvider(nodeIndex, options) {
|
|
5848
|
+
return this.callFactoryMethod('createEdgesProvider', HeapSnapshotProviderProxy, nodeIndex, options);
|
|
5939
5849
|
}
|
|
5940
5850
|
createRetainingEdgesProvider(nodeIndex) {
|
|
5941
5851
|
return this.callFactoryMethod('createRetainingEdgesProvider', HeapSnapshotProviderProxy, nodeIndex);
|
|
@@ -5952,6 +5862,9 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
|
|
|
5952
5862
|
createNodesProviderForClass(classKey, nodeFilter) {
|
|
5953
5863
|
return this.callFactoryMethod('createNodesProviderForClass', HeapSnapshotProviderProxy, classKey, nodeFilter);
|
|
5954
5864
|
}
|
|
5865
|
+
queryObjects(queryOptions) {
|
|
5866
|
+
return this.callFactoryMethod('queryObjects', HeapSnapshotProviderProxy, queryOptions);
|
|
5867
|
+
}
|
|
5955
5868
|
allocationTracesTops() {
|
|
5956
5869
|
return this.callMethodPromise('allocationTracesTops');
|
|
5957
5870
|
}
|
|
@@ -5991,6 +5904,12 @@ class HeapSnapshotProxy extends HeapSnapshotProxyObject {
|
|
|
5991
5904
|
ignoreNodeInRetainersView(nodeIndex) {
|
|
5992
5905
|
return this.callMethodPromise('ignoreNodeInRetainersView', nodeIndex);
|
|
5993
5906
|
}
|
|
5907
|
+
getRetainingPaths(nodeIndex, maxDepth, maxNodes, maxSiblings) {
|
|
5908
|
+
return this.callMethodPromise('getRetainingPaths', nodeIndex, maxDepth, maxNodes, maxSiblings);
|
|
5909
|
+
}
|
|
5910
|
+
getDominatorsOf(nodeIndex) {
|
|
5911
|
+
return this.callMethodPromise('getDominatorsOf', nodeIndex);
|
|
5912
|
+
}
|
|
5994
5913
|
unignoreNodeInRetainersView(nodeIndex) {
|
|
5995
5914
|
return this.callMethodPromise('unignoreNodeInRetainersView', nodeIndex);
|
|
5996
5915
|
}
|
|
@@ -6673,21 +6592,10 @@ class HeapSnapshotNode {
|
|
|
6673
6592
|
return false;
|
|
6674
6593
|
}
|
|
6675
6594
|
#detachednessAndClassIndex() {
|
|
6676
|
-
|
|
6677
|
-
const nodeDetachednessAndClassIndexOffset = snapshot.nodeDetachednessAndClassIndexOffset;
|
|
6678
|
-
return nodeDetachednessAndClassIndexOffset !== -1 ?
|
|
6679
|
-
snapshot.nodes.getValue(nodeIndex + nodeDetachednessAndClassIndexOffset) :
|
|
6680
|
-
snapshot.detachednessAndClassIndexArray[nodeIndex / snapshot.nodeFieldCount];
|
|
6595
|
+
return this.snapshot.detachednessAndClassIndexArray[this.nodeIndex / this.snapshot.nodeFieldCount];
|
|
6681
6596
|
}
|
|
6682
6597
|
#setDetachednessAndClassIndex(value) {
|
|
6683
|
-
|
|
6684
|
-
const nodeDetachednessAndClassIndexOffset = snapshot.nodeDetachednessAndClassIndexOffset;
|
|
6685
|
-
if (nodeDetachednessAndClassIndexOffset !== -1) {
|
|
6686
|
-
snapshot.nodes.setValue(nodeIndex + nodeDetachednessAndClassIndexOffset, value);
|
|
6687
|
-
}
|
|
6688
|
-
else {
|
|
6689
|
-
snapshot.detachednessAndClassIndexArray[nodeIndex / snapshot.nodeFieldCount] = value;
|
|
6690
|
-
}
|
|
6598
|
+
this.snapshot.detachednessAndClassIndexArray[this.nodeIndex / this.snapshot.nodeFieldCount] = value;
|
|
6691
6599
|
}
|
|
6692
6600
|
detachedness() {
|
|
6693
6601
|
return this.#detachednessAndClassIndex() & BITMASK_FOR_DOM_LINK_STATE;
|
|
@@ -6698,6 +6606,67 @@ class HeapSnapshotNode {
|
|
|
6698
6606
|
value |= detachedness;
|
|
6699
6607
|
this.#setDetachednessAndClassIndex(value);
|
|
6700
6608
|
}
|
|
6609
|
+
findInternalEdgeTarget(name) {
|
|
6610
|
+
for (let iter = this.edges(); iter.hasNext(); iter.next()) {
|
|
6611
|
+
const edge = iter.edge;
|
|
6612
|
+
if (!edge.isInternal()) {
|
|
6613
|
+
continue;
|
|
6614
|
+
}
|
|
6615
|
+
if (edge.name() === name) {
|
|
6616
|
+
return edge.node();
|
|
6617
|
+
}
|
|
6618
|
+
}
|
|
6619
|
+
return undefined;
|
|
6620
|
+
}
|
|
6621
|
+
nodeValueAsBool() {
|
|
6622
|
+
if (this.rawType() !== this.snapshot.nodeNumberType) {
|
|
6623
|
+
return undefined;
|
|
6624
|
+
}
|
|
6625
|
+
if (this.rawName() !== 'bool') {
|
|
6626
|
+
return undefined;
|
|
6627
|
+
}
|
|
6628
|
+
const valNode = this.findInternalEdgeTarget('value');
|
|
6629
|
+
if (!valNode) {
|
|
6630
|
+
return undefined;
|
|
6631
|
+
}
|
|
6632
|
+
const rawName = valNode.rawName();
|
|
6633
|
+
if (rawName === 'true') {
|
|
6634
|
+
return true;
|
|
6635
|
+
}
|
|
6636
|
+
if (rawName === 'false') {
|
|
6637
|
+
return false;
|
|
6638
|
+
}
|
|
6639
|
+
return undefined;
|
|
6640
|
+
}
|
|
6641
|
+
nodeValueAsInt() {
|
|
6642
|
+
if (this.rawType() !== this.snapshot.nodeNumberType) {
|
|
6643
|
+
return undefined;
|
|
6644
|
+
}
|
|
6645
|
+
if (this.rawName() !== 'int') {
|
|
6646
|
+
return undefined;
|
|
6647
|
+
}
|
|
6648
|
+
const valNode = this.findInternalEdgeTarget('value');
|
|
6649
|
+
if (!valNode) {
|
|
6650
|
+
return undefined;
|
|
6651
|
+
}
|
|
6652
|
+
const value = parseInt(valNode.rawName(), 10);
|
|
6653
|
+
return isNaN(value) ? undefined : value;
|
|
6654
|
+
}
|
|
6655
|
+
nodeStringLength() {
|
|
6656
|
+
const lengthNode = this.findInternalEdgeTarget('length');
|
|
6657
|
+
return lengthNode ? lengthNode.nodeValueAsInt() : undefined;
|
|
6658
|
+
}
|
|
6659
|
+
nodeStringHash() {
|
|
6660
|
+
const hashNode = this.findInternalEdgeTarget('hash');
|
|
6661
|
+
return hashNode ? hashNode.nodeValueAsInt() : undefined;
|
|
6662
|
+
}
|
|
6663
|
+
nodeIsTruncatedString() {
|
|
6664
|
+
const truncNode = this.findInternalEdgeTarget('truncated');
|
|
6665
|
+
if (!truncNode) {
|
|
6666
|
+
return false;
|
|
6667
|
+
}
|
|
6668
|
+
return truncNode.nodeValueAsBool() === true;
|
|
6669
|
+
}
|
|
6701
6670
|
}
|
|
6702
6671
|
class HeapSnapshotNodeIterator {
|
|
6703
6672
|
node;
|
|
@@ -6848,7 +6817,7 @@ class SecondaryInitManager {
|
|
|
6848
6817
|
...retainers,
|
|
6849
6818
|
essentialEdges: createBitVector(argsStep2.essentialEdgesBuffer),
|
|
6850
6819
|
port,
|
|
6851
|
-
nodeSelfSizesPromise: this.getNodeSelfSizes()
|
|
6820
|
+
nodeSelfSizesPromise: this.getNodeSelfSizes(),
|
|
6852
6821
|
};
|
|
6853
6822
|
const dominatorsAndRetainedSizes = await HeapSnapshot.calculateDominatorsAndRetainedSizes(args);
|
|
6854
6823
|
const dominatedNodesOutputs = HeapSnapshot.buildDominatedNodes({ ...args, ...dominatorsAndRetainedSizes });
|
|
@@ -6878,6 +6847,8 @@ const MIN_INTERFACE_PROPERTY_COUNT = 1;
|
|
|
6878
6847
|
const MAX_INTERFACE_NAME_LENGTH = 120;
|
|
6879
6848
|
const MIN_OBJECT_COUNT_PER_INTERFACE = 2;
|
|
6880
6849
|
const MIN_OBJECT_PROPORTION_PER_INTERFACE = 1000;
|
|
6850
|
+
const NO_NATIVE_CONTEXT = -1;
|
|
6851
|
+
const SHARED_NATIVE_CONTEXT = -2;
|
|
6881
6852
|
class HeapSnapshot {
|
|
6882
6853
|
nodes;
|
|
6883
6854
|
containmentEdges;
|
|
@@ -6913,6 +6884,7 @@ class HeapSnapshot {
|
|
|
6913
6884
|
nodeSyntheticType;
|
|
6914
6885
|
nodeClosureType;
|
|
6915
6886
|
nodeRegExpType;
|
|
6887
|
+
nodeNumberType;
|
|
6916
6888
|
edgeFieldsCount;
|
|
6917
6889
|
edgeTypeOffset;
|
|
6918
6890
|
edgeNameOffset;
|
|
@@ -6949,6 +6921,9 @@ class HeapSnapshot {
|
|
|
6949
6921
|
#nodeDistancesForRetainersView;
|
|
6950
6922
|
#edgeNamesThatAreNotWeakMaps;
|
|
6951
6923
|
detachednessAndClassIndexArray;
|
|
6924
|
+
nodeNativeContextAttribution;
|
|
6925
|
+
#nativeContextSizes;
|
|
6926
|
+
#nativeContextOrdinals;
|
|
6952
6927
|
#interfaceNames = new Map();
|
|
6953
6928
|
#interfaceDefinitions;
|
|
6954
6929
|
constructor(profile, progress) {
|
|
@@ -6987,6 +6962,7 @@ class HeapSnapshot {
|
|
|
6987
6962
|
this.nodeSyntheticType = this.nodeTypes.indexOf('synthetic');
|
|
6988
6963
|
this.nodeClosureType = this.nodeTypes.indexOf('closure');
|
|
6989
6964
|
this.nodeRegExpType = this.nodeTypes.indexOf('regexp');
|
|
6965
|
+
this.nodeNumberType = this.nodeTypes.indexOf('number');
|
|
6990
6966
|
this.edgeFieldsCount = meta.edge_fields.length;
|
|
6991
6967
|
this.edgeTypeOffset = meta.edge_fields.indexOf('type');
|
|
6992
6968
|
this.edgeNameOffset = meta.edge_fields.indexOf('name_or_index');
|
|
@@ -7014,6 +6990,7 @@ class HeapSnapshot {
|
|
|
7014
6990
|
this.#progress.updateStatus('Building retainers…');
|
|
7015
6991
|
const resultsFromSecondWorker = this.startInitStep1InSecondThread(secondWorker);
|
|
7016
6992
|
this.#progress.updateStatus('Propagating DOM state…');
|
|
6993
|
+
this.initDetachednessAndClassIndex();
|
|
7017
6994
|
this.propagateDOMState();
|
|
7018
6995
|
this.#progress.updateStatus('Calculating node flags…');
|
|
7019
6996
|
this.calculateFlags();
|
|
@@ -7033,8 +7010,11 @@ class HeapSnapshot {
|
|
|
7033
7010
|
this.buildSamples();
|
|
7034
7011
|
this.#progress.updateStatus('Building locations…');
|
|
7035
7012
|
this.buildLocationMap();
|
|
7013
|
+
this.#progress.updateStatus('Calculating native context attribution…');
|
|
7014
|
+
this.calculateNativeContextAttribution();
|
|
7036
7015
|
this.#progress.updateStatus('Calculating retained sizes…');
|
|
7037
7016
|
await this.installResultsFromSecondThread(resultsFromSecondWorker);
|
|
7017
|
+
this.calculateNativeContextSizes();
|
|
7038
7018
|
this.#progress.updateStatus('Calculating statistics…');
|
|
7039
7019
|
this.calculateStatistics();
|
|
7040
7020
|
if (this.profile.snapshot.trace_function_count) {
|
|
@@ -7059,6 +7039,36 @@ class HeapSnapshot {
|
|
|
7059
7039
|
}
|
|
7060
7040
|
this.#progress.updateStatus('Finished processing.');
|
|
7061
7041
|
}
|
|
7042
|
+
nodeIndexForId(nodeId) {
|
|
7043
|
+
const nodesLength = this.nodes.length;
|
|
7044
|
+
const { nodes, nodeFieldCount, nodeIdOffset } = this;
|
|
7045
|
+
for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
|
|
7046
|
+
if (nodes.getValue(nodeIndex + nodeIdOffset) === nodeId) {
|
|
7047
|
+
return nodeIndex;
|
|
7048
|
+
}
|
|
7049
|
+
}
|
|
7050
|
+
return undefined;
|
|
7051
|
+
}
|
|
7052
|
+
getObjectInfo(nodeIndex) {
|
|
7053
|
+
const nodesLength = this.nodes.length;
|
|
7054
|
+
const nodeFieldCount = this.nodeFieldCount;
|
|
7055
|
+
if (!Number.isInteger(nodeIndex) || nodeIndex < 0 || nodeIndex >= nodesLength || nodeIndex % nodeFieldCount !== 0) {
|
|
7056
|
+
throw new Error('Invalid nodeIndex ' + nodeIndex);
|
|
7057
|
+
}
|
|
7058
|
+
const node = this.createNode(nodeIndex);
|
|
7059
|
+
return {
|
|
7060
|
+
id: node.id(),
|
|
7061
|
+
name: node.name(),
|
|
7062
|
+
type: node.type(),
|
|
7063
|
+
nodeIndex,
|
|
7064
|
+
detachedness: node.detachedness(),
|
|
7065
|
+
selfSize: node.selfSize(),
|
|
7066
|
+
retainedSize: node.retainedSize(),
|
|
7067
|
+
distance: node.distance(),
|
|
7068
|
+
edgeCount: node.edgesCount(),
|
|
7069
|
+
retainerCount: node.retainersCount(),
|
|
7070
|
+
};
|
|
7071
|
+
}
|
|
7062
7072
|
startInitStep1InSecondThread(secondWorker) {
|
|
7063
7073
|
const resultsFromSecondWorker = new Promise((resolve, reject) => {
|
|
7064
7074
|
const listener = (e) => {
|
|
@@ -7256,6 +7266,79 @@ class HeapSnapshot {
|
|
|
7256
7266
|
const key = filter ? filter.key : 'allObjects';
|
|
7257
7267
|
return this.getAggregatesByClassKey(false, key, filter);
|
|
7258
7268
|
}
|
|
7269
|
+
getDuplicateStrings() {
|
|
7270
|
+
const filter = this.createNamedFilter('duplicatedStrings');
|
|
7271
|
+
const untruncatedGroups = new Map();
|
|
7272
|
+
const truncatedGroups = new Map();
|
|
7273
|
+
const node = this.createNode(0);
|
|
7274
|
+
for (let i = 0; i < this.nodeCount; ++i) {
|
|
7275
|
+
node.nodeIndex = i * this.nodeFieldCount;
|
|
7276
|
+
if (filter(node)) {
|
|
7277
|
+
const name = node.name();
|
|
7278
|
+
const truncated = node.nodeIsTruncatedString();
|
|
7279
|
+
if (truncated) {
|
|
7280
|
+
const length = node.nodeStringLength();
|
|
7281
|
+
const hash = node.nodeStringHash();
|
|
7282
|
+
let groups = truncatedGroups.get(name);
|
|
7283
|
+
if (!groups) {
|
|
7284
|
+
groups = [];
|
|
7285
|
+
truncatedGroups.set(name, groups);
|
|
7286
|
+
}
|
|
7287
|
+
let group = groups.find(g => g.length === length && g.hash === hash);
|
|
7288
|
+
if (!group) {
|
|
7289
|
+
group = {
|
|
7290
|
+
value: name,
|
|
7291
|
+
count: 0,
|
|
7292
|
+
totalSelfSize: 0,
|
|
7293
|
+
totalRetainedSize: 0,
|
|
7294
|
+
nodes: [],
|
|
7295
|
+
truncated: true,
|
|
7296
|
+
length,
|
|
7297
|
+
hash,
|
|
7298
|
+
};
|
|
7299
|
+
groups.push(group);
|
|
7300
|
+
}
|
|
7301
|
+
group.count++;
|
|
7302
|
+
group.totalSelfSize += node.selfSize();
|
|
7303
|
+
group.totalRetainedSize += node.retainedSize();
|
|
7304
|
+
group.nodes.push({
|
|
7305
|
+
id: node.id(),
|
|
7306
|
+
selfSize: node.selfSize(),
|
|
7307
|
+
retainedSize: node.retainedSize(),
|
|
7308
|
+
distance: node.distance(),
|
|
7309
|
+
});
|
|
7310
|
+
}
|
|
7311
|
+
else {
|
|
7312
|
+
let group = untruncatedGroups.get(name);
|
|
7313
|
+
if (!group) {
|
|
7314
|
+
group = {
|
|
7315
|
+
value: name,
|
|
7316
|
+
count: 0,
|
|
7317
|
+
totalSelfSize: 0,
|
|
7318
|
+
totalRetainedSize: 0,
|
|
7319
|
+
nodes: [],
|
|
7320
|
+
truncated: false,
|
|
7321
|
+
};
|
|
7322
|
+
untruncatedGroups.set(name, group);
|
|
7323
|
+
}
|
|
7324
|
+
group.count++;
|
|
7325
|
+
group.totalSelfSize += node.selfSize();
|
|
7326
|
+
group.totalRetainedSize += node.retainedSize();
|
|
7327
|
+
group.nodes.push({
|
|
7328
|
+
id: node.id(),
|
|
7329
|
+
selfSize: node.selfSize(),
|
|
7330
|
+
retainedSize: node.retainedSize(),
|
|
7331
|
+
distance: node.distance(),
|
|
7332
|
+
});
|
|
7333
|
+
}
|
|
7334
|
+
}
|
|
7335
|
+
}
|
|
7336
|
+
const allGroups = [
|
|
7337
|
+
...untruncatedGroups.values(),
|
|
7338
|
+
...Array.from(truncatedGroups.values()).flat(),
|
|
7339
|
+
];
|
|
7340
|
+
return allGroups.sort((a, b) => b.totalRetainedSize - a.totalRetainedSize);
|
|
7341
|
+
}
|
|
7259
7342
|
createNodeIdFilter(minNodeId, maxNodeId) {
|
|
7260
7343
|
function nodeIdFilter(node) {
|
|
7261
7344
|
const id = node.id();
|
|
@@ -7310,6 +7393,12 @@ class HeapSnapshot {
|
|
|
7310
7393
|
}
|
|
7311
7394
|
};
|
|
7312
7395
|
switch (filterName) {
|
|
7396
|
+
case 'objectsRetainedByContexts':
|
|
7397
|
+
traverse((_node, edge) => {
|
|
7398
|
+
return !this.isContextObject(edge.node());
|
|
7399
|
+
});
|
|
7400
|
+
markUnreachableNodes();
|
|
7401
|
+
return (node) => !getBit(node);
|
|
7313
7402
|
case 'objectsRetainedByDetachedDomNodes':
|
|
7314
7403
|
traverse((_node, edge) => {
|
|
7315
7404
|
return edge.node().detachedness() !== 2 ;
|
|
@@ -7322,29 +7411,8 @@ class HeapSnapshot {
|
|
|
7322
7411
|
});
|
|
7323
7412
|
markUnreachableNodes();
|
|
7324
7413
|
return (node) => !getBit(node);
|
|
7325
|
-
case 'duplicatedStrings':
|
|
7326
|
-
|
|
7327
|
-
const node = this.createNode(0);
|
|
7328
|
-
for (let i = 0; i < this.nodeCount; ++i) {
|
|
7329
|
-
node.nodeIndex = i * this.nodeFieldCount;
|
|
7330
|
-
const rawType = node.rawType();
|
|
7331
|
-
if (rawType === this.nodeStringType || rawType === this.nodeConsStringType) {
|
|
7332
|
-
if (node.isFlatConsString()) {
|
|
7333
|
-
continue;
|
|
7334
|
-
}
|
|
7335
|
-
const name = node.name();
|
|
7336
|
-
const alreadyVisitedNodeIndex = stringToNodeIndexMap.get(name);
|
|
7337
|
-
if (alreadyVisitedNodeIndex === undefined) {
|
|
7338
|
-
stringToNodeIndexMap.set(name, node.nodeIndex);
|
|
7339
|
-
}
|
|
7340
|
-
else {
|
|
7341
|
-
bitmap.setBit(alreadyVisitedNodeIndex / this.nodeFieldCount);
|
|
7342
|
-
bitmap.setBit(node.nodeIndex / this.nodeFieldCount);
|
|
7343
|
-
}
|
|
7344
|
-
}
|
|
7345
|
-
}
|
|
7346
|
-
return getBit;
|
|
7347
|
-
}
|
|
7414
|
+
case 'duplicatedStrings':
|
|
7415
|
+
return this.createDuplicatedStringsFilter(bitmap);
|
|
7348
7416
|
case 'objectsRetainedByEventHandlers': {
|
|
7349
7417
|
const node = this.createNode(0);
|
|
7350
7418
|
const nodeFieldCount = this.nodeFieldCount;
|
|
@@ -7383,9 +7451,79 @@ class HeapSnapshot {
|
|
|
7383
7451
|
markUnreachableNodes();
|
|
7384
7452
|
return (node) => !getBit(node);
|
|
7385
7453
|
}
|
|
7454
|
+
case 'sharedNativeContext':
|
|
7455
|
+
return (node) => {
|
|
7456
|
+
const ordinal = node.nodeIndex / this.nodeFieldCount;
|
|
7457
|
+
return this.nodeNativeContextAttribution[ordinal] === SHARED_NATIVE_CONTEXT;
|
|
7458
|
+
};
|
|
7459
|
+
case 'noNativeContext':
|
|
7460
|
+
return (node) => {
|
|
7461
|
+
const ordinal = node.nodeIndex / this.nodeFieldCount;
|
|
7462
|
+
return this.nodeNativeContextAttribution[ordinal] === NO_NATIVE_CONTEXT;
|
|
7463
|
+
};
|
|
7464
|
+
default:
|
|
7465
|
+
if (filterName.startsWith('nativeContext_')) {
|
|
7466
|
+
const targetNodeIndex = Number(filterName.substring('nativeContext_'.length));
|
|
7467
|
+
const targetOrdinal = targetNodeIndex / this.nodeFieldCount;
|
|
7468
|
+
return (node) => {
|
|
7469
|
+
const ordinal = node.nodeIndex / this.nodeFieldCount;
|
|
7470
|
+
return this.nodeNativeContextAttribution[ordinal] === targetOrdinal;
|
|
7471
|
+
};
|
|
7472
|
+
}
|
|
7386
7473
|
}
|
|
7387
7474
|
throw new Error('Invalid filter name');
|
|
7388
7475
|
}
|
|
7476
|
+
createDuplicatedStringsFilter(bitmap) {
|
|
7477
|
+
const untruncatedStringToNodeIndexMap = new Map();
|
|
7478
|
+
const truncatedStringToNodeIndexesMap = new Map();
|
|
7479
|
+
const node = this.createNode(0);
|
|
7480
|
+
for (let i = 0; i < this.nodeCount; ++i) {
|
|
7481
|
+
node.nodeIndex = i * this.nodeFieldCount;
|
|
7482
|
+
const rawType = node.rawType();
|
|
7483
|
+
if (rawType !== this.nodeStringType && rawType !== this.nodeConsStringType) {
|
|
7484
|
+
continue;
|
|
7485
|
+
}
|
|
7486
|
+
if (node.isFlatConsString()) {
|
|
7487
|
+
continue;
|
|
7488
|
+
}
|
|
7489
|
+
if (node.selfSize() === 0) {
|
|
7490
|
+
continue;
|
|
7491
|
+
}
|
|
7492
|
+
const name = node.name();
|
|
7493
|
+
const truncated = node.nodeIsTruncatedString();
|
|
7494
|
+
if (truncated) {
|
|
7495
|
+
const length = node.nodeStringLength();
|
|
7496
|
+
const hash = node.nodeStringHash();
|
|
7497
|
+
let entries = truncatedStringToNodeIndexesMap.get(name);
|
|
7498
|
+
if (!entries) {
|
|
7499
|
+
entries = [];
|
|
7500
|
+
truncatedStringToNodeIndexesMap.set(name, entries);
|
|
7501
|
+
}
|
|
7502
|
+
const match = entries.find(e => e.length === length && e.hash === hash);
|
|
7503
|
+
if (match) {
|
|
7504
|
+
bitmap.setBit(match.nodeIndex / this.nodeFieldCount);
|
|
7505
|
+
bitmap.setBit(node.nodeIndex / this.nodeFieldCount);
|
|
7506
|
+
}
|
|
7507
|
+
else {
|
|
7508
|
+
entries.push({ nodeIndex: node.nodeIndex, length, hash });
|
|
7509
|
+
}
|
|
7510
|
+
}
|
|
7511
|
+
else {
|
|
7512
|
+
const alreadyVisitedNodeIndex = untruncatedStringToNodeIndexMap.get(name);
|
|
7513
|
+
if (alreadyVisitedNodeIndex === undefined) {
|
|
7514
|
+
untruncatedStringToNodeIndexMap.set(name, node.nodeIndex);
|
|
7515
|
+
}
|
|
7516
|
+
else {
|
|
7517
|
+
bitmap.setBit(alreadyVisitedNodeIndex / this.nodeFieldCount);
|
|
7518
|
+
bitmap.setBit(node.nodeIndex / this.nodeFieldCount);
|
|
7519
|
+
}
|
|
7520
|
+
}
|
|
7521
|
+
}
|
|
7522
|
+
return (node) => {
|
|
7523
|
+
const ordinal = node.nodeIndex / this.nodeFieldCount;
|
|
7524
|
+
return bitmap.getBit(ordinal);
|
|
7525
|
+
};
|
|
7526
|
+
}
|
|
7389
7527
|
getAggregatesByClassKey(sortedIndexes, key, filter) {
|
|
7390
7528
|
let aggregates;
|
|
7391
7529
|
if (key && this.#aggregates[key]) {
|
|
@@ -7453,6 +7591,9 @@ class HeapSnapshot {
|
|
|
7453
7591
|
isUserRoot(_node) {
|
|
7454
7592
|
return true;
|
|
7455
7593
|
}
|
|
7594
|
+
isContextObject(_node) {
|
|
7595
|
+
return false;
|
|
7596
|
+
}
|
|
7456
7597
|
calculateShallowSizes() {
|
|
7457
7598
|
}
|
|
7458
7599
|
calculateDistances(isForRetainersView, filter) {
|
|
@@ -7701,7 +7842,7 @@ class HeapSnapshot {
|
|
|
7701
7842
|
return true;
|
|
7702
7843
|
}
|
|
7703
7844
|
static async calculateDominatorsAndRetainedSizes(inputs) {
|
|
7704
|
-
const { nodeCount, firstEdgeIndexes, edgeFieldsCount, nodeFieldCount, firstRetainerIndex, retainingEdges, retainingNodes, edgeToNodeOrdinals, rootNodeOrdinal, essentialEdges, nodeSelfSizesPromise, port } = inputs;
|
|
7845
|
+
const { nodeCount, firstEdgeIndexes, edgeFieldsCount, nodeFieldCount, firstRetainerIndex, retainingEdges, retainingNodes, edgeToNodeOrdinals, rootNodeOrdinal, essentialEdges, nodeSelfSizesPromise, port, } = inputs;
|
|
7705
7846
|
function isEssentialEdge(edgeIndex) {
|
|
7706
7847
|
return essentialEdges.getBit(edgeIndex / edgeFieldsCount);
|
|
7707
7848
|
}
|
|
@@ -7885,9 +8026,6 @@ class HeapSnapshot {
|
|
|
7885
8026
|
}
|
|
7886
8027
|
calculateObjectNames() {
|
|
7887
8028
|
const { nodes, nodeCount, nodeNameOffset, nodeNativeType, nodeHiddenType, nodeObjectType, nodeCodeType, nodeClosureType, nodeRegExpType, } = this;
|
|
7888
|
-
if (this.nodeDetachednessAndClassIndexOffset === -1) {
|
|
7889
|
-
this.detachednessAndClassIndexArray = new Uint32Array(nodeCount);
|
|
7890
|
-
}
|
|
7891
8029
|
const stringTable = new Map();
|
|
7892
8030
|
const getIndexForString = (s) => {
|
|
7893
8031
|
let index = stringTable.get(s);
|
|
@@ -7940,6 +8078,215 @@ class HeapSnapshot {
|
|
|
7940
8078
|
node.nodeIndex = node.nextNodeIndex();
|
|
7941
8079
|
}
|
|
7942
8080
|
}
|
|
8081
|
+
calculateNativeContextAttribution() {
|
|
8082
|
+
const attribution = new Int32Array(this.nodeCount).fill(NO_NATIVE_CONTEXT);
|
|
8083
|
+
const isFixed = createBitVector(this.nodeCount);
|
|
8084
|
+
const edgeTargets = this.buildInitEdgeTargets();
|
|
8085
|
+
this.#nativeContextOrdinals = [];
|
|
8086
|
+
for (let ordinal = 0; ordinal < this.nodeCount; ordinal++) {
|
|
8087
|
+
if (this.isNativeContext(ordinal)) {
|
|
8088
|
+
this.#nativeContextOrdinals.push(ordinal);
|
|
8089
|
+
attribution[ordinal] = ordinal;
|
|
8090
|
+
isFixed.setBit(ordinal);
|
|
8091
|
+
}
|
|
8092
|
+
else {
|
|
8093
|
+
const owner = this.inferFixedNativeContextForOrdinal(ordinal, edgeTargets);
|
|
8094
|
+
if (owner >= 0) {
|
|
8095
|
+
attribution[ordinal] = owner;
|
|
8096
|
+
isFixed.setBit(ordinal);
|
|
8097
|
+
}
|
|
8098
|
+
}
|
|
8099
|
+
}
|
|
8100
|
+
this.propagateNativeContextAttribution(attribution, isFixed);
|
|
8101
|
+
this.nodeNativeContextAttribution = attribution;
|
|
8102
|
+
}
|
|
8103
|
+
calculateNativeContextSizes() {
|
|
8104
|
+
const nodeFieldCount = this.nodeFieldCount;
|
|
8105
|
+
const node = this.createNode(0);
|
|
8106
|
+
const nativeContexts = [];
|
|
8107
|
+
const ordinalToInfo = new Map();
|
|
8108
|
+
for (const ordinal of this.#nativeContextOrdinals) {
|
|
8109
|
+
node.nodeIndex = ordinal * nodeFieldCount;
|
|
8110
|
+
const info = {
|
|
8111
|
+
nodeId: node.id(),
|
|
8112
|
+
nodeIndex: node.nodeIndex,
|
|
8113
|
+
nodeName: node.name(),
|
|
8114
|
+
attributedSize: 0,
|
|
8115
|
+
retainedSize: node.retainedSize(),
|
|
8116
|
+
selfSize: node.selfSize(),
|
|
8117
|
+
};
|
|
8118
|
+
nativeContexts.push(info);
|
|
8119
|
+
ordinalToInfo.set(ordinal, info);
|
|
8120
|
+
}
|
|
8121
|
+
let sharedSize = 0;
|
|
8122
|
+
let noAttributionSize = 0;
|
|
8123
|
+
const selfSizeOffset = this.nodeSelfSizeOffset;
|
|
8124
|
+
const nodes = this.nodes;
|
|
8125
|
+
for (let i = 0; i < this.nodeCount; ++i) {
|
|
8126
|
+
const ownerOrdinal = this.nodeNativeContextAttribution[i];
|
|
8127
|
+
const selfSize = nodes.getValue(i * nodeFieldCount + selfSizeOffset);
|
|
8128
|
+
if (ownerOrdinal === SHARED_NATIVE_CONTEXT) {
|
|
8129
|
+
sharedSize += selfSize;
|
|
8130
|
+
}
|
|
8131
|
+
else if (ownerOrdinal === NO_NATIVE_CONTEXT) {
|
|
8132
|
+
noAttributionSize += selfSize;
|
|
8133
|
+
}
|
|
8134
|
+
else {
|
|
8135
|
+
console.assert(ownerOrdinal >= 0, 'ownerOrdinal should be >= 0');
|
|
8136
|
+
const info = ordinalToInfo.get(ownerOrdinal);
|
|
8137
|
+
console.assert(info !== undefined, 'info should exist');
|
|
8138
|
+
if (info) {
|
|
8139
|
+
info.attributedSize += selfSize;
|
|
8140
|
+
}
|
|
8141
|
+
}
|
|
8142
|
+
}
|
|
8143
|
+
this.#nativeContextSizes = {
|
|
8144
|
+
nativeContexts,
|
|
8145
|
+
sharedSize,
|
|
8146
|
+
noAttributionSize,
|
|
8147
|
+
};
|
|
8148
|
+
}
|
|
8149
|
+
buildInitEdgeTargets() {
|
|
8150
|
+
const { nodeCount, nodeFieldCount, containmentEdges, edgeFieldsCount, edgeTypeOffset, edgeNameOffset, edgeToNodeOffset, edgeInternalType, firstEdgeIndexes, strings, } = this;
|
|
8151
|
+
const nativeContext = new Int32Array(nodeCount).fill(-1);
|
|
8152
|
+
const map = new Int32Array(nodeCount).fill(-1);
|
|
8153
|
+
const nativeContextIdx = strings.indexOf('native_context');
|
|
8154
|
+
const mapIdx = strings.indexOf('map');
|
|
8155
|
+
for (let ordinal = 0; ordinal < nodeCount; ordinal++) {
|
|
8156
|
+
const first = firstEdgeIndexes[ordinal];
|
|
8157
|
+
const last = firstEdgeIndexes[ordinal + 1];
|
|
8158
|
+
for (let edgeIndex = first; edgeIndex < last; edgeIndex += edgeFieldsCount) {
|
|
8159
|
+
const edgeType = containmentEdges.getValue(edgeIndex + edgeTypeOffset);
|
|
8160
|
+
if (edgeType !== edgeInternalType) {
|
|
8161
|
+
continue;
|
|
8162
|
+
}
|
|
8163
|
+
const nameIdx = containmentEdges.getValue(edgeIndex + edgeNameOffset);
|
|
8164
|
+
const childNodeIndex = containmentEdges.getValue(edgeIndex + edgeToNodeOffset);
|
|
8165
|
+
const childOrdinal = childNodeIndex / nodeFieldCount;
|
|
8166
|
+
if (nameIdx === nativeContextIdx && nativeContext[ordinal] === -1 && this.isNativeContext(childOrdinal)) {
|
|
8167
|
+
nativeContext[ordinal] = childOrdinal;
|
|
8168
|
+
}
|
|
8169
|
+
else if (nameIdx === mapIdx && map[ordinal] === -1) {
|
|
8170
|
+
map[ordinal] = childOrdinal;
|
|
8171
|
+
}
|
|
8172
|
+
}
|
|
8173
|
+
}
|
|
8174
|
+
return { nativeContext, map };
|
|
8175
|
+
}
|
|
8176
|
+
inferFixedNativeContextForOrdinal(ordinal, edgeTargets) {
|
|
8177
|
+
const mapOrdinal = edgeTargets.map[ordinal];
|
|
8178
|
+
if (mapOrdinal >= 0) {
|
|
8179
|
+
const metaMapOrdinal = edgeTargets.map[mapOrdinal];
|
|
8180
|
+
if (metaMapOrdinal >= 0) {
|
|
8181
|
+
const mapNativeContextOrdinal = edgeTargets.nativeContext[metaMapOrdinal];
|
|
8182
|
+
if (mapNativeContextOrdinal >= 0) {
|
|
8183
|
+
return mapNativeContextOrdinal;
|
|
8184
|
+
}
|
|
8185
|
+
}
|
|
8186
|
+
}
|
|
8187
|
+
return NO_NATIVE_CONTEXT;
|
|
8188
|
+
}
|
|
8189
|
+
mergeNativeContextOwner(current, incoming) {
|
|
8190
|
+
console.assert(incoming !== NO_NATIVE_CONTEXT, 'Incoming owner should not be NO_NATIVE_CONTEXT');
|
|
8191
|
+
if (current === SHARED_NATIVE_CONTEXT || incoming === SHARED_NATIVE_CONTEXT) {
|
|
8192
|
+
return SHARED_NATIVE_CONTEXT;
|
|
8193
|
+
}
|
|
8194
|
+
if (current === NO_NATIVE_CONTEXT) {
|
|
8195
|
+
return incoming;
|
|
8196
|
+
}
|
|
8197
|
+
if (current === incoming) {
|
|
8198
|
+
return current;
|
|
8199
|
+
}
|
|
8200
|
+
return SHARED_NATIVE_CONTEXT;
|
|
8201
|
+
}
|
|
8202
|
+
propagateNativeContextAttribution(attribution, isFixed) {
|
|
8203
|
+
const { nodeCount, containmentEdges, edgeFieldsCount, edgeTypeOffset, edgeToNodeOffset, edgeShortcutType, edgeWeakType, nodeFieldCount, firstEdgeIndexes, } = this;
|
|
8204
|
+
const queue = [];
|
|
8205
|
+
for (let ordinal = 0; ordinal < nodeCount; ordinal++) {
|
|
8206
|
+
if (isFixed.getBit(ordinal)) {
|
|
8207
|
+
queue.push(ordinal);
|
|
8208
|
+
}
|
|
8209
|
+
}
|
|
8210
|
+
let queueIndex = 0;
|
|
8211
|
+
while (queueIndex < queue.length) {
|
|
8212
|
+
const ordinal = queue[queueIndex];
|
|
8213
|
+
queueIndex++;
|
|
8214
|
+
const current = attribution[ordinal];
|
|
8215
|
+
console.assert(current !== NO_NATIVE_CONTEXT, 'Queue should not contain unattributed nodes');
|
|
8216
|
+
const first = firstEdgeIndexes[ordinal];
|
|
8217
|
+
const last = firstEdgeIndexes[ordinal + 1];
|
|
8218
|
+
for (let edgeIndex = first; edgeIndex < last; edgeIndex += edgeFieldsCount) {
|
|
8219
|
+
const edgeType = containmentEdges.getValue(edgeIndex + edgeTypeOffset);
|
|
8220
|
+
if (edgeType === edgeShortcutType || edgeType === edgeWeakType) {
|
|
8221
|
+
continue;
|
|
8222
|
+
}
|
|
8223
|
+
const childNodeIndex = containmentEdges.getValue(edgeIndex + edgeToNodeOffset);
|
|
8224
|
+
const childOrdinal = childNodeIndex / nodeFieldCount;
|
|
8225
|
+
if (childOrdinal === ordinal || isFixed.getBit(childOrdinal)) {
|
|
8226
|
+
continue;
|
|
8227
|
+
}
|
|
8228
|
+
const merged = this.mergeNativeContextOwner(attribution[childOrdinal], current);
|
|
8229
|
+
if (merged !== attribution[childOrdinal]) {
|
|
8230
|
+
attribution[childOrdinal] = merged;
|
|
8231
|
+
queue.push(childOrdinal);
|
|
8232
|
+
}
|
|
8233
|
+
}
|
|
8234
|
+
}
|
|
8235
|
+
}
|
|
8236
|
+
getNativeContextSizes() {
|
|
8237
|
+
return this.#nativeContextSizes;
|
|
8238
|
+
}
|
|
8239
|
+
getRetainedByContextSummary() {
|
|
8240
|
+
const isRetainedByContext = this.createNamedFilter('objectsRetainedByContexts');
|
|
8241
|
+
let contextCount = 0;
|
|
8242
|
+
let retainedByContextSize = 0;
|
|
8243
|
+
let retainedByContextCount = 0;
|
|
8244
|
+
let notRetainedByContextSize = 0;
|
|
8245
|
+
let notRetainedByContextCount = 0;
|
|
8246
|
+
const node = this.rootNode();
|
|
8247
|
+
const { nodes, nodeFieldCount, nodeSelfSizeOffset: selfSizeOffset } = this;
|
|
8248
|
+
const nodesLength = nodes.length;
|
|
8249
|
+
for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
|
|
8250
|
+
const selfSize = nodes.getValue(nodeIndex + selfSizeOffset);
|
|
8251
|
+
if (!selfSize) {
|
|
8252
|
+
continue;
|
|
8253
|
+
}
|
|
8254
|
+
node.nodeIndex = nodeIndex;
|
|
8255
|
+
if (isRetainedByContext(node)) {
|
|
8256
|
+
retainedByContextCount++;
|
|
8257
|
+
retainedByContextSize += selfSize;
|
|
8258
|
+
}
|
|
8259
|
+
else {
|
|
8260
|
+
notRetainedByContextCount++;
|
|
8261
|
+
notRetainedByContextSize += selfSize;
|
|
8262
|
+
}
|
|
8263
|
+
if (this.isContextObject(node)) {
|
|
8264
|
+
contextCount++;
|
|
8265
|
+
}
|
|
8266
|
+
}
|
|
8267
|
+
return {
|
|
8268
|
+
contextCount,
|
|
8269
|
+
retainedByContextSize,
|
|
8270
|
+
retainedByContextCount,
|
|
8271
|
+
notRetainedByContextSize,
|
|
8272
|
+
notRetainedByContextCount,
|
|
8273
|
+
totalSize: retainedByContextSize + notRetainedByContextSize,
|
|
8274
|
+
};
|
|
8275
|
+
}
|
|
8276
|
+
nodeNativeContext(nodeIndex) {
|
|
8277
|
+
const ordinal = nodeIndex / this.nodeFieldCount;
|
|
8278
|
+
const nativeContextOrdinal = this.nodeNativeContextAttribution[ordinal];
|
|
8279
|
+
if (nativeContextOrdinal < 0) {
|
|
8280
|
+
return nativeContextOrdinal;
|
|
8281
|
+
}
|
|
8282
|
+
return nativeContextOrdinal * this.nodeFieldCount;
|
|
8283
|
+
}
|
|
8284
|
+
isNativeContext(nodeOrdinal) {
|
|
8285
|
+
const nameIdx = this.nodes.getValue(nodeOrdinal * this.nodeFieldCount + this.nodeNameOffset);
|
|
8286
|
+
const name = this.strings[nameIdx];
|
|
8287
|
+
return name === 'system / NativeContext' || name.startsWith('system / NativeContext / ') ||
|
|
8288
|
+
name === 'Detached system / NativeContext' || name.startsWith('Detached system / NativeContext / ');
|
|
8289
|
+
}
|
|
7943
8290
|
interfaceDefinitions() {
|
|
7944
8291
|
return JSON.stringify(this.#interfaceDefinitions ?? []);
|
|
7945
8292
|
}
|
|
@@ -8114,11 +8461,32 @@ class HeapSnapshot {
|
|
|
8114
8461
|
}
|
|
8115
8462
|
return null;
|
|
8116
8463
|
}
|
|
8464
|
+
initDetachednessAndClassIndex() {
|
|
8465
|
+
this.detachednessAndClassIndexArray = new Uint32Array(this.nodeCount);
|
|
8466
|
+
if (this.nodeDetachednessAndClassIndexOffset !== -1) {
|
|
8467
|
+
const { nodeFieldCount, nodeDetachednessAndClassIndexOffset: offset } = this;
|
|
8468
|
+
for (let i = 0; i < this.nodeCount; ++i) {
|
|
8469
|
+
this.detachednessAndClassIndexArray[i] = Number(this.nodes.getValue(i * nodeFieldCount + offset));
|
|
8470
|
+
}
|
|
8471
|
+
}
|
|
8472
|
+
else {
|
|
8473
|
+
const node = this.rootNode();
|
|
8474
|
+
const nodesLength = this.nodes.length;
|
|
8475
|
+
const { nodeFieldCount, nodeNativeType, nodeTypeOffset } = this;
|
|
8476
|
+
for (let nodeIndex = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount) {
|
|
8477
|
+
if (this.nodes.getValue(nodeIndex + nodeTypeOffset) === nodeNativeType) {
|
|
8478
|
+
node.nodeIndex = nodeIndex;
|
|
8479
|
+
if (node.name().startsWith('Detached ')) {
|
|
8480
|
+
node.setDetachedness(2 );
|
|
8481
|
+
}
|
|
8482
|
+
}
|
|
8483
|
+
}
|
|
8484
|
+
}
|
|
8485
|
+
}
|
|
8117
8486
|
propagateDOMState() {
|
|
8118
8487
|
if (this.nodeDetachednessAndClassIndexOffset === -1) {
|
|
8119
8488
|
return;
|
|
8120
8489
|
}
|
|
8121
|
-
console.time('propagateDOMState');
|
|
8122
8490
|
const visited = new Uint8Array(this.nodeCount);
|
|
8123
8491
|
const attached = [];
|
|
8124
8492
|
const detached = [];
|
|
@@ -8177,7 +8545,6 @@ class HeapSnapshot {
|
|
|
8177
8545
|
}
|
|
8178
8546
|
propagateState(this, nodeOrdinal, 2 );
|
|
8179
8547
|
}
|
|
8180
|
-
console.timeEnd('propagateDOMState');
|
|
8181
8548
|
}
|
|
8182
8549
|
buildSamples() {
|
|
8183
8550
|
const samples = this.#rawSamples;
|
|
@@ -8282,6 +8649,8 @@ class HeapSnapshot {
|
|
|
8282
8649
|
const nodeAId = baseIds[i];
|
|
8283
8650
|
if (nodeAId < nodeB.id()) {
|
|
8284
8651
|
diff.deletedIndexes.push(baseIndexes[i]);
|
|
8652
|
+
diff.deletedIds.push(nodeAId);
|
|
8653
|
+
diff.deletedSelfSizes.push(baseSelfSizes[i]);
|
|
8285
8654
|
diff.removedCount++;
|
|
8286
8655
|
diff.removedSize += baseSelfSizes[i];
|
|
8287
8656
|
++i;
|
|
@@ -8289,6 +8658,8 @@ class HeapSnapshot {
|
|
|
8289
8658
|
else if (nodeAId >
|
|
8290
8659
|
nodeB.id()) {
|
|
8291
8660
|
diff.addedIndexes.push(indexes[j]);
|
|
8661
|
+
diff.addedIds.push(nodeB.id());
|
|
8662
|
+
diff.addedSelfSizes.push(nodeB.selfSize());
|
|
8292
8663
|
diff.addedCount++;
|
|
8293
8664
|
diff.addedSize += nodeB.selfSize();
|
|
8294
8665
|
nodeB.nodeIndex = indexes[++j];
|
|
@@ -8300,12 +8671,16 @@ class HeapSnapshot {
|
|
|
8300
8671
|
}
|
|
8301
8672
|
while (i < l) {
|
|
8302
8673
|
diff.deletedIndexes.push(baseIndexes[i]);
|
|
8674
|
+
diff.deletedIds.push(baseIds[i]);
|
|
8675
|
+
diff.deletedSelfSizes.push(baseSelfSizes[i]);
|
|
8303
8676
|
diff.removedCount++;
|
|
8304
8677
|
diff.removedSize += baseSelfSizes[i];
|
|
8305
8678
|
++i;
|
|
8306
8679
|
}
|
|
8307
8680
|
while (j < m) {
|
|
8308
8681
|
diff.addedIndexes.push(indexes[j]);
|
|
8682
|
+
diff.addedIds.push(nodeB.id());
|
|
8683
|
+
diff.addedSelfSizes.push(nodeB.selfSize());
|
|
8309
8684
|
diff.addedCount++;
|
|
8310
8685
|
diff.addedSize += nodeB.selfSize();
|
|
8311
8686
|
nodeB.nodeIndex = indexes[++j];
|
|
@@ -8335,11 +8710,54 @@ class HeapSnapshot {
|
|
|
8335
8710
|
}
|
|
8336
8711
|
return null;
|
|
8337
8712
|
}
|
|
8338
|
-
createEdgesProvider(nodeIndex) {
|
|
8713
|
+
createEdgesProvider(nodeIndex, options) {
|
|
8339
8714
|
const node = this.createNode(nodeIndex);
|
|
8340
|
-
const
|
|
8715
|
+
const defaultFilter = this.containmentEdgesFilter();
|
|
8716
|
+
const minRetainedSize = options?.minRetainedSize;
|
|
8717
|
+
const excludePrimitives = options?.excludePrimitives ?? false;
|
|
8718
|
+
let filter = defaultFilter;
|
|
8719
|
+
if (minRetainedSize !== undefined || excludePrimitives) {
|
|
8720
|
+
filter = (edge) => {
|
|
8721
|
+
if (defaultFilter && !defaultFilter(edge)) {
|
|
8722
|
+
return false;
|
|
8723
|
+
}
|
|
8724
|
+
const targetNode = edge.node();
|
|
8725
|
+
if (minRetainedSize !== undefined && targetNode.retainedSize() < minRetainedSize) {
|
|
8726
|
+
return false;
|
|
8727
|
+
}
|
|
8728
|
+
if (excludePrimitives) {
|
|
8729
|
+
const rawType = targetNode.rawType();
|
|
8730
|
+
if (rawType === this.nodeNumberType) {
|
|
8731
|
+
return false;
|
|
8732
|
+
}
|
|
8733
|
+
if (rawType === this.nodeNativeType) {
|
|
8734
|
+
const targetName = targetNode.rawName();
|
|
8735
|
+
if (targetName === 'undefined' || targetName === 'null' || targetName === 'true' ||
|
|
8736
|
+
targetName === 'false') {
|
|
8737
|
+
return false;
|
|
8738
|
+
}
|
|
8739
|
+
}
|
|
8740
|
+
}
|
|
8741
|
+
return true;
|
|
8742
|
+
};
|
|
8743
|
+
}
|
|
8341
8744
|
const indexProvider = new HeapSnapshotEdgeIndexProvider(this);
|
|
8342
|
-
|
|
8745
|
+
const provider = new HeapSnapshotEdgesProvider(this, filter, node.edges(), indexProvider);
|
|
8746
|
+
if (options?.sortBy) {
|
|
8747
|
+
const sortBy = options.sortBy;
|
|
8748
|
+
let comparator;
|
|
8749
|
+
if (sortBy === 'selfSize') {
|
|
8750
|
+
comparator = new ComparatorConfig('selfSize', false, '!edgeName', true);
|
|
8751
|
+
}
|
|
8752
|
+
else if (sortBy === 'name') {
|
|
8753
|
+
comparator = new ComparatorConfig('!edgeName', true, 'retainedSize', false);
|
|
8754
|
+
}
|
|
8755
|
+
else {
|
|
8756
|
+
comparator = new ComparatorConfig('retainedSize', false, '!edgeName', true);
|
|
8757
|
+
}
|
|
8758
|
+
provider.sortAndRewind(comparator);
|
|
8759
|
+
}
|
|
8760
|
+
return provider;
|
|
8343
8761
|
}
|
|
8344
8762
|
createEdgesProviderForTest(nodeIndex, filter) {
|
|
8345
8763
|
const node = this.createNode(nodeIndex);
|
|
@@ -8358,6 +8776,133 @@ class HeapSnapshot {
|
|
|
8358
8776
|
const indexProvider = new HeapSnapshotRetainerEdgeIndexProvider(this);
|
|
8359
8777
|
return new HeapSnapshotEdgesProvider(this, filter, node.retainers(), indexProvider);
|
|
8360
8778
|
}
|
|
8779
|
+
getRetainingPaths(nodeIndex, maxDepth = 30, maxNodes = 5000, maxSiblings = 100) {
|
|
8780
|
+
const { nodeFieldCount, firstRetainerIndex, retainingNodes, retainingEdges, edgeTypeOffset, edgeWeakType, containmentEdges, } = this;
|
|
8781
|
+
const distances = this.#nodeDistancesForRetainersView ?? this.nodeDistances;
|
|
8782
|
+
let traversedNodesCount = 0;
|
|
8783
|
+
const visiting = new Set();
|
|
8784
|
+
const visited = new Map();
|
|
8785
|
+
const rootDistance = 2;
|
|
8786
|
+
const limitsReached = {};
|
|
8787
|
+
const buildForest = (currentIndex, currentDepth) => {
|
|
8788
|
+
traversedNodesCount++;
|
|
8789
|
+
if (traversedNodesCount > maxNodes) {
|
|
8790
|
+
limitsReached.nodes = true;
|
|
8791
|
+
return [];
|
|
8792
|
+
}
|
|
8793
|
+
if (currentDepth >= maxDepth) {
|
|
8794
|
+
limitsReached.depth = true;
|
|
8795
|
+
return [];
|
|
8796
|
+
}
|
|
8797
|
+
const ordinal = currentIndex / nodeFieldCount;
|
|
8798
|
+
const currentDistance = distances[ordinal];
|
|
8799
|
+
if (currentDistance <= rootDistance) {
|
|
8800
|
+
return [];
|
|
8801
|
+
}
|
|
8802
|
+
if (visiting.has(currentIndex)) {
|
|
8803
|
+
return [];
|
|
8804
|
+
}
|
|
8805
|
+
const cachedDepth = visited.get(currentIndex);
|
|
8806
|
+
if (cachedDepth !== undefined) {
|
|
8807
|
+
if (currentDepth >= cachedDepth) {
|
|
8808
|
+
return [];
|
|
8809
|
+
}
|
|
8810
|
+
}
|
|
8811
|
+
visiting.add(currentIndex);
|
|
8812
|
+
const beginRetainerIndex = firstRetainerIndex[ordinal];
|
|
8813
|
+
const endRetainerIndex = firstRetainerIndex[ordinal + 1];
|
|
8814
|
+
const retainers = [];
|
|
8815
|
+
for (let retainerIndex = beginRetainerIndex; retainerIndex < endRetainerIndex; ++retainerIndex) {
|
|
8816
|
+
const retainerNodeIndex = retainingNodes[retainerIndex];
|
|
8817
|
+
const retainerNodeOrdinal = retainerNodeIndex / nodeFieldCount;
|
|
8818
|
+
const dist = distances[retainerNodeOrdinal];
|
|
8819
|
+
const globalEdgeIndex = retainingEdges[retainerIndex];
|
|
8820
|
+
if (this.isEdgeIgnoredInRetainersView(globalEdgeIndex)) {
|
|
8821
|
+
continue;
|
|
8822
|
+
}
|
|
8823
|
+
const edgeType = containmentEdges.getValue(globalEdgeIndex + edgeTypeOffset);
|
|
8824
|
+
if (edgeType === edgeWeakType) {
|
|
8825
|
+
continue;
|
|
8826
|
+
}
|
|
8827
|
+
if (dist >= 0) {
|
|
8828
|
+
const remainingDepth = maxDepth - currentDepth;
|
|
8829
|
+
const neededDepth = dist - rootDistance;
|
|
8830
|
+
if (neededDepth < remainingDepth) {
|
|
8831
|
+
retainers.push({ retainerIndex, dist, nodeIndex: retainerNodeIndex });
|
|
8832
|
+
}
|
|
8833
|
+
else {
|
|
8834
|
+
limitsReached.depth = true;
|
|
8835
|
+
}
|
|
8836
|
+
}
|
|
8837
|
+
}
|
|
8838
|
+
retainers.sort((a, b) => a.dist - b.dist);
|
|
8839
|
+
const length = Math.min(retainers.length, maxSiblings);
|
|
8840
|
+
if (retainers.length > maxSiblings) {
|
|
8841
|
+
limitsReached.siblings = true;
|
|
8842
|
+
}
|
|
8843
|
+
const forest = [];
|
|
8844
|
+
for (let i = 0; i < length; i++) {
|
|
8845
|
+
const retainer = retainers[i];
|
|
8846
|
+
const edge = this.createRetainingEdge(retainer.retainerIndex);
|
|
8847
|
+
const globalEdgeIndex = retainingEdges[retainer.retainerIndex];
|
|
8848
|
+
const isRoot = retainer.dist === rootDistance;
|
|
8849
|
+
let children = [];
|
|
8850
|
+
if (isRoot) {
|
|
8851
|
+
traversedNodesCount++;
|
|
8852
|
+
if (traversedNodesCount > maxNodes) {
|
|
8853
|
+
limitsReached.nodes = true;
|
|
8854
|
+
break;
|
|
8855
|
+
}
|
|
8856
|
+
}
|
|
8857
|
+
else {
|
|
8858
|
+
children = buildForest(retainer.nodeIndex, currentDepth + 1);
|
|
8859
|
+
if (children.length === 0) {
|
|
8860
|
+
continue;
|
|
8861
|
+
}
|
|
8862
|
+
}
|
|
8863
|
+
const retainerNode = this.createNode(retainer.nodeIndex);
|
|
8864
|
+
forest.push({
|
|
8865
|
+
edgeIndex: globalEdgeIndex,
|
|
8866
|
+
edgeName: edge.name(),
|
|
8867
|
+
edgeType: edge.type(),
|
|
8868
|
+
nodeId: retainerNode.id(),
|
|
8869
|
+
nodeIndex: retainer.nodeIndex,
|
|
8870
|
+
nodeName: retainerNode.name(),
|
|
8871
|
+
distance: retainer.dist,
|
|
8872
|
+
children,
|
|
8873
|
+
});
|
|
8874
|
+
}
|
|
8875
|
+
visiting.delete(currentIndex);
|
|
8876
|
+
visited.set(currentIndex, currentDepth);
|
|
8877
|
+
return forest;
|
|
8878
|
+
};
|
|
8879
|
+
const paths = buildForest(nodeIndex, 0);
|
|
8880
|
+
return { paths, limitsReached };
|
|
8881
|
+
}
|
|
8882
|
+
getDominatorsOf(nodeIndex) {
|
|
8883
|
+
const chain = [];
|
|
8884
|
+
let currentIndex = nodeIndex;
|
|
8885
|
+
const rootIndex = this.rootNodeIndex;
|
|
8886
|
+
while (currentIndex !== undefined) {
|
|
8887
|
+
const node = this.createNode(currentIndex);
|
|
8888
|
+
chain.push({
|
|
8889
|
+
nodeId: node.id(),
|
|
8890
|
+
nodeIndex: currentIndex,
|
|
8891
|
+
nodeName: node.name(),
|
|
8892
|
+
retainedSize: node.retainedSize(),
|
|
8893
|
+
selfSize: node.selfSize(),
|
|
8894
|
+
});
|
|
8895
|
+
if (currentIndex === rootIndex) {
|
|
8896
|
+
break;
|
|
8897
|
+
}
|
|
8898
|
+
const nextIndex = node.dominatorIndex();
|
|
8899
|
+
if (nextIndex === currentIndex) {
|
|
8900
|
+
break;
|
|
8901
|
+
}
|
|
8902
|
+
currentIndex = nextIndex;
|
|
8903
|
+
}
|
|
8904
|
+
return chain;
|
|
8905
|
+
}
|
|
8361
8906
|
createAddedNodesProvider(baseSnapshotId, classKey) {
|
|
8362
8907
|
const snapshotDiff = this.#snapshotDiffs[baseSnapshotId];
|
|
8363
8908
|
const diffForClass = snapshotDiff[classKey];
|
|
@@ -8369,6 +8914,85 @@ class HeapSnapshot {
|
|
|
8369
8914
|
createNodesProviderForClass(classKey, nodeFilter) {
|
|
8370
8915
|
return new HeapSnapshotNodesProvider(this, this.aggregatesWithFilter(nodeFilter)[classKey].idxs);
|
|
8371
8916
|
}
|
|
8917
|
+
queryObjects(queryOptions) {
|
|
8918
|
+
const { nodes, nodeFieldCount, retainedSizes } = this;
|
|
8919
|
+
const nodesLength = nodes.length;
|
|
8920
|
+
const matchingIndexes = [];
|
|
8921
|
+
const classNamePattern = queryOptions.className ? new RegExp(queryOptions.className, 'i') : null;
|
|
8922
|
+
const propertyNamePattern = queryOptions.propertyName ? new RegExp(queryOptions.propertyName, 'i') : null;
|
|
8923
|
+
const targetNodeType = queryOptions.nodeType ? queryOptions.nodeType.toLowerCase() : null;
|
|
8924
|
+
const node = this.rootNode();
|
|
8925
|
+
for (let nodeIndex = 0, ordinal = 0; nodeIndex < nodesLength; nodeIndex += nodeFieldCount, ordinal++) {
|
|
8926
|
+
node.nodeIndex = nodeIndex;
|
|
8927
|
+
if (queryOptions.minSelfSize !== undefined && node.selfSize() < queryOptions.minSelfSize) {
|
|
8928
|
+
continue;
|
|
8929
|
+
}
|
|
8930
|
+
if (queryOptions.maxSelfSize !== undefined && node.selfSize() > queryOptions.maxSelfSize) {
|
|
8931
|
+
continue;
|
|
8932
|
+
}
|
|
8933
|
+
const retainedSize = retainedSizes[ordinal];
|
|
8934
|
+
if (queryOptions.minRetainedSize !== undefined && retainedSize < queryOptions.minRetainedSize) {
|
|
8935
|
+
continue;
|
|
8936
|
+
}
|
|
8937
|
+
if (queryOptions.maxRetainedSize !== undefined && retainedSize > queryOptions.maxRetainedSize) {
|
|
8938
|
+
continue;
|
|
8939
|
+
}
|
|
8940
|
+
if (queryOptions.isDetached !== undefined) {
|
|
8941
|
+
const isDetached = node.detachedness() === 2 ;
|
|
8942
|
+
if (isDetached !== queryOptions.isDetached) {
|
|
8943
|
+
continue;
|
|
8944
|
+
}
|
|
8945
|
+
}
|
|
8946
|
+
if (classNamePattern) {
|
|
8947
|
+
const name = node.name();
|
|
8948
|
+
if (!classNamePattern.test(name)) {
|
|
8949
|
+
continue;
|
|
8950
|
+
}
|
|
8951
|
+
}
|
|
8952
|
+
if (targetNodeType) {
|
|
8953
|
+
const typeStr = node.type();
|
|
8954
|
+
if (typeStr.toLowerCase() !== targetNodeType) {
|
|
8955
|
+
continue;
|
|
8956
|
+
}
|
|
8957
|
+
}
|
|
8958
|
+
if (propertyNamePattern) {
|
|
8959
|
+
let propMatch = false;
|
|
8960
|
+
for (const iter = node.edges(); iter.hasNext(); iter.next()) {
|
|
8961
|
+
if (propertyNamePattern.test(iter.edge.name())) {
|
|
8962
|
+
propMatch = true;
|
|
8963
|
+
break;
|
|
8964
|
+
}
|
|
8965
|
+
}
|
|
8966
|
+
if (!propMatch) {
|
|
8967
|
+
continue;
|
|
8968
|
+
}
|
|
8969
|
+
}
|
|
8970
|
+
matchingIndexes.push(nodeIndex);
|
|
8971
|
+
}
|
|
8972
|
+
const sortBy = queryOptions.sortBy ?? 'retainedSize';
|
|
8973
|
+
if (sortBy === 'retainedSize') {
|
|
8974
|
+
matchingIndexes.sort((a, b) => retainedSizes[b / nodeFieldCount] - retainedSizes[a / nodeFieldCount]);
|
|
8975
|
+
}
|
|
8976
|
+
else if (sortBy === 'selfSize') {
|
|
8977
|
+
matchingIndexes.sort((a, b) => {
|
|
8978
|
+
node.nodeIndex = b;
|
|
8979
|
+
const sizeB = node.selfSize();
|
|
8980
|
+
node.nodeIndex = a;
|
|
8981
|
+
const sizeA = node.selfSize();
|
|
8982
|
+
return sizeB - sizeA;
|
|
8983
|
+
});
|
|
8984
|
+
}
|
|
8985
|
+
else if (sortBy === 'id') {
|
|
8986
|
+
matchingIndexes.sort((a, b) => {
|
|
8987
|
+
node.nodeIndex = b;
|
|
8988
|
+
const idB = node.id();
|
|
8989
|
+
node.nodeIndex = a;
|
|
8990
|
+
const idA = node.id();
|
|
8991
|
+
return idA - idB;
|
|
8992
|
+
});
|
|
8993
|
+
}
|
|
8994
|
+
return new HeapSnapshotNodesProvider(this, matchingIndexes);
|
|
8995
|
+
}
|
|
8372
8996
|
maxJsNodeId() {
|
|
8373
8997
|
const nodeFieldCount = this.nodeFieldCount;
|
|
8374
8998
|
const nodes = this.nodes;
|
|
@@ -8852,6 +9476,10 @@ class JSHeapSnapshot extends HeapSnapshot {
|
|
|
8852
9476
|
isUserRoot(node) {
|
|
8853
9477
|
return node.isUserRoot() || node.isDocumentDOMTreesRoot();
|
|
8854
9478
|
}
|
|
9479
|
+
isContextObject(node) {
|
|
9480
|
+
const name = node.rawName();
|
|
9481
|
+
return name === 'system / Context' || name.startsWith('system / Context / ');
|
|
9482
|
+
}
|
|
8855
9483
|
userObjectsMapAndFlag() {
|
|
8856
9484
|
return { map: this.flags, flag: this.nodeFlags.pageObject };
|
|
8857
9485
|
}
|
|
@@ -8872,7 +9500,7 @@ class JSHeapSnapshot extends HeapSnapshot {
|
|
|
8872
9500
|
continue;
|
|
8873
9501
|
}
|
|
8874
9502
|
node.nodeIndex = nodeIndex;
|
|
8875
|
-
if (node.
|
|
9503
|
+
if (node.detachedness() === 2 ) {
|
|
8876
9504
|
this.flags[ordinal] |= flag;
|
|
8877
9505
|
}
|
|
8878
9506
|
}
|
|
@@ -9026,7 +9654,7 @@ class JSHeapSnapshot extends HeapSnapshot {
|
|
|
9026
9654
|
jsArrays: sizeJSArrays,
|
|
9027
9655
|
strings: sizeStrings,
|
|
9028
9656
|
system: sizeSystem,
|
|
9029
|
-
}
|
|
9657
|
+
},
|
|
9030
9658
|
};
|
|
9031
9659
|
}
|
|
9032
9660
|
calculateArraySize(node) {
|
|
@@ -9708,4 +10336,3 @@ class HeapSnapshotWorkerDispatcher {
|
|
|
9708
10336
|
const dispatcher = new HeapSnapshotWorkerDispatcher(HOST_RUNTIME.workerScope.postMessage.bind(HOST_RUNTIME.workerScope));
|
|
9709
10337
|
HOST_RUNTIME.workerScope.onmessage = dispatcher.dispatchMessage.bind(dispatcher);
|
|
9710
10338
|
HOST_RUNTIME.workerScope.postMessage('workerReady');
|
|
9711
|
-
//# sourceMappingURL=devtools-heap-snapshot-worker.js.map
|