Merge inbound to mozilla-central r=merge a=merge

This commit is contained in:
Coroiu Cristina 2017-11-12 00:05:11 +02:00
Родитель 8d0fc743e2 49c97adb4e
Коммит 230207fe30
24 изменённых файлов: 578 добавлений и 105 удалений

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

@ -1,7 +1,7 @@
This is the debugger.html project output.
See https://github.com/devtools-html/debugger.html
Taken from upstream commit: be179268c9b89390c13bdc9c4cca6000f6f583e5
Taken from upstream commit: 09d6d4f93135367b2639d78ad884434f73ab449c
Packages:
- babel-plugin-transform-es2015-modules-commonjs @6.26.0

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

@ -3739,5 +3739,3 @@ html[dir="rtl"] .dropdown {
.theme-dark .result-list {
background-color: var(--theme-body-background);
}
/*# sourceMappingURL=debugger.css.map*/

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

@ -17612,7 +17612,7 @@ const {
isOriginalId
} = __webpack_require__(1389);
const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1363);
const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1390);
const dispatcher = new WorkerDispatcher();
@ -18277,9 +18277,9 @@ WorkerDispatcher.prototype = {
}
if (!this.worker) {
reject("Oops, The worker has shutdown!");
return;
}
this.worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
@ -20810,9 +20810,181 @@ module.exports = {
};
/***/ }),
/* 1390 */,
/* 1391 */,
/* 1392 */,
/* 1390 */
/***/ (function(module, exports, __webpack_require__) {
/* 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/. */
const networkRequest = __webpack_require__(1391);
const workerUtils = __webpack_require__(1392);
module.exports = {
networkRequest,
workerUtils
};
/***/ }),
/* 1391 */
/***/ (function(module, exports) {
/* 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/. */
function networkRequest(url, opts) {
return fetch(url, {
cache: opts.loadFromCache ? "default" : "no-cache"
}).then(res => {
if (res.status >= 200 && res.status < 300) {
return res.text().then(text => ({ content: text }));
}
return Promise.reject(`request failed with status ${res.status}`);
});
}
module.exports = networkRequest;
/***/ }),
/* 1392 */
/***/ (function(module, exports) {
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
function WorkerDispatcher() {
this.msgId = 1;
this.worker = null;
} /* 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/. */
WorkerDispatcher.prototype = {
start(url) {
this.worker = new Worker(url);
this.worker.onerror = () => {
console.error(`Error in worker ${url}`);
};
},
stop() {
if (!this.worker) {
return;
}
this.worker.terminate();
this.worker = null;
},
task(method) {
return (...args) => {
return new Promise((resolve, reject) => {
const id = this.msgId++;
this.worker.postMessage({ id, method, args });
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
if (!this.worker) {
reject("Oops, The worker has shutdown!");
return;
}
this.worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
} else {
resolve(result.response);
}
};
this.worker.addEventListener("message", listener);
});
};
}
};
function workerHandler(publicInterface) {
return function (msg) {
const { id, method, args } = msg.data;
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
response.then(val => self.postMessage({ id, response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => self.postMessage({ id, error: err.toString() }));
} else {
self.postMessage({ id, response });
}
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
self.postMessage({ id, error: error.toString() });
}
};
}
function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker = self) {
let streamingWorker = (() => {
var _ref = _asyncToGenerator(function* (id, tasks) {
let isWorking = true;
const intervalId = setTimeout(function () {
isWorking = false;
}, timeout);
const results = [];
while (tasks.length !== 0 && isWorking) {
const { callback, context, args } = tasks.shift();
const result = yield callback.call(context, args);
results.push(result);
}
worker.postMessage({ id, status: "pending", data: results });
clearInterval(intervalId);
if (tasks.length !== 0) {
yield streamingWorker(id, tasks);
}
});
return function streamingWorker(_x, _x2) {
return _ref.apply(this, arguments);
};
})();
return (() => {
var _ref2 = _asyncToGenerator(function* (msg) {
const { id, method, args } = msg.data;
const workerMethod = publicInterface[method];
if (!workerMethod) {
console.error(`Could not find ${method} defined in worker.`);
}
worker.postMessage({ id, status: "start" });
try {
const tasks = workerMethod(args);
yield streamingWorker(id, tasks);
worker.postMessage({ id, status: "done" });
} catch (error) {
worker.postMessage({ id, status: "error", error });
}
});
return function (_x3) {
return _ref2.apply(this, arguments);
};
})();
}
module.exports = {
WorkerDispatcher,
workerHandler,
streamingWorkerHandler
};
/***/ }),
/* 1393 */
/***/ (function(module, exports, __webpack_require__) {
@ -21820,6 +21992,9 @@ function setSymbols(sourceId) {
source,
symbols
});
dispatch(setEmptyLines(source.id));
dispatch(setSourceMetaData(source.id));
};
}
@ -24782,9 +24957,7 @@ function loadSourceText(source) {
}
await (0, _parser.setSource)(newSource);
await dispatch((0, _ast.setSymbols)(source.id));
await dispatch((0, _ast.setEmptyLines)(source.id));
await dispatch((0, _ast.setSourceMetaData)(source.id));
dispatch((0, _ast.setSymbols)(source.id));
};
}
@ -45768,4 +45941,3 @@ function timing(store) {
/***/ })
/******/ ]);
});
//# sourceMappingURL=debugger.js.map

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

