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

This commit is contained in:
Narcis Beleuzu 2018-09-19 13:03:12 +03:00
Родитель d48833fbbc 94e37e71ff
Коммит 756c9d5a26
58 изменённых файлов: 762 добавлений и 677 удалений

Просмотреть файл

@ -10,7 +10,6 @@
#include "Accessible-inl.h"
#include "AccIterator.h"
#include "nsCoreUtils.h"
#include "nsIDOMXULLabeledControlEl.h"
#include "mozilla/dom/Text.h"
using namespace mozilla;
@ -307,20 +306,17 @@ nsTextEquivUtils::AppendFromDOMNode(nsIContent *aContent, nsAString *aString)
if (aContent->IsXULElement()) {
nsAutoString textEquivalent;
nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl =
do_QueryInterface(aContent);
if (labeledEl) {
labeledEl->GetLabel(textEquivalent);
if (aContent->NodeInfo()->Equals(nsGkAtoms::label, kNameSpaceID_XUL)) {
aContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value,
textEquivalent);
} else {
if (aContent->NodeInfo()->Equals(nsGkAtoms::label,
kNameSpaceID_XUL))
aContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::value,
textEquivalent);
aContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::label,
textEquivalent);
}
if (textEquivalent.IsEmpty())
aContent->AsElement()->GetAttr(kNameSpaceID_None,
nsGkAtoms::tooltiptext, textEquivalent);
if (textEquivalent.IsEmpty()) {
aContent->AsElement()->GetAttr(kNameSpaceID_None,
nsGkAtoms::tooltiptext, textEquivalent);
}
AppendString(aString, textEquivalent);

Просмотреть файл

