Title: [189714] releases/WebKitGTK/webkit-2.10/Source/_javascript_Core
Revision
189714
Author
carlo...@webkit.org
Date
2015-09-14 05:32:57 -0700 (Mon, 14 Sep 2015)

Log Message

Merge r189012 - MarkedBlock::allocateBlock will have the wrong allocation size when (sizeof(MarkedBlock) + bytes) is divisible by WTF::pageSize()
https://bugs.webkit.org/show_bug.cgi?id=148500

Reviewed by Mark Lam.

Consider the following scenario:
- On OS X, WTF::pageSize() is 4*1024 bytes.
- JSEnvironmentRecord::allocationSizeForScopeSize(6621) == 53000
- sizeof(MarkedBlock) == 248
- (248 + 53000) is a multiple of 4*1024.
- (248 + 53000)/(4*1024) == 13

We will allocate a chunk of memory of size 53248 bytes that looks like this:
0            248       256                       53248       53256
[Marked Block | 8 bytes |  payload     ......      ]  8 bytes  |
                        ^                                      ^
                   Our Environment record starts here.         ^
                                                               ^
                                                         Our last JSValue in the environment record will go from byte 53248 to 53256. But, we don't own this memory.

We need to ensure that we round up sizeof(MarkedBlock) to an
atomSize boundary. We need to do this because the first atom
inside the MarkedBlock will start at the rounded up multiple
of atomSize past MarkedBlock. If we end up with an allocation
that is perfectly aligned to the page size, then we will be short
8 bytes (in the current implementation where atomSize is 16 bytes,
and MarkedBlock is 248 bytes).

* heap/MarkedAllocator.cpp:
(JSC::MarkedAllocator::allocateBlock):
* tests/stress/heap-allocator-allocates-incorrect-size-for-activation.js: Added.
(use):
(makeFunction):

Modified Paths

Added Paths

Diff

Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ChangeLog (189713 => 189714)


--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ChangeLog	2015-09-14 12:28:32 UTC (rev 189713)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/ChangeLog	2015-09-14 12:32:57 UTC (rev 189714)
@@ -1,3 +1,39 @@
+2015-08-26  Saam barati  <sbar...@apple.com>
+
+        MarkedBlock::allocateBlock will have the wrong allocation size when (sizeof(MarkedBlock) + bytes) is divisible by WTF::pageSize()
+        https://bugs.webkit.org/show_bug.cgi?id=148500
+
+        Reviewed by Mark Lam.
+
+        Consider the following scenario:
+        - On OS X, WTF::pageSize() is 4*1024 bytes.
+        - JSEnvironmentRecord::allocationSizeForScopeSize(6621) == 53000
+        - sizeof(MarkedBlock) == 248
+        - (248 + 53000) is a multiple of 4*1024.
+        - (248 + 53000)/(4*1024) == 13
+
+        We will allocate a chunk of memory of size 53248 bytes that looks like this:
+        0            248       256                       53248       53256
+        [Marked Block | 8 bytes |  payload     ......      ]  8 bytes  |
+                                ^                                      ^
+                           Our Environment record starts here.         ^
+                                                                       ^
+                                                                 Our last JSValue in the environment record will go from byte 53248 to 53256. But, we don't own this memory.
+
+        We need to ensure that we round up sizeof(MarkedBlock) to an
+        atomSize boundary. We need to do this because the first atom
+        inside the MarkedBlock will start at the rounded up multiple
+        of atomSize past MarkedBlock. If we end up with an allocation
+        that is perfectly aligned to the page size, then we will be short
+        8 bytes (in the current implementation where atomSize is 16 bytes,
+        and MarkedBlock is 248 bytes).
+
+        * heap/MarkedAllocator.cpp:
+        (JSC::MarkedAllocator::allocateBlock):
+        * tests/stress/heap-allocator-allocates-incorrect-size-for-activation.js: Added.
+        (use):
+        (makeFunction):
+
 2015-08-26  Mark Lam  <mark....@apple.com>
 
         watchdog m_didFire state erroneously retained.

Modified: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/heap/MarkedAllocator.cpp (189713 => 189714)


--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/heap/MarkedAllocator.cpp	2015-09-14 12:28:32 UTC (rev 189713)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/heap/MarkedAllocator.cpp	2015-09-14 12:32:57 UTC (rev 189714)
@@ -175,7 +175,8 @@
 MarkedBlock* MarkedAllocator::allocateBlock(size_t bytes)
 {
     size_t minBlockSize = MarkedBlock::blockSize;
-    size_t minAllocationSize = WTF::roundUpToMultipleOf(WTF::pageSize(), sizeof(MarkedBlock) + bytes);
+    size_t minAllocationSize = WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(sizeof(MarkedBlock)) + WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(bytes);
+    minAllocationSize = WTF::roundUpToMultipleOf(WTF::pageSize(), minAllocationSize);
     size_t blockSize = std::max(minBlockSize, minAllocationSize);
 
     size_t cellSize = m_cellSize ? m_cellSize : WTF::roundUpToMultipleOf<MarkedBlock::atomSize>(bytes);

Added: releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/tests/stress/heap-allocator-allocates-incorrect-size-for-activation.js (0 => 189714)


--- releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/tests/stress/heap-allocator-allocates-incorrect-size-for-activation.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.10/Source/_javascript_Core/tests/stress/heap-allocator-allocates-incorrect-size-for-activation.js	2015-09-14 12:32:57 UTC (rev 189714)
@@ -0,0 +1,41 @@
+
+// Consider the following scenario:
+// - On OS X, WTF::pageSize() is 4*1024 bytes.
+// - JSEnvironmentRecord::allocationSizeForScopeSize(6621) == 53000
+// - sizeof(MarkedBlock) == 248
+// - (248 + 53000) is a multiple of 4*1024.
+// - (248 + 53000)/(4*1024) == 13
+
+// We will allocate a chunk of memory of size 53248 bytes that looks like this:
+// 0            248       256                       53248       53256
+// [Marked Block | 8 bytes |  payload     ......      ]  8 bytes  |
+//                         ^                                      ^
+//                    Our Environment record starts here.         ^
+//                                                                ^
+//                                                        Our last JSValue in the environment record will go from byte 53248 to 53256. But, we don't own this memory.
+
+var numberOfCapturedVariables = 6621;
+function use() { }
+function makeFunction() { 
+    var varName;
+    var outerFunction = "";
+    var innerFunction = "";
+
+    for (var i = 0; i < numberOfCapturedVariables; i++) {
+        varName = "_" + i;
+        outerFunction += "var " + varName + ";";
+        innerFunction += "use(" + varName + ");";
+    }
+    outerFunction += "function foo() {" + innerFunction + "}";
+    var functionString = "(function() { " + outerFunction + "})";
+    var result = eval(functionString);
+    return result;
+}
+
+var arr = [];
+for (var i = 0; i < 50; i++) {
+    var f = makeFunction();
+    f();
+    fullGC();
+}
+
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to