Merge mozilla-central to inbound. a=merge CLOSED TREE

This commit is contained in:
Gurzau Raul 2019-06-22 01:09:53 +03:00
commit d2e89cd600
48 changed files with 605 additions and 489 deletions

View File

@ -13,7 +13,6 @@
#include "nsEscape.h"
#include "nsCRT.h"
#include "nsIUUIDGenerator.h"
#include "mozilla/GkRustUtils.h"

View File

@ -23,7 +23,7 @@ import type {
const breakpointSvg = document.createElement("div");
breakpointSvg.innerHTML =
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 15" width="60" height="15"><path d="M53.07.5H1.5c-.54 0-1 .46-1 1v12c0 .54.46 1 1 1h51.57c.58 0 1.15-.26 1.53-.7l4.7-6.3-4.7-6.3c-.38-.44-.95-.7-1.53-.7z"/></svg>';
'<svg viewBox="0 0 60 15" width="60" height="15"><path d="M53.07.5H1.5c-.54 0-1 .46-1 1v12c0 .54.46 1 1 1h51.57c.58 0 1.15-.26 1.53-.7l4.7-6.3-4.7-6.3c-.38-.44-.95-.7-1.53-.7z"/></svg>';
type Props = {
cx: ThreadContext,

View File

@ -30,7 +30,7 @@ type Props = {
const breakpointButton = document.createElement("button");
breakpointButton.innerHTML =
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 13" width="11" height="13"><path d="M5.07.5H1.5c-.54 0-1 .46-1 1v10c0 .54.46 1 1 1h3.57c.58 0 1.15-.26 1.53-.7l3.7-5.3-3.7-5.3C6.22.76 5.65.5 5.07.5z"/></svg>';
'<svg viewBox="0 0 11 13" width="11" height="13"><path d="M5.07.5H1.5c-.54 0-1 .46-1 1v10c0 .54.46 1 1 1h3.57c.58 0 1.15-.26 1.53-.7l3.7-5.3-3.7-5.3C6.22.76 5.65.5 5.07.5z"/></svg>';
function makeBookmark({ breakpoint }, { onClick, onContextMenu }) {
const bp = breakpointButton.cloneNode(true);

View File

@ -61,14 +61,14 @@ class WhyPaused extends PureComponent<Props, State> {
renderMessage(why: ExceptionReason) {
if (why.type == "exception" && why.exception) {
return (
<div className={"message warning"}>
<div className="message warning">
{this.renderExceptionSummary(why.exception)}
</div>
);
}
if (typeof why.message == "string") {
return <div className={"message"}>{why.message}</div>;
return <div className="message">{why.message}</div>;
}
return null;
@ -78,33 +78,29 @@ class WhyPaused extends PureComponent<Props, State> {
const { endPanelCollapsed, why } = this.props;
const reason = getPauseReason(why);
if (reason) {
if (!endPanelCollapsed) {
return (
<div className={"pane why-paused"}>
<div>
<div className="pause reason">
{L10N.getStr(reason)}
{this.renderMessage(why)}
</div>
<div className="info icon">
<AccessibleImage className="info" />
</div>
</div>
</div>
);
}
if (!reason || endPanelCollapsed) {
return <div className={this.state.hideWhyPaused} />;
}
return <div className={this.state.hideWhyPaused} />;
return (
<div className="pane why-paused">
<div>
<div className="pause reason">
{L10N.getStr(reason)}
{this.renderMessage(why)}
</div>
<div className="info icon">
<AccessibleImage className="info" />
</div>
</div>
</div>
);
}
}
const mapStateToProps = state => {
const thread = getCurrentThread(state);
return {
endPanelCollapsed: getPaneCollapse(state, "end"),
why: getWhy(state, thread),
};
};
const mapStateToProps = state => ({
endPanelCollapsed: getPaneCollapse(state, "end"),
why: getWhy(state, getCurrentThread(state)),
});
export default connect(mapStateToProps)(WhyPaused);

View File

@ -82,6 +82,15 @@ void CanonicalBrowsingContext::GetCurrentRemoteType(nsAString& aRemoteType,
aRemoteType.Assign(cp->GetRemoteType());
}
void CanonicalBrowsingContext::SetOwnerProcessId(uint64_t aProcessId) {
MOZ_LOG(GetLog(), LogLevel::Debug,
("SetOwnerProcessId for 0x%08" PRIx64 " (0x%08" PRIx64
" -> 0x%08" PRIx64 ")",
Id(), mProcessId, aProcessId));
mProcessId = aProcessId;
}
void CanonicalBrowsingContext::GetWindowGlobals(
nsTArray<RefPtr<WindowGlobalParent>>& aWindows) {
aWindows.SetCapacity(mWindowGlobals.Count());
@ -129,6 +138,18 @@ void CanonicalBrowsingContext::SetEmbedderWindowGlobal(
bool CanonicalBrowsingContext::ValidateTransaction(
const Transaction& aTransaction, ContentParent* aProcess) {
if (MOZ_LOG_TEST(GetLog(), LogLevel::Debug)) {
#define MOZ_BC_FIELD(name, ...) \
if (aTransaction.m##name.isSome()) { \
MOZ_LOG(GetLog(), LogLevel::Debug, \
("Validate Transaction 0x%08" PRIx64 " set " #name \
" (from: 0x%08" PRIx64 " owner: 0x%08" PRIx64 ")", \
Id(), aProcess ? static_cast<uint64_t>(aProcess->ChildID()) : 0, \
mProcessId)); \
}
#include "mozilla/dom/BrowsingContextFieldList.h"
}
// Check that the correct process is performing sets for transactions with
// non-racy fields.
if (aTransaction.HasNonRacyField()) {

View File

@ -38,7 +38,7 @@ class CanonicalBrowsingContext final : public BrowsingContext {
void GetCurrentRemoteType(nsAString& aRemoteType, ErrorResult& aRv) const;
void SetOwnerProcessId(uint64_t aProcessId) { mProcessId = aProcessId; }
void SetOwnerProcessId(uint64_t aProcessId);
void GetWindowGlobals(nsTArray<RefPtr<WindowGlobalParent>>& aWindows);

View File

@ -175,6 +175,7 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext,
mDetachedSubdocFrame(nullptr),
mPendingSwitchID(0),
mChildID(0),
mRemoteType(VoidString()),
mDepthTooGreat(false),
mIsTopLevelContent(false),
mDestroyCalled(false),
@ -191,6 +192,11 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext,
mIsRemoteFrame = ShouldUseRemoteProcess();
MOZ_ASSERT(!mIsRemoteFrame || !mBrowsingContext->HasOpener(),
"Cannot pass aOpener for a remote frame!");
if (mIsRemoteFrame &&
!aOwner->GetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType, mRemoteType)) {
mRemoteType.AssignLiteral(DEFAULT_REMOTE_TYPE);
}
}
nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext,
@ -200,6 +206,7 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext,
mDetachedSubdocFrame(nullptr),
mPendingSwitchID(0),
mChildID(0),
mRemoteType(VoidString()),
mDepthTooGreat(false),
mIsTopLevelContent(false),
mDestroyCalled(false),
@ -216,6 +223,7 @@ nsFrameLoader::nsFrameLoader(Element* aOwner, BrowsingContext* aBrowsingContext,
if (aOptions.mRemoteType.WasPassed() &&
(!aOptions.mRemoteType.Value().IsVoid())) {
mIsRemoteFrame = true;
mRemoteType = aOptions.mRemoteType.Value();
}
}
@ -2661,14 +2669,13 @@ bool nsFrameLoader::TryRemoteBrowserInternal() {
if (XRE_IsContentProcess()) {
mBrowsingContext->SetEmbedderElement(mOwnerContent);
mRemoteBrowser = ContentChild::CreateBrowser(
this, context, NS_LITERAL_STRING(DEFAULT_REMOTE_TYPE),
mBrowsingContext);
mRemoteBrowser = ContentChild::CreateBrowser(this, context, mRemoteType,
mBrowsingContext);
return !!mRemoteBrowser;
}
mRemoteBrowser = ContentParent::CreateBrowser(
context, ownerElement, mBrowsingContext, openerContentParent,
context, ownerElement, mRemoteType, mBrowsingContext, openerContentParent,
sameTabGroupAs, nextRemoteTabId);
if (!mRemoteBrowser) {
return false;

View File

@ -512,6 +512,8 @@ class nsFrameLoader final : public nsStubMutationObserver,
RefPtr<mozilla::dom::TabListener> mSessionStoreListener;
nsString mRemoteType;
bool mDepthTooGreat : 1;
bool mIsTopLevelContent : 1;
bool mDestroyCalled : 1;

View File

@ -6,6 +6,7 @@
#ifndef WEBGLCONTEXT_H_
#define WEBGLCONTEXT_H_
#include <memory>
#include <stdarg.h>
#include "GLContextTypes.h"
@ -1507,7 +1508,8 @@ class WebGLContext : public nsICanvasRenderingContextInternal,
mutable GLenum mWebGLError;
webgl::ShaderValidator* CreateShaderValidator(GLenum shaderType) const;
std::unique_ptr<webgl::ShaderValidator> CreateShaderValidator(
GLenum shaderType) const;
// some GL constants
uint32_t mGLMaxTextureUnits = 0;

View File

@ -474,51 +474,46 @@ static RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(
{
const auto& fragShader = prog->FragShader();
MOZ_RELEASE_ASSERT(fragShader);
MOZ_RELEASE_ASSERT(fragShader->Validator());
const auto& handle = fragShader->Validator()->mHandle;
const auto version = sh::GetShaderVersion(handle);
const auto& compileResults = fragShader->CompileResults();
const auto version = compileResults->mShaderVersion;
const auto fnAddInfo = [&](const webgl::FragOutputInfo& x) {
info->fragOutputs.insert({x.loc, x});
};
if (version == 300) {
const auto& fragOutputs = sh::GetOutputVariables(handle);
if (fragOutputs) {
for (const auto& cur : *fragOutputs) {
auto loc = cur.location;
if (loc == -1) loc = 0;
for (const auto& cur : compileResults->mOutputVariables) {
auto loc = cur.location;
if (loc == -1) loc = 0;
const auto info = webgl::FragOutputInfo{
uint8_t(loc), nsCString(cur.name.c_str()),
nsCString(cur.mappedName.c_str()), FragOutputBaseType(cur.type)};
if (!cur.isArray()) {
fnAddInfo(info);
continue;
}
MOZ_ASSERT(cur.arraySizes.size() == 1);
for (uint32_t i = 0; i < cur.arraySizes[0]; ++i) {
const auto indexStr = nsPrintfCString("[%u]", i);
const auto info = webgl::FragOutputInfo{
uint8_t(loc), nsCString(cur.name.c_str()),
nsCString(cur.mappedName.c_str()), FragOutputBaseType(cur.type)};
if (!cur.isArray()) {
fnAddInfo(info);
continue;
}
MOZ_ASSERT(cur.arraySizes.size() == 1);
for (uint32_t i = 0; i < cur.arraySizes[0]; ++i) {
const auto indexStr = nsPrintfCString("[%u]", i);
auto userName = info.userName;
userName.Append(indexStr);
auto mappedName = info.mappedName;
mappedName.Append(indexStr);
auto userName = info.userName;
userName.Append(indexStr);
auto mappedName = info.mappedName;
mappedName.Append(indexStr);
const auto indexedInfo = webgl::FragOutputInfo{
uint8_t(info.loc + i), userName, mappedName, info.baseType};
fnAddInfo(indexedInfo);
}
const auto indexedInfo = webgl::FragOutputInfo{
uint8_t(info.loc + i), userName, mappedName, info.baseType};
fnAddInfo(indexedInfo);
}
}
} else {
// ANGLE's translator doesn't tell us about non-user frag outputs. :(
const auto& translatedSource = fragShader->TranslatedSource();
const auto& translatedSource = compileResults->mObjectCode;
uint32_t drawBuffers = 1;
if (translatedSource.Find("(gl_FragData[1]") != -1 ||
translatedSource.Find("(webgl_FragData[1]") != -1) {
if (translatedSource.find("(gl_FragData[1]") != std::string::npos ||
translatedSource.find("(webgl_FragData[1]") != std::string::npos) {
// The matching with the leading '(' prevents cleverly-named user vars
// breaking this. Since ANGLE initializes all outputs, if this is an MRT
// shader, FragData[1] will be present. FragData[0] is valid for non-MRT
@ -536,10 +531,8 @@ static RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(
}
const auto& vertShader = prog->VertShader();
MOZ_RELEASE_ASSERT(vertShader);
MOZ_RELEASE_ASSERT(vertShader->Validator());
const auto& handle = vertShader->Validator()->mHandle;
const auto numViews = sh::GetVertexShaderNumViews(handle);
const auto& vertCompileResults = vertShader->CompileResults();
const auto numViews = vertCompileResults->mVertexShaderNumViews;
if (numViews != -1) {
info->zLayerCount = AssertedCast<uint8_t>(numViews);
}
@ -1153,13 +1146,15 @@ bool WebGLProgram::ValidateForLink() {
mLinkLog.AssignLiteral("Must have a compiled vertex shader attached.");
return false;
}
const auto& vertInfo = *mVertShader->CompileResults();
if (!mFragShader || !mFragShader->IsCompiled()) {
mLinkLog.AssignLiteral("Must have an compiled fragment shader attached.");
return false;
}
const auto& fragInfo = *mFragShader->CompileResults();
if (!mFragShader->CanLinkTo(mVertShader, &mLinkLog)) return false;
if (!fragInfo.CanLinkTo(vertInfo, &mLinkLog)) return false;
const auto& gl = mContext->gl;

View File

@ -38,25 +38,6 @@ static void PrintLongString(const char* const begin, const size_t len) {
printf_stderr("%s", chunkBegin);
}
// On success, writes to out_validator and out_translatedSource.
// On failure, writes to out_translationLog.
static bool Translate(const nsACString& source,
webgl::ShaderValidator* validator,
nsACString* const out_translationLog,
nsACString* const out_translatedSource) {
if (!validator->ValidateAndTranslate(source.BeginReading())) {
const std::string& log = sh::GetInfoLog(validator->mHandle);
out_translationLog->Assign(log.data(), log.length());
return false;
}
// Success
const std::string& output = sh::GetObjectCode(validator->mHandle);
out_translatedSource->Assign(output.data(), output.length());
return true;
}
template <size_t N>
static bool SubstringStartsWith(const std::string& testStr, size_t offset,
const char (&refStr)[N]) {
@ -93,9 +74,8 @@ static void GetCompilationStatusAndLog(gl::GLContext* gl, GLuint shader,
WebGLShader::WebGLShader(WebGLContext* webgl, GLenum type)
: WebGLRefCountedObject(webgl),
mGLName(webgl->gl->fCreateShader(type)),
mType(type),
mTranslationSuccessful(false),
mCompilationSuccessful(false) {
mType(type) {
mCompileResults = std::make_unique<webgl::ShaderValidatorResults>();
mContext->mShaders.insertBack(this);
}
@ -119,41 +99,44 @@ void WebGLShader::ShaderSource(const nsAString& source) {
}
void WebGLShader::CompileShader() {
mValidator = nullptr;
mTranslationSuccessful = false;
mCompilationSuccessful = false;
gl::GLContext* gl = mContext->gl;
mValidator.reset(mContext->CreateShaderValidator(mType));
MOZ_ASSERT(mValidator);
static const bool kDumpShaders = PR_GetEnv("MOZ_WEBGL_DUMP_SHADERS");
if (MOZ_UNLIKELY(kDumpShaders)) {
printf_stderr("==== begin MOZ_WEBGL_DUMP_SHADERS ====\n");
PrintLongString(mCleanSource.BeginReading(), mCleanSource.Length());
}
const bool success = Translate(mCleanSource, mValidator.get(),
&mValidationLog, &mTranslatedSource);
{
const auto validator = mContext->CreateShaderValidator(mType);
MOZ_ASSERT(validator);
mCompileResults =
validator->ValidateAndTranslate(mCleanSource.BeginReading());
}
mCompilationLog = mCompileResults->mInfoLog.c_str();
const auto& success = mCompileResults->mValid;
if (MOZ_UNLIKELY(kDumpShaders)) {
printf_stderr("\n==== \\/ \\/ \\/ ====\n");
if (success) {
PrintLongString(mTranslatedSource.BeginReading(),
mTranslatedSource.Length());
const auto& translated = mCompileResults->mObjectCode;
PrintLongString(translated.data(), translated.length());
} else {
printf_stderr("Validation failed:\n%s", mValidationLog.BeginReading());
printf_stderr("Validation failed:\n%s",
mCompileResults->mInfoLog.c_str());
}
printf_stderr("\n==== end ====\n");
}
if (!success) return;
mTranslationSuccessful = true;
const char* const parts[] = {mTranslatedSource.BeginReading()};
gl->fShaderSource(mGLName, ArrayLength(parts), parts, nullptr);
const std::array<const char*, 1> parts = {
mCompileResults->mObjectCode.c_str()};
gl->fShaderSource(mGLName, parts.size(), parts.data(), nullptr);
gl->fCompileShader(mGLName);
@ -161,10 +144,8 @@ void WebGLShader::CompileShader() {
&mCompilationLog);
}
void WebGLShader::GetShaderInfoLog(nsAString* out) const {
const nsCString& log =
!mTranslationSuccessful ? mValidationLog : mCompilationLog;
CopyASCIItoUTF16(log, *out);
void WebGLShader::GetShaderInfoLog(nsAString* const out) const {
CopyASCIItoUTF16(mCompilationLog, *out);
}
JS::Value WebGLShader::GetShaderParameter(GLenum pname) const {
@ -191,20 +172,16 @@ void WebGLShader::GetShaderSource(nsAString* out) const {
void WebGLShader::GetShaderTranslatedSource(nsAString* out) const {
out->SetIsVoid(false);
CopyASCIItoUTF16(mTranslatedSource, *out);
const auto& wrapper =
nsDependentCString(mCompileResults->mObjectCode.c_str());
CopyASCIItoUTF16(wrapper, *out);
}
////////////////////////////////////////////////////////////////////////////////
bool WebGLShader::CanLinkTo(const WebGLShader* prev,
nsCString* const out_log) const {
return mValidator->CanLinkTo(prev->mValidator.get(), out_log);
}
size_t WebGLShader::CalcNumSamplerUniforms() const {
const auto& uniforms = *sh::GetUniforms(mValidator->mHandle);
size_t accum = 0;
for (const auto& cur : uniforms) {
for (const auto& cur : mCompileResults->mUniforms) {
const auto& type = cur.type;
if (type == LOCAL_GL_SAMPLER_2D || type == LOCAL_GL_SAMPLER_CUBE) {
accum += cur.getArraySizeProduct();
@ -214,13 +191,12 @@ size_t WebGLShader::CalcNumSamplerUniforms() const {
}
size_t WebGLShader::NumAttributes() const {
return sh::GetAttributes(mValidator->mHandle)->size();
return mCompileResults->mAttributes.size();
}
void WebGLShader::BindAttribLocation(GLuint prog, const std::string& userName,
GLuint index) const {
const auto& attribs = *sh::GetAttributes(mValidator->mHandle);
for (const auto& attrib : attribs) {
for (const auto& attrib : mCompileResults->mAttributes) {
if (attrib.name == userName) {
mContext->gl->fBindAttribLocation(prog, index, attrib.mappedName.c_str());
return;
@ -232,8 +208,7 @@ bool WebGLShader::FindAttribUserNameByMappedName(
const nsACString& mappedName, nsCString* const out_userName) const {
const std::string mappedNameStr(mappedName.BeginReading());
const auto& attribs = *sh::GetAttributes(mValidator->mHandle);
for (const auto& cur : attribs) {
for (const auto& cur : mCompileResults->mAttributes) {
if (cur.mappedName == mappedNameStr) {
*out_userName = cur.name.c_str();
return true;
@ -247,8 +222,7 @@ bool WebGLShader::FindVaryingByMappedName(const nsACString& mappedName,
bool* const out_isArray) const {
const std::string mappedNameStr(mappedName.BeginReading());
const auto& varyings = *sh::GetVaryings(mValidator->mHandle);
for (const auto& cur : varyings) {
for (const auto& cur : mCompileResults->mVaryings) {
const sh::ShaderVariable* found;
std::string userName;
if (!cur.findInfoByMappedName(mappedNameStr, &found, &userName)) continue;
@ -267,8 +241,8 @@ bool WebGLShader::FindUniformByMappedName(const nsACString& mappedName,
const std::string mappedNameStr(mappedName.BeginReading(),
mappedName.Length());
std::string userNameStr;
if (!mValidator->FindUniformByMappedName(mappedNameStr, &userNameStr,
out_isArray))
if (!mCompileResults->FindUniformByMappedName(mappedNameStr, &userNameStr,
out_isArray))
return false;
*out_userName = userNameStr.c_str();
@ -277,8 +251,7 @@ bool WebGLShader::FindUniformByMappedName(const nsACString& mappedName,
bool WebGLShader::UnmapUniformBlockName(
const nsACString& baseMappedName, nsCString* const out_baseUserName) const {
const auto& interfaces = *sh::GetInterfaceBlocks(mValidator->mHandle);
for (const auto& interface : interfaces) {
for (const auto& interface : mCompileResults->mInterfaceBlocks) {
const nsDependentCString interfaceMappedName(interface.mappedName.data(),
interface.mappedName.size());
if (baseMappedName == interfaceMappedName) {
@ -299,7 +272,7 @@ void WebGLShader::MapTransformFeedbackVaryings(
out_mappedVaryings->clear();
out_mappedVaryings->reserve(varyings.size());
const auto& shaderVaryings = *sh::GetVaryings(mValidator->mHandle);
const auto& shaderVaryings = mCompileResults->mVaryings;
for (const auto& wideUserName : varyings) {
const NS_LossyConvertUTF16toASCII mozUserName(
@ -326,13 +299,10 @@ JSObject* WebGLShader::WrapObject(JSContext* js,
}
size_t WebGLShader::SizeOfIncludingThis(MallocSizeOf mallocSizeOf) const {
size_t validatorSize = mValidator ? mallocSizeOf(mValidator.get()) : 0;
return mallocSizeOf(this) +
mSource.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
mCleanSource.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
validatorSize +
mValidationLog.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
mTranslatedSource.SizeOfExcludingThisIfUnshared(mallocSizeOf) +
mCompileResults->SizeOfIncludingThis(mallocSizeOf) +
mCompilationLog.SizeOfExcludingThisIfUnshared(mallocSizeOf);
}

View File

@ -7,6 +7,7 @@
#define WEBGL_SHADER_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
@ -21,7 +22,7 @@
namespace mozilla {
namespace webgl {
class ShaderValidator;
class ShaderValidatorResults;
} // namespace webgl
class WebGLShader final : public nsWrapperCache,
@ -46,7 +47,6 @@ class WebGLShader final : public nsWrapperCache,
void ShaderSource(const nsAString& source);
// Util funcs
bool CanLinkTo(const WebGLShader* prev, nsCString* const out_log) const;
size_t CalcNumSamplerUniforms() const;
size_t NumAttributes() const;
bool FindAttribUserNameByMappedName(const nsACString& mappedName,
@ -60,11 +60,8 @@ class WebGLShader final : public nsWrapperCache,
bool UnmapUniformBlockName(const nsACString& baseMappedName,
nsCString* const out_baseUserName) const;
bool IsCompiled() const {
return mTranslationSuccessful && mCompilationSuccessful;
}
const auto* Validator() const { return mValidator.get(); }
const auto& TranslatedSource() const { return mTranslatedSource; }
bool IsCompiled() const { return mCompilationSuccessful; }
const auto& CompileResults() const { return mCompileResults; }
private:
void BindAttribLocation(GLuint prog, const std::string& userName,
@ -94,12 +91,9 @@ class WebGLShader final : public nsWrapperCache,
nsString mSource;
nsCString mCleanSource;
UniquePtr<webgl::ShaderValidator> mValidator;
nsCString mValidationLog;
bool mTranslationSuccessful;
nsCString mTranslatedSource;
bool mCompilationSuccessful;
std::unique_ptr<const webgl::ShaderValidatorResults>
mCompileResults; // Never null.
bool mCompilationSuccessful = false;
nsCString mCompilationLog;
};

View File

@ -139,7 +139,7 @@ static ShShaderOutput ShaderOutput(gl::GLContext* gl) {
return SH_GLSL_COMPATIBILITY_OUTPUT;
}
webgl::ShaderValidator* WebGLContext::CreateShaderValidator(
std::unique_ptr<webgl::ShaderValidator> WebGLContext::CreateShaderValidator(
GLenum shaderType) const {
const auto spec = (IsWebGL2() ? SH_WEBGL2_SPEC : SH_WEBGL_SPEC);
const auto outputLanguage = ShaderOutput(gl);
@ -212,27 +212,46 @@ webgl::ShaderValidator* WebGLContext::CreateShaderValidator(
namespace webgl {
/*static*/
ShaderValidator* ShaderValidator::Create(GLenum shaderType, ShShaderSpec spec,
ShShaderOutput outputLanguage,
const ShBuiltInResources& resources,
ShCompileOptions compileOptions) {
std::unique_ptr<ShaderValidator> ShaderValidator::Create(
GLenum shaderType, ShShaderSpec spec, ShShaderOutput outputLanguage,
const ShBuiltInResources& resources, ShCompileOptions compileOptions) {
ShHandle handle =
sh::ConstructCompiler(shaderType, spec, outputLanguage, &resources);
MOZ_RELEASE_ASSERT(handle);
if (!handle) return nullptr;
return new ShaderValidator(handle, compileOptions,
resources.MaxVaryingVectors);
return std::unique_ptr<ShaderValidator>(
new ShaderValidator(handle, compileOptions, resources.MaxVaryingVectors));
}
ShaderValidator::~ShaderValidator() { sh::Destruct(mHandle); }
bool ShaderValidator::ValidateAndTranslate(const char* source) {
MOZ_ASSERT(!mHasRun);
mHasRun = true;
std::unique_ptr<const ShaderValidatorResults>
ShaderValidator::ValidateAndTranslate(const char* const source) const {
auto ret = std::make_unique<ShaderValidatorResults>();
const char* const parts[] = {source};
return sh::Compile(mHandle, parts, ArrayLength(parts), mCompileOptions);
const std::array<const char*, 1> parts = {source};
ret->mValid =
sh::Compile(mHandle, parts.data(), parts.size(), mCompileOptions);
ret->mInfoLog = sh::GetInfoLog(mHandle);
if (ret->mValid) {
ret->mObjectCode = sh::GetObjectCode(mHandle);
ret->mShaderVersion = sh::GetShaderVersion(mHandle);
ret->mVertexShaderNumViews = sh::GetVertexShaderNumViews(mHandle);
ret->mAttributes = *sh::GetAttributes(mHandle);
ret->mInterfaceBlocks = *sh::GetInterfaceBlocks(mHandle);
ret->mOutputVariables = *sh::GetOutputVariables(mHandle);
ret->mUniforms = *sh::GetUniforms(mHandle);
ret->mVaryings = *sh::GetVaryings(mHandle);
ret->mMaxVaryingVectors = mMaxVaryingVectors;
}
sh::ClearResults(mHandle);
return ret;
}
template <size_t N>
@ -240,91 +259,58 @@ static bool StartsWith(const std::string& haystack, const char (&needle)[N]) {
return haystack.compare(0, N - 1, needle) == 0;
}
bool ShaderValidator::CanLinkTo(const ShaderValidator* prev,
nsCString* const out_log) const {
if (!prev) {
nsPrintfCString error("Passed in NULL prev ShaderValidator.");
*out_log = error;
return false;
}
bool ShaderValidatorResults::CanLinkTo(const ShaderValidatorResults& vert,
nsCString* const out_log) const {
MOZ_ASSERT(mValid);
MOZ_ASSERT(vert.mValid);
const auto shaderVersion = sh::GetShaderVersion(mHandle);
if (sh::GetShaderVersion(prev->mHandle) != shaderVersion) {
if (vert.mShaderVersion != mShaderVersion) {
nsPrintfCString error(
"Vertex shader version %d does not match"
" fragment shader version %d.",
sh::GetShaderVersion(prev->mHandle), sh::GetShaderVersion(mHandle));
vert.mShaderVersion, mShaderVersion);
*out_log = error;
return false;
}
{
const std::vector<sh::Uniform>* vertPtr = sh::GetUniforms(prev->mHandle);
const std::vector<sh::Uniform>* fragPtr = sh::GetUniforms(mHandle);
if (!vertPtr || !fragPtr) {
nsPrintfCString error("Could not create uniform list.");
*out_log = error;
return false;
}
for (const auto& itrFrag : mUniforms) {
for (const auto& itrVert : vert.mUniforms) {
if (itrVert.name != itrFrag.name) continue;
for (auto itrFrag = fragPtr->begin(); itrFrag != fragPtr->end();
++itrFrag) {
for (auto itrVert = vertPtr->begin(); itrVert != vertPtr->end();
++itrVert) {
if (itrVert->name != itrFrag->name) continue;
if (!itrVert->isSameUniformAtLinkTime(*itrFrag)) {
nsPrintfCString error(
"Uniform `%s` is not linkable between"
" attached shaders.",
itrFrag->name.c_str());
*out_log = error;
return false;
}
break;
if (!itrVert.isSameUniformAtLinkTime(itrFrag)) {
nsPrintfCString error(
"Uniform `%s` is not linkable between"
" attached shaders.",
itrFrag.name.c_str());
*out_log = error;
return false;
}
}
}
{
const auto vertVars = sh::GetInterfaceBlocks(prev->mHandle);
const auto fragVars = sh::GetInterfaceBlocks(mHandle);
if (!vertVars || !fragVars) {
nsPrintfCString error("Could not create uniform block list.");
*out_log = error;
return false;
}
for (const auto& fragVar : *fragVars) {
for (const auto& vertVar : *vertVars) {
if (vertVar.name != fragVar.name) continue;
if (!vertVar.isSameInterfaceBlockAtLinkTime(fragVar)) {
nsPrintfCString error(
"Interface block `%s` is not linkable between"
" attached shaders.",
fragVar.name.c_str());
*out_log = error;
return false;
}
break;
}
break;
}
}
const auto& vertVaryings = sh::GetVaryings(prev->mHandle);
const auto& fragVaryings = sh::GetVaryings(mHandle);
if (!vertVaryings || !fragVaryings) {
nsPrintfCString error("Could not create varying list.");
*out_log = error;
return false;
for (const auto& fragVar : mInterfaceBlocks) {
for (const auto& vertVar : vert.mInterfaceBlocks) {
if (vertVar.name != fragVar.name) continue;
if (!vertVar.isSameInterfaceBlockAtLinkTime(fragVar)) {
nsPrintfCString error(
"Interface block `%s` is not linkable between"
" attached shaders.",
fragVar.name.c_str());
*out_log = error;
return false;
}
break;
}
}
{
std::vector<sh::ShaderVariable> staticUseVaryingList;
for (const auto& fragVarying : *fragVaryings) {
for (const auto& fragVarying : mVaryings) {
static const char prefix[] = "gl_";
if (StartsWith(fragVarying.name, prefix)) {
if (fragVarying.staticUse) {
@ -336,10 +322,10 @@ bool ShaderValidator::CanLinkTo(const ShaderValidator* prev,
bool definedInVertShader = false;
bool staticVertUse = false;
for (const auto& vertVarying : *vertVaryings) {
for (const auto& vertVarying : vert.mVaryings) {
if (vertVarying.name != fragVarying.name) continue;
if (!vertVarying.isSameVaryingAtLinkTime(fragVarying, shaderVersion)) {
if (!vertVarying.isSameVaryingAtLinkTime(fragVarying, mShaderVersion)) {
nsPrintfCString error(
"Varying `%s`is not linkable between"
" attached shaders.",
@ -377,14 +363,14 @@ bool ShaderValidator::CanLinkTo(const ShaderValidator* prev,
}
}
if (shaderVersion == 100) {
if (mShaderVersion == 100) {
// Enforce ESSL1 invariant linking rules.
bool isInvariant_Position = false;
bool isInvariant_PointSize = false;
bool isInvariant_FragCoord = false;
bool isInvariant_PointCoord = false;
for (const auto& varying : *vertVaryings) {
for (const auto& varying : vert.mVaryings) {
if (varying.name == "gl_Position") {
isInvariant_Position = varying.isInvariant;
} else if (varying.name == "gl_PointSize") {
@ -392,7 +378,7 @@ bool ShaderValidator::CanLinkTo(const ShaderValidator* prev,
}
}
for (const auto& varying : *fragVaryings) {
for (const auto& varying : mVaryings) {
if (varying.name == "gl_FragCoord") {
isInvariant_FragCoord = varying.isInvariant;
} else if (varying.name == "gl_PointCoord") {
@ -428,13 +414,12 @@ bool ShaderValidator::CanLinkTo(const ShaderValidator* prev,
}
// This must handle names like "foo.bar[0]".
bool ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
std::string* const out_userName,
bool* const out_isArray) const {
const std::vector<sh::Uniform>& uniforms = *sh::GetUniforms(mHandle);
for (auto itr = uniforms.begin(); itr != uniforms.end(); ++itr) {
bool ShaderValidatorResults::FindUniformByMappedName(
const std::string& mappedName, std::string* const out_userName,
bool* const out_isArray) const {
for (const auto& cur : mUniforms) {
const sh::ShaderVariable* found;
if (!itr->findInfoByMappedName(mappedName, &found, out_userName)) continue;
if (!cur.findInfoByMappedName(mappedName, &found, out_userName)) continue;
*out_isArray = found->isArray();
return true;
@ -442,9 +427,7 @@ bool ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
const size_t dotPos = mappedName.find(".");
const std::vector<sh::InterfaceBlock>& interfaces =
*sh::GetInterfaceBlocks(mHandle);
for (const auto& interface : interfaces) {
for (const auto& interface : mInterfaceBlocks) {
std::string mappedFieldName;
const bool hasInstanceName = !interface.instanceName.empty();
@ -483,5 +466,30 @@ bool ShaderValidator::FindUniformByMappedName(const std::string& mappedName,
return false;
}
size_t ShaderValidatorResults::SizeOfIncludingThis(
const MallocSizeOf fnSizeOf) const {
auto ret = fnSizeOf(this);
ret += mInfoLog.size();
ret += mObjectCode.size();
for (const auto& cur : mAttributes) {
ret += fnSizeOf(&cur);
}
for (const auto& cur : mInterfaceBlocks) {
ret += fnSizeOf(&cur);
}
for (const auto& cur : mOutputVariables) {
ret += fnSizeOf(&cur);
}
for (const auto& cur : mUniforms) {
ret += fnSizeOf(&cur);
}
for (const auto& cur : mVaryings) {
ret += fnSizeOf(&cur);
}
return ret;
}
} // namespace webgl
} // namespace mozilla

View File

@ -15,6 +15,31 @@
namespace mozilla {
namespace webgl {
class ShaderValidatorResults final {
public:
std::string mInfoLog;
bool mValid = false;
std::string mObjectCode;
int mShaderVersion = 0;
int mVertexShaderNumViews = 0;
std::vector<sh::Attribute> mAttributes;
std::vector<sh::InterfaceBlock> mInterfaceBlocks;
std::vector<sh::OutputVariable> mOutputVariables;
std::vector<sh::Uniform> mUniforms;
std::vector<sh::Varying> mVaryings;
int mMaxVaryingVectors = 0;
bool CanLinkTo(const ShaderValidatorResults& vert,
nsCString* const out_log) const;
bool FindUniformByMappedName(const std::string& mappedName,
std::string* const out_userName,
bool* const out_isArray) const;
size_t SizeOfIncludingThis(MallocSizeOf) const;
};
class ShaderValidator final {
public:
const ShHandle mHandle;
@ -22,36 +47,24 @@ class ShaderValidator final {
private:
const ShCompileOptions mCompileOptions;
const int mMaxVaryingVectors;
bool mHasRun;
public:
static ShaderValidator* Create(GLenum shaderType, ShShaderSpec spec,
ShShaderOutput outputLanguage,
const ShBuiltInResources& resources,
ShCompileOptions compileOptions);
static std::unique_ptr<ShaderValidator> Create(
GLenum shaderType, ShShaderSpec spec, ShShaderOutput outputLanguage,
const ShBuiltInResources& resources, ShCompileOptions compileOptions);
private:
ShaderValidator(ShHandle handle, ShCompileOptions compileOptions,
int maxVaryingVectors)
: mHandle(handle),
mCompileOptions(compileOptions),
mMaxVaryingVectors(maxVaryingVectors),
mHasRun(false) {}
mMaxVaryingVectors(maxVaryingVectors) {}
public:
~ShaderValidator();
bool ValidateAndTranslate(const char* source);
bool CanLinkTo(const ShaderValidator* prev, nsCString* const out_log) const;
bool FindUniformByMappedName(const std::string& mappedName,
std::string* const out_userName,
bool* const out_isArray) const;
bool ValidateTransformFeedback(
const std::vector<nsString>& userNames, uint32_t maxComponents,
nsCString* const out_errorText,
std::vector<std::string>* const out_mappedNames);
std::unique_ptr<const ShaderValidatorResults> ValidateAndTranslate(
const char*) const;
};
} // namespace webgl

View File

@ -1921,8 +1921,9 @@ static bool ValidateCopyTexImageForFeedback(const WebGLContext& webgl,
}
static bool DoCopyTexOrSubImage(WebGLContext* webgl, bool isSubImage,
WebGLTexture* const tex, const TexImageTarget target,
GLint level, GLint xWithinSrc, GLint yWithinSrc,
WebGLTexture* const tex,
const TexImageTarget target, GLint level,
GLint xWithinSrc, GLint yWithinSrc,
uint32_t srcTotalWidth, uint32_t srcTotalHeight,
const webgl::FormatUsageInfo* srcUsage,
GLint xOffset, GLint yOffset, GLint zOffset,

View File

@ -1097,17 +1097,17 @@ mozilla::ipc::IPCResult ContentParent::RecvLaunchRDDProcess(
/*static*/
already_AddRefed<RemoteBrowser> ContentParent::CreateBrowser(
const TabContext& aContext, Element* aFrameElement,
BrowsingContext* aBrowsingContext, ContentParent* aOpenerContentParent,
BrowserParent* aSameTabGroupAs, uint64_t aNextRemoteTabId) {
const nsAString& aRemoteType, BrowsingContext* aBrowsingContext,
ContentParent* aOpenerContentParent, BrowserParent* aSameTabGroupAs,
uint64_t aNextRemoteTabId) {
AUTO_PROFILER_LABEL("ContentParent::CreateBrowser", OTHER);
if (!sCanLaunchSubprocesses) {
return nullptr;
}
nsAutoString remoteType;
if (!aFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::RemoteType,
remoteType)) {
nsAutoString remoteType(aRemoteType);
if (remoteType.IsEmpty()) {
remoteType.AssignLiteral(DEFAULT_REMOTE_TYPE);
}

View File

@ -212,8 +212,9 @@ class ContentParent final : public PContentParent,
*/
static already_AddRefed<RemoteBrowser> CreateBrowser(
const TabContext& aContext, Element* aFrameElement,
BrowsingContext* aBrowsingContext, ContentParent* aOpenerContentParent,
BrowserParent* aSameTabGroupAs, uint64_t aNextRemoteTabId);
const nsAString& aRemoteType, BrowsingContext* aBrowsingContext,
ContentParent* aOpenerContentParent, BrowserParent* aSameTabGroupAs,
uint64_t aNextRemoteTabId);
static void GetAll(nsTArray<ContentParent*>& aArray);

View File

@ -203,9 +203,13 @@ static nsresult ChangeFrameRemoteness(WindowGlobalChild* aWgc,
// Actually perform the remoteness swap.
RemotenessOptions options;
options.mRemoteType.Construct(aRemoteType);
options.mPendingSwitchID.Construct(aPendingSwitchId);
// Only set mRemoteType if it doesn't match the current process' remote type.
if (!ContentChild::GetSingleton()->GetRemoteType().Equals(aRemoteType)) {
options.mRemoteType.Construct(aRemoteType);
}
ErrorResult error;
flo->ChangeRemoteness(options, error);
if (NS_WARN_IF(error.Failed())) {

View File

@ -278,8 +278,8 @@ IPCResult WindowGlobalParent::RecvDidEmbedBrowsingContext(
already_AddRefed<Promise> WindowGlobalParent::ChangeFrameRemoteness(
dom::BrowsingContext* aBc, const nsAString& aRemoteType,
uint64_t aPendingSwitchId, ErrorResult& aRv) {
RefPtr<BrowserParent> browserParent = GetBrowserParent();
if (NS_WARN_IF(!browserParent)) {
RefPtr<BrowserParent> embedderBrowserParent = GetBrowserParent();
if (NS_WARN_IF(!embedderBrowserParent)) {
aRv.Throw(NS_ERROR_FAILURE);
return nullptr;
}
@ -290,6 +290,9 @@ already_AddRefed<Promise> WindowGlobalParent::ChangeFrameRemoteness(
return nullptr;
}
RefPtr<CanonicalBrowsingContext> browsingContext =
CanonicalBrowsingContext::Cast(aBc);
// When the reply comes back from content, either resolve or reject.
auto resolve =
[=](mozilla::Tuple<nsresult, PBrowserBridgeParent*>&& aResult) {
@ -301,15 +304,31 @@ already_AddRefed<Promise> WindowGlobalParent::ChangeFrameRemoteness(
return;
}
// If we got a BrowserBridgeParent, the frame is out-of-process, so pull
// our target content process off of it. Otherwise, it's an in-process
// frame, so we can directly use ours.
// If we got a `BrowserBridgeParent`, the frame is out-of-process, so we
// can get the target off of it. Otherwise, it's an in-process frame, so
// we can use the embedder `BrowserParent`.
RefPtr<BrowserParent> browserParent;
if (bridge) {
promise->MaybeResolve(
bridge->GetBrowserParent()->Manager()->ChildID());
browserParent = bridge->GetBrowserParent();
} else {
promise->MaybeResolve(browserParent->Manager()->ChildID());
browserParent = embedderBrowserParent;
}
MOZ_ASSERT(browserParent);
if (!browserParent || !browserParent->CanSend()) {
promise->MaybeReject(NS_ERROR_FAILURE);
return;
}
// Update our BrowsingContext to its new owner, if it hasn't been
// updated yet. This can happen when switching from a out-of-process to
// in-process frame. For remote frames, the BrowserBridgeParent::Init
// method should've already set up the OwnerProcessId.
uint64_t childId = browserParent->Manager()->ChildID();
MOZ_ASSERT_IF(bridge, browsingContext->IsOwnedByProcess(childId));
browsingContext->SetOwnerProcessId(childId);
promise->MaybeResolve(childId);
};
auto reject = [=](ResponseRejectReason aReason) {

View File

@ -46,7 +46,6 @@ using mozilla::DefaultXDisplay;
#include "nsIDocShell.h"
#include "ImageContainer.h"
#include "GLContext.h"
#include "EGLUtils.h"
#include "nsIContentInlines.h"
#include "mozilla/MiscEvents.h"
#include "mozilla/MouseEvents.h"

View File

@ -84,8 +84,6 @@ add_task(async function() {
ok(!Cu.isDeadWrapper(content.win1), "win1 shouldn't be a dead wrapper after navigation");
// This load still doesn't work for some reason, so we skip it for now.
/*
askLoad(URL3);
await waitLoad();
@ -94,23 +92,15 @@ add_task(async function() {
is(content.bc2, content.bc3, "cross to cross-origin navigation BrowsingContext match");
ok(content.win2 == content.win3, "cross to cross-origin navigation WindowProxy match");
*/
// It would also be useful and important to handle navigating back into an
// in-process URL, but that actually doesn't work yet... so........
/*
askLoad(URL1);
await waitLoad();
let win4 = iframe.contentWindow;
let bc4 = iframe.browsingContext;
is(bc3, bc4, "cross to same-origin navigation BrowsingContext match");
try {
is(win3, win4, "cross to same-origin navigation WindowProxy match");
} catch(e) {
ok(false, "cross to same-origin navigation WindowProxy exception");
}
*/
content.win4 = iframe.contentWindow;
content.bc4 = iframe.browsingContext;
is(content.bc3, content.bc4, "cross to same-origin navigation BrowsingContext match");
todo(content.win3 == content.win4, "cross to same-origin navigation WindowProxty match");
});
} finally {
await BrowserTestUtils.closeWindow(win);

View File

@ -1,104 +0,0 @@
/* 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/. */
#include "EGLUtils.h"
#include "GLContextEGL.h"
#include "GLLibraryEGL.h"
namespace mozilla {
namespace gl {
bool DoesEGLContextSupportSharingWithEGLImage(GLContext* gl) {
const auto& gle = GLContextEGL::Cast(gl);
const auto& egl = gle->mEgl;
return egl->HasKHRImageBase() && egl->HasKHRImageTexture2D() &&
gl->IsExtensionSupported(GLContext::OES_EGL_image);
}
EGLImage CreateEGLImage(GLContext* gl, GLuint tex) {
MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));
const auto& gle = GLContextEGL::Cast(gl);
const auto& egl = gle->mEgl;
EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
EGLImage image =
egl->fCreateImage(egl->Display(), gle->mContext, LOCAL_EGL_GL_TEXTURE_2D,
clientBuffer, nullptr);
return image;
}
////////////////////////////////////////////////////////////////////////
// EGLImageWrapper
/*static*/
EGLImageWrapper* EGLImageWrapper::Create(GLContext* gl, GLuint tex) {
MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl));
const auto& gle = GLContextEGL::Cast(gl);
const auto& egl = gle->mEgl;
const auto& display = egl->Display();
EGLClientBuffer clientBuffer = (EGLClientBuffer)((uint64_t)tex);
EGLImage image = egl->fCreateImage(
display, gle->mContext, LOCAL_EGL_GL_TEXTURE_2D, clientBuffer, nullptr);
if (!image) {
#ifdef DEBUG
printf_stderr("Could not create EGL images: ERROR (0x%04x)\n",
egl->fGetError());
#endif
return nullptr;
}
return new EGLImageWrapper(egl, display, image);
}
EGLImageWrapper::EGLImageWrapper(GLLibraryEGL* library, EGLDisplay display,
EGLImage image)
: mLibrary(library), mDisplay(display), mImage(image), mSync(0) {
MOZ_ASSERT(mImage);
}
EGLImageWrapper::~EGLImageWrapper() {
mLibrary->fDestroyImage(mDisplay, mImage);
}
bool EGLImageWrapper::FenceSync(GLContext* gl) {
MOZ_ASSERT(!mSync);
if (mLibrary->IsExtensionSupported(GLLibraryEGL::KHR_fence_sync)) {
mSync = mLibrary->fCreateSync(mDisplay, LOCAL_EGL_SYNC_FENCE, nullptr);
// We need to flush to make sure the sync object enters the command stream;
// we can't use EGL_SYNC_FLUSH_COMMANDS_BIT at wait time, because the wait
// happens on a different thread/context.
gl->fFlush();
}
if (!mSync) {
// we failed to create one, so just do a finish
gl->fFinish();
}
return true;
}
bool EGLImageWrapper::ClientWaitSync() {
if (!mSync) {
// if we have no sync object, then we did a Finish() earlier
return true;
}
// wait at most 1 second; this should really be never/rarely hit
const uint64_t ns_per_ms = 1000 * 1000;
EGLTime timeout = 1000 * ns_per_ms;
EGLint result = mLibrary->fClientWaitSync(mDisplay, mSync, 0, timeout);
mLibrary->fDestroySync(mDisplay, mSync);
mSync = nullptr;
return result == LOCAL_EGL_CONDITION_SATISFIED;
}
} // namespace gl
} // namespace mozilla

View File

@ -1,52 +0,0 @@
/* 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 EGLUTILS_H_
#define EGLUTILS_H_
#include "GLContextTypes.h"
#include "GLTypes.h"
#include "mozilla/Assertions.h"
namespace mozilla {
namespace gl {
class GLLibraryEGL;
bool DoesEGLContextSupportSharingWithEGLImage(GLContext* gl);
EGLImage CreateEGLImage(GLContext* gl, GLuint tex);
////////////////////////////////////////////////////////////////////////
// EGLImageWrapper
class EGLImageWrapper {
public:
static EGLImageWrapper* Create(GLContext* gl, GLuint tex);
private:
const RefPtr<GLLibraryEGL> mLibrary;
const EGLDisplay mDisplay;
public:
const EGLImage mImage;
private:
EGLSync mSync;
EGLImageWrapper(GLLibraryEGL* library, EGLDisplay display, EGLImage image);
public:
~EGLImageWrapper();
// Insert a sync point on the given context, which should be the current
// active context.
bool FenceSync(GLContext* gl);
bool ClientWaitSync();
};
} // namespace gl
} // namespace mozilla
#endif

View File

@ -8,7 +8,7 @@
#include <d3d11.h>
#include "GLContext.h"
#include "GLContextEGL.h"
#include "GLLibraryEGL.h"
#include "GPUVideoImage.h"
#include "ScopedGLHelpers.h"

View File

@ -542,6 +542,8 @@ class GLLibraryEGL final {
static StaticRefPtr<GLLibraryEGL> sEGLLibrary;
};
bool DoesEGLContextSupportSharingWithEGLImage(GLContext* gl);
} /* namespace gl */
} /* namespace mozilla */

View File

@ -27,7 +27,6 @@ EXPORTS += [
'AndroidNativeWindow.h',
'AndroidSurfaceTexture.h',
'DecomposeIntoNoRepeatTriangles.h',
'EGLUtils.h',
'ForceDiscreteGPUHelperCGL.h',
'GfxTexturesReporter.h',
'GLBlitHelper.h',
@ -119,7 +118,6 @@ if CONFIG['MOZ_WAYLAND']:
UNIFIED_SOURCES += [
'AndroidSurfaceTexture.cpp',
'DecomposeIntoNoRepeatTriangles.cpp',
'EGLUtils.cpp',
'GfxTexturesReporter.cpp',
'GLBlitHelper.cpp',
'GLContext.cpp',

View File

@ -6,8 +6,7 @@
#include "TextureHostOGL.h"
#include "EGLUtils.h"
#include "GLContext.h" // for GLContext, etc
#include "GLContextEGL.h" // for GLContext, etc
#include "GLLibraryEGL.h" // for GLLibraryEGL
#include "GLUploadHelpers.h"
#include "GLReadTexImageHelper.h"
@ -711,8 +710,17 @@ void EGLImageTextureSource::BindTexture(GLenum aTextureUnit,
return;
}
MOZ_ASSERT(DoesEGLContextSupportSharingWithEGLImage(gl),
#ifdef DEBUG
const bool supportsEglImage = [&]() {
const auto& gle = GLContextEGL::Cast(gl);
const auto& egl = gle->mEgl;
return egl->HasKHRImageBase() && egl->HasKHRImageTexture2D() &&
gl->IsExtensionSupported(GLContext::OES_EGL_image);
}();
MOZ_ASSERT(supportsEglImage,
"EGLImage not supported or disabled in runtime");
#endif
GLuint tex = mCompositor->GetTemporaryTexture(mTextureTarget, aTextureUnit);

View File

@ -105,15 +105,34 @@ class MOZ_NON_PARAM JS_PUBLIC_API ProfilingFrameIterator {
// and less than older native and psuedo-stack frame addresses
void* stackAddress() const;
enum FrameKind { Frame_Baseline, Frame_Ion, Frame_Wasm };
enum FrameKind {
Frame_BaselineInterpreter,
Frame_Baseline,
Frame_Ion,
Frame_Wasm
};
struct Frame {
FrameKind kind;
void* stackAddress;
void* returnAddress;
union {
void* returnAddress_;
jsbytecode* interpreterPC_;
};
void* activation;
void* endStackAddress;
const char* label;
JSScript* interpreterScript;
public:
void* returnAddress() const {
MOZ_ASSERT(kind != Frame_BaselineInterpreter);
return returnAddress_;
}
jsbytecode* interpreterPC() const {
MOZ_ASSERT(kind == Frame_BaselineInterpreter);
return interpreterPC_;
}
} JS_HAZ_GC_INVALIDATED;
bool isWasm() const;

View File

@ -2586,8 +2586,11 @@ static bool ReadGeckoProfilingStack(JSContext* cx, unsigned argc, Value* vp) {
for (uint32_t i = 0; i < nframes; i++) {
const char* frameKindStr = nullptr;
switch (frames[i].kind) {
case JS::ProfilingFrameIterator::Frame_BaselineInterpreter:
frameKindStr = "baseline-interpreter";
break;
case JS::ProfilingFrameIterator::Frame_Baseline:
frameKindStr = "baseline";
frameKindStr = "baseline-jit";
break;
case JS::ProfilingFrameIterator::Frame_Ion:
frameKindStr = "ion";

View File

@ -6923,6 +6923,21 @@ bool BaselineInterpreterGenerator::generate(BaselineInterpreter& interpreter) {
return false;
}
// Register BaselineInterpreter code with the profiler's JitCode table.
{
JitcodeGlobalEntry::BaselineInterpreterEntry entry;
entry.init(code, code->raw(), code->rawEnd());
JitcodeGlobalTable* globalTable =
cx->runtime()->jitRuntime()->getJitcodeGlobalTable();
if (!globalTable->addEntry(entry)) {
ReportOutOfMemory(cx);
return false;
}
code->setHasBytecodeMap();
}
// Patch loads now that we know the tableswitch base address.
for (CodeOffset off : tableLabels_) {
Assembler::PatchDataWithValueCheck(CodeLocationLabel(code, off),
@ -6945,6 +6960,10 @@ bool BaselineInterpreterGenerator::generate(BaselineInterpreter& interpreter) {
std::move(handler.codeCoverageOffsets()));
}
if (cx->runtime()->geckoProfiler().enabled()) {
interpreter.toggleProfilerInstrumentation(true);
}
if (coverage::IsLCovEnabled()) {
interpreter.toggleCodeCoverageInstrumentationUnchecked(true);
}

View File

@ -1049,17 +1049,22 @@ void jit::AddSizeOfBaselineData(JSScript* script,
}
}
void jit::ToggleBaselineProfiling(JSRuntime* runtime, bool enable) {
JitRuntime* jrt = runtime->jitRuntime();
void jit::ToggleBaselineProfiling(JSContext* cx, bool enable) {
JitRuntime* jrt = cx->runtime()->jitRuntime();
if (!jrt) {
return;
}
jrt->baselineInterpreter().toggleProfilerInstrumentation(enable);
for (ZonesIter zone(runtime, SkipAtoms); !zone.done(); zone.next()) {
for (ZonesIter zone(cx->runtime(), SkipAtoms); !zone.done(); zone.next()) {
for (auto script = zone->cellIter<JSScript>(); !script.done();
script.next()) {
if (enable) {
if (JitScript* jitScript = script->jitScript()) {
jitScript->ensureProfileString(cx, script);
}
}
if (!script->hasBaselineScript()) {
continue;
}

View File

@ -557,7 +557,7 @@ void FinishDiscardBaselineScript(FreeOp* fop, JSScript* script);
void AddSizeOfBaselineData(JSScript* script, mozilla::MallocSizeOf mallocSizeOf,
size_t* data);
void ToggleBaselineProfiling(JSRuntime* runtime, bool enable);
void ToggleBaselineProfiling(JSContext* cx, bool enable);
void ToggleBaselineTraceLoggerScripts(JSRuntime* runtime, bool enable);
void ToggleBaselineTraceLoggerEngine(JSRuntime* runtime, bool enable);

View File

@ -36,12 +36,12 @@ inline size_t JSJitFrameIter::prevFrameLocalSize() const {
return current->prevFrameLocalSize();
}
inline JitFrameLayout* JSJitProfilingFrameIterator::framePtr() {
inline JitFrameLayout* JSJitProfilingFrameIterator::framePtr() const {
MOZ_ASSERT(!done());
return (JitFrameLayout*)fp_;
}
inline JSScript* JSJitProfilingFrameIterator::frameScript() {
inline JSScript* JSJitProfilingFrameIterator::frameScript() const {
return ScriptFromCalleeToken(framePtr()->calleeToken());
}

View File

@ -10,6 +10,7 @@
#include "jit/BaselineIC.h"
#include "jit/JitcodeMap.h"
#include "jit/JitFrames.h"
#include "jit/JitScript.h"
#include "jit/Safepoints.h"
using namespace js;
@ -509,12 +510,16 @@ JSJitProfilingFrameIterator::JSJitProfilingFrameIterator(JSContext* cx,
}
}
MOZ_ASSERT(frameScript()->hasBaselineScript());
// If nothing matches, for now just assume we are at the start of the last
// frame's baseline jit code.
// frame's baseline jit code or interpreter code.
type_ = FrameType::BaselineJS;
resumePCinCurrentFrame_ = frameScript()->baselineScript()->method()->raw();
if (frameScript()->hasBaselineScript()) {
resumePCinCurrentFrame_ = frameScript()->baselineScript()->method()->raw();
} else {
MOZ_ASSERT(JitOptions.baselineInterpreter);
resumePCinCurrentFrame_ =
cx->runtime()->jitRuntime()->baselineInterpreter().codeRaw();
}
}
template <typename ReturnType = CommonFrameLayout*>
@ -565,7 +570,7 @@ bool JSJitProfilingFrameIterator::tryInitWithTable(JitcodeGlobalTable* table,
JSScript* callee = frameScript();
MOZ_ASSERT(entry->isIon() || entry->isBaseline() || entry->isIonCache() ||
entry->isDummy());
entry->isBaselineInterpreter() || entry->isDummy());
// Treat dummy lookups as an empty frame sequence.
if (entry->isDummy()) {
@ -599,6 +604,12 @@ bool JSJitProfilingFrameIterator::tryInitWithTable(JitcodeGlobalTable* table,
return true;
}
if (entry->isBaselineInterpreter()) {
type_ = FrameType::BaselineJS;
resumePCinCurrentFrame_ = pc;
return true;
}
if (entry->isIonCache()) {
void* ptr = entry->ionCacheEntry().rejoinAddr();
const JitcodeGlobalEntry& ionEntry = table->lookupInfallible(ptr);
@ -631,12 +642,15 @@ void JSJitProfilingFrameIterator::fixBaselineReturnAddress() {
// Certain exception handling cases such as debug OSR or resuming a generator
// with .throw() will use BaselineFrame::setOverridePc() to indicate the
// effective |pc|. We translate the effective-pc into a Baseline code
// address.
if (jsbytecode* override = bl->maybeOverridePc()) {
// address. Don't do this for frames running in the Baseline Interpreter,
// because we don't use the return address in that case.
jsbytecode* overridePC = bl->maybeOverridePc();
if (overridePC && !bl->runningInInterpreter()) {
PCMappingSlotInfo slotInfo;
JSScript* script = bl->script();
BaselineScript* blScript = script->baselineScript();
resumePCinCurrentFrame_ =
script->baselineScript()->nativeCodeForPC(script, override, &slotInfo);
blScript->nativeCodeForPC(script, overridePC, &slotInfo);
// NOTE: The stack may not be synced at this PC. For the purpose of
// profiler sampling this is fine.
@ -644,6 +658,29 @@ void JSJitProfilingFrameIterator::fixBaselineReturnAddress() {
}
}
const char* JSJitProfilingFrameIterator::baselineInterpreterLabel() const {
MOZ_ASSERT(type_ == FrameType::BaselineJS);
return frameScript()->jitScript()->profileString();
}
void JSJitProfilingFrameIterator::baselineInterpreterScriptPC(
JSScript** script, jsbytecode** pc) const {
MOZ_ASSERT(type_ == FrameType::BaselineJS);
BaselineFrame* blFrame =
(BaselineFrame*)(fp_ - BaselineFrame::FramePointerOffset -
BaselineFrame::Size());
*script = frameScript();
*pc = (*script)->code();
if (blFrame->runningInInterpreter() &&
blFrame->interpreterScript() == *script) {
jsbytecode* interpPC = blFrame->interpreterPC();
if ((*script)->containsPC(interpPC)) {
*pc = interpPC;
}
}
}
void JSJitProfilingFrameIterator::operator++() {
JitFrameLayout* frame = framePtr();
moveToNextFrame(frame);

View File

@ -275,8 +275,8 @@ class JSJitProfilingFrameIterator {
FrameType type_;
void* resumePCinCurrentFrame_;
inline JitFrameLayout* framePtr();
inline JSScript* frameScript();
inline JitFrameLayout* framePtr() const;
inline JSScript* frameScript() const;
MOZ_MUST_USE bool tryInitWithPC(void* pc);
MOZ_MUST_USE bool tryInitWithTable(JitcodeGlobalTable* table, void* pc,
bool forLastCallSite);
@ -293,6 +293,9 @@ class JSJitProfilingFrameIterator {
void operator++();
bool done() const { return fp_ == nullptr; }
const char* baselineInterpreterLabel() const;
void baselineInterpreterScriptPC(JSScript** script, jsbytecode** pc) const;
void* fp() const {
MOZ_ASSERT(!done());
return fp_;

View File

@ -40,8 +40,10 @@ static size_t NumTypeSets(JSScript* script) {
}
JitScript::JitScript(JSScript* script, uint32_t typeSetOffset,
uint32_t bytecodeTypeMapOffset, uint32_t allocBytes)
: typeSetOffset_(typeSetOffset),
uint32_t bytecodeTypeMapOffset, uint32_t allocBytes,
const char* profileString)
: profileString_(profileString),
typeSetOffset_(typeSetOffset),
bytecodeTypeMapOffset_(bytecodeTypeMapOffset),
allocBytes_(allocBytes) {
setTypesGeneration(script->zone()->types.generation);
@ -71,6 +73,15 @@ bool JSScript::createJitScript(JSContext* cx) {
return true;
}
// Store the profile string in the JitScript if the profiler is enabled.
const char* profileString = nullptr;
if (cx->runtime()->geckoProfiler().enabled()) {
profileString = cx->runtime()->geckoProfiler().profileString(cx, this);
if (!profileString) {
return false;
}
}
size_t numTypeSets = NumTypeSets(this);
static_assert(sizeof(JitScript) % sizeof(uintptr_t) == 0,
@ -99,8 +110,9 @@ bool JSScript::createJitScript(JSContext* cx) {
uint32_t typeSetOffset = sizeof(JitScript) + numICEntries() * sizeof(ICEntry);
uint32_t bytecodeTypeMapOffset =
typeSetOffset + numTypeSets * sizeof(StackTypeSet);
UniquePtr<JitScript> jitScript(new (raw) JitScript(
this, typeSetOffset, bytecodeTypeMapOffset, allocSize.value()));
UniquePtr<JitScript> jitScript(
new (raw) JitScript(this, typeSetOffset, bytecodeTypeMapOffset,
allocSize.value(), profileString));
// Sanity check the length computations.
MOZ_ASSERT(jitScript->numICEntries() == numICEntries());
@ -173,6 +185,19 @@ void JitScript::trace(JSTracer* trc) {
}
}
void JitScript::ensureProfileString(JSContext* cx, JSScript* script) {
MOZ_ASSERT(cx->runtime()->geckoProfiler().enabled());
if (profileString_) {
return;
}
profileString_ = cx->runtime()->geckoProfiler().profileString(cx, script);
if (!profileString_) {
MOZ_CRASH("Failed to allocate profile string");
}
}
#ifdef DEBUG
void JitScript::printTypes(JSContext* cx, HandleScript script) {
AutoSweepJitScript sweep(script);

View File

@ -105,6 +105,9 @@ class alignas(uintptr_t) JitScript final {
// directly to this script.
js::UniquePtr<Vector<DependentWasmImport>> dependentWasmImports_;
// Profile string used by the profiler for Baseline Interpreter frames.
const char* profileString_ = nullptr;
// Offset of the StackTypeSet array.
uint32_t typeSetOffset_ = 0;
@ -150,7 +153,8 @@ class alignas(uintptr_t) JitScript final {
public:
JitScript(JSScript* script, uint32_t typeSetOffset,
uint32_t bytecodeTypeMapOffset, uint32_t allocBytes);
uint32_t bytecodeTypeMapOffset, uint32_t allocBytes,
const char* profileString);
#ifdef DEBUG
~JitScript() {
@ -202,6 +206,13 @@ class alignas(uintptr_t) JitScript final {
void setActive() { flags_.active = true; }
void resetActive() { flags_.active = false; }
void ensureProfileString(JSContext* cx, JSScript* script);
const char* profileString() const {
MOZ_ASSERT(profileString_);
return profileString_;
}
/* Array of type sets for variables and JOF_TYPESET ops. */
StackTypeSet* typeArray(const js::AutoSweepJitScript& sweep) {
MOZ_ASSERT(sweep.jitScript() == this);

View File

@ -198,6 +198,26 @@ void JitcodeGlobalEntry::BaselineEntry::destroy() {
str_ = nullptr;
}
void* JitcodeGlobalEntry::BaselineInterpreterEntry::canonicalNativeAddrFor(
void* ptr) const {
return ptr;
}
bool JitcodeGlobalEntry::BaselineInterpreterEntry::callStackAtAddr(
void* ptr, BytecodeLocationVector& results, uint32_t* depth) const {
MOZ_CRASH("shouldn't be called for BaselineInterpreter entries");
}
uint32_t JitcodeGlobalEntry::BaselineInterpreterEntry::callStackAtAddr(
void* ptr, const char** results, uint32_t maxResults) const {
MOZ_CRASH("shouldn't be called for BaselineInterpreter entries");
}
void JitcodeGlobalEntry::BaselineInterpreterEntry::youngestFrameLocationAtAddr(
void* ptr, JSScript** script, jsbytecode** pc) const {
MOZ_CRASH("shouldn't be called for BaselineInterpreter entries");
}
static inline JitcodeGlobalEntry& RejoinEntry(
JSRuntime* rt, const JitcodeGlobalEntry::IonCacheEntry& cache, void* ptr) {
MOZ_ASSERT(cache.containsPointer(ptr));
@ -367,7 +387,7 @@ JitcodeGlobalEntry* JitcodeGlobalTable::lookupInternal(void* ptr) {
bool JitcodeGlobalTable::addEntry(const JitcodeGlobalEntry& entry) {
MOZ_ASSERT(entry.isIon() || entry.isBaseline() || entry.isIonCache() ||
entry.isDummy());
entry.isBaselineInterpreter() || entry.isDummy());
JitcodeGlobalEntry* searchTower[JitcodeSkiplistTower::MAX_HEIGHT];
searchInternal(entry, searchTower);
@ -1523,6 +1543,9 @@ JS::ProfiledFrameHandle::ProfiledFrameHandle(JSRuntime* rt,
JS_PUBLIC_API JS::ProfilingFrameIterator::FrameKind
JS::ProfiledFrameHandle::frameKind() const {
if (entry_.isBaselineInterpreter()) {
return JS::ProfilingFrameIterator::Frame_BaselineInterpreter;
}
if (entry_.isBaseline()) {
return JS::ProfilingFrameIterator::Frame_Baseline;
}

View File

@ -123,7 +123,16 @@ class JitcodeGlobalEntry {
friend class JitcodeGlobalTable;
public:
enum Kind { INVALID = 0, Ion, Baseline, IonCache, Dummy, Query, LIMIT };
enum Kind {
INVALID = 0,
Ion,
Baseline,
BaselineInterpreter,
IonCache,
Dummy,
Query,
LIMIT
};
JS_STATIC_ASSERT(LIMIT <= 8);
struct BytecodeLocation {
@ -414,6 +423,27 @@ class JitcodeGlobalEntry {
bool isMarkedFromAnyThread(JSRuntime* rt);
};
struct BaselineInterpreterEntry : public BaseEntry {
void init(JitCode* code, void* nativeStartAddr, void* nativeEndAddr) {
BaseEntry::init(BaselineInterpreter, code, nativeStartAddr,
nativeEndAddr);
}
void destroy() {}
void* canonicalNativeAddrFor(void* ptr) const;
MOZ_MUST_USE bool callStackAtAddr(void* ptr,
BytecodeLocationVector& results,
uint32_t* depth) const;
uint32_t callStackAtAddr(void* ptr, const char** results,
uint32_t maxResults) const;
void youngestFrameLocationAtAddr(void* ptr, JSScript** script,
jsbytecode** pc) const;
};
struct IonCacheEntry : public BaseEntry {
void* rejoinAddr_;
JS::TrackedOutcome trackedOutcome_;
@ -517,6 +547,9 @@ class JitcodeGlobalEntry {
// Baseline jitcode.
BaselineEntry baseline_;
// BaselineInterpreter code.
BaselineInterpreterEntry baselineInterpreter_;
// IonCache stubs.
IonCacheEntry ionCache_;
@ -540,6 +573,11 @@ class JitcodeGlobalEntry {
baseline_ = baseline;
}
explicit JitcodeGlobalEntry(const BaselineInterpreterEntry& baselineInterp)
: JitcodeGlobalEntry() {
baselineInterpreter_ = baselineInterp;
}
explicit JitcodeGlobalEntry(const IonCacheEntry& ionCache)
: JitcodeGlobalEntry() {
ionCache_ = ionCache;
@ -567,6 +605,9 @@ class JitcodeGlobalEntry {
case Baseline:
baselineEntry().destroy();
break;
case BaselineInterpreter:
baselineInterpreterEntry().destroy();
break;
case IonCache:
ionCacheEntry().destroy();
break;
@ -620,6 +661,7 @@ class JitcodeGlobalEntry {
bool isValid() const { return (kind() > INVALID) && (kind() < LIMIT); }
bool isIon() const { return kind() == Ion; }
bool isBaseline() const { return kind() == Baseline; }
bool isBaselineInterpreter() const { return kind() == BaselineInterpreter; }
bool isIonCache() const { return kind() == IonCache; }
bool isDummy() const { return kind() == Dummy; }
bool isQuery() const { return kind() == Query; }
@ -636,6 +678,10 @@ class JitcodeGlobalEntry {
MOZ_ASSERT(isBaseline());
return baseline_;
}
BaselineInterpreterEntry& baselineInterpreterEntry() {
MOZ_ASSERT(isBaselineInterpreter());
return baselineInterpreter_;
}
IonCacheEntry& ionCacheEntry() {
MOZ_ASSERT(isIonCache());
return ionCache_;
@ -661,6 +707,10 @@ class JitcodeGlobalEntry {
MOZ_ASSERT(isBaseline());
return baseline_;
}
const BaselineInterpreterEntry& baselineInterpreterEntry() const {
MOZ_ASSERT(isBaselineInterpreter());
return baselineInterpreter_;
}
const IonCacheEntry& ionCacheEntry() const {
MOZ_ASSERT(isIonCache());
return ionCache_;
@ -703,6 +753,8 @@ class JitcodeGlobalEntry {
return ionEntry().callStackAtAddr(ptr, results, depth);
case Baseline:
return baselineEntry().callStackAtAddr(ptr, results, depth);
case BaselineInterpreter:
return baselineInterpreterEntry().callStackAtAddr(ptr, results, depth);
case IonCache:
return ionCacheEntry().callStackAtAddr(rt, ptr, results, depth);
case Dummy:
@ -720,6 +772,9 @@ class JitcodeGlobalEntry {
return ionEntry().callStackAtAddr(ptr, results, maxResults);
case Baseline:
return baselineEntry().callStackAtAddr(ptr, results, maxResults);
case BaselineInterpreter:
return baselineInterpreterEntry().callStackAtAddr(ptr, results,
maxResults);
case IonCache:
return ionCacheEntry().callStackAtAddr(rt, ptr, results, maxResults);
case Dummy:
@ -855,6 +910,7 @@ class JitcodeGlobalEntry {
case IonCache:
tracedAny |= ionCacheEntry().trace<ShouldTraceProvider>(trc);
break;
case BaselineInterpreter:
case Dummy:
break;
default:
@ -874,6 +930,7 @@ class JitcodeGlobalEntry {
case IonCache:
ionCacheEntry().sweepChildren(rt);
break;
case BaselineInterpreter:
case Dummy:
break;
default:
@ -982,6 +1039,10 @@ class JitcodeGlobalTable {
MOZ_MUST_USE bool addEntry(const JitcodeGlobalEntry::BaselineEntry& entry) {
return addEntry(JitcodeGlobalEntry(entry));
}
MOZ_MUST_USE bool addEntry(
const JitcodeGlobalEntry::BaselineInterpreterEntry& entry) {
return addEntry(JitcodeGlobalEntry(entry));
}
MOZ_MUST_USE bool addEntry(const JitcodeGlobalEntry::IonCacheEntry& entry) {
return addEntry(JitcodeGlobalEntry(entry));
}

View File

@ -116,7 +116,7 @@ void GeckoProfilerRuntime::enable(bool enabled) {
* but not jitcode for scripts with active frames on the stack. These scripts
* need to have their profiler state toggled so they behave properly.
*/
jit::ToggleBaselineProfiling(rt, enabled);
jit::ToggleBaselineProfiling(cx, enabled);
// Update lastProfilingFrame to point to the top-most JS jit-frame currently
// on stack.

View File

@ -1934,10 +1934,11 @@ JS::ProfilingFrameIterator::getPhysicalFrameAndEntry(
Frame frame;
frame.kind = Frame_Wasm;
frame.stackAddress = stackAddr;
frame.returnAddress = nullptr;
frame.returnAddress_ = nullptr;
frame.activation = activation_;
frame.label = nullptr;
frame.endStackAddress = activation_->asJit()->jsOrWasmExitFP();
frame.interpreterScript = nullptr;
return mozilla::Some(frame);
}
@ -1955,7 +1956,7 @@ JS::ProfilingFrameIterator::getPhysicalFrameAndEntry(
}
MOZ_ASSERT(entry->isIon() || entry->isIonCache() || entry->isBaseline() ||
entry->isDummy());
entry->isBaselineInterpreter() || entry->isDummy());
// Dummy frames produce no stack frames.
if (entry->isDummy()) {
@ -1963,11 +1964,26 @@ JS::ProfilingFrameIterator::getPhysicalFrameAndEntry(
}
Frame frame;
frame.kind = entry->isBaseline() ? Frame_Baseline : Frame_Ion;
if (entry->isBaselineInterpreter()) {
frame.kind = Frame_BaselineInterpreter;
} else if (entry->isBaseline()) {
frame.kind = Frame_Baseline;
} else {
frame.kind = Frame_Ion;
}
frame.stackAddress = stackAddr;
frame.returnAddress = returnAddr;
if (entry->isBaselineInterpreter()) {
frame.label = jsJitIter().baselineInterpreterLabel();
jsJitIter().baselineInterpreterScriptPC(&frame.interpreterScript,
&frame.interpreterPC_);
MOZ_ASSERT(frame.interpreterScript);
MOZ_ASSERT(frame.interpreterPC_);
} else {
frame.interpreterScript = nullptr;
frame.returnAddress_ = returnAddr;
frame.label = nullptr;
}
frame.activation = activation_;
frame.label = nullptr;
frame.endStackAddress = activation_->asJit()->jsOrWasmExitFP();
return mozilla::Some(frame);
}
@ -1993,6 +2009,11 @@ uint32_t JS::ProfilingFrameIterator::extractStack(Frame* frames,
return 1;
}
if (physicalFrame->kind == Frame_BaselineInterpreter) {
frames[offset] = physicalFrame.value();
return 1;
}
// Extract the stack for the entry. Assume maximum inlining depth is <64
const char* labels[64];
uint32_t depth = entry.callStackAtAddr(cx_->runtime(),

View File

@ -3160,6 +3160,9 @@ pref("dom.largeAllocationHeader.enabled", true);
// Disable e10s for Gecko by default. This is overridden in firefox.js.
pref("browser.tabs.remote.autostart", false);
// Disable fission for Gecko by default.
pref("fission.autostart", false);
// Pref to control whether we use separate content processes for top-level load
// of file:// URIs.
pref("browser.tabs.remote.separateFileUriProcess", true);

View File

@ -1,3 +1,3 @@
[form-control.html]
expected:
if os == "android": FAIL
if os == "android": FAIL # Bug 1550895

View File

@ -1,3 +1,3 @@
[contain-layout-baseline-005.html]
expected:
if os == "android": "FAIL"
if (os == "android"): FAIL # bug 1550895 (frequently fails on geckoview), bug 1554342

View File

@ -1,3 +1,3 @@
[contain-layout-button-001.html]
expected:
if os == "android": "FAIL"
if (os == "android"): FAIL # bug 1550895 (frequently fails on geckoview), bug 1556282

View File

@ -1,2 +1,4 @@
[navigation.https.sub.html]
disabled:
if (os == "android"): bug 1550895 (frequently fails on geckoview)
expected: ERROR

View File

@ -1,2 +1,4 @@
[null.tentative.html]
disabled:
if (os == "android"): bug 1550895 (frequently fails on geckoview)
prefs: [browser.tabs.remote.useCrossOriginPolicy:true]

View File

@ -1302,10 +1302,19 @@ static void MergeStacks(uint32_t aFeatures, bool aIsSynchronous,
if (aIsSynchronous ||
jsFrame.kind == JS::ProfilingFrameIterator::Frame_Wasm) {
aCollector.CollectWasmFrame(jsFrame.label);
} else if (jsFrame.kind ==
JS::ProfilingFrameIterator::Frame_BaselineInterpreter) {
// For now treat this as a C++ Interpreter frame by materializing a
// ProfilingStackFrame.
JSScript* script = jsFrame.interpreterScript;
jsbytecode* pc = jsFrame.interpreterPC();
js::ProfilingStackFrame stackFrame;
stackFrame.initJsFrame("", jsFrame.label, script, pc);
aCollector.CollectProfilingStackFrame(stackFrame);
} else {
MOZ_ASSERT(jsFrame.kind == JS::ProfilingFrameIterator::Frame_Ion ||
jsFrame.kind == JS::ProfilingFrameIterator::Frame_Baseline);
aCollector.CollectJitReturnAddr(jsFrame.returnAddress);
aCollector.CollectJitReturnAddr(jsFrame.returnAddress());
}
jsIndex--;