replaced by .editorconfig # ignore-this-changeset Differential Revision: https://phabricator.services.mozilla.com/D287851
263 lines
9.0 KiB
C++
263 lines
9.0 KiB
C++
/* 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/HashFunctions.h"
|
|
#include "mozilla/Variant.h"
|
|
|
|
#include <stdint.h>
|
|
|
|
#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<SourceTextUTF16, SourceTextUTF8, RetrievableFile,
|
|
Unavailable>;
|
|
|
|
// Constructors
|
|
ProfilerJSSourceData(uint32_t sourceId, JS::UniqueChars&& filePath,
|
|
size_t pathLen, uint32_t startLine, uint32_t startColumn,
|
|
JS::UniqueTwoByteChars&& sourceMapURL,
|
|
size_t sourceMapURLLen)
|
|
: sourceId_(sourceId),
|
|
filePath_(std::move(filePath)),
|
|
filePathLength_(pathLen),
|
|
data_(Unavailable{}),
|
|
startLine_(startLine),
|
|
startColumn_(startColumn),
|
|
sourceMapURL_(std::move(sourceMapURL)),
|
|
sourceMapURLLength_(sourceMapURLLen) {}
|
|
|
|
// UTF-8 source text with filePath
|
|
ProfilerJSSourceData(uint32_t sourceId, JS::UniqueChars&& chars,
|
|
size_t length, JS::UniqueChars&& filePath,
|
|
size_t pathLen, uint32_t startLine, uint32_t startColumn,
|
|
JS::UniqueTwoByteChars&& sourceMapURL,
|
|
size_t sourceMapURLLen)
|
|
: sourceId_(sourceId),
|
|
filePath_(std::move(filePath)),
|
|
filePathLength_(pathLen),
|
|
data_(SourceTextUTF8{std::move(chars), length}),
|
|
startLine_(startLine),
|
|
startColumn_(startColumn),
|
|
sourceMapURL_(std::move(sourceMapURL)),
|
|
sourceMapURLLength_(sourceMapURLLen) {}
|
|
|
|
// UTF-16 source text with filePath
|
|
ProfilerJSSourceData(uint32_t sourceId, JS::UniqueTwoByteChars&& chars,
|
|
size_t length, JS::UniqueChars&& filePath,
|
|
size_t pathLen, uint32_t startLine, uint32_t startColumn,
|
|
JS::UniqueTwoByteChars&& sourceMapURL,
|
|
size_t sourceMapURLLen)
|
|
: sourceId_(sourceId),
|
|
filePath_(std::move(filePath)),
|
|
filePathLength_(pathLen),
|
|
data_(SourceTextUTF16{std::move(chars), length}),
|
|
startLine_(startLine),
|
|
startColumn_(startColumn),
|
|
sourceMapURL_(std::move(sourceMapURL)),
|
|
sourceMapURLLength_(sourceMapURLLen) {}
|
|
|
|
// 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}),
|
|
sourceMapURL_(nullptr),
|
|
sourceMapURLLength_(0) {}
|
|
|
|
ProfilerJSSourceData()
|
|
: sourceId_(0),
|
|
filePathLength_(0),
|
|
data_(Unavailable{}),
|
|
sourceMapURLLength_(0) {}
|
|
|
|
static ProfilerJSSourceData CreateRetrievableFile(
|
|
uint32_t sourceId, JS::UniqueChars&& filePath, size_t pathLength,
|
|
uint32_t startLine, uint32_t startColumn,
|
|
JS::UniqueTwoByteChars&& sourceMapURL, size_t sourceMapURLLength) {
|
|
ProfilerJSSourceData result(sourceId, std::move(filePath), pathLength,
|
|
startLine, startColumn, std::move(sourceMapURL),
|
|
sourceMapURLLength);
|
|
result.data_.emplace<RetrievableFile>();
|
|
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_; }
|
|
// Consumer should always check for sourceMapURLLength before calling this.
|
|
const char16_t* sourceMapURL() const {
|
|
MOZ_ASSERT(sourceMapURL_);
|
|
return sourceMapURL_.get();
|
|
}
|
|
size_t sourceMapURLLength() const { return sourceMapURLLength_; }
|
|
const ProfilerSourceVariant& data() const { return data_; }
|
|
uint32_t startLine() const { return startLine_; }
|
|
uint32_t startColumn() const { return startColumn_; }
|
|
|
|
// Used only for memory reporting.
|
|
size_t SizeOf() const {
|
|
// Size of sourceId + filepath + sourceMapURL + startLine + startColumn.
|
|
size_t size = sizeof(uint32_t) + filePathLength_ * sizeof(char) +
|
|
sourceMapURLLength_ * sizeof(char16_t) + sizeof(uint32_t) +
|
|
sizeof(uint32_t);
|
|
|
|
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;
|
|
}
|
|
|
|
mozilla::HashNumber hash() const {
|
|
using mozilla::HashBytes;
|
|
using mozilla::HashNumber;
|
|
|
|
HashNumber hash = 0;
|
|
|
|
if (filePathLength_ > 0) {
|
|
hash = HashBytes(filePath_.get(), filePathLength_, hash);
|
|
}
|
|
|
|
hash = mozilla::AddToHash(hash, startLine_);
|
|
hash = mozilla::AddToHash(hash, startColumn_);
|
|
|
|
if (sourceMapURLLength_ > 0) {
|
|
hash = HashBytes(sourceMapURL_.get(),
|
|
sourceMapURLLength_ * sizeof(char16_t), hash);
|
|
}
|
|
|
|
hash = data_.addTagToHash(hash);
|
|
data_.match(
|
|
[&](const SourceTextUTF16& srcText) {
|
|
hash = HashBytes(srcText.chars().get(),
|
|
srcText.length() * sizeof(char16_t), hash);
|
|
},
|
|
[&](const SourceTextUTF8& srcText) {
|
|
hash = HashBytes(srcText.chars().get(), srcText.length(), hash);
|
|
},
|
|
[](const RetrievableFile&) {}, [](const Unavailable&) {});
|
|
|
|
return hash;
|
|
}
|
|
|
|
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_;
|
|
// Line number within the file where this source starts (1-based).
|
|
// This is used for inline scripts within HTML pages.
|
|
uint32_t startLine_ = 1;
|
|
// Column number within the file where this source starts (1-based).
|
|
// This is used for inline scripts within HTML pages.
|
|
uint32_t startColumn_ = 1;
|
|
// Null-terminated source map URL for the source.
|
|
// It can be nullptr if:
|
|
// - The source has no sourceMapURL.
|
|
// - sourceMapURL allocation fails during copy.
|
|
JS::UniqueTwoByteChars sourceMapURL_;
|
|
size_t sourceMapURLLength_;
|
|
};
|
|
|
|
namespace js {
|
|
|
|
using ProfilerJSSources =
|
|
js::Vector<ProfilerJSSourceData, 0, js::SystemAllocPolicy>;
|
|
|
|
/*
|
|
* Main API for getting the profiled JS sources.
|
|
* If gatherSourceText is false, only metadata (filename, sourceMapURL) will
|
|
* be gathered, not the actual source text.
|
|
*/
|
|
JS_PUBLIC_API ProfilerJSSources GetProfilerScriptSources(JSRuntime* rt,
|
|
bool gatherSourceText);
|
|
|
|
/**
|
|
* 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 */
|