@ -804,20 +804,15 @@ Accessible::XULElmName(DocAccessible* aDocument,
*/
// CASE #1 (via label attribute) -- great majority of the cases
nsCOMPtr<nsIDOMXULLabeledControlElement> labeledEl = do_QueryInterface(aElm);
if (labeledEl) {
labeledEl->GetLabel(aName);
nsCOMPtr<nsIDOMXULSelectControlItemElement> itemEl = do_QueryInterface(aElm);
if (itemEl) {
itemEl->GetLabel(aName);
} else {
nsCOMPtr<nsIDOMXULSelectControlItemElement> itemEl = do_QueryInterface(aElm);
if (itemEl) {
itemEl->GetLabel(aName);
} else {
nsCOMPtr<nsIDOMXULSelectControlElement> select = do_QueryInterface(aElm);
// Use label if this is not a select control element which
// uses label attribute to indicate which option is selected
if (!select && aElm->IsElement()) {
aElm->AsElement()->GetAttribute(NS_LITERAL_STRING("label"), aName);
}
// Use @label if this is not a select control element, which uses label
// attribute to indicate, which option is selected.
nsCOMPtr<nsIDOMXULSelectControlElement> select = do_QueryInterface(aElm);
if (!select) {
aElm->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::label, aName);
}
}

Просмотреть файл

@ -72,10 +72,10 @@
//////////////////////////////////////////////////////////////////////////
// Name for nsIDOMXULLabeledControlElement.
// Name from @label attribute.
// Gets the name from @label attribute.
testName("btn_nsIDOMXULLabeledControlElement", "labeled element");
testName("btn_labelattr", "labeled element");
//////////////////////////////////////////////////////////////////////////
@ -271,8 +271,8 @@
<button id="btn_labelledby_mixed_menulist"
aria-labelledby="labelledby_mixed_menulist"/>
<!-- nsIDOMXULLabeledControlElement -->
<button id="btn_nsIDOMXULLabeledControlElement"
<!-- @label -->
<button id="btn_labelattr"
label="labeled element"/>
<!-- nsIDOMXULSelectControlItemElement -->

Просмотреть файл

@ -5295,7 +5295,8 @@ AssertContentPrivilegedAboutPageHasCSP(nsIURI* aDocumentURI, nsIPrincipal* aPrin
// Potentially init the legacy whitelist of about URIs without a CSP.
static StaticAutoPtr<nsTArray<nsCString>> sLegacyAboutPagesWithNoCSP;
if (!sLegacyAboutPagesWithNoCSP) {
if (!sLegacyAboutPagesWithNoCSP ||
Preferences::GetBool("csp.overrule_content_privileged_about_uris_without_csp_whitelist")) {
sLegacyAboutPagesWithNoCSP = new nsTArray<nsCString>();
nsAutoCString legacyAboutPages;
Preferences::GetCString("csp.content_privileged_about_uris_without_csp",
@ -5334,6 +5335,10 @@ AssertContentPrivilegedAboutPageHasCSP(nsIURI* aDocumentURI, nsIPrincipal* aPrin
csp->GetPolicyString(0, parsedPolicyStr);
}
}
if (Preferences::GetBool("csp.overrule_content_privileged_about_uris_without_csp_whitelist")) {
NS_ASSERTION(parsedPolicyStr.Find("default-src") >= 0, "about: page must have a CSP");
return;
}
MOZ_ASSERT(parsedPolicyStr.Find("default-src") >= 0,
"about: page must contain a CSP including default-src");
}

Просмотреть файл

@ -12,7 +12,6 @@ XPIDL_SOURCES += [
'nsIDOMXULCommandDispatcher.idl',
'nsIDOMXULContainerElement.idl',
'nsIDOMXULControlElement.idl',
'nsIDOMXULLabeledControlEl.idl',
'nsIDOMXULMenuListElement.idl',
'nsIDOMXULMultSelectCntrlEl.idl',
'nsIDOMXULRelatedElement.idl',

Просмотреть файл

@ -3,10 +3,10 @@
* 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 "nsIDOMXULLabeledControlEl.idl"
#include "nsIDOMXULControlElement.idl"
[scriptable, uuid(6ed53cfb-9e59-424c-af8d-e74582381951)]
interface nsIDOMXULButtonElement : nsIDOMXULLabeledControlElement {
interface nsIDOMXULButtonElement : nsIDOMXULControlElement {
attribute DOMString type;
attribute DOMString dlgType;
@ -19,4 +19,3 @@ interface nsIDOMXULButtonElement : nsIDOMXULLabeledControlElement {
// For buttons of type="radio" only.
attribute DOMString group;
};

Просмотреть файл

@ -1,18 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 "nsIDOMXULControlElement.idl"
[scriptable, uuid(c58a159f-e27d-40c8-865a-d4dcfd928f62)]
interface nsIDOMXULLabeledControlElement : nsIDOMXULControlElement {
attribute DOMString crop;
attribute DOMString image;
attribute DOMString label;
attribute DOMString accessKey;
attribute DOMString command;
// void doCommand();
};

Просмотреть файл

@ -42,3 +42,5 @@ skip-if = toolkit == 'android'
[test_same_site_cookies_toplevel_set_cookie.html]
[test_same_site_cookies_iframe.html]
[test_same_site_cookies_about.html]
[test_assert_about_page_no_csp.html]
skip-if = !debug || toolkit == 'android'

Просмотреть файл

@ -0,0 +1,41 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 1490977: Test Assertion if content privileged about: page has no CSP</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<iframe id="testframe"></iframe>
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
SimpleTest.expectAssertions(0, 1);
// Test Setup:
// The test overrules the whitelist of about: pages that are allowed to load without a CSP
// and makes sure to hit the assertion within AssertContentPrivilegedAboutPageHasCSP().
// However, due to the caching mechanism within AssertContentPrivilegedAboutPageHasCSP this
// test loads a second dummy data: URI to reset the old cache and finally resets the pref
// used for testing purposes.
let origWhiteList = SpecialPowers.getCharPref("csp.content_privileged_about_uris_without_csp");
SpecialPowers.setCharPref("csp.content_privileged_about_uris_without_csp", "");
SpecialPowers.setBoolPref("csp.overrule_content_privileged_about_uris_without_csp_whitelist", true);
ok(true, "sanity: prefs flipped and test runs");
let myFrame = document.getElementById("testframe");
myFrame.src = "about:blank";
// booom :-)
SpecialPowers.setCharPref("csp.content_privileged_about_uris_without_csp", origWhiteList);
myFrame.src = "data:text/html,<body>just a dumy data: URI</body>";
SpecialPowers.setBoolPref("csp.overrule_content_privileged_about_uris_without_csp_whitelist", false);
SimpleTest.finish();
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -66,8 +66,8 @@ pub enum SourceTexture {
RenderTaskCache(SavedTargetIndex),
}
pub const ORTHO_NEAR_PLANE: f32 = -1000000.0;
pub const ORTHO_FAR_PLANE: f32 = 1000000.0;
pub const ORTHO_NEAR_PLANE: f32 = -100000.0;
pub const ORTHO_FAR_PLANE: f32 = 100000.0;
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "capture", derive(Serialize))]

Просмотреть файл

@ -1 +1 @@
6fa046c936b9d720726d27c3b0514ee66a305b69
5b5b4145ecef117acb02fd1f9b72bf02e85c650b

Просмотреть файл

@ -118,6 +118,9 @@ IsValidAllocKind(AllocKind kind)
return kind >= AllocKind::FIRST && kind <= AllocKind::LAST;
}
const char*
AllocKindName(AllocKind kind);
inline bool
IsObjectAllocKind(AllocKind kind)
{

Просмотреть файл

@ -1268,8 +1268,8 @@ GCRuntime::parseAndSetZeal(const char* str)
return true;
}
static const char*
AllocKindName(AllocKind kind)
const char*
js::gc::AllocKindName(AllocKind kind)
{
static const char* const names[] = {
#define EXPAND_THING_NAME(allocKind, _1, _2, _3, _4, _5, _6) \

Просмотреть файл

@ -32,6 +32,6 @@ assertEq(s.format, "wasm");
var source2 = s.source;
// The text is predefined if wasm binary sources are enabled.
assertEq(source2.text, '[wasm]');
assertEq(source2.text, '[debugger missing wasm binary-to-text conversion]');
// The binary contains Uint8Array which is equal to wasm bytecode;
arraysEqual(source2.binary, wasmTextToBinary('(module (func) (export "" 0))'));

Просмотреть файл

@ -66,9 +66,9 @@ assertEq(gotScript.source.sourceMapURL, 'http://example.org/test');
// The sourceMapURL is read-only for wasm
assertThrowsInstanceOf(() => gotScript.source.sourceMapURL = 'foo', Error);
// The sourceMappingURL section is present, but is not available when wasm
// The sourceMappingURL section is present, and is still available when wasm
// binary source is disabled.
dbg.allowWasmBinarySource = false;
g.eval(`o = new WebAssembly.Instance(new WebAssembly.Module(toWasm('(module (func) (export "a" 0))', 'http://example.org/test2')));`);
assertEq(gotScript.format, "wasm");
assertEq(gotScript.source.sourceMapURL, null);
assertEq(gotScript.source.sourceMapURL, 'http://example.org/test2');

Просмотреть файл

@ -7007,7 +7007,7 @@ JS_PUBLIC_API(RefPtr<JS::WasmModule>)
JS::GetWasmModule(HandleObject obj)
{
MOZ_ASSERT(JS::IsWasmModuleObject(obj));
return &CheckedUnwrap(obj)->as<WasmModuleObject>().module();
return const_cast<wasm::Module*>(&CheckedUnwrap(obj)->as<WasmModuleObject>().module());
}
JS_PUBLIC_API(RefPtr<JS::WasmModule>)

Просмотреть файл

@ -6579,7 +6579,7 @@ struct SharedObjectMailbox
SharedArrayRawBuffer* buffer;
uint32_t length;
} sarb;
wasm::Module* module;
const wasm::Module* module;
};
SharedObjectMailbox() : tag(MailboxTag::Empty) {}

Просмотреть файл

@ -2785,7 +2785,7 @@ UpdateExecutionObservabilityOfScriptsInZone(JSContext* cx, Zone* zone,
}
bool enableTrap = observing == Debugger::IsObserving::Observing;
instance->ensureEnterFrameTrapsState(cx, enableTrap);
instance->debug().ensureEnterFrameTrapsState(cx, enableTrap);
}
}
@ -5931,12 +5931,13 @@ struct DebuggerScriptGetLineCountMatcher
}
return match(script);
}
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
uint32_t result;
if (!wasmInstance->instance().debug().totalSourceLines(cx_, &result)) {
return false;
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
if (instance.debugEnabled()) {
totalLines = double(instance.debug().totalSourceLines());
} else {
totalLines = 0;
}
totalLines = double(result);
return true;
}
};
@ -6390,15 +6391,16 @@ class DebuggerScriptGetOffsetLocationMatcher
}
return match(script);
}
ReturnType match(Handle<WasmInstanceObject*> instance) {
size_t lineno;
size_t column;
bool found;
if (!instance->instance().debug().getOffsetLocation(cx_, offset_, &found, &lineno, &column)) {
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
if (!instance.debugEnabled()) {
JS_ReportErrorNumberASCII(cx_, GetErrorMessage, nullptr, JSMSG_DEBUG_BAD_OFFSET);
return false;
}
if (!found) {
size_t lineno;
size_t column;
if (!instance.debug().getOffsetLocation(offset_, &lineno, &column)) {
JS_ReportErrorNumberASCII(cx_, GetErrorMessage, nullptr, JSMSG_DEBUG_BAD_OFFSET);
return false;
}
@ -6696,9 +6698,11 @@ class DebuggerScriptGetAllColumnOffsetsMatcher
}
return match(script);
}
ReturnType match(Handle<WasmInstanceObject*> instance) {
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
Vector<wasm::ExprLoc> offsets(cx_);
if (!instance->instance().debug().getAllColumnOffsets(cx_, &offsets)) {
if (instance.debugEnabled() && !instance.debug().getAllColumnOffsets(cx_, &offsets)) {
return false;
}
@ -6785,9 +6789,11 @@ class DebuggerScriptGetLineOffsetsMatcher
}
return match(script);
}
ReturnType match(Handle<WasmInstanceObject*> instance) {
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
Vector<uint32_t> offsets(cx_);
if (!instance->instance().debug().getLineOffsets(cx_, lineno_, &offsets)) {
if (instance.debugEnabled() && !instance.debug().getLineOffsets(cx_, lineno_, &offsets)) {
return false;
}
@ -7108,7 +7114,7 @@ struct DebuggerScriptSetBreakpointMatcher
}
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
wasm::Instance& instance = wasmInstance->instance();
if (!instance.debug().hasBreakpointTrapAtOffset(offset_)) {
if (!instance.debugEnabled() || !instance.debug().hasBreakpointTrapAtOffset(offset_)) {
JS_ReportErrorNumberASCII(cx_, GetErrorMessage, nullptr, JSMSG_DEBUG_BAD_OFFSET);
return false;
}
@ -7216,8 +7222,12 @@ class DebuggerScriptClearBreakpointMatcher
}
return match(script);
}
ReturnType match(Handle<WasmInstanceObject*> instance) {
return instance->instance().debug().clearBreakpointsIn(cx_, instance, dbg_, handler_);
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
if (!instance.debugEnabled()) {
return true;
}
return instance.debug().clearBreakpointsIn(cx_, instanceObj, dbg_, handler_);
}
};
@ -7653,13 +7663,15 @@ class DebuggerSourceGetTextMatcher
return ss->substring(cx_, 0, ss->length());
}
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
if (wasmInstance->instance().debug().maybeBytecode() &&
wasmInstance->instance().debug().binarySource())
{
return NewStringCopyZ<CanGC>(cx_, "[wasm]");
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
const char* msg;
if (!instance.debugEnabled()) {
msg = "Restart with developer tools open to view WebAssembly source.";
} else {
msg = "[debugger missing wasm binary-to-text conversion]";
}
return wasmInstance->instance().debug().createText(cx_);
return NewStringCopyZ<CanGC>(cx_, msg);
}
};
@ -7696,22 +7708,22 @@ DebuggerSource_getBinary(JSContext* cx, unsigned argc, Value* vp)
return false;
}
RootedWasmInstanceObject wasmInstance(cx, referent.as<WasmInstanceObject*>());
if (!wasmInstance->instance().debug().binarySource()) {
RootedWasmInstanceObject instanceObj(cx, referent.as<WasmInstanceObject*>());
wasm::Instance& instance = instanceObj->instance();
if (!instance.debugEnabled() || !instance.debug().binarySource()) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_DEBUG_NO_BINARY_SOURCE);
return false;
}
auto bytecode = wasmInstance->instance().debug().maybeBytecode();
size_t arrLength = bytecode ? bytecode->length() : 0;
RootedObject arr(cx, JS_NewUint8Array(cx, arrLength));
const wasm::Bytes& bytecode = instance.debug().bytecode();
RootedObject arr(cx, JS_NewUint8Array(cx, bytecode.length()));
if (!arr) {
return false;
}
if (bytecode) {
memcpy(arr->as<TypedArrayObject>().viewDataUnshared(), bytecode->begin(), arrLength);
}
memcpy(arr->as<TypedArrayObject>().viewDataUnshared(), bytecode.begin(), bytecode.length());
args.rval().setObject(*arr);
return true;
@ -7735,18 +7747,8 @@ class DebuggerSourceGetURLMatcher
}
return Nothing();
}
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
if (wasmInstance->instance().metadata().filenameIsURL) {
JSString* str = NewStringCopyZ<CanGC>(cx_, wasmInstance->instance().metadata().filename.get());
if (!str) {
return Nothing();
}
return Some(str);
}
if (JSString* str = wasmInstance->instance().debug().debugDisplayURL(cx_)) {
return Some(str);
}
return Nothing();
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
return Some(instanceObj->instance().createDisplayURL(cx_));
}
};
@ -8009,17 +8011,18 @@ class DebuggerSourceGetSourceMapURLMatcher
result_.set(str);
return true;
}
ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
// sourceMapURL is not available if debugger was not in
// allowWasmBinarySource mode.
if (!wasmInstance->instance().debug().binarySource()) {
ReturnType match(Handle<WasmInstanceObject*> instanceObj) {
wasm::Instance& instance = instanceObj->instance();
if (!instance.debugEnabled()) {
result_.set(nullptr);
return true;
}
RootedString str(cx_);
if (!wasmInstance->instance().debug().getSourceMappingURL(cx_, &str)) {
if (!instance.debug().getSourceMappingURL(cx_, &str)) {
return false;
}
result_.set(str);
return true;
}

Просмотреть файл

@ -468,7 +468,7 @@ StatsCellCallback(JSRuntime* rt, void* data, void* thing, JS::TraceKind traceKin
// These classes require special handling due to shared resources which
// we must be careful not to report twice.
if (obj->is<WasmModuleObject>()) {
wasm::Module& module = obj->as<WasmModuleObject>().module();
const wasm::Module& module = obj->as<WasmModuleObject>().module();
if (ScriptSource* ss = module.metadata().maybeScriptSource()) {
CollectScriptSourceStats<granularity>(closure, ss);
}

Просмотреть файл

@ -484,7 +484,7 @@ class ObjectGroupRealm::NewTable : public JS::WeakCache<js::GCHashSet<NewEntry,
};
/* static*/ ObjectGroupRealm&
ObjectGroupRealm::get(ObjectGroup* group)
ObjectGroupRealm::get(const ObjectGroup* group)
{
return group->realm()->objectGroups_;
}
@ -1696,7 +1696,7 @@ ObjectGroup::getCopyOnWriteObject(JSScript* script, jsbytecode* pc)
}
/* static */ bool
ObjectGroup::findAllocationSite(JSContext* cx, ObjectGroup* group,
ObjectGroup::findAllocationSite(JSContext* cx, const ObjectGroup* group,
JSScript** script, uint32_t* offset)
{
*script = nullptr;

Просмотреть файл

@ -588,7 +588,7 @@ class ObjectGroup : public gc::TenuredCell
static ArrayObject* getCopyOnWriteObject(JSScript* script, jsbytecode* pc);
// Returns false if not found.
static bool findAllocationSite(JSContext* cx, ObjectGroup* group,
static bool findAllocationSite(JSContext* cx, const ObjectGroup* group,
JSScript** script, uint32_t* offset);
private:
@ -693,7 +693,7 @@ class ObjectGroupRealm
ObjectGroupRealm(ObjectGroupRealm&) = delete;
void operator=(ObjectGroupRealm&) = delete;
static ObjectGroupRealm& get(ObjectGroup* group);
static ObjectGroupRealm& get(const ObjectGroup* group);
static ObjectGroupRealm& getForNewObject(JSContext* cx);
void replaceAllocationSiteGroup(JSScript* script, jsbytecode* pc,

Просмотреть файл

@ -320,7 +320,7 @@ class JS::Realm : public JS::shadow::Realm
// Object group tables and other state in the realm. This is private to
// enforce use of ObjectGroupRealm::get(group)/getForNewObject(cx).
js::ObjectGroupRealm objectGroups_;
friend js::ObjectGroupRealm& js::ObjectGroupRealm::get(js::ObjectGroup* group);
friend js::ObjectGroupRealm& js::ObjectGroupRealm::get(const js::ObjectGroup* group);
friend js::ObjectGroupRealm& js::ObjectGroupRealm::getForNewObject(JSContext* cx);
// The global environment record's [[VarNames]] list that contains all

Просмотреть файл

@ -139,7 +139,7 @@ TypeSet::ObjectKey::maybeCompartment()
}
/* static */ inline TypeSet::Type
TypeSet::ObjectType(JSObject* obj)
TypeSet::ObjectType(const JSObject* obj)
{
if (obj->isSingleton()) {
return Type(uintptr_t(obj) | 1);
@ -148,7 +148,7 @@ TypeSet::ObjectType(JSObject* obj)
}
/* static */ inline TypeSet::Type
TypeSet::ObjectType(ObjectGroup* group)
TypeSet::ObjectType(const ObjectGroup* group)
{
if (group->singleton()) {
return Type(uintptr_t(group->singleton()) | 1);
@ -157,7 +157,7 @@ TypeSet::ObjectType(ObjectGroup* group)
}
/* static */ inline TypeSet::Type
TypeSet::ObjectType(ObjectKey* obj)
TypeSet::ObjectType(const ObjectKey* obj)
{
return Type(uintptr_t(obj));
}

Просмотреть файл

@ -145,7 +145,7 @@ static UniqueChars MakeStringCopy(const char* s)
}
/* static */ UniqueChars
TypeSet::TypeString(TypeSet::Type type)
TypeSet::TypeString(const TypeSet::Type type)
{
if (type.isPrimitive() || type.isUnknown() || type.isAnyObject()) {
return MakeStringCopy(NonObjectTypeString(type));
@ -163,7 +163,7 @@ TypeSet::TypeString(TypeSet::Type type)
}
/* static */ UniqueChars
TypeSet::ObjectGroupString(ObjectGroup* group)
TypeSet::ObjectGroupString(const ObjectGroup* group)
{
return TypeString(TypeSet::ObjectType(group));
}

Просмотреть файл

@ -435,14 +435,14 @@ class TypeSet
return Type(type);
}
static inline Type ObjectType(JSObject* obj);
static inline Type ObjectType(ObjectGroup* group);
static inline Type ObjectType(ObjectKey* key);
static inline Type ObjectType(const JSObject* obj);
static inline Type ObjectType(const ObjectGroup* group);
static inline Type ObjectType(const ObjectKey* key);
static const char* NonObjectTypeString(Type type);
static JS::UniqueChars TypeString(Type type);
static JS::UniqueChars ObjectGroupString(ObjectGroup* group);
static JS::UniqueChars TypeString(const Type type);
static JS::UniqueChars ObjectGroupString(const ObjectGroup* group);
public:
void print(FILE* fp = stderr);

Просмотреть файл

@ -367,9 +367,7 @@ struct js::AsmJSMetadata : Metadata, AsmJSMetadataCacheablePod
ScriptSource* maybeScriptSource() const override {
return scriptSource.get();
}
bool getFuncName(NameContext ctx, const Bytes* maybeBytecode, uint32_t funcIndex,
UTF8Bytes* name) const override
{
bool getFuncName(NameContext ctx, uint32_t funcIndex, UTF8Bytes* name) const override {
const char* p = asmJSFuncNames[funcIndex].get();
if (!p) {
return true;
@ -2404,7 +2402,7 @@ IsLiteralInt(ModuleValidator& m, ParseNode* pn, uint32_t* u32)
namespace {
typedef Vector<PropertyName*, 4, SystemAllocPolicy> NameVector;
typedef Vector<PropertyName*, 4, SystemAllocPolicy> LabelVector;
// Encapsulates the building of an asm bytecode function from an asm.js function
// source code, packing the asm.js code into the asm bytecode form that can
@ -2534,7 +2532,7 @@ class MOZ_STACK_CLASS FunctionValidator
return encoder().writeOp(Op::End);
}
bool pushUnbreakableBlock(const NameVector* labels = nullptr) {
bool pushUnbreakableBlock(const LabelVector* labels = nullptr) {
if (labels) {
for (PropertyName* label : *labels) {
if (!breakLabels_.putNew(label, blockDepth_)) {
@ -2546,7 +2544,7 @@ class MOZ_STACK_CLASS FunctionValidator
return encoder().writeOp(Op::Block) &&
encoder().writeFixedU8(uint8_t(ExprType::Void));
}
bool popUnbreakableBlock(const NameVector* labels = nullptr) {
bool popUnbreakableBlock(const LabelVector* labels = nullptr) {
if (labels) {
for (PropertyName* label : *labels) {
removeLabel(label, &breakLabels_);
@ -2622,7 +2620,7 @@ class MOZ_STACK_CLASS FunctionValidator
return writeBr(continuableStack_.back());
}
bool addLabels(const NameVector& labels, uint32_t relativeBreakDepth,
bool addLabels(const LabelVector& labels, uint32_t relativeBreakDepth,
uint32_t relativeContinueDepth)
{
for (PropertyName* label : labels) {
@ -2635,7 +2633,7 @@ class MOZ_STACK_CLASS FunctionValidator
}
return true;
}
void removeLabels(const NameVector& labels) {
void removeLabels(const LabelVector& labels) {
for (PropertyName* label : labels) {
removeLabel(label, &breakLabels_);
removeLabel(label, &continueLabels_);
@ -5171,7 +5169,7 @@ CheckLoopConditionOnEntry(FunctionValidator& f, ParseNode* cond)
}
static bool
CheckWhile(FunctionValidator& f, ParseNode* whileStmt, const NameVector* labels = nullptr)
CheckWhile(FunctionValidator& f, ParseNode* whileStmt, const LabelVector* labels = nullptr)
{
MOZ_ASSERT(whileStmt->isKind(ParseNodeKind::While));
ParseNode* cond = BinaryLeft(whileStmt);
@ -5213,7 +5211,7 @@ CheckWhile(FunctionValidator& f, ParseNode* whileStmt, const NameVector* labels
}
static bool
CheckFor(FunctionValidator& f, ParseNode* forStmt, const NameVector* labels = nullptr)
CheckFor(FunctionValidator& f, ParseNode* forStmt, const LabelVector* labels = nullptr)
{
MOZ_ASSERT(forStmt->isKind(ParseNodeKind::For));
ParseNode* forHead = BinaryLeft(forStmt);
@ -5299,7 +5297,7 @@ CheckFor(FunctionValidator& f, ParseNode* forStmt, const NameVector* labels = nu
}
static bool
CheckDoWhile(FunctionValidator& f, ParseNode* whileStmt, const NameVector* labels = nullptr)
CheckDoWhile(FunctionValidator& f, ParseNode* whileStmt, const LabelVector* labels = nullptr)
{
MOZ_ASSERT(whileStmt->isKind(ParseNodeKind::DoWhile));
ParseNode* body = BinaryLeft(whileStmt);
@ -5356,14 +5354,14 @@ CheckDoWhile(FunctionValidator& f, ParseNode* whileStmt, const NameVector* label
return true;
}
static bool CheckStatementList(FunctionValidator& f, ParseNode*, const NameVector* = nullptr);
static bool CheckStatementList(FunctionValidator& f, ParseNode*, const LabelVector* = nullptr);
static bool
CheckLabel(FunctionValidator& f, ParseNode* labeledStmt)
{
MOZ_ASSERT(labeledStmt->isKind(ParseNodeKind::Label));
NameVector labels;
LabelVector labels;
ParseNode* innermost = labeledStmt;
do {
if (!labels.append(LabeledStatementLabel(innermost))) {
@ -5751,7 +5749,7 @@ CheckReturn(FunctionValidator& f, ParseNode* returnStmt)
}
static bool
CheckStatementList(FunctionValidator& f, ParseNode* stmtList, const NameVector* labels /*= nullptr */)
CheckStatementList(FunctionValidator& f, ParseNode* stmtList, const LabelVector* labels /*= nullptr */)
{
MOZ_ASSERT(stmtList->isKind(ParseNodeKind::StatementList));
@ -6630,7 +6628,7 @@ GetImports(JSContext* cx, const AsmJSMetadata& metadata, HandleValue globalVal,
}
static bool
TryInstantiate(JSContext* cx, CallArgs args, Module& module, const AsmJSMetadata& metadata,
TryInstantiate(JSContext* cx, CallArgs args, const Module& module, const AsmJSMetadata& metadata,
MutableHandleWasmInstanceObject instanceObj, MutableHandleObject exportObj)
{
HandleValue globalVal = args.get(0);
@ -6734,7 +6732,7 @@ HandleInstantiationFailure(JSContext* cx, CallArgs args, const AsmJSMetadata& me
return InternalCallOrConstruct(cx, args, args.isConstructing() ? CONSTRUCT : NO_CONSTRUCT);
}
static Module&
static const Module&
AsmJSModuleFunctionToModule(JSFunction* fun)
{
MOZ_ASSERT(IsAsmJSModule(fun));
@ -6749,7 +6747,7 @@ js::InstantiateAsmJS(JSContext* cx, unsigned argc, JS::Value* vp)
CallArgs args = CallArgsFromVp(argc, vp);
JSFunction* callee = &args.callee().as<JSFunction>();
Module& module = AsmJSModuleFunctionToModule(callee);
const Module& module = AsmJSModuleFunctionToModule(callee);
const AsmJSMetadata& metadata = module.metadata().asAsmJS();
RootedWasmInstanceObject instanceObj(cx);
@ -7151,15 +7149,14 @@ struct ScopedCacheEntryOpenedForRead
} // unnamed namespace
static JS::AsmJSCacheResult
StoreAsmJSModuleInCache(AsmJSParser& parser, Module& module, const LinkData& linkData, JSContext* cx)
StoreAsmJSModuleInCache(AsmJSParser& parser, const Module& module, const LinkData& linkData,
JSContext* cx)
{
ModuleCharsForStore moduleChars;
if (!moduleChars.init(parser)) {
return JS::AsmJSCache_InternalError;
}
MOZ_RELEASE_ASSERT(module.bytecode().length() == 0);
size_t moduleSize = module.serializedSize(linkData);
MOZ_RELEASE_ASSERT(moduleSize <= UINT32_MAX);

Просмотреть файл

@ -89,7 +89,7 @@ WasmHandleDebugTrap()
DebugFrame* debugFrame = DebugFrame::from(fp);
if (site->kind() == CallSite::EnterFrame) {
if (!instance->enterFrameTrapsEnabled()) {
if (!instance->debug().enterFrameTrapsEnabled()) {
return true;
}
debugFrame->setIsDebuggee();

Просмотреть файл

@ -281,7 +281,7 @@ AppendToString(const char* str, UTF8Bytes* bytes)
#endif
static void
SendCodeRangesToProfiler(const ModuleSegment& ms, const Bytes& bytecode, const Metadata& metadata,
SendCodeRangesToProfiler(const ModuleSegment& ms, const Metadata& metadata,
const CodeRangeVector& codeRanges)
{
bool enabled = false;
@ -304,7 +304,7 @@ SendCodeRangesToProfiler(const ModuleSegment& ms, const Bytes& bytecode, const M
uintptr_t size = codeRange.end() - codeRange.begin();
UTF8Bytes name;
if (!metadata.getFuncNameStandalone(&bytecode, codeRange.funcIndex(), &name)) {
if (!metadata.getFuncNameStandalone(codeRange.funcIndex(), &name)) {
return;
}
@ -404,7 +404,6 @@ ModuleSegment::create(Tier tier, const Bytes& unlinkedBytes, const LinkData& lin
bool
ModuleSegment::initialize(const CodeTier& codeTier,
const ShareableBytes& bytecode,
const LinkData& linkData,
const Metadata& metadata,
const MetadataTier& metadataTier)
@ -420,7 +419,7 @@ ModuleSegment::initialize(const CodeTier& codeTier,
return false;
}
SendCodeRangesToProfiler(*this, bytecode.bytes, metadata, metadataTier.codeRanges);
SendCodeRangesToProfiler(*this, metadata, metadataTier.codeRanges);
// See comments in CodeSegment::initialize() for why this must be last.
return CodeSegment::initialize(codeTier);
@ -976,24 +975,12 @@ Metadata::serializedSize() const
SerializedVectorSize(funcTypeIds) +
SerializedPodVectorSize(globals) +
SerializedPodVectorSize(tables) +
sizeof(moduleName) +
SerializedPodVectorSize(funcNames) +
SerializedPodVectorSize(customSections) +
filename.serializedSize() +
sourceMapURL.serializedSize();
}
size_t
Metadata::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
{
return SizeOfVectorExcludingThis(funcTypeIds, mallocSizeOf) +
globals.sizeOfExcludingThis(mallocSizeOf) +
tables.sizeOfExcludingThis(mallocSizeOf) +
funcNames.sizeOfExcludingThis(mallocSizeOf) +
customSections.sizeOfExcludingThis(mallocSizeOf) +
filename.sizeOfExcludingThis(mallocSizeOf) +
sourceMapURL.sizeOfExcludingThis(mallocSizeOf);
}
uint8_t*
Metadata::serialize(uint8_t* cursor) const
{
@ -1002,8 +989,8 @@ Metadata::serialize(uint8_t* cursor) const
cursor = SerializeVector(cursor, funcTypeIds);
cursor = SerializePodVector(cursor, globals);
cursor = SerializePodVector(cursor, tables);
cursor = WriteBytes(cursor, &moduleName, sizeof(moduleName));
cursor = SerializePodVector(cursor, funcNames);
cursor = SerializePodVector(cursor, customSections);
cursor = filename.serialize(cursor);
cursor = sourceMapURL.serialize(cursor);
return cursor;
@ -1016,8 +1003,8 @@ Metadata::deserialize(const uint8_t* cursor)
(cursor = DeserializeVector(cursor, &funcTypeIds)) &&
(cursor = DeserializePodVector(cursor, &globals)) &&
(cursor = DeserializePodVector(cursor, &tables)) &&
(cursor = ReadBytes(cursor, &moduleName, sizeof(moduleName))) &&
(cursor = DeserializePodVector(cursor, &funcNames)) &&
(cursor = DeserializePodVector(cursor, &customSections)) &&
(cursor = filename.deserialize(cursor)) &&
(cursor = sourceMapURL.deserialize(cursor));
debugEnabled = false;
@ -1026,6 +1013,17 @@ Metadata::deserialize(const uint8_t* cursor)
return cursor;
}
size_t
Metadata::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
{
return SizeOfVectorExcludingThis(funcTypeIds, mallocSizeOf) +
globals.sizeOfExcludingThis(mallocSizeOf) +
tables.sizeOfExcludingThis(mallocSizeOf) +
funcNames.sizeOfExcludingThis(mallocSizeOf) +
filename.sizeOfExcludingThis(mallocSizeOf) +
sourceMapURL.sizeOfExcludingThis(mallocSizeOf);
}
struct ProjectFuncIndex
{
const FuncExportVector& funcExports;
@ -1057,11 +1055,11 @@ MetadataTier::lookupFuncExport(uint32_t funcIndex, size_t* funcExportIndex) cons
}
static bool
AppendNameInBytecode(const Bytes* maybeBytecode, const NameInBytecode& name, UTF8Bytes* bytes)
AppendName(const Bytes& namePayload, const Name& name, UTF8Bytes* bytes)
{
MOZ_RELEASE_ASSERT(name.offset <= maybeBytecode->length());
MOZ_RELEASE_ASSERT(name.length <= maybeBytecode->length() - name.offset);
return bytes->append((const char*)maybeBytecode->begin() + name.offset, name.length);
MOZ_RELEASE_ASSERT(name.offsetInNamePayload <= namePayload.length());
MOZ_RELEASE_ASSERT(name.length <= namePayload.length() - name.offsetInNamePayload);
return bytes->append((const char*)namePayload.begin() + name.offsetInNamePayload, name.length);
}
static bool
@ -1080,11 +1078,10 @@ AppendFunctionIndexName(uint32_t funcIndex, UTF8Bytes* bytes)
}
bool
Metadata::getFuncName(NameContext ctx, const Bytes* maybeBytecode, uint32_t funcIndex,
UTF8Bytes* name) const
Metadata::getFuncName(NameContext ctx, uint32_t funcIndex, UTF8Bytes* name) const
{
if (moduleName && moduleName->length != 0) {
if (!AppendNameInBytecode(maybeBytecode, *moduleName, name)) {
if (!AppendName(namePayload->bytes, *moduleName, name)) {
return false;
}
if (!name->append('.')) {
@ -1093,7 +1090,7 @@ Metadata::getFuncName(NameContext ctx, const Bytes* maybeBytecode, uint32_t func
}
if (funcIndex < funcNames.length() && funcNames[funcIndex].length != 0) {
return AppendNameInBytecode(maybeBytecode, funcNames[funcIndex], name);
return AppendName(namePayload->bytes, funcNames[funcIndex], name);
}
if (ctx == NameContext::BeforeLocation) {
@ -1103,6 +1100,25 @@ Metadata::getFuncName(NameContext ctx, const Bytes* maybeBytecode, uint32_t func
return AppendFunctionIndexName(funcIndex, name);
}
bool
CodeTier::initialize(const Code& code,
const LinkData& linkData,
const Metadata& metadata)
{
MOZ_ASSERT(!initialized());
code_ = &code;
MOZ_ASSERT(lazyStubs_.lock()->empty());
// See comments in CodeSegment::initialize() for why this must be last.
if (!segment_->initialize(*this, linkData, metadata, *metadata_)) {
return false;
}
MOZ_ASSERT(initialized());
return true;
}
size_t
CodeTier::serializedSize() const
{
@ -1222,11 +1238,11 @@ Code::Code(UniqueCodeTier tier1, const Metadata& metadata, JumpTables&& maybeJum
{}
bool
Code::initialize(const ShareableBytes& bytecode, const LinkData& linkData)
Code::initialize(const LinkData& linkData)
{
MOZ_ASSERT(!initialized());
if (!tier1_->initialize(*this, bytecode, linkData, *metadata_)) {
if (!tier1_->initialize(*this, linkData, *metadata_)) {
return false;
}
@ -1235,13 +1251,12 @@ Code::initialize(const ShareableBytes& bytecode, const LinkData& linkData)
}
bool
Code::setTier2(UniqueCodeTier tier2, const ShareableBytes& bytecode,
const LinkData& linkData) const
Code::setTier2(UniqueCodeTier tier2, const LinkData& linkData) const
{
MOZ_RELEASE_ASSERT(!hasTier2());
MOZ_RELEASE_ASSERT(tier2->tier() == Tier::Ion && tier1_->tier() == Tier::Baseline);
if (!tier2->initialize(*this, bytecode, linkData, *metadata_)) {
if (!tier2->initialize(*this, linkData, *metadata_)) {
return false;
}
@ -1415,7 +1430,7 @@ Code::lookupTrap(void* pc, Trap* trapOut, BytecodeOffset* bytecode) const
// since, once we start sampling, we'll be in a signal-handing context where we
// cannot malloc.
void
Code::ensureProfilingLabels(const Bytes* maybeBytecode, bool profilingEnabled) const
Code::ensureProfilingLabels(bool profilingEnabled) const
{
auto labels = profilingLabels_.lock();
@ -1441,7 +1456,7 @@ Code::ensureProfilingLabels(const Bytes* maybeBytecode, bool profilingEnabled) c
MOZ_ASSERT(bytecodeStr);
UTF8Bytes name;
if (!metadata().getFuncNameStandalone(maybeBytecode, codeRange.funcIndex(), &name)) {
if (!metadata().getFuncNameStandalone(codeRange.funcIndex(), &name)) {
return;
}
if (!name.append(" (", 2)) {
@ -1515,26 +1530,6 @@ Code::addSizeOfMiscIfNotSeen(MallocSizeOf mallocSizeOf,
}
}
bool
CodeTier::initialize(const Code& code,
const ShareableBytes& bytecode,
const LinkData& linkData,
const Metadata& metadata)
{
MOZ_ASSERT(!initialized());
code_ = &code;
MOZ_ASSERT(lazyStubs_.lock()->empty());
// See comments in CodeSegment::initialize() for why this must be last.
if (!segment_->initialize(*this, bytecode, linkData, metadata, *metadata_)) {
return false;
}
MOZ_ASSERT(initialized());
return true;
}
size_t
Code::serializedSize() const
{
@ -1554,7 +1549,6 @@ Code::serialize(uint8_t* cursor, const LinkData& linkData) const
/* static */ const uint8_t*
Code::deserialize(const uint8_t* cursor,
const ShareableBytes& bytecode,
const LinkData& linkData,
Metadata& metadata,
SharedCode* out)
@ -1576,7 +1570,7 @@ Code::deserialize(const uint8_t* cursor,
}
MutableCode code = js_new<Code>(std::move(codeTier), metadata, std::move(jumpTables));
if (!code || !code->initialize(bytecode, linkData)) {
if (!code || !code->initialize(linkData)) {
return nullptr;
}

Просмотреть файл

@ -178,7 +178,6 @@ class ModuleSegment : public CodeSegment
const LinkData& linkData);
bool initialize(const CodeTier& codeTier,
const ShareableBytes& bytecode,
const LinkData& linkData,
const Metadata& metadata,
const MetadataTier& metadataTier);
@ -327,44 +326,6 @@ enum class MemoryUsage
Shared = 2
};
// NameInBytecode represents a name that is embedded in the wasm bytecode.
// The presence of NameInBytecode implies that bytecode has been kept.
struct NameInBytecode
{
uint32_t offset;
uint32_t length;
NameInBytecode()
: offset(UINT32_MAX), length(0)
{}
NameInBytecode(uint32_t offset, uint32_t length)
: offset(offset), length(length)
{}
};
typedef Vector<NameInBytecode, 0, SystemAllocPolicy> NameInBytecodeVector;
// CustomSection represents a custom section in the bytecode which can be
// extracted via Module.customSections. The (offset, length) pair does not
// include the custom section name.
struct CustomSection
{
NameInBytecode name;
uint32_t offset;
uint32_t length;
CustomSection() = default;
CustomSection(NameInBytecode name, uint32_t offset, uint32_t length)
: name(name), offset(offset), length(length)
{}
};
typedef Vector<CustomSection, 0, SystemAllocPolicy> CustomSectionVector;
typedef Vector<ValTypeVector, 0, SystemAllocPolicy> FuncArgTypesVector;
typedef Vector<ExprType, 0, SystemAllocPolicy> FuncReturnTypesVector;
// Metadata holds all the data that is needed to describe compiled wasm code
// at runtime (as opposed to data that is only used to statically link or
// instantiate a module).
@ -386,7 +347,7 @@ struct MetadataCacheablePod
uint32_t globalDataLength;
Maybe<uint32_t> maxMemoryLength;
Maybe<uint32_t> startFuncIndex;
Maybe<NameInBytecode> moduleName;
Maybe<uint32_t> nameCustomSectionIndex;
bool filenameIsURL;
explicit MetadataCacheablePod(ModuleKind kind)
@ -400,17 +361,24 @@ struct MetadataCacheablePod
};
typedef uint8_t ModuleHash[8];
typedef Vector<ValTypeVector, 0, SystemAllocPolicy> FuncArgTypesVector;
typedef Vector<ExprType, 0, SystemAllocPolicy> FuncReturnTypesVector;
struct Metadata : public ShareableBase<Metadata>, public MetadataCacheablePod
{
FuncTypeWithIdVector funcTypeIds;
GlobalDescVector globals;
TableDescVector tables;
NameInBytecodeVector funcNames;
CustomSectionVector customSections;
CacheableChars filename;
CacheableChars sourceMapURL;
// namePayload points at the name section's CustomSection::payload so that
// the Names (which are use payload-relative offsets) can be used
// independently of the Module without duplicating the name section.
SharedBytes namePayload;
Maybe<Name> moduleName;
NameVector funcNames;
// Debug-enabled code is not serialized.
bool debugEnabled;
FuncArgTypesVector debugFuncArgTypes;
@ -459,14 +427,13 @@ struct Metadata : public ShareableBase<Metadata>, public MetadataCacheablePod
enum NameContext { Standalone, BeforeLocation };
virtual bool getFuncName(NameContext ctx, const Bytes* maybeBytecode, uint32_t funcIndex,
UTF8Bytes* name) const;
virtual bool getFuncName(NameContext ctx, uint32_t funcIndex, UTF8Bytes* name) const;
bool getFuncNameStandalone(const Bytes* maybeBytecode, uint32_t funcIndex, UTF8Bytes* name) const {
return getFuncName(NameContext::Standalone, maybeBytecode, funcIndex, name);
bool getFuncNameStandalone(uint32_t funcIndex, UTF8Bytes* name) const {
return getFuncName(NameContext::Standalone, funcIndex, name);
}
bool getFuncNameBeforeLocation(const Bytes* maybeBytecode, uint32_t funcIndex, UTF8Bytes* name) const {
return getFuncName(NameContext::BeforeLocation, maybeBytecode, funcIndex, name);
bool getFuncNameBeforeLocation(uint32_t funcIndex, UTF8Bytes* name) const {
return getFuncName(NameContext::BeforeLocation, funcIndex, name);
}
WASM_DECLARE_SERIALIZABLE_VIRTUAL(Metadata);
@ -634,11 +601,7 @@ class CodeTier
{}
bool initialized() const { return !!code_ && segment_->initialized(); }
bool initialize(const Code& code,
const ShareableBytes& bytecode,
const LinkData& linkData,
const Metadata& metadata);
bool initialize(const Code& code, const LinkData& linkData, const Metadata& metadata);
Tier tier() const { return segment_->tier(); }
const ExclusiveData<LazyStubTier>& lazyStubs() const { return lazyStubs_; }
@ -730,7 +693,7 @@ class Code : public ShareableBase<Code>
JumpTables&& maybeJumpTables);
bool initialized() const { return tier1_->initialized(); }
bool initialize(const ShareableBytes& bytecode, const LinkData& linkData);
bool initialize(const LinkData& linkData);
void setTieringEntry(size_t i, void* target) const { jumpTables_.setTieringEntry(i, target); }
void** tieringJumpTable() const { return jumpTables_.tiering(); }
@ -739,8 +702,7 @@ class Code : public ShareableBase<Code>
void** getAddressOfJitEntry(size_t i) const { return jumpTables_.getAddressOfJitEntry(i); }
uint32_t getFuncIndex(JSFunction* fun) const;
bool setTier2(UniqueCodeTier tier2, const ShareableBytes& bytecode,
const LinkData& linkData) const;
bool setTier2(UniqueCodeTier tier2, const LinkData& linkData) const;
void commitTier2() const;
bool hasTier2() const { return hasTier2_; }
@ -770,7 +732,7 @@ class Code : public ShareableBase<Code>
// To save memory, profilingLabels_ are generated lazily when profiling mode
// is enabled.
void ensureProfilingLabels(const Bytes* maybeBytecode, bool profilingEnabled) const;
void ensureProfilingLabels(bool profilingEnabled) const;
const char* profilingLabel(uint32_t funcIndex) const;
// about:memory reporting:
@ -788,7 +750,6 @@ class Code : public ShareableBase<Code>
size_t serializedSize() const;
uint8_t* serialize(uint8_t* cursor, const LinkData& linkData) const;
static const uint8_t* deserialize(const uint8_t* cursor,
const ShareableBytes& bytecode,
const LinkData& linkData,
Metadata& metadata,
SharedCode* code);

Просмотреть файл

@ -543,12 +543,13 @@ wasm::CompileBuffer(const CompileArgs& args, const ShareableBytes& bytecode, Uni
}
void
wasm::CompileTier2(const CompileArgs& args, Module& module, Atomic<bool>* cancelled)
wasm::CompileTier2(const CompileArgs& args, const Bytes& bytecode, const Module& module,
Atomic<bool>* cancelled)
{
MOZ_RELEASE_ASSERT(wasm::HaveSignalHandlers());
UniqueChars error;
Decoder d(module.bytecode().bytes, 0, &error);
Decoder d(bytecode, 0, &error);
HasGcTypes gcTypesConfigured = HasGcTypes::False; // No Ion support yet
CompilerEnvironment compilerEnv(CompileMode::Tier2, Tier::Ion, DebugEnabled::False,

Просмотреть файл

@ -92,7 +92,8 @@ CompileBuffer(const CompileArgs& args,
// Attempt to compile the second tier of the given wasm::Module.
void
CompileTier2(const CompileArgs& args, Module& module, Atomic<bool>* cancelled);
CompileTier2(const CompileArgs& args, const Bytes& bytecode, const Module& module,
Atomic<bool>* cancelled);
// Compile the given WebAssembly module which has been broken into three
// partitions:

Просмотреть файл

@ -24,8 +24,6 @@
#include "gc/FreeOp.h"
#include "jit/ExecutableAllocator.h"
#include "jit/MacroAssembler.h"
#include "util/StringBuffer.h"
#include "util/Text.h"
#include "vm/Debugger.h"
#include "wasm/WasmInstance.h"
#include "wasm/WasmValidate.h"
@ -36,26 +34,16 @@ using namespace js::wasm;
using mozilla::BinarySearchIf;
DebugState::DebugState(SharedCode code,
const ShareableBytes* maybeBytecode,
bool binarySource)
: code_(std::move(code)),
maybeBytecode_(maybeBytecode),
DebugState::DebugState(const Code& code, const Module& module, bool binarySource)
: code_(&code),
module_(&module),
binarySource_(binarySource),
enterFrameTrapsEnabled_(false),
enterAndLeaveFrameTrapsCounter_(0)
{
MOZ_ASSERT_IF(debugEnabled(), maybeBytecode);
MOZ_ASSERT(code.metadata().debugEnabled);
}
const char enabledMessage[] =
"Restart with developer tools open to view WebAssembly source.";
const char noBinarySource[] =
"Configure the debugger to display WebAssembly bytecode.";
const char notGeneratedMessage[] =
"WebAssembly text generation was disabled.";
static const uint32_t DefaultBinarySourceColumnNumber = 1;
static const CallSite*
@ -69,32 +57,9 @@ SlowCallSiteSearchByOffset(const MetadataTier& metadata, uint32_t offset)
return nullptr;
}
JSString*
DebugState::createText(JSContext* cx)
{
StringBuffer buffer(cx);
if (!maybeBytecode_) {
if (!buffer.append(enabledMessage)) {
return nullptr;
}
} else if (binarySource_) {
if (!buffer.append(notGeneratedMessage)) {
return nullptr;
}
} else {
if (!buffer.append(noBinarySource)) {
return nullptr;
}
}
return buffer.finishString();
}
bool
DebugState::getLineOffsets(JSContext* cx, size_t lineno, Vector<uint32_t>* offsets)
{
if (!debugEnabled()) {
return true;
}
if (!binarySource_) {
return true;
}
@ -108,9 +73,6 @@ DebugState::getLineOffsets(JSContext* cx, size_t lineno, Vector<uint32_t>* offse
bool
DebugState::getAllColumnOffsets(JSContext* cx, Vector<ExprLoc>* offsets)
{
if (!metadata().debugEnabled) {
return true;
}
if (!binarySource_) {
return true;
}
@ -127,38 +89,23 @@ DebugState::getAllColumnOffsets(JSContext* cx, Vector<ExprLoc>* offsets)
}
bool
DebugState::getOffsetLocation(JSContext* cx, uint32_t offset, bool* found, size_t* lineno, size_t* column)
DebugState::getOffsetLocation(uint32_t offset, size_t* lineno, size_t* column)
{
*found = false;
if (!debugEnabled()) {
return true;
}
if (!binarySource_) {
return true;
return false;
}
if (!SlowCallSiteSearchByOffset(metadata(Tier::Debug), offset)) {
return true; // offset was not found
return false;
}
*found = true;
*lineno = offset;
*column = DefaultBinarySourceColumnNumber;
return true;
}
bool
DebugState::totalSourceLines(JSContext* cx, uint32_t* count)
uint32_t
DebugState::totalSourceLines()
{
*count = 0;
if (!debugEnabled()) {
return true;
}
if (!binarySource_) {
return true;
}
if (maybeBytecode_) {
*count = maybeBytecode_->length();
}
return true;
return binarySource_ ? bytecode().length() : 0;
}
bool
@ -170,7 +117,6 @@ DebugState::stepModeEnabled(uint32_t funcIndex) const
bool
DebugState::incrementStepModeCount(JSContext* cx, uint32_t funcIndex)
{
MOZ_ASSERT(debugEnabled());
const CodeRange& codeRange = codeRanges(Tier::Debug)[funcToCodeRangeIndex(funcIndex)];
MOZ_ASSERT(codeRange.isFunction());
@ -204,7 +150,6 @@ DebugState::incrementStepModeCount(JSContext* cx, uint32_t funcIndex)
bool
DebugState::decrementStepModeCount(FreeOp* fop, uint32_t funcIndex)
{
MOZ_ASSERT(debugEnabled());
const CodeRange& codeRange = codeRanges(Tier::Debug)[funcToCodeRangeIndex(funcIndex)];
MOZ_ASSERT(codeRange.isFunction());
@ -237,16 +182,12 @@ DebugState::decrementStepModeCount(FreeOp* fop, uint32_t funcIndex)
bool
DebugState::hasBreakpointTrapAtOffset(uint32_t offset)
{
if (!debugEnabled()) {
return false;
}
return SlowCallSiteSearchByOffset(metadata(Tier::Debug), offset);
}
void
DebugState::toggleBreakpointTrap(JSRuntime* rt, uint32_t offset, bool enabled)
{
MOZ_ASSERT(debugEnabled());
const CallSite* callSite = SlowCallSiteSearchByOffset(metadata(Tier::Debug), offset);
if (!callSite) {
return;
@ -364,7 +305,6 @@ DebugState::toggleDebugTrap(uint32_t offset, bool enabled)
void
DebugState::adjustEnterAndLeaveFrameTrapsState(JSContext* cx, bool enabled)
{
MOZ_ASSERT(debugEnabled());
MOZ_ASSERT_IF(!enabled, enterAndLeaveFrameTrapsCounter_ > 0);
bool wasEnabled = enterAndLeaveFrameTrapsCounter_ > 0;
@ -390,11 +330,21 @@ DebugState::adjustEnterAndLeaveFrameTrapsState(JSContext* cx, bool enabled)
}
}
void
DebugState::ensureEnterFrameTrapsState(JSContext* cx, bool enabled)
{
if (enterFrameTrapsEnabled_ == enabled) {
return;
}
adjustEnterAndLeaveFrameTrapsState(cx, enabled);
enterFrameTrapsEnabled_ = enabled;
}
bool
DebugState::debugGetLocalTypes(uint32_t funcIndex, ValTypeVector* locals, size_t* argsLength)
{
MOZ_ASSERT(debugEnabled());
const ValTypeVector& args = metadata().debugFuncArgTypes[funcIndex];
*argsLength = args.length();
if (!locals->appendAll(args)) {
@ -404,17 +354,15 @@ DebugState::debugGetLocalTypes(uint32_t funcIndex, ValTypeVector* locals, size_t
// Decode local var types from wasm binary function body.
const CodeRange& range = codeRanges(Tier::Debug)[funcToCodeRangeIndex(funcIndex)];
// In wasm, the Code points to the function start via funcLineOrBytecode.
MOZ_ASSERT(!metadata().isAsmJS() && maybeBytecode_);
size_t offsetInModule = range.funcLineOrBytecode();
Decoder d(maybeBytecode_->begin() + offsetInModule, maybeBytecode_->end(),
offsetInModule, /* error = */ nullptr);
Decoder d(bytecode().begin() + offsetInModule, bytecode().end(), offsetInModule,
/* error = */ nullptr);
return DecodeValidatedLocalEntries(d, locals);
}
ExprType
DebugState::debugGetResultType(uint32_t funcIndex)
{
MOZ_ASSERT(debugEnabled());
return metadata().debugFuncReturnTypes[funcIndex];
}
@ -475,77 +423,21 @@ DebugState::getGlobal(Instance& instance, uint32_t globalIndex, MutableHandleVal
return true;
}
JSString*
DebugState::debugDisplayURL(JSContext* cx) const
{
// Build wasm module URL from following parts:
// - "wasm:" as protocol;
// - URI encoded filename from metadata (if can be encoded), plus ":";
// - 64-bit hash of the module bytes (as hex dump).
js::StringBuffer result(cx);
if (!result.append("wasm:")) {
return nullptr;
}
if (const char* filename = metadata().filename.get()) {
// EncodeURI returns false due to invalid chars or OOM -- fail only
// during OOM.
JSString* filenamePrefix = EncodeURI(cx, filename, strlen(filename));
if (!filenamePrefix) {
if (cx->isThrowingOutOfMemory()) {
return nullptr;
}
MOZ_ASSERT(!cx->isThrowingOverRecursed());
cx->clearPendingException(); // ignore invalid URI
} else if (!result.append(filenamePrefix)) {
return nullptr;
}
}
if (metadata().debugEnabled) {
if (!result.append(":")) {
return nullptr;
}
const ModuleHash& hash = metadata().debugHash;
for (size_t i = 0; i < sizeof(ModuleHash); i++) {
char digit1 = hash[i] / 16, digit2 = hash[i] % 16;
if (!result.append((char)(digit1 < 10 ? digit1 + '0' : digit1 + 'a' - 10))) {
return nullptr;
}
if (!result.append((char)(digit2 < 10 ? digit2 + '0' : digit2 + 'a' - 10))) {
return nullptr;
}
}
}
return result.finishString();
}
bool
DebugState::getSourceMappingURL(JSContext* cx, MutableHandleString result) const
{
result.set(nullptr);
if (!maybeBytecode_) {
return true;
}
for (const CustomSection& customSection : metadata().customSections) {
const NameInBytecode& sectionName = customSection.name;
if (strlen(SourceMappingURLSectionName) != sectionName.length ||
memcmp(SourceMappingURLSectionName, maybeBytecode_->begin() + sectionName.offset,
sectionName.length) != 0)
for (const CustomSection& customSection : module_->customSections()) {
const Bytes& sectionName = customSection.name;
if (strlen(SourceMappingURLSectionName) != sectionName.length() ||
memcmp(SourceMappingURLSectionName, sectionName.begin(), sectionName.length()) != 0)
{
continue;
}
// Parse found "SourceMappingURL" custom section.
Decoder d(maybeBytecode_->begin() + customSection.offset,
maybeBytecode_->begin() + customSection.offset + customSection.length,
customSection.offset,
Decoder d(customSection.payload->begin(), customSection.payload->end(), 0,
/* error = */ nullptr);
uint32_t nchars;
if (!d.readVarU32(&nchars)) {
@ -587,7 +479,5 @@ DebugState::addSizeOfMisc(MallocSizeOf mallocSizeOf,
size_t* data) const
{
code_->addSizeOfMiscIfNotSeen(mallocSizeOf, seenMetadata, seenCode, code, data);
if (maybeBytecode_) {
*data += maybeBytecode_->sizeOfIncludingThisIfNotSeen(mallocSizeOf, seenBytes);
}
module_->addSizeOfMisc(mallocSizeOf, seenMetadata, seenBytes, seenCode, code, data);
}

Просмотреть файл

@ -20,7 +20,7 @@
#define wasm_debug_h
#include "js/HashTable.h"
#include "wasm/WasmCode.h"
#include "wasm/WasmModule.h"
#include "wasm/WasmTypes.h"
namespace js {
@ -55,13 +55,14 @@ typedef HashMap<uint32_t, WasmBreakpointSite*, DefaultHasher<uint32_t>, SystemAl
class DebugState
{
const SharedCode code_;
const SharedBytes maybeBytecode_;
const SharedModule module_;
bool binarySource_;
// State maintained when debugging is enabled. In this case, the Code is
// not actually shared, but is referenced uniquely by the instance that is
// being debugged.
bool enterFrameTrapsEnabled_;
uint32_t enterAndLeaveFrameTrapsCounter_;
WasmBreakpointSiteMap breakpointSites_;
StepModeCounters stepModeCounters_;
@ -69,24 +70,23 @@ class DebugState
void toggleDebugTrap(uint32_t offset, bool enabled);
public:
DebugState(SharedCode code,
const ShareableBytes* maybeBytecode,
bool binarySource);
DebugState(const Code& code, const Module& module, bool binarySource);
const Bytes* maybeBytecode() const { return maybeBytecode_ ? &maybeBytecode_->bytes : nullptr; }
const Bytes& bytecode() const { return module_->debugBytecode(); }
bool binarySource() const { return binarySource_; }
JSString* createText(JSContext* cx);
bool getLineOffsets(JSContext* cx, size_t lineno, Vector<uint32_t>* offsets);
bool getAllColumnOffsets(JSContext* cx, Vector<ExprLoc>* offsets);
bool getOffsetLocation(JSContext* cx, uint32_t offset, bool* found, size_t* lineno, size_t* column);
bool totalSourceLines(JSContext* cx, uint32_t* count);
bool getOffsetLocation(uint32_t offset, size_t* lineno, size_t* column);
uint32_t totalSourceLines();
// The Code can track enter/leave frame events. Any such event triggers
// debug trap. The enter/leave frame events enabled or disabled across
// all functions.
void adjustEnterAndLeaveFrameTrapsState(JSContext* cx, bool enabled);
void ensureEnterFrameTrapsState(JSContext* cx, bool enabled);
bool enterFrameTrapsEnabled() const { return enterFrameTrapsEnabled_; }
// When the Code is debugEnabled, individual breakpoints can be enabled or
// disabled at instruction offsets.
@ -113,14 +113,12 @@ class DebugState
// Debug URL helpers.
JSString* debugDisplayURL(JSContext* cx) const;
bool getSourceMappingURL(JSContext* cx, MutableHandleString result) const;
// Accessors for commonly used elements of linked structures.
const MetadataTier& metadata(Tier t) const { return code_->metadata(t); }
const Metadata& metadata() const { return code_->metadata(); }
bool debugEnabled() const { return metadata().debugEnabled; }
const CodeRangeVector& codeRanges(Tier t) const { return metadata(t).codeRanges; }
const CallSiteVector& callSites(Tier t) const { return metadata(t).callSites; }

Просмотреть файл

@ -449,17 +449,11 @@ ModuleGenerator::linkCallSites()
masm_.haltingAlign(CodeAlignment);
// Create far jumps for calls that have relative offsets that may otherwise
// go out of range. Far jumps are created for two cases: direct calls
// between function definitions and calls to trap exits by trap out-of-line
// paths. Far jump code is shared when possible to reduce bloat. This method
// is called both between function bodies (at a frequency determined by the
// ISA's jump range) and once at the very end of a module's codegen after
// all possible calls/traps have been emitted.
// go out of range. This method is called both between function bodies (at a
// frequency determined by the ISA's jump range) and once at the very end of
// a module's codegen after all possible calls/traps have been emitted.
OffsetMap existingCallFarJumps;
TrapMaybeOffsetArray existingTrapFarJumps;
for (; lastPatchedCallSite_ < metadataTier_->callSites.length(); lastPatchedCallSite_++) {
const CallSite& callSite = metadataTier_->callSites[lastPatchedCallSite_];
const CallSiteTarget& target = callSiteTargets_[lastPatchedCallSite_];
@ -838,7 +832,7 @@ ModuleGenerator::finishFuncDefs()
}
bool
ModuleGenerator::finishCode()
ModuleGenerator::finishCodegen()
{
// Now that all functions and stubs are generated and their CodeRanges
// known, patch all calls (which can emit far jumps) and far jumps. Linking
@ -870,7 +864,7 @@ ModuleGenerator::finishCode()
}
bool
ModuleGenerator::finishMetadata(const ShareableBytes& bytecode)
ModuleGenerator::finishMetadataTier()
{
// Assert all sorted metadata is sorted.
#ifdef DEBUG
@ -901,24 +895,6 @@ ModuleGenerator::finishMetadata(const ShareableBytes& bytecode)
}
#endif
// Copy over data from the ModuleEnvironment.
metadata_->memoryUsage = env_->memoryUsage;
metadata_->temporaryGcTypesConfigured = env_->gcTypesConfigured;
metadata_->minMemoryLength = env_->minMemoryLength;
metadata_->maxMemoryLength = env_->maxMemoryLength;
metadata_->startFuncIndex = env_->startFuncIndex;
metadata_->moduleName = env_->moduleName;
metadata_->tables = std::move(env_->tables);
metadata_->globals = std::move(env_->globals);
metadata_->funcNames = std::move(env_->funcNames);
metadata_->customSections = std::move(env_->customSections);
// Inflate the global bytes up to page size so that the total bytes are a
// page size (as required by the allocator functions).
metadata_->globalDataLength = AlignBytes(metadata_->globalDataLength, gc::SystemPageSize());
// These Vectors can get large and the excess capacity can be significant,
// so realloc them down to size.
@ -931,39 +907,11 @@ ModuleGenerator::finishMetadata(const ShareableBytes& bytecode)
metadataTier_->trapSites[trap].podResizeToFit();
}
// Copy over additional debug information.
if (env_->debugEnabled()) {
metadata_->debugEnabled = true;
const size_t numFuncTypes = env_->funcTypes.length();
if (!metadata_->debugFuncArgTypes.resize(numFuncTypes)) {
return false;
}
if (!metadata_->debugFuncReturnTypes.resize(numFuncTypes)) {
return false;
}
for (size_t i = 0; i < numFuncTypes; i++) {
if (!metadata_->debugFuncArgTypes[i].appendAll(env_->funcTypes[i]->args())) {
return false;
}
metadata_->debugFuncReturnTypes[i] = env_->funcTypes[i]->ret();
}
static_assert(sizeof(ModuleHash) <= sizeof(mozilla::SHA1Sum::Hash),
"The ModuleHash size shall not exceed the SHA1 hash size.");
mozilla::SHA1Sum::Hash hash;
mozilla::SHA1Sum sha1Sum;
sha1Sum.update(bytecode.begin(), bytecode.length());
sha1Sum.finish(hash);
memcpy(metadata_->debugHash, hash, sizeof(ModuleHash));
}
return true;
}
UniqueModuleSegment
ModuleGenerator::finish(const ShareableBytes& bytecode)
UniqueCodeTier
ModuleGenerator::finishCodeTier()
{
MOZ_ASSERT(finishedFuncDefs_);
@ -1001,15 +949,71 @@ ModuleGenerator::finish(const ShareableBytes& bytecode)
// Finish linking and metadata.
if (!finishCode()) {
if (!finishCodegen()) {
return nullptr;
}
if (!finishMetadata(bytecode)) {
if (!finishMetadataTier()) {
return nullptr;
}
return ModuleSegment::create(tier(), masm_, *linkData_);
UniqueModuleSegment segment = ModuleSegment::create(tier(), masm_, *linkData_);
if (!segment) {
return nullptr;
}
return js::MakeUnique<CodeTier>(std::move(metadataTier_), std::move(segment));
}
bool
ModuleGenerator::finishMetadata(const Bytes& bytecode)
{
// Finish initialization of Metadata, which is only needed for constructing
// the initial Module, not for tier-2 compilation.
MOZ_ASSERT(mode() != CompileMode::Tier2);
// Copy over data from the ModuleEnvironment.
metadata_->memoryUsage = env_->memoryUsage;
metadata_->temporaryGcTypesConfigured = env_->gcTypesConfigured;
metadata_->minMemoryLength = env_->minMemoryLength;
metadata_->maxMemoryLength = env_->maxMemoryLength;
metadata_->startFuncIndex = env_->startFuncIndex;
metadata_->tables = std::move(env_->tables);
metadata_->globals = std::move(env_->globals);
metadata_->nameCustomSectionIndex = env_->nameCustomSectionIndex;
metadata_->moduleName = env_->moduleName;
metadata_->funcNames = std::move(env_->funcNames);
// Copy over additional debug information.
if (env_->debugEnabled()) {
metadata_->debugEnabled = true;
const size_t numFuncTypes = env_->funcTypes.length();
if (!metadata_->debugFuncArgTypes.resize(numFuncTypes)) {
return false;
}
if (!metadata_->debugFuncReturnTypes.resize(numFuncTypes)) {
return false;
}
for (size_t i = 0; i < numFuncTypes; i++) {
if (!metadata_->debugFuncArgTypes[i].appendAll(env_->funcTypes[i]->args())) {
return false;
}
metadata_->debugFuncReturnTypes[i] = env_->funcTypes[i]->ret();
}
static_assert(sizeof(ModuleHash) <= sizeof(mozilla::SHA1Sum::Hash),
"The ModuleHash size shall not exceed the SHA1 hash size.");
mozilla::SHA1Sum::Hash hash;
mozilla::SHA1Sum sha1Sum;
sha1Sum.update(bytecode.begin(), bytecode.length());
sha1Sum.finish(hash);
memcpy(metadata_->debugHash, hash, sizeof(ModuleHash));
}
return true;
}
SharedModule
@ -1017,23 +1021,22 @@ ModuleGenerator::finishModule(const ShareableBytes& bytecode, UniqueLinkData* li
{
MOZ_ASSERT(mode() == CompileMode::Once || mode() == CompileMode::Tier1);
UniqueModuleSegment moduleSegment = finish(bytecode);
if (!moduleSegment) {
return nullptr;
}
JumpTables jumpTables;
if (!jumpTables.init(mode(), *moduleSegment, metadataTier_->codeRanges)) {
return nullptr;
}
auto codeTier = js::MakeUnique<CodeTier>(std::move(metadataTier_), std::move(moduleSegment));
UniqueCodeTier codeTier = finishCodeTier();
if (!codeTier) {
return nullptr;
}
JumpTables jumpTables;
if (!jumpTables.init(mode(), codeTier->segment(), codeTier->metadata().codeRanges)) {
return nullptr;
}
if (!finishMetadata(bytecode.bytes)) {
return nullptr;
}
MutableCode code = js_new<Code>(std::move(codeTier), *metadata_, std::move(jumpTables));
if (!code || !code->initialize(bytecode, *linkData_)) {
if (!code || !code->initialize(*linkData_)) {
return nullptr;
}
@ -1044,11 +1047,14 @@ ModuleGenerator::finishModule(const ShareableBytes& bytecode, UniqueLinkData* li
}
}
// Copy over data from the Bytecode, which is going away at the end of
// compilation.
DataSegmentVector dataSegments;
if (!dataSegments.reserve(env_->dataSegments.length())) {
return nullptr;
}
for (DataSegmentEnv& srcSeg : env_->dataSegments) {
for (const DataSegmentEnv& srcSeg : env_->dataSegments) {
MutableDataSegment dstSeg = js_new<DataSegment>(srcSeg);
if (!dstSeg) {
return nullptr;
@ -1059,8 +1065,36 @@ ModuleGenerator::finishModule(const ShareableBytes& bytecode, UniqueLinkData* li
dataSegments.infallibleAppend(std::move(dstSeg));
}
CustomSectionVector customSections;
if (!customSections.reserve(env_->customSections.length())) {
return nullptr;
}
for (const CustomSectionEnv& srcSec : env_->customSections) {
CustomSection sec;
if (!sec.name.append(bytecode.begin() + srcSec.nameOffset, srcSec.nameLength)) {
return nullptr;
}
MutableBytes payload = js_new<ShareableBytes>();
if (!payload) {
return nullptr;
}
if (!payload->append(bytecode.begin() + srcSec.payloadOffset, srcSec.payloadLength)) {
return nullptr;
}
sec.payload = std::move(payload);
customSections.infallibleAppend(std::move(sec));
}
if (env_->nameCustomSectionIndex) {
metadata_->namePayload = customSections[*env_->nameCustomSectionIndex].payload;
}
// See Module debugCodeClaimed_ comments for why we need to make a separate
// debug copy.
UniqueBytes debugUnlinkedCode;
UniqueLinkData debugLinkData;
const ShareableBytes* debugBytecode = nullptr;
if (env_->debugEnabled()) {
MOZ_ASSERT(mode() == CompileMode::Once);
MOZ_ASSERT(tier() == Tier::Debug);
@ -1073,23 +1107,28 @@ ModuleGenerator::finishModule(const ShareableBytes& bytecode, UniqueLinkData* li
masm_.executableCopy(debugUnlinkedCode->begin(), /* flushICache = */ false);
debugLinkData = std::move(linkData_);
debugBytecode = &bytecode;
}
SharedModule module(js_new<Module>(*code,
std::move(env_->imports),
std::move(env_->exports),
std::move(structTypes),
std::move(dataSegments),
std::move(env_->elemSegments),
bytecode,
std::move(debugUnlinkedCode),
std::move(debugLinkData)));
// All the components are finished, so create the complete Module and start
// tier-2 compilation if requested.
MutableModule module = js_new<Module>(*code,
std::move(env_->imports),
std::move(env_->exports),
std::move(structTypes),
std::move(dataSegments),
std::move(env_->elemSegments),
std::move(customSections),
std::move(debugUnlinkedCode),
std::move(debugLinkData),
debugBytecode);
if (!module) {
return nullptr;
}
if (mode() == CompileMode::Tier1) {
module->startTier2(*compileArgs_);
module->startTier2(*compileArgs_, bytecode);
}
if (linkData) {
@ -1102,7 +1141,7 @@ ModuleGenerator::finishModule(const ShareableBytes& bytecode, UniqueLinkData* li
}
bool
ModuleGenerator::finishTier2(Module& module)
ModuleGenerator::finishTier2(const Module& module)
{
MOZ_ASSERT(mode() == CompileMode::Tier2);
MOZ_ASSERT(tier() == Tier::Ion);
@ -1112,13 +1151,8 @@ ModuleGenerator::finishTier2(Module& module)
return false;
}
UniqueModuleSegment moduleSegment = finish(module.bytecode());
if (!moduleSegment) {
return false;
}
auto code = js::MakeUnique<CodeTier>(std::move(metadataTier_), std::move(moduleSegment));
if (!code) {
UniqueCodeTier codeTier = finishCodeTier();
if (!codeTier) {
return false;
}
@ -1128,7 +1162,7 @@ ModuleGenerator::finishTier2(Module& module)
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
return module.finishTier2(*linkData_, std::move(code));
return module.finishTier2(*linkData_, std::move(codeTier));
}
size_t

Просмотреть файл

@ -199,9 +199,10 @@ class MOZ_STACK_CLASS ModuleGenerator
bool finishTask(CompileTask* task);
bool launchBatchCompile();
bool finishOutstandingTask();
bool finishCode();
bool finishMetadata(const ShareableBytes& bytecode);
UniqueModuleSegment finish(const ShareableBytes& bytecode);
bool finishCodegen();
bool finishMetadataTier();
UniqueCodeTier finishCodeTier();
bool finishMetadata(const Bytes& bytecode);
bool isAsmJS() const { return env_->isAsmJS(); }
Tier tier() const { return env_->tier(); }
@ -231,7 +232,7 @@ class MOZ_STACK_CLASS ModuleGenerator
// called to augment the given Module with tier 2 code.
SharedModule finishModule(const ShareableBytes& bytecode, UniqueLinkData* linkData = nullptr);
MOZ_MUST_USE bool finishTier2(Module& module);
MOZ_MUST_USE bool finishTier2(const Module& module);
ExclusiveDeferredValidationState& deferredValidationState() {
return deferredValidationState_;

Просмотреть файл

@ -23,6 +23,8 @@
#include "jit/InlinableNatives.h"
#include "jit/JitCommon.h"
#include "jit/JitRealm.h"
#include "util/StringBuffer.h"
#include "util/Text.h"
#include "wasm/WasmBuiltins.h"
#include "wasm/WasmModule.h"
@ -697,22 +699,23 @@ Instance::postBarrier(Instance* instance, gc::Cell** location)
Instance::Instance(JSContext* cx,
Handle<WasmInstanceObject*> object,
SharedCode code,
UniqueDebugState debug,
UniqueTlsData tlsDataIn,
HandleWasmMemoryObject memory,
SharedTableVector&& tables,
Handle<FunctionVector> funcImports,
HandleValVector globalImportValues,
const WasmGlobalObjectVector& globalObjs)
const WasmGlobalObjectVector& globalObjs,
UniqueDebugState maybeDebug)
: realm_(cx->realm()),
object_(object),
code_(code),
debug_(std::move(debug)),
tlsData_(std::move(tlsDataIn)),
memory_(memory),
tables_(std::move(tables)),
enterFrameTrapsEnabled_(false)
maybeDebug_(std::move(maybeDebug))
{
MOZ_ASSERT(!!maybeDebug_ == metadata().debugEnabled);
#ifdef DEBUG
for (auto t : code_->tiers()) {
MOZ_ASSERT(funcImports.length() == metadata(t).funcImports.length());
@ -1145,7 +1148,7 @@ Instance::getFuncDisplayAtom(JSContext* cx, uint32_t funcIndex) const
// The "display name" of a function is primarily shown in Error.stack which
// also includes location, so use getFuncNameBeforeLocation.
UTF8Bytes name;
if (!metadata().getFuncNameBeforeLocation(debug_->maybeBytecode(), funcIndex, &name)) {
if (!metadata().getFuncNameBeforeLocation(funcIndex, &name)) {
return nullptr;
}
@ -1155,7 +1158,7 @@ Instance::getFuncDisplayAtom(JSContext* cx, uint32_t funcIndex) const
void
Instance::ensureProfilingLabels(bool profilingEnabled) const
{
return code_->ensureProfilingLabels(debug_->maybeBytecode(), profilingEnabled);
return code_->ensureProfilingLabels(profilingEnabled);
}
void
@ -1191,15 +1194,63 @@ Instance::deoptimizeImportExit(uint32_t funcImportIndex)
import.baselineScript = nullptr;
}
void
Instance::ensureEnterFrameTrapsState(JSContext* cx, bool enabled)
JSString*
Instance::createDisplayURL(JSContext* cx)
{
if (enterFrameTrapsEnabled_ == enabled) {
return;
// In the best case, we simply have a URL, from a streaming compilation of a
// fetched Response.
if (metadata().filenameIsURL) {
return NewStringCopyZ<CanGC>(cx, metadata().filename.get());
}
debug_->adjustEnterAndLeaveFrameTrapsState(cx, enabled);
enterFrameTrapsEnabled_ = enabled;
// Otherwise, build wasm module URL from following parts:
// - "wasm:" as protocol;
// - URI encoded filename from metadata (if can be encoded), plus ":";
// - 64-bit hash of the module bytes (as hex dump).
StringBuffer result(cx);
if (!result.append("wasm:")) {
return nullptr;
}
if (const char* filename = metadata().filename.get()) {
// EncodeURI returns false due to invalid chars or OOM -- fail only
// during OOM.
JSString* filenamePrefix = EncodeURI(cx, filename, strlen(filename));
if (!filenamePrefix) {
if (cx->isThrowingOutOfMemory()) {
return nullptr;
}
MOZ_ASSERT(!cx->isThrowingOverRecursed());
cx->clearPendingException();
return nullptr;
}
if (!result.append(filenamePrefix)) {
return nullptr;
}
}
if (metadata().debugEnabled) {
if (!result.append(":")) {
return nullptr;
}
const ModuleHash& hash = metadata().debugHash;
for (size_t i = 0; i < sizeof(ModuleHash); i++) {
char digit1 = hash[i] / 16, digit2 = hash[i] % 16;
if (!result.append((char)(digit1 < 10 ? digit1 + '0' : digit1 + 'a' - 10))) {
return nullptr;
}
if (!result.append((char)(digit2 < 10 ? digit2 + '0' : digit2 + 'a' - 10))) {
return nullptr;
}
}
}
return result.finishString();
}
void
@ -1217,6 +1268,9 @@ Instance::addSizeOfMisc(MallocSizeOf mallocSizeOf,
*data += table->sizeOfIncludingThisIfNotSeen(mallocSizeOf, seenTables);
}
debug_->addSizeOfMisc(mallocSizeOf, seenMetadata, seenBytes, seenCode, code, data);
if (maybeDebug_) {
maybeDebug_->addSizeOfMisc(mallocSizeOf, seenMetadata, seenBytes, seenCode, code, data);
}
code_->addSizeOfMiscIfNotSeen(mallocSizeOf, seenMetadata, seenCode, code, data);
}

Просмотреть файл

@ -51,13 +51,12 @@ class Instance
jit::TrampolinePtr preBarrierCode_;
#endif
const SharedCode code_;
const UniqueDebugState debug_;
const UniqueTlsData tlsData_;
GCPtrWasmMemoryObject memory_;
SharedTableVector tables_;
const SharedTableVector tables_;
DataSegmentVector passiveDataSegments_;
ElemSegmentVector passiveElemSegments_;
bool enterFrameTrapsEnabled_;
const UniqueDebugState maybeDebug_;
// Internal helpers:
const void** addressOfFuncTypeId(const FuncTypeIdDesc& funcTypeId) const;
@ -75,13 +74,13 @@ class Instance
Instance(JSContext* cx,
HandleWasmInstanceObject object,
SharedCode code,
UniqueDebugState debug,
UniqueTlsData tlsData,
HandleWasmMemoryObject memory,
SharedTableVector&& tables,
Handle<FunctionVector> funcImports,
HandleValVector globalImportValues,
const WasmGlobalObjectVector& globalObjs);
const WasmGlobalObjectVector& globalObjs,
UniqueDebugState maybeDebug);
~Instance();
bool init(JSContext* cx,
const DataSegmentVector& dataSegments,
@ -91,8 +90,8 @@ class Instance
JS::Realm* realm() const { return realm_; }
const Code& code() const { return *code_; }
const CodeTier& code(Tier t) const { return code_->codeTier(t); }
DebugState& debug() { return *debug_; }
const DebugState& debug() const { return *debug_; }
bool debugEnabled() const { return !!maybeDebug_; }
DebugState& debug() { return *maybeDebug_; }
const ModuleSegment& moduleSegment(Tier t) const { return code_->segment(t); }
TlsData* tlsData() const { return tlsData_.get(); }
uint8_t* globalData() const { return (uint8_t*)&tlsData_->globalArea; }
@ -158,11 +157,9 @@ class Instance
void initElems(const ElemSegment& seg, uint32_t dstOffset, uint32_t srcOffset, uint32_t len);
// Debug support:
// Debugger support:
bool debugEnabled() const { return metadata().debugEnabled; }
bool enterFrameTrapsEnabled() const { return enterFrameTrapsEnabled_; }
void ensureEnterFrameTrapsState(JSContext* cx, bool enabled);
JSString* createDisplayURL(JSContext* cx);
// about:memory reporting:

Просмотреть файл

@ -598,7 +598,7 @@ WasmModuleObject::finalize(FreeOp* fop, JSObject* obj)
}
static bool
IsModuleObject(JSObject* obj, Module** module)
IsModuleObject(JSObject* obj, const Module** module)
{
JSObject* unwrapped = CheckedUnwrap(obj);
if (!unwrapped || !unwrapped->is<WasmModuleObject>()) {
@ -610,7 +610,7 @@ IsModuleObject(JSObject* obj, Module** module)
}
static bool
GetModuleArg(JSContext* cx, CallArgs args, const char* name, Module** module)
GetModuleArg(JSContext* cx, CallArgs args, const char* name, const Module** module)
{
if (!args.requireAtLeast(cx, name, 1)) {
return false;
@ -732,7 +732,7 @@ WasmModuleObject::imports(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Module* module;
const Module* module;
if (!GetModuleArg(cx, args, "WebAssembly.Module.imports", &module)) {
return false;
}
@ -806,7 +806,7 @@ WasmModuleObject::exports(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Module* module;
const Module* module;
if (!GetModuleArg(cx, args, "WebAssembly.Module.exports", &module)) {
return false;
}
@ -874,7 +874,7 @@ WasmModuleObject::customSections(JSContext* cx, unsigned argc, Value* vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
Module* module;
const Module* module;
if (!GetModuleArg(cx, args, "WebAssembly.Module.customSections", &module)) {
return false;
}
@ -898,24 +898,22 @@ WasmModuleObject::customSections(JSContext* cx, unsigned argc, Value* vp)
JS::DeflateStringToUTF8Buffer(flat, RangedPtr<char>(name.begin(), name.length()));
}
const uint8_t* bytecode = module->bytecode().begin();
AutoValueVector elems(cx);
RootedArrayBufferObject buf(cx);
for (const CustomSection& sec : module->metadata().customSections) {
if (name.length() != sec.name.length) {
for (const CustomSection& cs : module->customSections()) {
if (name.length() != cs.name.length()) {
continue;
}
if (memcmp(name.begin(), bytecode + sec.name.offset, name.length())) {
if (memcmp(name.begin(), cs.name.begin(), name.length())) {
continue;
}
buf = ArrayBufferObject::create(cx, sec.length);
buf = ArrayBufferObject::create(cx, cs.payload->length());
if (!buf) {
return false;
}
memcpy(buf->dataPointer(), bytecode + sec.offset, sec.length);
memcpy(buf->dataPointer(), cs.payload->begin(), cs.payload->length());
if (!elems.append(ObjectValue(*buf))) {
return false;
}
@ -931,7 +929,7 @@ WasmModuleObject::customSections(JSContext* cx, unsigned argc, Value* vp)
}
/* static */ WasmModuleObject*
WasmModuleObject::create(JSContext* cx, Module& module, HandleObject proto)
WasmModuleObject::create(JSContext* cx, const Module& module, HandleObject proto)
{
AutoSetNewObjectMetadata metadata(cx);
auto* obj = NewObjectWithGivenProto<WasmModuleObject>(cx, proto);
@ -939,7 +937,7 @@ WasmModuleObject::create(JSContext* cx, Module& module, HandleObject proto)
return nullptr;
}
obj->initReservedSlot(MODULE_SLOT, PrivateValue(&module));
obj->initReservedSlot(MODULE_SLOT, PrivateValue(const_cast<Module*>(&module)));
module.AddRef();
// We account for the first tier here; the second tier, if different, will be
// accounted for separately when it's been compiled.
@ -1059,11 +1057,11 @@ WasmModuleObject::construct(JSContext* cx, unsigned argc, Value* vp)
return true;
}
Module&
const Module&
WasmModuleObject::module() const
{
MOZ_ASSERT(is<WasmModuleObject>());
return *(Module*)getReservedSlot(MODULE_SLOT).toPrivate();
return *(const Module*)getReservedSlot(MODULE_SLOT).toPrivate();
}
// ============================================================================
@ -1159,7 +1157,6 @@ WasmInstanceObject::create(JSContext* cx,
SharedCode code,
const DataSegmentVector& dataSegments,
const ElemSegmentVector& elemSegments,
UniqueDebugState debug,
UniqueTlsData tlsData,
HandleWasmMemoryObject memory,
SharedTableVector&& tables,
@ -1167,7 +1164,8 @@ WasmInstanceObject::create(JSContext* cx,
const GlobalDescVector& globals,
HandleValVector globalImportValues,
const WasmGlobalObjectVector& globalObjs,
HandleObject proto)
HandleObject proto,
UniqueDebugState maybeDebug)
{
UniquePtr<ExportMap> exports = js::MakeUnique<ExportMap>();
if (!exports) {
@ -1227,13 +1225,13 @@ WasmInstanceObject::create(JSContext* cx,
auto* instance = cx->new_<Instance>(cx,
obj,
code,
std::move(debug),
std::move(tlsData),
memory,
std::move(tables),
funcImports,
globalImportValues,
globalObjs);
globalObjs,
std::move(maybeDebug));
if (!instance) {
return nullptr;
}
@ -1300,7 +1298,7 @@ WasmInstanceObject::construct(JSContext* cx, unsigned argc, Value* vp)
return false;
}
Module* module;
const Module* module;
if (!args[0].isObject() || !IsModuleObject(&args[0].toObject(), &module)) {
JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_MOD_ARG);
return false;
@ -2686,7 +2684,7 @@ Reject(JSContext* cx, const CompileArgs& args, Handle<PromiseObject*> promise,
}
static bool
Resolve(JSContext* cx, Module& module, Handle<PromiseObject*> promise, bool instantiate,
Resolve(JSContext* cx, const Module& module, Handle<PromiseObject*> promise, bool instantiate,
HandleObject importObj, const UniqueCharsVector& warnings)
{
if (!ReportCompileWarnings(cx, warnings)) {
@ -2879,7 +2877,7 @@ WebAssembly_instantiate(JSContext* cx, unsigned argc, Value* vp)
return RejectWithPendingException(cx, promise, callArgs);
}
Module* module;
const Module* module;
if (IsModuleObject(firstArg, &module)) {
RootedWasmInstanceObject instanceObj(cx);
if (!Instantiate(cx, *module, importObj, &instanceObj)) {

Просмотреть файл

@ -107,9 +107,9 @@ class WasmModuleObject : public NativeObject
static bool construct(JSContext*, unsigned, Value*);
static WasmModuleObject* create(JSContext* cx,
wasm::Module& module,
const wasm::Module& module,
HandleObject proto = nullptr);
wasm::Module& module() const;
const wasm::Module& module() const;
};
// The class of WebAssembly.Global. This wraps a storage location, and there is
@ -216,7 +216,6 @@ class WasmInstanceObject : public NativeObject
RefPtr<const wasm::Code> code,
const wasm::DataSegmentVector& dataSegments,
const wasm::ElemSegmentVector& elemSegments,
UniquePtr<wasm::DebugState> debug,
wasm::UniqueTlsData tlsData,
HandleWasmMemoryObject memory,
Vector<RefPtr<wasm::Table>, 0, SystemAllocPolicy>&& tables,
@ -224,7 +223,8 @@ class WasmInstanceObject : public NativeObject
const wasm::GlobalDescVector& globals,
wasm::HandleValVector globalImportValues,
const WasmGlobalObjectVector& globalObjs,
HandleObject proto);
HandleObject proto,
UniquePtr<wasm::DebugState> maybeDebug);
void initExportsObj(JSObject& exportsObj);
wasm::Instance& instance() const;

Просмотреть файл

@ -39,14 +39,17 @@ using namespace js::wasm;
class Module::Tier2GeneratorTaskImpl : public Tier2GeneratorTask
{
SharedModule module_;
SharedCompileArgs compileArgs_;
SharedBytes bytecode_;
SharedModule module_;
Atomic<bool> cancelled_;
public:
Tier2GeneratorTaskImpl(Module& module, const CompileArgs& compileArgs)
: module_(&module),
compileArgs_(&compileArgs),
Tier2GeneratorTaskImpl(const CompileArgs& compileArgs, const ShareableBytes& bytecode,
Module& module)
: compileArgs_(&compileArgs),
bytecode_(&bytecode),
module_(&module),
cancelled_(false)
{}
@ -59,16 +62,16 @@ class Module::Tier2GeneratorTaskImpl : public Tier2GeneratorTask
}
void execute() override {
CompileTier2(*compileArgs_, *module_, &cancelled_);
CompileTier2(*compileArgs_, bytecode_->bytes, *module_, &cancelled_);
}
};
void
Module::startTier2(const CompileArgs& args)
Module::startTier2(const CompileArgs& args, const ShareableBytes& bytecode)
{
MOZ_ASSERT(!testingTier2Active_);
auto task = MakeUnique<Tier2GeneratorTaskImpl>(*this, args);
auto task = MakeUnique<Tier2GeneratorTaskImpl>(args, bytecode, *this);
if (!task) {
return;
}
@ -81,14 +84,14 @@ Module::startTier2(const CompileArgs& args)
}
bool
Module::finishTier2(const LinkData& linkData2, UniqueCodeTier code2)
Module::finishTier2(const LinkData& linkData2, UniqueCodeTier code2) const
{
MOZ_ASSERT(code().bestTier() == Tier::Baseline && code2->tier() == Tier::Ion);
// Install the data in the data structures. They will not be visible
// until commitTier2().
if (!code().setTier2(std::move(code2), *bytecode_, linkData2)) {
if (!code().setTier2(std::move(code2), linkData2)) {
return false;
}
@ -173,6 +176,7 @@ Module::serializedSize(const LinkData& linkData) const
SerializedVectorSize(structTypes_) +
SerializedVectorSize(dataSegments_) +
SerializedVectorSize(elemSegments_) +
SerializedVectorSize(customSections_) +
code_->serializedSize();
}
@ -190,11 +194,12 @@ Module::serialize(const LinkData& linkData, uint8_t* begin, size_t size) const
cursor = SerializeVector(cursor, structTypes_);
cursor = SerializeVector(cursor, dataSegments_);
cursor = SerializeVector(cursor, elemSegments_);
cursor = SerializeVector(cursor, customSections_);
cursor = code_->serialize(cursor, linkData);
MOZ_RELEASE_ASSERT(cursor == begin + size);
}
/* static */ SharedModule
/* static */ MutableModule
Module::deserialize(const uint8_t* begin, size_t size, Metadata* maybeMetadata)
{
MutableMetadata metadata(maybeMetadata);
@ -207,13 +212,6 @@ Module::deserialize(const uint8_t* begin, size_t size, Metadata* maybeMetadata)
const uint8_t* cursor = begin;
// Temporary. (asm.js doesn't save bytecode)
MOZ_RELEASE_ASSERT(maybeMetadata->isAsmJS());
MutableBytes bytecode = js_new<ShareableBytes>();
if (!bytecode) {
return nullptr;
}
LinkData linkData(Tier::Serialized);
cursor = linkData.deserialize(cursor);
if (!cursor) {
@ -250,8 +248,21 @@ Module::deserialize(const uint8_t* begin, size_t size, Metadata* maybeMetadata)
return nullptr;
}
CustomSectionVector customSections;
cursor = DeserializeVector(cursor, &customSections);
if (!cursor) {
return nullptr;
}
if (metadata->nameCustomSectionIndex) {
metadata->namePayload = customSections[*metadata->nameCustomSectionIndex].payload;
} else {
MOZ_RELEASE_ASSERT(!metadata->moduleName);
MOZ_RELEASE_ASSERT(metadata->funcNames.empty());
}
SharedCode code;
cursor = Code::deserialize(cursor, *bytecode, linkData, *metadata, &code);
cursor = Code::deserialize(cursor, linkData, *metadata, &code);
if (!cursor) {
return nullptr;
}
@ -265,7 +276,7 @@ Module::deserialize(const uint8_t* begin, size_t size, Metadata* maybeMetadata)
std::move(structTypes),
std::move(dataSegments),
std::move(elemSegments),
*bytecode);
std::move(customSections));
}
/* virtual */ JSObject*
@ -309,7 +320,7 @@ MapFile(PRFileDesc* file, PRFileInfo* info)
return UniqueMapping(memory, MemUnmap(info->size));
}
SharedModule
RefPtr<JS::WasmModule>
wasm::DeserializeModule(PRFileDesc* bytecodeFile, UniqueChars filename, unsigned line)
{
PRFileInfo bytecodeInfo;
@ -349,7 +360,13 @@ wasm::DeserializeModule(PRFileDesc* bytecodeFile, UniqueChars filename, unsigned
UniqueChars error;
UniqueCharsVector warnings;
return CompileBuffer(*args, *bytecode, &error, &warnings);
SharedModule module = CompileBuffer(*args, *bytecode, &error, &warnings);
if (!module) {
return nullptr;
}
// The public interface is effectively const.
return RefPtr<JS::WasmModule>(const_cast<Module*>(module.get()));
}
/* virtual */ void
@ -367,7 +384,7 @@ Module::addSizeOfMisc(MallocSizeOf mallocSizeOf,
SizeOfVectorExcludingThis(structTypes_, mallocSizeOf) +
SizeOfVectorExcludingThis(dataSegments_, mallocSizeOf) +
SizeOfVectorExcludingThis(elemSegments_, mallocSizeOf) +
bytecode_->sizeOfIncludingThisIfNotSeen(mallocSizeOf, seenBytes);
SizeOfVectorExcludingThis(customSections_, mallocSizeOf);
if (debugUnlinkedCode_) {
*data += debugUnlinkedCode_->sizeOfExcludingThis(mallocSizeOf);
@ -885,7 +902,7 @@ Module::getDebugEnabledCode() const
}
MutableCode debugCode = js_new<Code>(std::move(codeTier), metadata(), std::move(jumpTables));
if (!debugCode || !debugCode->initialize(*bytecode_, *debugLinkData_)) {
if (!debugCode || !debugCode->initialize(*debugLinkData_)) {
return nullptr;
}
@ -1021,48 +1038,28 @@ Module::instantiate(JSContext* cx,
return false;
}
// Debugging mutates code (for traps, stepping, etc) and thus may need to
// clone the code on each instantiation.
SharedCode code(code_);
SharedCode code;
UniqueDebugState maybeDebug;
if (metadata().debugEnabled) {
code = getDebugEnabledCode();
if (!code) {
ReportOutOfMemory(cx);
return false;
}
}
// To support viewing the source of an instance (Instance::createText), the
// instance must hold onto a ref of the bytecode (keeping it alive). This
// wastes memory for most users, so we try to only save the source when a
// developer actually cares: when the realm is debuggable (which is true
// when the web console is open), has code compiled with debug flag
// enabled or a names section is present (since this going to be stripped
// for non-developer builds).
const ShareableBytes* maybeBytecode = nullptr;
if (cx->realm()->isDebuggee() || metadata().debugEnabled ||
!metadata().funcNames.empty() || !!metadata().moduleName)
{
maybeBytecode = bytecode_.get();
}
// The debug object must be present even when debugging is not enabled: It
// provides the lazily created source text for the program, even if that
// text is a placeholder message when debugging is not enabled.
bool binarySource = cx->realm()->debuggerObservesBinarySource();
auto debug = cx->make_unique<DebugState>(code, maybeBytecode, binarySource);
if (!debug) {
return false;
bool binarySource = cx->realm()->debuggerObservesBinarySource();
maybeDebug = cx->make_unique<DebugState>(*code, *this, binarySource);
if (!maybeDebug) {
return false;
}
} else {
code = code_;
}
instance.set(WasmInstanceObject::create(cx,
code,
dataSegments_,
elemSegments_,
std::move(debug),
std::move(tlsData),
memory,
std::move(tables),
@ -1070,7 +1067,8 @@ Module::instantiate(JSContext* cx,
metadata().globals,
globalImportValues,
globalObjs,
instanceProto));
instanceProto,
std::move(maybeDebug)));
if (!instance) {
return false;
}

Просмотреть файл

@ -48,13 +48,13 @@ struct CompileArgs;
class Module : public JS::WasmModule
{
const SharedCode code_;
const ImportVector imports_;
const ExportVector exports_;
const StructTypeVector structTypes_;
const DataSegmentVector dataSegments_;
const ElemSegmentVector elemSegments_;
const SharedBytes bytecode_;
const SharedCode code_;
const ImportVector imports_;
const ExportVector exports_;
const StructTypeVector structTypes_;
const DataSegmentVector dataSegments_;
const ElemSegmentVector elemSegments_;
const CustomSectionVector customSections_;
// These fields are only meaningful when code_->metadata().debugEnabled.
// `debugCodeClaimed_` is set to false initially and then to true when
@ -67,6 +67,7 @@ class Module : public JS::WasmModule
mutable Atomic<bool> debugCodeClaimed_;
const UniqueConstBytes debugUnlinkedCode_;
const UniqueLinkData debugLinkData_;
const SharedBytes debugBytecode_;
// This flag is only used for testing purposes and is racily updated as soon
// as tier-2 compilation finishes (in success or failure).
@ -96,19 +97,21 @@ class Module : public JS::WasmModule
StructTypeVector&& structTypes,
DataSegmentVector&& dataSegments,
ElemSegmentVector&& elemSegments,
const ShareableBytes& bytecode,
CustomSectionVector&& customSections,
UniqueConstBytes debugUnlinkedCode = nullptr,
UniqueLinkData debugLinkData = nullptr)
UniqueLinkData debugLinkData = nullptr,
const ShareableBytes* debugBytecode = nullptr)
: code_(&code),
imports_(std::move(imports)),
exports_(std::move(exports)),
structTypes_(std::move(structTypes)),
dataSegments_(std::move(dataSegments)),
elemSegments_(std::move(elemSegments)),
bytecode_(&bytecode),
customSections_(std::move(customSections)),
debugCodeClaimed_(false),
debugUnlinkedCode_(std::move(debugUnlinkedCode)),
debugLinkData_(std::move(debugLinkData)),
debugBytecode_(debugBytecode),
testingTier2Active_(false)
{
MOZ_ASSERT_IF(metadata().debugEnabled, debugUnlinkedCode_ && debugLinkData_);
@ -121,7 +124,8 @@ class Module : public JS::WasmModule
const MetadataTier& metadata(Tier t) const { return code_->metadata(t); }
const ImportVector& imports() const { return imports_; }
const ExportVector& exports() const { return exports_; }
const ShareableBytes& bytecode() const { return *bytecode_; }
const CustomSectionVector& customSections() const { return customSections_; }
const Bytes& debugBytecode() const { return debugBytecode_->bytes; }
uint32_t codeLength(Tier t) const { return code_->segment(t).length(); }
// Instantiate this module with the given imports:
@ -140,8 +144,8 @@ class Module : public JS::WasmModule
// finishTier2() from a helper thread, passing tier-variant data which will
// be installed and made visible.
void startTier2(const CompileArgs& args);
bool finishTier2(const LinkData& linkData2, UniqueCodeTier code2);
void startTier2(const CompileArgs& args, const ShareableBytes& bytecode);
bool finishTier2(const LinkData& linkData2, UniqueCodeTier code2) const;
void testingBlockOnTier2Complete() const;
bool testingTier2Active() const { return testingTier2Active_; }
@ -171,11 +175,12 @@ class Module : public JS::WasmModule
bool extractCode(JSContext* cx, Tier tier, MutableHandleValue vp) const;
};
typedef RefPtr<Module> SharedModule;
typedef RefPtr<Module> MutableModule;
typedef RefPtr<const Module> SharedModule;
// JS API implementations:
SharedModule
RefPtr<JS::WasmModule>
DeserializeModule(PRFileDesc* bytecode, UniqueChars filename, unsigned line);
} // namespace wasm

Просмотреть файл

@ -73,7 +73,7 @@ wasm::Realm::registerInstance(JSContext* cx, HandleWasmInstanceObject instanceOb
instance.ensureProfilingLabels(cx->runtime()->geckoProfiler().enabled());
if (instance.debugEnabled() && instance.realm()->debuggerObservesAllExecution()) {
instance.ensureEnterFrameTrapsState(cx, true);
instance.debug().ensureEnterFrameTrapsState(cx, true);
}
{

Просмотреть файл

@ -517,6 +517,50 @@ DataSegment::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
return bytes.sizeOfExcludingThis(mallocSizeOf);
}
size_t
CustomSection::serializedSize() const
{
return SerializedPodVectorSize(name) +
SerializedPodVectorSize(payload->bytes);
}
uint8_t*
CustomSection::serialize(uint8_t* cursor) const
{
cursor = SerializePodVector(cursor, name);
cursor = SerializePodVector(cursor, payload->bytes);
return cursor;
}
const uint8_t*
CustomSection::deserialize(const uint8_t* cursor)
{
cursor = DeserializePodVector(cursor, &name);
if (!cursor) {
return nullptr;
}
Bytes bytes;
cursor = DeserializePodVector(cursor, &bytes);
if (!cursor) {
return nullptr;
}
payload = js_new<ShareableBytes>(std::move(bytes));
if (!payload) {
return nullptr;
}
return cursor;
}
size_t
CustomSection::sizeOfExcludingThis(MallocSizeOf mallocSizeOf) const
{
return name.sizeOfExcludingThis(mallocSizeOf) +
sizeof(*payload) +
payload->sizeOfExcludingThis(mallocSizeOf);
}
// Heap length on ARM should fit in an ARM immediate. We approximate the set
// of valid ARM immediates with the predicate:
// 2^n for n in [16, 24)
@ -922,8 +966,6 @@ wasm::LookupInSorted(const CodeRangeVector& codeRanges, CodeRange::OffsetInCode
UniqueTlsData
wasm::CreateTlsData(uint32_t globalDataLength)
{
MOZ_ASSERT(globalDataLength % gc::SystemPageSize() == 0);
void* allocatedBase = js_calloc(TlsDataAlign + offsetof(TlsData, globalArea) + globalDataLength);
if (!allocatedBase) {
return nullptr;

Просмотреть файл

@ -1179,6 +1179,48 @@ typedef RefPtr<DataSegment> MutableDataSegment;
typedef SerializableRefPtr<const DataSegment> SharedDataSegment;
typedef Vector<SharedDataSegment, 0, SystemAllocPolicy> DataSegmentVector;
// The CustomSection(Env) structs are like DataSegment(Env): CustomSectionEnv is
// stored in the ModuleEnvironment and CustomSection holds a copy of the payload
// and is stored in the wasm::Module.
struct CustomSectionEnv
{
uint32_t nameOffset;
uint32_t nameLength;
uint32_t payloadOffset;
uint32_t payloadLength;
};
typedef Vector<CustomSectionEnv, 0, SystemAllocPolicy> CustomSectionEnvVector;
struct CustomSection
{
Bytes name;
SharedBytes payload;
WASM_DECLARE_SERIALIZABLE(CustomSection)
};
typedef Vector<CustomSection, 0, SystemAllocPolicy> CustomSectionVector;
// A Name represents a string of utf8 chars embedded within the name custom
// section. The offset of a name is expressed relative to the beginning of the
// name section's payload so that Names can stored in wasm::Code, which only
// holds the name section's bytes, not the whole bytecode.
struct Name
{
// All fields are treated as cacheable POD:
uint32_t offsetInNamePayload;
uint32_t length;
Name()
: offsetInNamePayload(UINT32_MAX), length(0)
{}
};
typedef Vector<Name, 0, SystemAllocPolicy> NameVector;
// FuncTypeIdDesc describes a function type that can be used by call_indirect
// and table-entry prologues to structurally compare whether the caller and
// callee's signatures *structurally* match. To handle the general case, a

Просмотреть файл

@ -204,29 +204,32 @@ Decoder::startCustomSection(const char* expected, size_t expectedLength, ModuleE
goto fail;
}
NameInBytecode name;
if (!readVarU32(&name.length) || name.length > bytesRemain()) {
CustomSectionEnv sec;
if (!readVarU32(&sec.nameLength) || sec.nameLength > bytesRemain()) {
goto fail;
}
name.offset = currentOffset();
uint32_t payloadOffset = name.offset + name.length;
sec.nameOffset = currentOffset();
sec.payloadOffset = sec.nameOffset + sec.nameLength;
uint32_t payloadEnd = (*range)->start + (*range)->size;
if (payloadOffset > payloadEnd) {
if (sec.payloadOffset > payloadEnd) {
goto fail;
}
sec.payloadLength = payloadEnd - sec.payloadOffset;
// Now that we have a valid custom section, record its offsets in the
// metadata which can be queried by the user via Module.customSections.
// Note: after an entry is appended, it may be popped if this loop or
// the loop in startSection needs to rewind.
if (!env->customSections.emplaceBack(name, payloadOffset, payloadEnd - payloadOffset)) {
if (!env->customSections.append(sec)) {
return false;
}
// If this is the expected custom section, we're done.
if (!expected || (expectedLength == name.length && !memcmp(cur_, expected, name.length))) {
cur_ += name.length;
if (!expected || (expectedLength == sec.nameLength && !memcmp(cur_, expected, sec.nameLength))) {
cur_ += sec.nameLength;
return true;
}
@ -2505,7 +2508,7 @@ DecodeDataSection(Decoder& d, ModuleEnvironment* env)
}
static bool
DecodeModuleNameSubsection(Decoder& d, ModuleEnvironment* env)
DecodeModuleNameSubsection(Decoder& d, const CustomSectionEnv& nameSection, ModuleEnvironment* env)
{
Maybe<uint32_t> endOffset;
if (!d.startNameSubsection(NameType::Module, &endOffset)) {
@ -2515,20 +2518,16 @@ DecodeModuleNameSubsection(Decoder& d, ModuleEnvironment* env)
return true;
}
// Don't use NameInBytecode for module name; instead store a copy of the
// string. This way supplying a module name doesn't need to save the whole
// bytecode. While function names are likely to be stripped in practice,
// module names aren't necessarily.
uint32_t nameLength;
if (!d.readVarU32(&nameLength)) {
Name moduleName;
if (!d.readVarU32(&moduleName.length)) {
return d.fail("failed to read module name length");
}
NameInBytecode moduleName(d.currentOffset(), nameLength);
MOZ_ASSERT(d.currentOffset() >= nameSection.payloadOffset);
moduleName.offsetInNamePayload = d.currentOffset() - nameSection.payloadOffset;
const uint8_t* bytes;
if (!d.readBytes(nameLength, &bytes)) {
if (!d.readBytes(moduleName.length, &bytes)) {
return d.fail("failed to read module name bytes");
}
@ -2538,7 +2537,7 @@ DecodeModuleNameSubsection(Decoder& d, ModuleEnvironment* env)
}
static bool
DecodeFunctionNameSubsection(Decoder& d, ModuleEnvironment* env)
DecodeFunctionNameSubsection(Decoder& d, const CustomSectionEnv& nameSection, ModuleEnvironment* env)
{
Maybe<uint32_t> endOffset;
if (!d.startNameSubsection(NameType::Function, &endOffset)) {
@ -2553,7 +2552,7 @@ DecodeFunctionNameSubsection(Decoder& d, ModuleEnvironment* env)
return d.fail("bad function name count");
}
NameInBytecodeVector funcNames;
NameVector funcNames;
for (uint32_t i = 0; i < nameCount; ++i) {
uint32_t funcIndex = 0;
@ -2566,12 +2565,12 @@ DecodeFunctionNameSubsection(Decoder& d, ModuleEnvironment* env)
return d.fail("invalid function index");
}
uint32_t nameLength = 0;
if (!d.readVarU32(&nameLength) || nameLength > MaxStringLength) {
Name funcName;
if (!d.readVarU32(&funcName.length) || funcName.length > MaxStringLength) {
return d.fail("unable to read function name length");
}
if (!nameLength) {
if (!funcName.length) {
continue;
}
@ -2579,9 +2578,10 @@ DecodeFunctionNameSubsection(Decoder& d, ModuleEnvironment* env)
return false;
}
NameInBytecode funcName(d.currentOffset(), nameLength);
MOZ_ASSERT(d.currentOffset() >= nameSection.payloadOffset);
funcName.offsetInNamePayload = d.currentOffset() - nameSection.payloadOffset;
if (!d.readBytes(nameLength)) {
if (!d.readBytes(funcName.length)) {
return d.fail("unable to read function name bytes");
}
@ -2609,13 +2609,16 @@ DecodeNameSection(Decoder& d, ModuleEnvironment* env)
return true;
}
env->nameCustomSectionIndex = Some(env->customSections.length() - 1);
const CustomSectionEnv& nameSection = env->customSections.back();
// Once started, custom sections do not report validation errors.
if (!DecodeModuleNameSubsection(d, env)) {
if (!DecodeModuleNameSubsection(d, nameSection, env)) {
goto finish;
}
if (!DecodeFunctionNameSubsection(d, env)) {
if (!DecodeFunctionNameSubsection(d, nameSection, env)) {
goto finish;
}

Просмотреть файл

@ -179,9 +179,10 @@ struct ModuleEnvironment
// Fields decoded as part of the wasm module tail:
DataSegmentEnvVector dataSegments;
Maybe<NameInBytecode> moduleName;
NameInBytecodeVector funcNames;
CustomSectionVector customSections;
CustomSectionEnvVector customSections;
Maybe<uint32_t> nameCustomSectionIndex;
Maybe<Name> moduleName;
NameVector funcNames;
explicit ModuleEnvironment(HasGcTypes gcTypesConfigured,
CompilerEnvironment* compilerEnv,
@ -436,7 +437,7 @@ class Encoder
}
// A "section" is a contiguous range of bytes that stores its own size so
// that it may be trivially skipped without examining the contents. Sections
// that it may be trivially skipped without examining the payload. Sections
// require backpatching since the size of the section is only known at the
// end while the size's varU32 must be stored at the beginning. Immediately
// after the section length is the string id of the section.

Просмотреть файл

@ -323,6 +323,26 @@ nsBlockFrame::~nsBlockFrame()
{
}
void
nsBlockFrame::AddSizeOfExcludingThisForTree(nsWindowSizes& aWindowSizes) const
{
nsContainerFrame::AddSizeOfExcludingThisForTree(aWindowSizes);
// Add the size of any nsLineBox::mFrames hashtables we might have:
for (ConstLineIterator line = LinesBegin(), line_end = LinesEnd();
line != line_end; ++line) {
line->AddSizeOfExcludingThis(aWindowSizes);
}
const FrameLines* overflowLines = GetOverflowLines();
if (overflowLines) {
ConstLineIterator line = overflowLines->mLines.begin(),
line_end = overflowLines->mLines.end();
for (; line != line_end; ++line) {
line->AddSizeOfExcludingThis(aWindowSizes);
}
}
}
void
nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData)
{

Просмотреть файл

@ -595,6 +595,10 @@ public:
int32_t aDepth,
int32_t aIncrement,
bool aForCounting) override;
// @see nsIFrame::AddSizeOfExcludingThisForTree
void AddSizeOfExcludingThisForTree(nsWindowSizes&) const override;
protected:
/** @see DoRemoveFrame */
void DoRemoveFrameInternal(nsIFrame* aDeletedFrame, uint32_t aFlags,

Просмотреть файл

@ -3610,7 +3610,7 @@ public:
// nsIFrames themselves are in the nsPresArena, and so are not measured here.
// Instead, this measures heap-allocated things hanging off the nsIFrame, and
// likewise for its descendants.
void AddSizeOfExcludingThisForTree(nsWindowSizes& aWindowSizes) const;
virtual void AddSizeOfExcludingThisForTree(nsWindowSizes& aWindowSizes) const;
/**
* Return true if and only if this frame obeys visibility:hidden.

Просмотреть файл

@ -11,13 +11,14 @@
#include "mozilla/ArenaObjectID.h"
#include "mozilla/Assertions.h"
#include "mozilla/Likely.h"
#include "mozilla/Sprintf.h"
#include "mozilla/WritingModes.h"
#include "nsBidiPresUtils.h"
#include "nsFrame.h"
#include "nsIFrameInlines.h"
#include "nsPresArena.h"
#include "nsPrintfCString.h"
#include "mozilla/Sprintf.h"
#include "nsWindowSizes.h"
#ifdef DEBUG
static int32_t ctorCount;
@ -93,6 +94,15 @@ NS_NewLineBox(nsIPresShell* aPresShell, nsLineBox* aFromLine,
return newLine;
}
void
nsLineBox::AddSizeOfExcludingThis(nsWindowSizes& aSizes) const
{
if (mFlags.mHasHashedFrames) {
aSizes.mLayoutFramePropertiesSize +=
mFrames->ShallowSizeOfIncludingThis(aSizes.mState.mMallocSizeOf);
}
}
void
nsLineBox::StealHashTableFrom(nsLineBox* aFromLine, uint32_t aFromLineNewCount)
{

Просмотреть файл

@ -20,6 +20,7 @@ class nsLineBox;
class nsFloatCache;
class nsFloatCacheList;
class nsFloatCacheFreeList;
class nsWindowSizes;
// State cached after reflowing a float. This state is used during
// incremental reflow when we avoid reflowing a float.
@ -582,6 +583,8 @@ public:
nsIFrame* LastChild() const;
#endif
void AddSizeOfExcludingThis(nsWindowSizes& aSizes) const;
private:
int32_t IndexOf(nsIFrame* aFrame) const;
public:

Просмотреть файл

@ -2578,6 +2578,8 @@ pref("security.notification_enable_delay", 500);
#if defined(DEBUG) && !defined(ANDROID)
pref("csp.content_privileged_about_uris_without_csp", "blank,printpreview,srcdoc");
// the following pref is for testing purposes only.
pref("csp.overrule_content_privileged_about_uris_without_csp_whitelist", false);
#endif
// Default Content Security Policy to apply to signed contents.

Просмотреть файл

@ -1206,7 +1206,7 @@ class BootstrapScope {
}
update(data, reason) {
Management.emit("update", {id: data.id, resourceURI: data.resourceURI});
return Management.emit("update", {id: data.id, resourceURI: data.resourceURI});
}
startup(data, reason) {

Просмотреть файл

@ -23,7 +23,7 @@
</binding>
<binding id="basetext" extends="chrome://global/content/bindings/general.xml#basecontrol">
<implementation implements="nsIDOMXULLabeledControlElement">
<implementation>
<!-- public implementation -->
<property name="label" onset="this.setAttribute('label',val); return val;"
onget="return this.getAttribute('label');"/>

Просмотреть файл

@ -70,7 +70,7 @@
var control = this.labeledControlElement;
if (!control) {
var bindingParent = document.getBindingParent(this);
if (bindingParent instanceof Ci.nsIDOMXULLabeledControlElement) {
if ("accessKey" in bindingParent) {
control = bindingParent; // For controls that make the <label> an anon child
}
}

Просмотреть файл

@ -32,7 +32,7 @@
</xul:moz-input-box>
</content>
<implementation implements="nsIDOMXULLabeledControlElement">
<implementation>
<!-- nsIDOMXULLabeledControlElement -->
<field name="crop">""</field>
<field name="image">""</field>

Просмотреть файл

@ -1797,6 +1797,10 @@ class AddonInstall {
if (this.existingAddon) {
await XPIInternal.BootstrapScope.get(this.existingAddon).update(
this.addon, !this.addon.disabled, install);
if (this.addon.disabled) {
flushJarCache(this.file);
}
} else {
await install();
await XPIInternal.BootstrapScope.get(this.addon).install(undefined, true);

Просмотреть файл

@ -1768,7 +1768,7 @@ class BootstrapScope {
async _install(reason, callUpdate, startup, extraArgs) {
if (callUpdate) {
this.callBootstrapMethod("update", reason, extraArgs);
await this.callBootstrapMethod("update", reason, extraArgs);
} else {
this.callBootstrapMethod("install", reason, extraArgs);
}