-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Performance optimizations (V8) #134
Conversation
- Add a `napi_get_cb_info` function to get args length, args, this, and data in a single call - Move the static exception to a class member to enable inlining of the `lastException()` method. - Refactor the `CallbackWrapper` group of helper classes to avoid most (non-inlinable) virtual function calls - Remove use of `v8::TryCatch` (via `NAPI_PREAMBLE`) from several places where it shouldn't be needed. Together, these optimizations reduce the overhead of every JS-to-C++ call through the NAPI layer by approximately 50%.
Would it not be possible to do the same to napi_status napi_delete_reference(napi_env e, napi_ref ref) {
NAPI_PREAMBLE(e);
CHECK_ARG(ref);
v8impl::Reference* reference = reinterpret_cast<v8impl::Reference*>(ref);
delete reference;
return GET_RETURN_STATUS();
} napi_status napi_delete_reference(napi_env, napi_ref ref) {
delete static_cast<v8impl::Reference*>(ref);
return napi_ok;
} |
@kkoopa Yes good point. That one wasn't related to any areas I was focusing on for performance, but the TryCatch obviously isn't necessary there either. I'll make that change. |
Actually I'm not sure about applying that change to |
Define non-trivial. I would not assume that template <class T>
void PersistentBase<T>::Reset() {
if (this->IsEmpty()) return;
V8::DisposeGlobal(reinterpret_cast<internal::Object**>(this->val_));
val_ = 0;
}
void V8::DisposeGlobal(i::Object** location) {
i::GlobalHandles::Destroy(location);
}
void GlobalHandles::Destroy(Object** location) {
if (location != NULL) Node::FromLocation(location)->Release();
}
void Release() {
DCHECK(IsInUse());
set_state(FREE);
// Zap the values for eager trapping.
object_ = reinterpret_cast<Object*>(kGlobalHandleZapValue);
class_id_ = v8::HeapProfiler::kPersistentHandleNoClassId;
set_independent(false);
set_active(false);
weak_callback_ = NULL;
DecreaseBlockUses();
}
/*-------------------------------------------------------------------------------*/
void GlobalHandles::Node::DecreaseBlockUses() {
NodeBlock* node_block = FindBlock();
GlobalHandles* global_handles = node_block->global_handles();
parameter_or_next_free_.next_free = global_handles->first_free_;
global_handles->first_free_ = this;
node_block->DecreaseUses();
global_handles->isolate()->counters()->global_handles()->Decrement();
global_handles->number_of_global_handles_--;
}
void DecreaseUses() {
DCHECK(used_nodes_ > 0);
if (--used_nodes_ == 0) {
if (next_used_ != NULL) next_used_->prev_used_ = prev_used_;
if (prev_used_ != NULL) prev_used_->next_used_ = next_used_;
if (this == global_handles_->first_used_block_) {
global_handles_->first_used_block_ = next_used_;
}
}
} As far as I see by skimming through the code, it is fairly trivial. |
OK you convinced me, it should be fine then. |
napi_get_cb_info
function to get args length, args, this, and data in a single calllastException()
method.CallbackWrapper
group of helper classes to avoid most (non-inlinable) virtual function callsv8::TryCatch
(viaNAPI_PREAMBLE
) from several places where it shouldn't be needed.Together, these optimizations reduce the overhead of every JS-to-C++ call through the NAPI layer by approximately 50%.