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

This commit is contained in:
Coroiu Cristina 2017-11-12 00:05:11 +02:00
commit 230207fe30
24 changed files with 578 additions and 105 deletions

View File

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

View File

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

View File

@ -17612,7 +17612,7 @@ const {
isOriginalId isOriginalId
} = __webpack_require__(1389); } = __webpack_require__(1389);
const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1363); const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1390);
const dispatcher = new WorkerDispatcher(); const dispatcher = new WorkerDispatcher();
@ -18277,9 +18277,9 @@ WorkerDispatcher.prototype = {
} }
if (!this.worker) { if (!this.worker) {
reject("Oops, The worker has shutdown!");
return; return;
} }
this.worker.removeEventListener("message", listener); this.worker.removeEventListener("message", listener);
if (result.error) { if (result.error) {
reject(result.error); reject(result.error);
@ -20810,9 +20810,181 @@ module.exports = {
}; };
/***/ }), /***/ }),
/* 1390 */, /* 1390 */
/* 1391 */, /***/ (function(module, exports, __webpack_require__) {
/* 1392 */,
/* 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 */ /* 1393 */
/***/ (function(module, exports, __webpack_require__) { /***/ (function(module, exports, __webpack_require__) {
@ -21820,6 +21992,9 @@ function setSymbols(sourceId) {
source, source,
symbols symbols
}); });
dispatch(setEmptyLines(source.id));
dispatch(setSourceMetaData(source.id));
}; };
} }
@ -24782,9 +24957,7 @@ function loadSourceText(source) {
} }
await (0, _parser.setSource)(newSource); await (0, _parser.setSource)(newSource);
await dispatch((0, _ast.setSymbols)(source.id)); dispatch((0, _ast.setSymbols)(source.id));
await dispatch((0, _ast.setEmptyLines)(source.id));
await dispatch((0, _ast.setSourceMetaData)(source.id));
}; };
} }
@ -45767,5 +45940,4 @@ function timing(store) {
/***/ }) /***/ })
/******/ ]); /******/ ]);
}); });
//# sourceMappingURL=debugger.js.map

View File

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

View File

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

View File

@ -746,7 +746,7 @@ const {
isOriginalId isOriginalId
} = __webpack_require__(1389); } = __webpack_require__(1389);
const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1363); const { workerUtils: { WorkerDispatcher } } = __webpack_require__(1390);
const dispatcher = new WorkerDispatcher(); const dispatcher = new WorkerDispatcher();
@ -945,9 +945,9 @@ WorkerDispatcher.prototype = {
} }
if (!this.worker) { if (!this.worker) {
reject("Oops, The worker has shutdown!");
return; return;
} }
this.worker.removeEventListener("message", listener); this.worker.removeEventListener("message", listener);
if (result.error) { if (result.error) {
reject(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: /***/ 1393:
/***/ (function(module, exports, __webpack_require__) { /***/ (function(module, exports, __webpack_require__) {
@ -3293,5 +3471,4 @@ module.exports = freeGlobal;
/***/ }) /***/ })
/******/ }); /******/ });
}); });
//# sourceMappingURL=search-worker.js.map

View File

