Skip to content

Commit 71150ff

Browse files
trop[bot]ckerr
andauthored
perf: have ErrorThrower lazily lookup the current isolate (#46417)
perf: have ErrorThrower lazy-lookup the current isolate ErrorThrower's default constructor is marked as "should rarely if ever be used" because it's expensive to call. Unfortunately, nearly every instance of ErrorThrower comes as an argument in gin_helper's JS-->C++ function marshalling where a thrower is default-constructed and then populated in gin_helper::GetNextArgument() with an assignment operator to a temporary ErrorThrower constructed with the gin::Arguments' isolate. tldr: most of the time we use the slow constructor first, then throw that work away unused by overwriting with a fast-constructed one. This refactor avoids that cost by deferring the expensive work to `ErrorThrower::isolate()`, where it happens only as a fallback iff isolate_ hasn't been set. Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Charles Kerr <charles@charleskerr.com>
1 parent 8bca8d2 commit 71150ff

File tree

2 files changed

+13
-13
lines changed

2 files changed

+13
-13
lines changed

shell/common/gin_helper/error_thrower.cc

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,11 @@
1010

1111
namespace gin_helper {
1212

13-
ErrorThrower::ErrorThrower(v8::Isolate* isolate) : isolate_(isolate) {}
14-
15-
// This constructor should be rarely if ever used, since
16-
// v8::Isolate::GetCurrent() uses atomic loads and is thus a bit
17-
// costly to invoke
18-
ErrorThrower::ErrorThrower() : isolate_(v8::Isolate::GetCurrent()) {}
13+
v8::Isolate* ErrorThrower::isolate() const {
14+
// Callers should prefer to specify the isolate in the constructor,
15+
// since GetCurrent() uses atomic loads and is thus a bit costly to invoke
16+
return isolate_ ? isolate_.get() : v8::Isolate::GetCurrent();
17+
}
1918

2019
void ErrorThrower::ThrowError(const std::string_view err_msg) const {
2120
Throw(v8::Exception::Error, err_msg);
@@ -39,9 +38,10 @@ void ErrorThrower::ThrowSyntaxError(const std::string_view err_msg) const {
3938

4039
void ErrorThrower::Throw(ErrorGenerator gen,
4140
const std::string_view err_msg) const {
42-
v8::Local<v8::Value> exception = gen(gin::StringToV8(isolate_, err_msg), {});
43-
if (!isolate_->IsExecutionTerminating())
44-
isolate_->ThrowException(exception);
41+
v8::Isolate* isolate = this->isolate();
42+
43+
if (!isolate->IsExecutionTerminating())
44+
isolate->ThrowException(gen(gin::StringToV8(isolate, err_msg), {}));
4545
}
4646

4747
} // namespace gin_helper

shell/common/gin_helper/error_thrower.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ namespace gin_helper {
1414

1515
class ErrorThrower {
1616
public:
17-
explicit ErrorThrower(v8::Isolate* isolate);
18-
ErrorThrower();
17+
constexpr explicit ErrorThrower(v8::Isolate* isolate) : isolate_{isolate} {}
18+
constexpr ErrorThrower() = default;
1919
~ErrorThrower() = default;
2020

2121
void ThrowError(std::string_view err_msg) const;
@@ -24,14 +24,14 @@ class ErrorThrower {
2424
void ThrowReferenceError(std::string_view err_msg) const;
2525
void ThrowSyntaxError(std::string_view err_msg) const;
2626

27-
v8::Isolate* isolate() const { return isolate_; }
27+
v8::Isolate* isolate() const;
2828

2929
private:
3030
using ErrorGenerator = v8::Local<v8::Value> (*)(v8::Local<v8::String> err_msg,
3131
v8::Local<v8::Value> options);
3232
void Throw(ErrorGenerator gen, std::string_view err_msg) const;
3333

34-
raw_ptr<v8::Isolate> isolate_;
34+
raw_ptr<v8::Isolate> isolate_ = {};
3535
};
3636

3737
} // namespace gin_helper

0 commit comments

Comments
 (0)