@ -35432,9 +35432,9 @@ WorkerDispatcher.prototype = {
}
if (!this.worker) {
reject("Oops, The worker has shutdown!");
return;
}
this.worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
@ -41825,4 +41825,3 @@ function extendsComponent(classes) {
/***/ })
/******/ ]);
});
//# sourceMappingURL=parser-worker.js.map

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

@ -163,9 +163,9 @@ WorkerDispatcher.prototype = {
}
if (!this.worker) {
reject("Oops, The worker has shutdown!");
return;
}
this.worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
@ -7592,4 +7592,3 @@ exports.SourceNode = SourceNode;
/******/ });
});
//# sourceMappingURL=pretty-print-worker.js.map

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

@ -746,7 +746,7 @@ const {
isOriginalId
} = __webpack_require__(1389);
const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1363);
const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1390);
const dispatcher = new WorkerDispatcher();
@ -945,9 +945,9 @@ WorkerDispatcher.prototype = {
}
if (!this.worker) {
reject("Oops, The worker has shutdown!");
return;
}
this.worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
@ -1124,6 +1124,184 @@ module.exports = {
/***/ }),
/***/ 1390:
/***/ (function(module, exports, __webpack_require__) {
/* 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/. */
const networkRequest = __webpack_require__(1391);
const workerUtils = __webpack_require__(1392);
module.exports = {
networkRequest,
workerUtils
};
/***/ }),
/***/ 1391:
/***/ (function(module, exports) {
/* 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/. */
function networkRequest(url, opts) {
return fetch(url, {
cache: opts.loadFromCache ? "default" : "no-cache"
}).then(res => {
if (res.status >= 200 && res.status < 300) {
return res.text().then(text => ({ content: text }));
}
return Promise.reject(`request failed with status ${res.status}`);
});
}
module.exports = networkRequest;
/***/ }),
/***/ 1392:
/***/ (function(module, exports) {
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
function WorkerDispatcher() {
this.msgId = 1;
this.worker = null;
} /* 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/. */
WorkerDispatcher.prototype = {
start(url) {
this.worker = new Worker(url);
this.worker.onerror = () => {
console.error(`Error in worker ${url}`);
};
},
stop() {
if (!this.worker) {
return;
}
this.worker.terminate();
this.worker = null;
},
task(method) {
return (...args) => {
return new Promise((resolve, reject) => {
const id = this.msgId++;
this.worker.postMessage({ id, method, args });
const listener = ({ data: result }) => {
if (result.id !== id) {
return;
}
if (!this.worker) {
reject("Oops, The worker has shutdown!");
return;
}
this.worker.removeEventListener("message", listener);
if (result.error) {
reject(result.error);
} else {
resolve(result.response);
}
};
this.worker.addEventListener("message", listener);
});
};
}
};
function workerHandler(publicInterface) {
return function (msg) {
const { id, method, args } = msg.data;
try {
const response = publicInterface[method].apply(undefined, args);
if (response instanceof Promise) {
response.then(val => self.postMessage({ id, response: val }),
// Error can't be sent via postMessage, so be sure to
// convert to string.
err => self.postMessage({ id, error: err.toString() }));
} else {
self.postMessage({ id, response });
}
} catch (error) {
// Error can't be sent via postMessage, so be sure to convert to
// string.
self.postMessage({ id, error: error.toString() });
}
};
}
function streamingWorkerHandler(publicInterface, { timeout = 100 } = {}, worker = self) {
let streamingWorker = (() => {
var _ref = _asyncToGenerator(function* (id, tasks) {
let isWorking = true;
const intervalId = setTimeout(function () {
isWorking = false;
}, timeout);
const results = [];
while (tasks.length !== 0 && isWorking) {
const { callback, context, args } = tasks.shift();
const result = yield callback.call(context, args);
results.push(result);
}
worker.postMessage({ id, status: "pending", data: results });
clearInterval(intervalId);
if (tasks.length !== 0) {
yield streamingWorker(id, tasks);
}
});
return function streamingWorker(_x, _x2) {
return _ref.apply(this, arguments);
};
})();
return (() => {
var _ref2 = _asyncToGenerator(function* (msg) {
const { id, method, args } = msg.data;
const workerMethod = publicInterface[method];
if (!workerMethod) {
console.error(`Could not find ${method} defined in worker.`);
}
worker.postMessage({ id, status: "start" });
try {
const tasks = workerMethod(args);
yield streamingWorker(id, tasks);
worker.postMessage({ id, status: "done" });
} catch (error) {
worker.postMessage({ id, status: "error", error });
}
});
return function (_x3) {
return _ref2.apply(this, arguments);
};
})();
}
module.exports = {
WorkerDispatcher,
workerHandler,
streamingWorkerHandler
};
/***/ }),
/***/ 1393:
/***/ (function(module, exports, __webpack_require__) {
@ -3294,4 +3472,3 @@ module.exports = freeGlobal;
/******/ });
});
//# sourceMappingURL=search-worker.js.map

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

