forked from extern/nushell
Box ShellError
in Value::Error
(#8375)
# Description Our `ShellError` at the moment has a `std::mem::size_of<ShellError>` of 136 bytes (on AMD64). As a result `Value` directly storing the struct also required 136 bytes (thanks to alignment requirements). This change stores the `Value::Error` `ShellError` on the heap. Pro: - Value now needs just 80 bytes - Should be 1 cacheline less (still at least 2 cachelines) Con: - More small heap allocations when dealing with `Value::Error` - More heap fragmentation - Potential for additional required memcopies # Further code changes Includes a small refactor of `try` due to a type mismatch in its large match. # User-Facing Changes None for regular users. Plugin authors may have to update their matches on `Value` if they use `nu-protocol` Needs benchmarking to see if there is a benefit in real world workloads. **Update** small improvements in runtime for workloads with high volume of values. Significant reduction in maximum resident set size, when many values are held in memory. # Tests + Formatting
This commit is contained in:
committed by
GitHub
parent
c26d91fb61
commit
a52386e837
@@ -111,7 +111,7 @@ fn exists(path: &Path, span: Span, args: &Arguments) -> Value {
|
||||
Ok(exists) => exists,
|
||||
Err(err) => {
|
||||
return Value::Error {
|
||||
error: ShellError::IOErrorSpanned(err.to_string(), span),
|
||||
error: Box::new(ShellError::IOErrorSpanned(err.to_string(), span)),
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -136,7 +136,7 @@ fn expand(path: &Path, span: Span, args: &Arguments) -> Value {
|
||||
}
|
||||
}
|
||||
Err(_) => Value::Error {
|
||||
error: ShellError::GenericError(
|
||||
error: Box::new(ShellError::GenericError(
|
||||
"Could not expand path".into(),
|
||||
"could not be expanded (path might not exist, non-final \
|
||||
component is not a directory, or other cause)"
|
||||
@@ -144,7 +144,7 @@ fn expand(path: &Path, span: Span, args: &Arguments) -> Value {
|
||||
Some(span),
|
||||
None,
|
||||
Vec::new(),
|
||||
),
|
||||
)),
|
||||
},
|
||||
}
|
||||
} else if args.not_follow_symlink {
|
||||
|
@@ -197,11 +197,11 @@ fn join_list(parts: &[Value], head: Span, span: Span, args: &Arguments) -> Value
|
||||
Value::List { vals, span }
|
||||
}
|
||||
Err(_) => Value::Error {
|
||||
error: ShellError::PipelineMismatch {
|
||||
error: Box::new(ShellError::PipelineMismatch {
|
||||
exp_input_type: "string or record".into(),
|
||||
dst_span: head,
|
||||
src_span: span,
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -223,7 +223,9 @@ fn join_record(cols: &[String], vals: &[Value], head: Span, span: Span, args: &A
|
||||
} else {
|
||||
match merge_record(cols, vals, head, span) {
|
||||
Ok(p) => join_single(p.as_path(), head, args),
|
||||
Err(error) => Value::Error { error },
|
||||
Err(error) => Value::Error {
|
||||
error: Box::new(error),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -48,12 +48,12 @@ where
|
||||
};
|
||||
if col.is_empty() {
|
||||
return Value::Error {
|
||||
error: ShellError::UnsupportedInput(
|
||||
error: Box::new(ShellError::UnsupportedInput(
|
||||
String::from("when the input is a table, you must specify the columns"),
|
||||
"value originates from here".into(),
|
||||
name,
|
||||
span,
|
||||
),
|
||||
)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ where
|
||||
|
||||
fn handle_invalid_values(rest: Value, name: Span) -> Value {
|
||||
Value::Error {
|
||||
error: err_from_value(&rest, name),
|
||||
error: Box::new(err_from_value(&rest, name)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -128,12 +128,12 @@ fn relative_to(path: &Path, span: Span, args: &Arguments) -> Value {
|
||||
match lhs.strip_prefix(&rhs) {
|
||||
Ok(p) => Value::string(p.to_string_lossy(), span),
|
||||
Err(e) => Value::Error {
|
||||
error: ShellError::CantConvert {
|
||||
error: Box::new(ShellError::CantConvert {
|
||||
to_type: e.to_string(),
|
||||
from_type: "string".into(),
|
||||
span,
|
||||
help: None,
|
||||
},
|
||||
}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user