/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- * vim: set ts=8 sts=2 et sw=2 tw=80: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef js_ProfilingSources_h #define js_ProfilingSources_h #include "mozilla/Variant.h" #include #include "jstypes.h" #include "js/TypeDecls.h" #include "js/Utility.h" #include "js/Vector.h" /* * Struct to pass JS source data with content type information for profiler use. */ struct JS_PUBLIC_API ProfilerJSSourceData { public: struct SourceTextUTF16 { public: SourceTextUTF16(JS::UniqueTwoByteChars&& c, size_t l) : chars_(std::move(c)), length_(l) {} const JS::UniqueTwoByteChars& chars() const { return chars_; } size_t length() const { return length_; } private: // Not null-terminated string for source text. Always use it with the // length. JS::UniqueTwoByteChars chars_; size_t length_; }; struct SourceTextUTF8 { public: SourceTextUTF8(JS::UniqueChars&& c, size_t l) : chars_(std::move(c)), length_(l) {} const JS::UniqueChars& chars() const { return chars_; } size_t length() const { return length_; } private: // Not null-terminated string for source text. Always use it with the // length. JS::UniqueChars chars_; size_t length_; }; /* * Represents a source file that can be retrieved later in the parent process. * Used when source text is not immediately available in the current process * but can be fetched using the file path information. */ struct RetrievableFile {}; struct Unavailable {}; using ProfilerSourceVariant = mozilla::Variant; // Constructors ProfilerJSSourceData(uint32_t sourceId, JS::UniqueChars&& filePath, size_t pathLen) : sourceId_(sourceId), filePath_(std::move(filePath)), filePathLength_(pathLen), data_(Unavailable{}) {} // UTF-8 source text with filePath ProfilerJSSourceData(uint32_t sourceId, JS::UniqueChars&& chars, size_t length, JS::UniqueChars&& filePath, size_t pathLen) : sourceId_(sourceId), filePath_(std::move(filePath)), filePathLength_(pathLen), data_(SourceTextUTF8{std::move(chars), length}) {} // UTF-16 source text with filePath ProfilerJSSourceData(uint32_t sourceId, JS::UniqueTwoByteChars&& chars, size_t length, JS::UniqueChars&& filePath, size_t pathLen) : sourceId_(sourceId), filePath_(std::move(filePath)), filePathLength_(pathLen), data_(SourceTextUTF16{std::move(chars), length}) {} // For the cases where no sourceId and filepath are needed. ProfilerJSSourceData(JS::UniqueChars&& chars, size_t length) : sourceId_(0), filePath_(nullptr), filePathLength_(0), data_(SourceTextUTF8{std::move(chars), length}) {} ProfilerJSSourceData() : sourceId_(0), filePathLength_(0), data_(Unavailable{}) {} static ProfilerJSSourceData CreateRetrievableFile(uint32_t sourceId, JS::UniqueChars&& filePath, size_t pathLength) { ProfilerJSSourceData result(sourceId, std::move(filePath), pathLength); result.data_.emplace(); return result; } ProfilerJSSourceData(ProfilerJSSourceData&&) = default; ProfilerJSSourceData& operator=(ProfilerJSSourceData&&) = default; // No copy constructors as this class owns its string storage. ProfilerJSSourceData(const ProfilerJSSourceData& other) = delete; ProfilerJSSourceData& operator=(const ProfilerJSSourceData&) = delete; uint32_t sourceId() const { return sourceId_; } // Consumer should always check for filePathLength before calling this. const char* filePath() const { MOZ_ASSERT(filePath_); return filePath_.get(); } size_t filePathLength() const { return filePathLength_; } const ProfilerSourceVariant& data() const { return data_; } // Used only for memory reporting. size_t SizeOf() const { // Size of sourceId + filepath size_t size = sizeof(uint32_t) + filePathLength_ * sizeof(char); data_.match( [&](const SourceTextUTF16& srcText) { size += srcText.length() * sizeof(char16_t); }, [&](const SourceTextUTF8& srcText) { size += srcText.length() * sizeof(char); }, [](const RetrievableFile&) {}, [](const Unavailable&) {}); return size; } private: // Unique identifier for this source across the process. This can be used // to refer to this source from places that don't want to hold a strong // reference on the source itself. // Generated by ScriptSource and retrieved via ScriptSource::id(). See // ScriptSource::id_ for more details. uint32_t sourceId_; // Null-terminated file path for the source. // It can be nullptr if: // - The source has no filename. // - filename allocation fails during copy. JS::UniqueChars filePath_; size_t filePathLength_; ProfilerSourceVariant data_; }; namespace js { using ProfilerJSSources = js::Vector; /* * Main API for getting the profiled JS sources. */ JS_PUBLIC_API ProfilerJSSources GetProfilerScriptSources(JSRuntime* rt); /** * Retrieve the JS sources that are only retrievable from the parent process. * See RetrievableFile struct for more information. * */ JS_PUBLIC_API ProfilerJSSourceData RetrieveProfilerSourceContent(JSContext* cx, const char* filename); } // namespace js #endif /* js_ProfilingSources_h */