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