mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Re-enable native module cache
This commit is contained in:
116
src/native-compile-cache.js
Normal file
116
src/native-compile-cache.js
Normal file
@@ -0,0 +1,116 @@
|
||||
const Module = require('module')
|
||||
const path = require('path')
|
||||
const cachedVm = require('cached-run-in-this-context')
|
||||
const crypto = require('crypto')
|
||||
|
||||
function computeHash (contents) {
|
||||
return crypto.createHash('sha1').update(contents, 'utf8').digest('hex')
|
||||
}
|
||||
|
||||
class NativeCompileCache {
|
||||
constructor () {
|
||||
this.cacheStore = null
|
||||
this.previousModuleCompile = null
|
||||
}
|
||||
|
||||
setCacheStore (store) {
|
||||
this.cacheStore = store
|
||||
}
|
||||
|
||||
setV8Version (v8Version) {
|
||||
this.v8Version = v8Version.toString()
|
||||
}
|
||||
|
||||
install () {
|
||||
this.savePreviousModuleCompile()
|
||||
this.overrideModuleCompile()
|
||||
}
|
||||
|
||||
uninstall () {
|
||||
this.restorePreviousModuleCompile()
|
||||
}
|
||||
|
||||
savePreviousModuleCompile () {
|
||||
this.previousModuleCompile = Module.prototype._compile
|
||||
}
|
||||
|
||||
overrideModuleCompile () {
|
||||
let self = this
|
||||
let resolvedArgv = null
|
||||
// Here we override Node's module.js
|
||||
// (https://github.com/atom/node/blob/atom/lib/module.js#L378), changing
|
||||
// only the bits that affect compilation in order to use the cached one.
|
||||
Module.prototype._compile = function (content, filename) {
|
||||
let moduleSelf = this
|
||||
// remove shebang
|
||||
content = content.replace(/^#!.*/, '')
|
||||
function require (path) {
|
||||
return moduleSelf.require(path)
|
||||
}
|
||||
require.resolve = function (request) {
|
||||
return Module._resolveFilename(request, moduleSelf)
|
||||
}
|
||||
require.main = process.mainModule
|
||||
|
||||
// Enable support to add extra extension types
|
||||
require.extensions = Module._extensions
|
||||
require.cache = Module._cache
|
||||
|
||||
let dirname = path.dirname(filename)
|
||||
|
||||
// create wrapper function
|
||||
let wrapper = Module.wrap(content)
|
||||
|
||||
let cacheKey = filename
|
||||
let invalidationKey = computeHash(wrapper + self.v8Version)
|
||||
let compiledWrapper = null
|
||||
if (self.cacheStore.has(cacheKey, invalidationKey)) {
|
||||
let buffer = self.cacheStore.get(cacheKey, invalidationKey)
|
||||
let compilationResult = cachedVm.runInThisContextCached(wrapper, filename, buffer)
|
||||
compiledWrapper = compilationResult.result
|
||||
if (compilationResult.wasRejected) {
|
||||
self.cacheStore.delete(cacheKey)
|
||||
}
|
||||
} else {
|
||||
let compilationResult
|
||||
try {
|
||||
compilationResult = cachedVm.runInThisContext(wrapper, filename)
|
||||
} catch (err) {
|
||||
console.error(`Error running script ${filename}`)
|
||||
throw err
|
||||
}
|
||||
if (compilationResult.cacheBuffer) {
|
||||
self.cacheStore.set(cacheKey, invalidationKey, compilationResult.cacheBuffer)
|
||||
}
|
||||
compiledWrapper = compilationResult.result
|
||||
}
|
||||
if (global.v8debug) {
|
||||
if (!resolvedArgv) {
|
||||
// we enter the repl if we're not given a filename argument.
|
||||
if (process.argv[1]) {
|
||||
resolvedArgv = Module._resolveFilename(process.argv[1], null)
|
||||
} else {
|
||||
resolvedArgv = 'repl'
|
||||
}
|
||||
}
|
||||
|
||||
// Set breakpoint on module start
|
||||
if (filename === resolvedArgv) {
|
||||
// Installing this dummy debug event listener tells V8 to start
|
||||
// the debugger. Without it, the setBreakPoint() fails with an
|
||||
// 'illegal access' error.
|
||||
global.v8debug.Debug.setListener(function () {})
|
||||
global.v8debug.Debug.setBreakPoint(compiledWrapper, 0, 0)
|
||||
}
|
||||
}
|
||||
let args = [moduleSelf.exports, require, moduleSelf, filename, dirname, process, global]
|
||||
return compiledWrapper.apply(moduleSelf.exports, args)
|
||||
}
|
||||
}
|
||||
|
||||
restorePreviousModuleCompile () {
|
||||
Module.prototype._compile = this.previousModuleCompile
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = new NativeCompileCache()
|
||||
Reference in New Issue
Block a user