mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
perf: cache node resolution when accesing a global (#19930)
Reclaims some of the performance hit introduced by https://github.com/denoland/deno/pull/19307.
This commit is contained in:
parent
5d8d1105a4
commit
06209f824c
4 changed files with 86 additions and 9 deletions
|
@ -1,9 +1,6 @@
|
|||
[WILDCARD]package.json file found at '[WILDCARD]with_package_json[WILDCARD]npm_binary[WILDCARD]package.json'
|
||||
[WILDCARD]
|
||||
this
|
||||
[WILDCARD]
|
||||
is
|
||||
[WILDCARD]
|
||||
a
|
||||
[WILDCARD]
|
||||
test
|
||||
|
|
|
@ -5,10 +5,42 @@ pub use inner::*;
|
|||
#[cfg(feature = "sync_fs")]
|
||||
mod inner {
|
||||
#![allow(clippy::disallowed_types)]
|
||||
|
||||
use std::ops::Deref;
|
||||
use std::ops::DerefMut;
|
||||
pub use std::sync::Arc as MaybeArc;
|
||||
|
||||
pub use core::marker::Send as MaybeSend;
|
||||
pub use core::marker::Sync as MaybeSync;
|
||||
|
||||
pub struct MaybeArcMutexGuard<'lock, T>(std::sync::MutexGuard<'lock, T>);
|
||||
|
||||
impl<'lock, T> Deref for MaybeArcMutexGuard<'lock, T> {
|
||||
type Target = std::sync::MutexGuard<'lock, T>;
|
||||
fn deref(&self) -> &std::sync::MutexGuard<'lock, T> {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lock, T> DerefMut for MaybeArcMutexGuard<'lock, T> {
|
||||
fn deref_mut(&mut self) -> &mut std::sync::MutexGuard<'lock, T> {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MaybeArcMutex<T>(std::sync::Arc<std::sync::Mutex<T>>);
|
||||
impl<T> MaybeArcMutex<T> {
|
||||
pub fn new(val: T) -> Self {
|
||||
Self(std::sync::Arc::new(std::sync::Mutex::new(val)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lock, T> MaybeArcMutex<T> {
|
||||
pub fn lock(&'lock self) -> MaybeArcMutexGuard<'lock, T> {
|
||||
MaybeArcMutexGuard(self.0.lock().unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "sync_fs"))]
|
||||
|
@ -19,4 +51,33 @@ mod inner {
|
|||
impl<T> MaybeSync for T where T: ?Sized {}
|
||||
pub trait MaybeSend {}
|
||||
impl<T> MaybeSend for T where T: ?Sized {}
|
||||
|
||||
pub struct MaybeArcMutexGuard<'lock, T>(std::cell::RefMut<'lock, T>);
|
||||
|
||||
impl<'lock, T> Deref for MaybeArcMutexGuard<'lock, T> {
|
||||
type Target = std::cell::RefMut<'lock, T>;
|
||||
fn deref(&self) -> &std::cell::RefMut<'lock, T> {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lock, T> DerefMut for MaybeArcMutexGuard<'lock, T> {
|
||||
fn deref_mut(&mut self) -> &mut std::cell::RefMut<'lock, T> {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MaybeArcMutex<T>(std::rc::Rc<std::cell::RefCell<T>>);
|
||||
impl<T> MaybeArcMutex<T> {
|
||||
pub fn new(val: T) -> Self {
|
||||
Self(std::rc::Rc::new(std::cell::RefCell::new(val)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lock, T> MaybeArcMutex<T> {
|
||||
pub fn lock(&'lock self) -> MaybeArcMutexGuard<'lock, T> {
|
||||
MaybeArcMutexGuard(self.0.borrow_mut())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -267,16 +267,12 @@ fn current_mode(scope: &mut v8::HandleScope) -> Mode {
|
|||
return Mode::Deno;
|
||||
};
|
||||
let string = v8_string.to_rust_string_lossy(scope);
|
||||
// TODO: don't require parsing the specifier
|
||||
let Ok(specifier) = deno_core::ModuleSpecifier::parse(&string) else {
|
||||
return Mode::Deno;
|
||||
};
|
||||
let op_state = deno_core::JsRuntime::op_state_from(scope);
|
||||
let op_state = op_state.borrow();
|
||||
let Some(node_resolver) = op_state.try_borrow::<Rc<NodeResolver>>() else {
|
||||
return Mode::Deno;
|
||||
};
|
||||
if node_resolver.in_npm_package(&specifier) {
|
||||
if node_resolver.in_npm_package_with_cache(string) {
|
||||
Mode::Node
|
||||
} else {
|
||||
Mode::Deno
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
|
||||
|
@ -111,17 +112,39 @@ pub type NodeResolverRc = deno_fs::sync::MaybeArc<NodeResolver>;
|
|||
pub struct NodeResolver {
|
||||
fs: FileSystemRc,
|
||||
npm_resolver: NpmResolverRc,
|
||||
in_npm_package_cache: deno_fs::sync::MaybeArcMutex<HashMap<String, bool>>,
|
||||
}
|
||||
|
||||
impl NodeResolver {
|
||||
pub fn new(fs: FileSystemRc, npm_resolver: NpmResolverRc) -> Self {
|
||||
Self { fs, npm_resolver }
|
||||
Self {
|
||||
fs,
|
||||
npm_resolver,
|
||||
in_npm_package_cache: deno_fs::sync::MaybeArcMutex::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn in_npm_package(&self, specifier: &ModuleSpecifier) -> bool {
|
||||
self.npm_resolver.in_npm_package(specifier)
|
||||
}
|
||||
|
||||
pub fn in_npm_package_with_cache(&self, specifier: String) -> bool {
|
||||
let mut cache = self.in_npm_package_cache.lock();
|
||||
|
||||
if let Some(result) = cache.get(&specifier) {
|
||||
return *result;
|
||||
}
|
||||
|
||||
let result =
|
||||
if let Ok(specifier) = deno_core::ModuleSpecifier::parse(&specifier) {
|
||||
self.npm_resolver.in_npm_package(&specifier)
|
||||
} else {
|
||||
false
|
||||
};
|
||||
cache.insert(specifier, result);
|
||||
result
|
||||
}
|
||||
|
||||
/// This function is an implementation of `defaultResolve` in
|
||||
/// `lib/internal/modules/esm/resolve.js` from Node.
|
||||
pub fn resolve(
|
||||
|
|
Loading…
Add table
Reference in a new issue