@ -101,6 +101,19 @@ void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname)
return reinterpret_cast<void*>(p);
}
void
gecko_profiler_register_thread(const char* name)
{
char stackTop;
profiler_register_thread(name, &stackTop);
}
void
gecko_profiler_unregister_thread()
{
profiler_unregister_thread();
}
namespace mozilla {
namespace layers {

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

@ -244,6 +244,8 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
uint32_t aLength,
CTRunRef aCTRun)
{
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
int32_t direction = aShapedText->IsRightToLeft() ? -1 : 1;
int32_t numGlyphs = ::CTRunGetGlyphCount(aCTRun);
@ -319,8 +321,7 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
nullptr, nullptr, nullptr);
AutoTArray<gfxShapedText::DetailedGlyph,1> detailedGlyphs;
gfxShapedText::CompressedGlyph *charGlyphs =
aShapedText->GetCharacterGlyphs() + aOffset;
CompressedGlyph* charGlyphs = aShapedText->GetCharacterGlyphs() + aOffset;
// CoreText gives us the glyphindex-to-charindex mapping, which relates each glyph
// to a source text character; we also need the charindex-to-glyphindex mapping to
@ -540,10 +541,10 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
advance = int32_t(toNextGlyph * appUnitsPerDevUnit);
}
gfxTextRun::CompressedGlyph textRunGlyph;
textRunGlyph.SetComplex(charGlyphs[baseCharIndex].IsClusterStart(),
true, detailedGlyphs.Length());
aShapedText->SetGlyphs(aOffset + baseCharIndex, textRunGlyph,
bool isClusterStart = charGlyphs[baseCharIndex].IsClusterStart();
aShapedText->SetGlyphs(aOffset + baseCharIndex,
CompressedGlyph::MakeComplex(isClusterStart, true,
detailedGlyphs.Length()),
detailedGlyphs.Elements());
detailedGlyphs.Clear();
@ -551,7 +552,7 @@ gfxCoreTextShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
// the rest of the chars in the group are ligature continuations, no associated glyphs
while (++baseCharIndex != endCharIndex && baseCharIndex < wordLength) {
gfxShapedText::CompressedGlyph &shapedTextGlyph = charGlyphs[baseCharIndex];
CompressedGlyph &shapedTextGlyph = charGlyphs[baseCharIndex];
NS_ASSERTION(!shapedTextGlyph.IsSimpleGlyph(), "overwriting a simple glyph");
shapedTextGlyph.SetComplex(inOrder && shapedTextGlyph.IsClusterStart(), false, 0);
}

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

@ -66,13 +66,14 @@ void
gfxFT2Font::AddRange(const char16_t *aText, uint32_t aOffset,
uint32_t aLength, gfxShapedText *aShapedText)
{
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
const uint32_t appUnitsPerDevUnit = aShapedText->GetAppUnitsPerDevUnit();
// we'll pass this in/figure it out dynamically, but at this point there can be only one face.
gfxFT2LockedFace faceLock(this);
FT_Face face = faceLock.get();
gfxShapedText::CompressedGlyph *charGlyphs =
aShapedText->GetCharacterGlyphs();
CompressedGlyph* charGlyphs = aShapedText->GetCharacterGlyphs();
const gfxFT2Font::CachedGlyphData *cgd = nullptr, *cgdNext = nullptr;
@ -139,8 +140,8 @@ gfxFT2Font::AddRange(const char16_t *aText, uint32_t aOffset,
}
if (advance >= 0 &&
gfxShapedText::CompressedGlyph::IsSimpleAdvance(advance) &&
gfxShapedText::CompressedGlyph::IsSimpleGlyphID(gid)) {
CompressedGlyph::IsSimpleAdvance(advance) &&
CompressedGlyph::IsSimpleGlyphID(gid)) {
charGlyphs[aOffset].SetSimpleGlyph(advance, gid);
} else if (gid == 0) {
// gid = 0 only happens when the glyph is missing from the font
@ -151,9 +152,11 @@ gfxFT2Font::AddRange(const char16_t *aText, uint32_t aOffset,
NS_ASSERTION(details.mGlyphID == gid,
"Seriously weird glyph ID detected!");
details.mAdvance = advance;
gfxShapedText::CompressedGlyph g;
g.SetComplex(charGlyphs[aOffset].IsClusterStart(), true, 1);
aShapedText->SetGlyphs(aOffset, g, &details);
bool isClusterStart = charGlyphs[aOffset].IsClusterStart();
aShapedText->SetGlyphs(aOffset,
CompressedGlyph::MakeComplex(isClusterStart,
true, 1),
&details);
}
}
}

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

@ -573,8 +573,8 @@ gfxShapedText::SetupClusterBoundaries(uint32_t aOffset,
{
CompressedGlyph* glyphs = GetCharacterGlyphs() + aOffset;
gfxTextRun::CompressedGlyph extendCluster;
extendCluster.SetComplex(false, true, 0);
CompressedGlyph extendCluster =
CompressedGlyph::MakeComplex(false, true, 0);
ClusterIterator iter(aString, aLength);

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

@ -763,8 +763,6 @@ public:
*/
class CompressedGlyph {
public:
CompressedGlyph() { mValue = 0; }
enum {
// Indicates that a cluster and ligature group starts at this
// character; this character has a single glyph with a reasonable
@ -894,25 +892,52 @@ public:
return toggle;
}
CompressedGlyph& SetSimpleGlyph(uint32_t aAdvanceAppUnits, uint32_t aGlyph) {
// Create a CompressedGlyph value representing a simple glyph with
// no extra flags (line-break or is_space) set.
static CompressedGlyph
MakeSimpleGlyph(uint32_t aAdvanceAppUnits, uint32_t aGlyph) {
NS_ASSERTION(IsSimpleAdvance(aAdvanceAppUnits), "Advance overflow");
NS_ASSERTION(IsSimpleGlyphID(aGlyph), "Glyph overflow");
CompressedGlyph g;
g.mValue = FLAG_IS_SIMPLE_GLYPH |
(aAdvanceAppUnits << ADVANCE_SHIFT) |
aGlyph;
return g;
}
// Assign a simple glyph value to an existing CompressedGlyph record,
// preserving line-break/is-space flags if present.
CompressedGlyph& SetSimpleGlyph(uint32_t aAdvanceAppUnits,
uint32_t aGlyph) {
NS_ASSERTION(!CharTypeFlags(), "Char type flags lost");
mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) |
FLAG_IS_SIMPLE_GLYPH |
(aAdvanceAppUnits << ADVANCE_SHIFT) | aGlyph;
MakeSimpleGlyph(aAdvanceAppUnits, aGlyph).mValue;
return *this;
}
CompressedGlyph& SetComplex(bool aClusterStart, bool aLigatureStart,
// Create a CompressedGlyph value representing a complex glyph record,
// without any line-break or char-type flags.
static CompressedGlyph
MakeComplex(bool aClusterStart, bool aLigatureStart,
uint32_t aGlyphCount) {
mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) |
FLAG_NOT_MISSING |
CharTypeFlags() |
CompressedGlyph g;
g.mValue = FLAG_NOT_MISSING |
(aClusterStart ? 0 : FLAG_NOT_CLUSTER_START) |
(aLigatureStart ? 0 : FLAG_NOT_LIGATURE_GROUP_START) |
(aGlyphCount << GLYPH_COUNT_SHIFT);
return g;
}
// Assign a complex glyph value to an existing CompressedGlyph record,
// preserving line-break/char-type flags if present.
CompressedGlyph& SetComplex(bool aClusterStart, bool aLigatureStart,
uint32_t aGlyphCount) {
mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) |
CharTypeFlags() |
MakeComplex(aClusterStart, aLigatureStart, aGlyphCount).mValue;
return *this;
}
/**
* Missing glyphs are treated as ligature group starts; don't mess with
* the cluster-start flag (see bugs 618870 and 619286).

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

@ -216,6 +216,8 @@ gfxGraphiteShaper::SetGlyphsFromSegment(gfxShapedText *aShapedText,
gr_segment *aSegment,
RoundingFlags aRounding)
{
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
int32_t dev2appUnits = aShapedText->GetAppUnitsPerDevUnit();
bool rtl = aShapedText->IsRightToLeft();
@ -289,8 +291,7 @@ gfxGraphiteShaper::SetGlyphsFromSegment(gfxShapedText *aShapedText,
}
}
gfxShapedText::CompressedGlyph *charGlyphs =
aShapedText->GetCharacterGlyphs() + aOffset;
CompressedGlyph* charGlyphs = aShapedText->GetCharacterGlyphs() + aOffset;
bool roundX = bool(aRounding & RoundingFlags::kRoundX);
bool roundY = bool(aRounding & RoundingFlags::kRoundY);
@ -326,8 +327,8 @@ gfxGraphiteShaper::SetGlyphsFromSegment(gfxShapedText *aShapedText,
uint32_t appAdvance = roundX ? NSToIntRound(adv) * dev2appUnits
: NSToIntRound(adv * dev2appUnits);
if (c.nGlyphs == 1 &&
gfxShapedText::CompressedGlyph::IsSimpleGlyphID(gids[c.baseGlyph]) &&
gfxShapedText::CompressedGlyph::IsSimpleAdvance(appAdvance) &&
CompressedGlyph::IsSimpleGlyphID(gids[c.baseGlyph]) &&
CompressedGlyph::IsSimpleAdvance(appAdvance) &&
charGlyphs[offs].IsClusterStart() &&
yLocs[c.baseGlyph] == 0)
{
@ -352,15 +353,17 @@ gfxGraphiteShaper::SetGlyphsFromSegment(gfxShapedText *aShapedText,
d->mAdvance = 0;
}
}
gfxShapedText::CompressedGlyph g;
g.SetComplex(charGlyphs[offs].IsClusterStart(),
true, details.Length());
aShapedText->SetGlyphs(aOffset + offs, g, details.Elements());
bool isClusterStart = charGlyphs[offs].IsClusterStart();
aShapedText->SetGlyphs(aOffset + offs,
CompressedGlyph::MakeComplex(isClusterStart,
true,
details.Length()),
details.Elements());
}
for (uint32_t j = c.baseChar + 1; j < c.baseChar + c.nChars; ++j) {
NS_ASSERTION(j < aLength, "unexpected offset");
gfxShapedText::CompressedGlyph &g = charGlyphs[j];
CompressedGlyph &g = charGlyphs[j];
NS_ASSERTION(!g.IsSimpleGlyph(), "overwriting a simple glyph");
g.SetComplex(g.IsClusterStart(), false, 0);
}

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

@ -1529,6 +1529,8 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
bool aVertical,
RoundingFlags aRounding)
{
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
uint32_t numGlyphs;
const hb_glyph_info_t *ginfo = hb_buffer_get_glyph_infos(mBuffer, &numGlyphs);
if (numGlyphs == 0) {
@ -1569,8 +1571,7 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
}
int32_t appUnitsPerDevUnit = aShapedText->GetAppUnitsPerDevUnit();
gfxShapedText::CompressedGlyph *charGlyphs =
aShapedText->GetCharacterGlyphs() + aOffset;
CompressedGlyph* charGlyphs = aShapedText->GetCharacterGlyphs() + aOffset;
// factor to convert 16.16 fixed-point pixels to app units
// (only used if not rounding)
@ -1718,8 +1719,8 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
}
// Check if it's a simple one-to-one mapping
if (glyphsInClump == 1 &&
gfxTextRun::CompressedGlyph::IsSimpleGlyphID(ginfo[glyphStart].codepoint) &&
gfxTextRun::CompressedGlyph::IsSimpleAdvance(advance) &&
CompressedGlyph::IsSimpleGlyphID(ginfo[glyphStart].codepoint) &&
CompressedGlyph::IsSimpleAdvance(advance) &&
charGlyphs[baseCharIndex].IsClusterStart() &&
iOffset == 0 && b_offset == 0 &&
b_advance == 0 && bPos == 0)
@ -1789,11 +1790,12 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
}
}
gfxShapedText::CompressedGlyph g;
g.SetComplex(charGlyphs[baseCharIndex].IsClusterStart(),
true, detailedGlyphs.Length());
bool isClusterStart = charGlyphs[baseCharIndex].IsClusterStart();
aShapedText->SetGlyphs(aOffset + baseCharIndex,
g, detailedGlyphs.Elements());
CompressedGlyph::MakeComplex(isClusterStart,
true,
detailedGlyphs.Length()),
detailedGlyphs.Elements());
detailedGlyphs.Clear();
}
@ -1802,7 +1804,7 @@ gfxHarfBuzzShaper::SetGlyphsFromRun(gfxShapedText *aShapedText,
// no associated glyphs
while (++baseCharIndex != endCharIndex &&
baseCharIndex < int32_t(wordLength)) {
gfxShapedText::CompressedGlyph &g = charGlyphs[baseCharIndex];
CompressedGlyph &g = charGlyphs[baseCharIndex];
NS_ASSERTION(!g.IsSimpleGlyph(), "overwriting a simple glyph");
g.SetComplex(g.IsClusterStart(), false, 0);
}

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

@ -1658,8 +1658,8 @@ gfxTextRun::SetSpaceGlyphIfSimple(gfxFont* aFont, uint32_t aCharIndex,
AddGlyphRun(aFont, gfxTextRange::kFontGroup, aCharIndex, false,
aOrientation);
CompressedGlyph g;
g.SetSimpleGlyph(spaceWidthAppUnits, spaceGlyph);
CompressedGlyph g =
CompressedGlyph::MakeSimpleGlyph(spaceWidthAppUnits, spaceGlyph);
if (aSpaceChar == ' ') {
g.SetIsSpace();
}
@ -2756,8 +2756,8 @@ gfxFontGroup::InitScriptRun(DrawTarget* aDrawTarget,
gfxTextRun::DetailedGlyph detailedGlyph;
detailedGlyph.mGlyphID = mainFont->GetSpaceGlyph();
detailedGlyph.mAdvance = advance;
gfxShapedText::CompressedGlyph g;
g.SetComplex(true, true, 1);
CompressedGlyph g =
CompressedGlyph::MakeComplex(true, true, 1);
aTextRun->SetGlyphs(aOffset + index,
g, &detailedGlyph);
}

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

@ -842,6 +842,7 @@ private:
class gfxFontGroup final : public gfxTextRunFactory {
public:
typedef mozilla::unicode::Script Script;
typedef gfxShapedText::CompressedGlyph CompressedGlyph;
static void Shutdown(); // platform must call this to release the languageAtomService

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

@ -7,7 +7,7 @@ use std::os::raw::{c_void, c_char, c_float};
use gleam::gl;
use webrender_api::*;
use webrender::{ReadPixelsFormat, Renderer, RendererOptions};
use webrender::{ReadPixelsFormat, Renderer, RendererOptions, ThreadListener};
use webrender::{ExternalImage, ExternalImageHandler, ExternalImageSource};
use webrender::DebugFlags;
use webrender::{ApiRecordingReceiver, BinaryRecorder};
@ -587,14 +587,48 @@ pub unsafe extern "C" fn wr_rendered_epochs_delete(pipeline_epochs: *mut WrRende
Box::from_raw(pipeline_epochs);
}
extern "C" {
fn gecko_profiler_register_thread(name: *const ::std::os::raw::c_char);
fn gecko_profiler_unregister_thread();
}
struct GeckoProfilerThreadListener {}
impl GeckoProfilerThreadListener {
pub fn new() -> GeckoProfilerThreadListener {
GeckoProfilerThreadListener{}
}
}
impl ThreadListener for GeckoProfilerThreadListener {
fn thread_started(&self, thread_name: &str) {
let name = CString::new(thread_name).unwrap();
unsafe {
// gecko_profiler_register_thread copies the passed name here.
gecko_profiler_register_thread(name.as_ptr());
}
}
fn thread_stopped(&self, _: &str) {
unsafe {
gecko_profiler_unregister_thread();
}
}
}
pub struct WrThreadPool(Arc<rayon::ThreadPool>);
#[no_mangle]
pub unsafe extern "C" fn wr_thread_pool_new() -> *mut WrThreadPool {
let worker_config = rayon::Configuration::new()
.thread_name(|idx|{ format!("WebRender:Worker#{}", idx) })
.thread_name(|idx|{ format!("WRWorker#{}", idx) })
.start_handler(|idx| {
register_thread_with_profiler(format!("WebRender:Worker#{}", idx));
let name = format!("WRWorker#{}", idx);
register_thread_with_profiler(name.clone());
gecko_profiler_register_thread(CString::new(name).unwrap().as_ptr());
})
.exit_handler(|_idx| {
gecko_profiler_unregister_thread();
});
let workers = Arc::new(rayon::ThreadPool::new(worker_config).unwrap());
@ -650,6 +684,7 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
recorder: recorder,
blob_image_renderer: Some(Box::new(Moz2dImageRenderer::new(workers.clone()))),
workers: Some(workers.clone()),
thread_listener: Some(Box::new(GeckoProfilerThreadListener::new())),
enable_render_on_scroll: false,
resource_override_path: unsafe {
let override_charptr = gfx_wr_resource_path_override();
@ -662,6 +697,7 @@ pub extern "C" fn wr_window_new(window_id: WrWindowId,
}
}
},
renderer_id: Some(window_id.0),
..Default::default()
};

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

@ -26,6 +26,8 @@ void gfx_critical_note(const char* msg);
void gfx_critical_error(const char* msg);
void gecko_printf_stderr_output(const char* msg);
void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname);
void gecko_profiler_register_thread(const char* threadname);
void gecko_profiler_unregister_thread();
} // extern "C"

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

@ -943,6 +943,10 @@ extern void DeleteFontData(WrFontKey aKey);
extern void gecko_printf_stderr_output(const char *aMsg);
extern void gecko_profiler_register_thread(const char *aName);
extern void gecko_profiler_unregister_thread();
extern void gfx_critical_error(const char *aMsg);
extern void gfx_critical_note(const char *aMsg);

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

@ -3673,7 +3673,8 @@ static bool
array_proto_finish(JSContext* cx, JS::HandleObject ctor, JS::HandleObject proto)
{
// Add Array.prototype[@@unscopables]. ECMA-262 draft (2016 Mar 19) 22.1.3.32.
RootedObject unscopables(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr, TenuredObject));
RootedObject unscopables(cx, NewObjectWithGivenProto<PlainObject>(cx, nullptr,
SingletonObject));
if (!unscopables)
return false;

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

@ -181,6 +181,7 @@ void counters_reset(int) {
static void
InstallCoverageSignalHandlers()
{
#ifndef XP_WIN
fprintf(stderr, "[CodeCoverage] Setting handlers for process %d.\n", getpid());
struct sigaction dump_sa;
@ -196,6 +197,7 @@ InstallCoverageSignalHandlers()
sigemptyset(&reset_sa.sa_mask);
mozilla::DebugOnly<int> r2 = sigaction(SIGUSR2, &reset_sa, nullptr);
MOZ_ASSERT(r2 == 0, "Failed to install GCOV SIGUSR2 handler");
#endif
}
#endif

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

@ -588,9 +588,9 @@ nsOpenTypeTable::MakeTextRun(DrawTarget* aDrawTarget,
NSToCoordRound(aAppUnitsPerDevPixel *
aFontGroup->GetFirstValidFont()->
GetGlyphHAdvance(aDrawTarget, aGlyph.glyphID));
gfxShapedText::CompressedGlyph g;
g.SetComplex(true, true, 1);
textRun->SetGlyphs(0, g, &detailedGlyph);
textRun->SetGlyphs(0,
gfxShapedText::CompressedGlyph::MakeComplex(true, true, 1),
&detailedGlyph);
return textRun.forget();
}

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

@ -0,0 +1,9 @@
[
{
"size": 271486,
"digest": "6956eb1cab16dff465861cd1966e3115f31b533334089553b8b94897bc138c6dec279bf7c60b34fe3fc67c8cb0d41e30f55982adaad07320090dab053e018dec",
"algorithm": "sha512",
"filename": "grcov-win-i686.tar.bz2",
"unpack": false
}
]

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

@ -5,8 +5,11 @@
import os
import shutil
import sys
import tarfile
import tempfile
import mozinfo
from mozharness.base.script import (
PreScriptAction,
PostScriptAction,
@ -50,7 +53,7 @@ class CodeCoverageMixin(object):
return True
# XXX workaround because bug 1110465 is hard
return self.buildbot_config['properties']['stage_platform'] in ('linux64-ccov',)
return 'ccov' in self.buildbot_config['properties']['stage_platform']
except (AttributeError, KeyError, TypeError):
return False
@ -70,7 +73,7 @@ class CodeCoverageMixin(object):
return True
# XXX workaround because bug 1110465 is hard
return self.buildbot_config['properties']['stage_platform'] in ('linux64-jsdcov',)
return 'jsdcov' in self.buildbot_config['properties']['stage_platform']
except (AttributeError, KeyError, TypeError):
return False
@ -94,15 +97,24 @@ class CodeCoverageMixin(object):
# Create the grcov directory, get the tooltool manifest, and finally
# download and unpack the grcov binary.
self.grcov_dir = tempfile.mkdtemp()
if mozinfo.os == 'linux':
platform = 'linux64'
tar_file = 'grcov-linux-standalone-x86_64.tar.bz2'
elif mozinfo.os == 'win':
platform = 'win32'
tar_file = 'grcov-win-i686.tar.bz2'
manifest = os.path.join(dirs.get('abs_test_install_dir', os.path.join(dirs['abs_work_dir'], 'tests')), \
'config/tooltool-manifests/linux64/ccov.manifest')
'config/tooltool-manifests/%s/ccov.manifest' % platform)
tooltool_path = self._fetch_tooltool_py()
cmd = [tooltool_path, '--url', 'https://tooltool.mozilla-releng.net/', 'fetch', \
cmd = [sys.executable, tooltool_path, '--url', 'https://tooltool.mozilla-releng.net/', 'fetch', \
'-m', manifest, '-o', '-c', '/builds/worker/tooltool-cache']
self.run_command(cmd, cwd=self.grcov_dir)
self.run_command(['tar', '-jxvf', os.path.join(self.grcov_dir, 'grcov-linux-standalone-x86_64.tar.bz2'), \
'-C', self.grcov_dir], cwd=self.grcov_dir)
with tarfile.open(os.path.join(self.grcov_dir, tar_file)) as tar:
tar.extractall(self.grcov_dir)
@PostScriptAction('run-tests')
def _package_coverage_data(self, action, success=None):
@ -126,6 +138,7 @@ class CodeCoverageMixin(object):
if not self.code_coverage_enabled:
return
del os.environ['GCOV_PREFIX']
del os.environ['JS_CODE_COVERAGE_OUTPUT_DIR']
@ -140,50 +153,59 @@ class CodeCoverageMixin(object):
if any(d in dirs for d in canary_dirs):
rel_topsrcdir = root
break
else:
if rel_topsrcdir is None:
# Unable to upload code coverage files. Since this is the whole
# point of code coverage, making this fatal.
self.fatal("Could not find relative topsrcdir in code coverage "
"data!")
self.fatal("Could not find relative topsrcdir in code coverage data!")
dirs = self.query_abs_dirs()
# Package GCOV coverage data.
dirs = self.query_abs_dirs()
file_path_gcda = os.path.join(
dirs['abs_blob_upload_dir'], 'code-coverage-gcda.zip')
command = ['zip', '-r', file_path_gcda, '.']
self.run_command(command, cwd=rel_topsrcdir)
file_path_gcda = os.path.join(dirs['abs_blob_upload_dir'], 'code-coverage-gcda.zip')
self.run_command(['zip', '-r', file_path_gcda, '.'], cwd=rel_topsrcdir)
# Package JSVM coverage data.
dirs = self.query_abs_dirs()
file_path_jsvm = os.path.join(
dirs['abs_blob_upload_dir'], 'code-coverage-jsvm.zip')
command = ['zip', '-r', file_path_jsvm, '.']
self.run_command(command, cwd=self.jsvm_dir)
file_path_jsvm = os.path.join(dirs['abs_blob_upload_dir'], 'code-coverage-jsvm.zip')
self.run_command(['zip', '-r', file_path_jsvm, '.'], cwd=self.jsvm_dir)
# GRCOV post-processing
# Download the gcno fom the build machine.
self.download_file(self.url_to_gcno, file_name=None, parent_dir=self.grcov_dir)
if mozinfo.os == 'linux':
prefix = '/builds/worker/workspace/build/src/'
elif mozinfo.os == 'win':
prefix = 'z:/build/build/src/'
# Run grcov on the zipped .gcno and .gcda files.
grcov_command = [
os.path.join(self.grcov_dir, 'grcov'),
'-t', 'lcov',
'-p', '/builds/worker/workspace/build/src/',
'-p', prefix,
'--ignore-dir', 'gcc',
os.path.join(self.grcov_dir, 'target.code-coverage-gcno.zip'), file_path_gcda
]
# 'grcov_output' will be a tuple, the first variable is the path to the lcov output,
# the other is the path to the standard error output.
grcov_output = self.get_output_from_command(grcov_command, cwd=self.grcov_dir, \
silent=True, tmpfile_base_path=os.path.join(self.grcov_dir, 'grcov_lcov_output'), \
save_tmpfiles=True, return_type='files')
grcov_output = self.get_output_from_command(
grcov_command,
cwd=self.grcov_dir,
silent=True,
tmpfile_base_path=os.path.join(self.grcov_dir, 'grcov_lcov_output'),
save_tmpfiles=True,
return_type='files'
)
new_output_name = grcov_output[0] + '.info'
os.rename(grcov_output[0], new_output_name)
# Zip the grcov output and upload it.
command = ['zip', os.path.join(dirs['abs_blob_upload_dir'], 'code-coverage-grcov.zip'), new_output_name]
self.run_command(command, cwd=self.grcov_dir)
self.run_command(
['zip', os.path.join(dirs['abs_blob_upload_dir'], 'code-coverage-grcov.zip'), new_output_name],
cwd=self.grcov_dir
)
shutil.rmtree(self.gcov_dir)
shutil.rmtree(self.jsvm_dir)
shutil.rmtree(self.grcov_dir)

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

@ -3,9 +3,11 @@
* 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 <signal.h>
#include <stdio.h>
#ifndef XP_WIN
#include <signal.h>
#include <unistd.h>
#endif
#include "mozilla/CodeCoverageHandler.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/DebugOnly.h"
@ -62,6 +64,7 @@ void CodeCoverageHandler::ResetCounters(int)
void CodeCoverageHandler::SetSignalHandlers()
{
#ifndef XP_WIN
printf_stderr("[CodeCoverage] Setting handlers for process %d.\n", getpid());
struct sigaction dump_sa;
@ -77,6 +80,7 @@ void CodeCoverageHandler::SetSignalHandlers()
sigemptyset(&reset_sa.sa_mask);
DebugOnly<int> r2 = sigaction(SIGUSR2, &reset_sa, nullptr);
MOZ_ASSERT(r2 == 0, "Failed to install GCOV SIGUSR2 handler");
#endif
}
CodeCoverageHandler::CodeCoverageHandler()