@ -101,6 +101,19 @@ void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname)
return reinterpret_cast<void*>(p); 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 mozilla {
namespace layers { namespace layers {

View File

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

View File

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

View File

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

View File

@ -763,8 +763,6 @@ public:
*/ */
class CompressedGlyph { class CompressedGlyph {
public: public:
CompressedGlyph() { mValue = 0; }
enum { enum {
// Indicates that a cluster and ligature group starts at this // Indicates that a cluster and ligature group starts at this
// character; this character has a single glyph with a reasonable // character; this character has a single glyph with a reasonable
@ -894,25 +892,52 @@ public:
return toggle; 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(IsSimpleAdvance(aAdvanceAppUnits), "Advance overflow");
NS_ASSERTION(IsSimpleGlyphID(aGlyph), "Glyph 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"); NS_ASSERTION(!CharTypeFlags(), "Char type flags lost");
mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) | mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) |
FLAG_IS_SIMPLE_GLYPH | MakeSimpleGlyph(aAdvanceAppUnits, aGlyph).mValue;
(aAdvanceAppUnits << ADVANCE_SHIFT) | aGlyph;
return *this; return *this;
} }
// 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) {
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, CompressedGlyph& SetComplex(bool aClusterStart, bool aLigatureStart,
uint32_t aGlyphCount) { uint32_t aGlyphCount) {
mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) | mValue = (mValue & (FLAGS_CAN_BREAK_BEFORE | FLAG_CHAR_IS_SPACE)) |
FLAG_NOT_MISSING |
CharTypeFlags() | CharTypeFlags() |
(aClusterStart ? 0 : FLAG_NOT_CLUSTER_START) | MakeComplex(aClusterStart, aLigatureStart, aGlyphCount).mValue;
(aLigatureStart ? 0 : FLAG_NOT_LIGATURE_GROUP_START) |
(aGlyphCount << GLYPH_COUNT_SHIFT);
return *this; return *this;
} }
/** /**
* Missing glyphs are treated as ligature group starts; don't mess with * Missing glyphs are treated as ligature group starts; don't mess with
* the cluster-start flag (see bugs 618870 and 619286). * the cluster-start flag (see bugs 618870 and 619286).

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@ use std::os::raw::{c_void, c_char, c_float};
use gleam::gl; use gleam::gl;
use webrender_api::*; use webrender_api::*;
use webrender::{ReadPixelsFormat, Renderer, RendererOptions}; use webrender::{ReadPixelsFormat, Renderer, RendererOptions, ThreadListener};
use webrender::{ExternalImage, ExternalImageHandler, ExternalImageSource}; use webrender::{ExternalImage, ExternalImageHandler, ExternalImageSource};
use webrender::DebugFlags; use webrender::DebugFlags;
use webrender::{ApiRecordingReceiver, BinaryRecorder}; 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); 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>); pub struct WrThreadPool(Arc<rayon::ThreadPool>);
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn wr_thread_pool_new() -> *mut WrThreadPool { pub unsafe extern "C" fn wr_thread_pool_new() -> *mut WrThreadPool {
let worker_config = rayon::Configuration::new() let worker_config = rayon::Configuration::new()
.thread_name(|idx|{ format!("WebRender:Worker#{}", idx) }) .thread_name(|idx|{ format!("WRWorker#{}", idx) })
.start_handler(|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()); 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, recorder: recorder,
blob_image_renderer: Some(Box::new(Moz2dImageRenderer::new(workers.clone()))), blob_image_renderer: Some(Box::new(Moz2dImageRenderer::new(workers.clone()))),
workers: Some(workers.clone()), workers: Some(workers.clone()),
thread_listener: Some(Box::new(GeckoProfilerThreadListener::new())),
enable_render_on_scroll: false, enable_render_on_scroll: false,
resource_override_path: unsafe { resource_override_path: unsafe {
let override_charptr = gfx_wr_resource_path_override(); 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() ..Default::default()
}; };

View File

@ -26,6 +26,8 @@ void gfx_critical_note(const char* msg);
void gfx_critical_error(const char* msg); void gfx_critical_error(const char* msg);
void gecko_printf_stderr_output(const char* msg); void gecko_printf_stderr_output(const char* msg);
void* get_proc_address_from_glcontext(void* glcontext_ptr, const char* procname); 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" } // extern "C"

View File

@ -943,6 +943,10 @@ extern void DeleteFontData(WrFontKey aKey);
extern void gecko_printf_stderr_output(const char *aMsg); 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_error(const char *aMsg);
extern void gfx_critical_note(const char *aMsg); extern void gfx_critical_note(const char *aMsg);

View File

@ -3673,7 +3673,8 @@ static bool
array_proto_finish(JSContext* cx, JS::HandleObject ctor, JS::HandleObject proto) 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. // 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) if (!unscopables)
return false; return false;

View File

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

View File

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

View File

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

View File

@ -5,8 +5,11 @@
import os import os
import shutil import shutil
import sys
import tarfile
import tempfile import tempfile
import mozinfo
from mozharness.base.script import ( from mozharness.base.script import (
PreScriptAction, PreScriptAction,
PostScriptAction, PostScriptAction,
@ -50,7 +53,7 @@ class CodeCoverageMixin(object):
return True return True
# XXX workaround because bug 1110465 is hard # 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): except (AttributeError, KeyError, TypeError):
return False return False
@ -70,7 +73,7 @@ class CodeCoverageMixin(object):
return True return True
# XXX workaround because bug 1110465 is hard # 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): except (AttributeError, KeyError, TypeError):
return False return False
@ -94,15 +97,24 @@ class CodeCoverageMixin(object):
# Create the grcov directory, get the tooltool manifest, and finally # Create the grcov directory, get the tooltool manifest, and finally
# download and unpack the grcov binary. # download and unpack the grcov binary.
self.grcov_dir = tempfile.mkdtemp() 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')), \ 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() 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'] '-m', manifest, '-o', '-c', '/builds/worker/tooltool-cache']
self.run_command(cmd, cwd=self.grcov_dir) 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') @PostScriptAction('run-tests')
def _package_coverage_data(self, action, success=None): def _package_coverage_data(self, action, success=None):
@ -126,6 +138,7 @@ class CodeCoverageMixin(object):
if not self.code_coverage_enabled: if not self.code_coverage_enabled:
return return
del os.environ['GCOV_PREFIX'] del os.environ['GCOV_PREFIX']
del os.environ['JS_CODE_COVERAGE_OUTPUT_DIR'] 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): if any(d in dirs for d in canary_dirs):
rel_topsrcdir = root rel_topsrcdir = root
break break
else:
if rel_topsrcdir is None:
# Unable to upload code coverage files. Since this is the whole # Unable to upload code coverage files. Since this is the whole
# point of code coverage, making this fatal. # point of code coverage, making this fatal.
self.fatal("Could not find relative topsrcdir in code coverage " self.fatal("Could not find relative topsrcdir in code coverage data!")
"data!")
dirs = self.query_abs_dirs()
# Package GCOV coverage data. # Package GCOV coverage data.
dirs = self.query_abs_dirs() file_path_gcda = os.path.join(dirs['abs_blob_upload_dir'], 'code-coverage-gcda.zip')
file_path_gcda = os.path.join( self.run_command(['zip', '-r', file_path_gcda, '.'], cwd=rel_topsrcdir)
dirs['abs_blob_upload_dir'], 'code-coverage-gcda.zip')
command = ['zip', '-r', file_path_gcda, '.']
self.run_command(command, cwd=rel_topsrcdir)
# Package JSVM coverage data. # Package JSVM coverage data.
dirs = self.query_abs_dirs() file_path_jsvm = os.path.join(dirs['abs_blob_upload_dir'], 'code-coverage-jsvm.zip')
file_path_jsvm = os.path.join( self.run_command(['zip', '-r', file_path_jsvm, '.'], cwd=self.jsvm_dir)
dirs['abs_blob_upload_dir'], 'code-coverage-jsvm.zip')
command = ['zip', '-r', file_path_jsvm, '.']
self.run_command(command, cwd=self.jsvm_dir)
# GRCOV post-processing # GRCOV post-processing
# Download the gcno fom the build machine. # Download the gcno fom the build machine.
self.download_file(self.url_to_gcno, file_name=None, parent_dir=self.grcov_dir) 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. # Run grcov on the zipped .gcno and .gcda files.
grcov_command = [ grcov_command = [
os.path.join(self.grcov_dir, 'grcov'), os.path.join(self.grcov_dir, 'grcov'),
'-t', 'lcov', '-t', 'lcov',
'-p', '/builds/worker/workspace/build/src/', '-p', prefix,
'--ignore-dir', 'gcc', '--ignore-dir', 'gcc',
os.path.join(self.grcov_dir, 'target.code-coverage-gcno.zip'), file_path_gcda 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, # '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. # the other is the path to the standard error output.
grcov_output = self.get_output_from_command(grcov_command, cwd=self.grcov_dir, \ grcov_output = self.get_output_from_command(
silent=True, tmpfile_base_path=os.path.join(self.grcov_dir, 'grcov_lcov_output'), \ grcov_command,
save_tmpfiles=True, return_type='files') 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' new_output_name = grcov_output[0] + '.info'
os.rename(grcov_output[0], new_output_name) os.rename(grcov_output[0], new_output_name)
# Zip the grcov output and upload it. # 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(
self.run_command(command, cwd=self.grcov_dir) ['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.gcov_dir)
shutil.rmtree(self.jsvm_dir) shutil.rmtree(self.jsvm_dir)
shutil.rmtree(self.grcov_dir) shutil.rmtree(self.grcov_dir)

View File

@ -3,9 +3,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file, * 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/. */ * You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <signal.h>
#include <stdio.h> #include <stdio.h>
#ifndef XP_WIN
#include <signal.h>
#include <unistd.h> #include <unistd.h>
#endif
#include "mozilla/CodeCoverageHandler.h" #include "mozilla/CodeCoverageHandler.h"
#include "mozilla/ClearOnShutdown.h" #include "mozilla/ClearOnShutdown.h"
#include "mozilla/DebugOnly.h" #include "mozilla/DebugOnly.h"
@ -62,6 +64,7 @@ void CodeCoverageHandler::ResetCounters(int)
void CodeCoverageHandler::SetSignalHandlers() void CodeCoverageHandler::SetSignalHandlers()
{ {
#ifndef XP_WIN
printf_stderr("[CodeCoverage] Setting handlers for process %d.\n", getpid()); printf_stderr("[CodeCoverage] Setting handlers for process %d.\n", getpid());
struct sigaction dump_sa; struct sigaction dump_sa;
@ -77,6 +80,7 @@ void CodeCoverageHandler::SetSignalHandlers()
sigemptyset(&reset_sa.sa_mask); sigemptyset(&reset_sa.sa_mask);
DebugOnly<int> r2 = sigaction(SIGUSR2, &reset_sa, nullptr); DebugOnly<int> r2 = sigaction(SIGUSR2, &reset_sa, nullptr);
MOZ_ASSERT(r2 == 0, "Failed to install GCOV SIGUSR2 handler"); MOZ_ASSERT(r2 == 0, "Failed to install GCOV SIGUSR2 handler");
#endif
} }
CodeCoverageHandler::CodeCoverageHandler() CodeCoverageHandler::CodeCoverageHandler()