зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to mozilla-central r=merge a=merge
This commit is contained in:
Коммит
230207fe30
|
@ -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()
|
||||
|
|
Загрузка…
Ссылка в новой задаче