55#include " node_buffer.h"
66#include " node_http2.h"
77#include " node_http2_state.h"
8+ #include " node_mem-inl.h"
89#include " node_perf.h"
910#include " node_revert.h"
1011#include " util-inl.h"
@@ -505,101 +506,20 @@ Http2Session::Callbacks::~Callbacks() {
505506 nghttp2_session_callbacks_del (callbacks);
506507}
507508
508- // Track memory allocated by nghttp2 using a custom allocator.
509- class Http2Session ::MemoryAllocatorInfo {
510- public:
511- explicit MemoryAllocatorInfo (Http2Session* session)
512- : info({ session, H2Malloc, H2Free, H2Calloc, H2Realloc }) {}
513-
514- static void * H2Malloc (size_t size, void * user_data) {
515- return H2Realloc (nullptr , size, user_data);
516- }
517-
518- static void * H2Calloc (size_t nmemb, size_t size, void * user_data) {
519- size_t real_size = MultiplyWithOverflowCheck (nmemb, size);
520- void * mem = H2Malloc (real_size, user_data);
521- if (mem != nullptr )
522- memset (mem, 0 , real_size);
523- return mem;
524- }
525-
526- static void H2Free (void * ptr, void * user_data) {
527- if (ptr == nullptr ) return ; // free(null); happens quite often.
528- void * result = H2Realloc (ptr, 0 , user_data);
529- CHECK_NULL (result);
530- }
531-
532- static void * H2Realloc (void * ptr, size_t size, void * user_data) {
533- Http2Session* session = static_cast <Http2Session*>(user_data);
534- size_t previous_size = 0 ;
535- char * original_ptr = nullptr ;
536-
537- // We prepend each allocated buffer with a size_t containing the full
538- // size of the allocation.
539- if (size > 0 ) size += sizeof (size_t );
540-
541- if (ptr != nullptr ) {
542- // We are free()ing or re-allocating.
543- original_ptr = static_cast <char *>(ptr) - sizeof (size_t );
544- previous_size = *reinterpret_cast <size_t *>(original_ptr);
545- // This means we called StopTracking() on this pointer before.
546- if (previous_size == 0 ) {
547- // Fall back to the standard Realloc() function.
548- char * ret = UncheckedRealloc (original_ptr, size);
549- if (ret != nullptr )
550- ret += sizeof (size_t );
551- return ret;
552- }
553- }
554- CHECK_GE (session->current_nghttp2_memory_ , previous_size);
555-
556- // TODO(addaleax): Add the following, and handle NGHTTP2_ERR_NOMEM properly
557- // everywhere:
558- //
559- // if (size > previous_size &&
560- // !session->IsAvailableSessionMemory(size - previous_size)) {
561- // return nullptr;
562- // }
563-
564- char * mem = UncheckedRealloc (original_ptr, size);
565-
566- if (mem != nullptr ) {
567- // Adjust the memory info counter.
568- // TODO(addaleax): Avoid the double bookkeeping we do with
569- // current_nghttp2_memory_ + AdjustAmountOfExternalAllocatedMemory
570- // and provide versions of our memory allocation utilities that take an
571- // Environment*/Isolate* parameter and call the V8 method transparently.
572- const int64_t new_size = size - previous_size;
573- session->current_nghttp2_memory_ += new_size;
574- session->env ()->isolate ()->AdjustAmountOfExternalAllocatedMemory (
575- new_size);
576- *reinterpret_cast <size_t *>(mem) = size;
577- mem += sizeof (size_t );
578- } else if (size == 0 ) {
579- session->current_nghttp2_memory_ -= previous_size;
580- session->env ()->isolate ()->AdjustAmountOfExternalAllocatedMemory (
581- -static_cast <int64_t >(previous_size));
582- }
583-
584- return mem;
585- }
586-
587- static void StopTracking (Http2Session* session, void * ptr) {
588- size_t * original_ptr = reinterpret_cast <size_t *>(
589- static_cast <char *>(ptr) - sizeof (size_t ));
590- session->current_nghttp2_memory_ -= *original_ptr;
591- session->env ()->isolate ()->AdjustAmountOfExternalAllocatedMemory (
592- -static_cast <int64_t >(*original_ptr));
593- *original_ptr = 0 ;
594- }
509+ void Http2Session::StopTrackingRcbuf (nghttp2_rcbuf* buf) {
510+ StopTrackingMemory (buf);
511+ }
595512
596- inline nghttp2_mem* operator *() { return &info; }
513+ void Http2Session::CheckAllocatedSize (size_t previous_size) const {
514+ CHECK_GE (current_nghttp2_memory_, previous_size);
515+ }
597516
598- nghttp2_mem info;
599- };
517+ void Http2Session::IncreaseAllocatedSize (size_t size) {
518+ current_nghttp2_memory_ += size;
519+ }
600520
601- void Http2Session::StopTrackingRcbuf (nghttp2_rcbuf* buf ) {
602- MemoryAllocatorInfo::StopTracking ( this , buf) ;
521+ void Http2Session::DecreaseAllocatedSize ( size_t size ) {
522+ current_nghttp2_memory_ -= size ;
603523}
604524
605525Http2Session::Http2Session (Environment* env,
@@ -636,14 +556,14 @@ Http2Session::Http2Session(Environment* env,
636556 nghttp2_session_server_new3 :
637557 nghttp2_session_client_new3;
638558
639- MemoryAllocatorInfo allocator_info ( this );
559+ nghttp2_mem alloc_info = MakeAllocator ( );
640560
641561 // This should fail only if the system is out of memory, which
642562 // is going to cause lots of other problems anyway, or if any
643563 // of the options are out of acceptable range, which we should
644564 // be catching before it gets this far. Either way, crash if this
645565 // fails.
646- CHECK_EQ (fn (&session_, callbacks, this , *opts, *allocator_info ), 0 );
566+ CHECK_EQ (fn (&session_, callbacks, this , *opts, &alloc_info ), 0 );
647567
648568 outgoing_storage_.reserve (1024 );
649569 outgoing_buffers_.reserve (32 );
0 commit comments