bug fix when rallocm fails
authorYasser Ganjisaffar <yasserg@fb.com>
Mon, 27 Jan 2014 18:36:22 +0000 (10:36 -0800)
committerSara Golemon <sgolemon@fb.com>
Thu, 6 Feb 2014 19:50:13 +0000 (11:50 -0800)
Summary:
rallocm sets the value of the second argument even if it has failed to allocate the requested size:
https://github.com/jemalloc/jemalloc/blob/898960247a8b2e6534738b7a3a244855f379faf9/src/jemalloc.c#L1903-L1906

As a result newAllocatedCapacity was being set to a value less than the original value and the logic was broken.

Test Plan: unit tests pass and my code which was crashing before now works!

Reviewed By: soren@fb.com

FB internal diff: D1144314

folly/io/IOBuf.cpp

index 950e629393089818089923ffb7f24d511f541f9f..b3cd4125999edd2c1696dcaa2df329dd29ccf986 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2014 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -714,11 +714,16 @@ void IOBuf::reserveSlow(uint32_t minHeadroom, uint32_t minTailroom) {
         size_t allocatedCapacity = capacity() + sizeof(SharedInfo);
         void* p = buf_;
         if (allocatedCapacity >= jemallocMinInPlaceExpandable) {
-          int r = rallocm(&p, &newAllocatedCapacity, newAllocatedCapacity,
+          // rallocm can write to its 2nd arg even if it returns
+          // ALLOCM_ERR_NOT_MOVED. So, we pass a temporary to its 2nd arg and
+          // update newAllocatedCapacity only on success.
+          size_t allocatedSize;
+          int r = rallocm(&p, &allocatedSize, newAllocatedCapacity,
                           0, ALLOCM_NO_MOVE);
           if (r == ALLOCM_SUCCESS) {
             newBuffer = static_cast<uint8_t*>(p);
             newHeadroom = oldHeadroom;
+            newAllocatedCapacity = allocatedSize;
           } else if (r == ALLOCM_ERR_OOM) {
             // shouldn't happen as we don't actually allocate new memory
             // (due to ALLOCM_NO_MOVE)