Title: [189012] trunk/Source/_javascript_Core
- Revision
- 189012
- Author
- saambara...@gmail.com
- Date
- 2015-08-26 22:54:21 -0700 (Wed, 26 Aug 2015)
Log Message
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: trunk/Source/_javascript_Core/ChangeLog (189011 => 189012)
--- trunk/Source/_javascript_Core/ChangeLog 2015-08-27 04:40:50 UTC (rev 189011)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-08-27 05:54:21 UTC (rev 189012)
@@ -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: trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp (189011 => 189012)
--- trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp 2015-08-27 04:40:50 UTC (rev 189011)
+++ trunk/Source/_javascript_Core/heap/MarkedAllocator.cpp 2015-08-27 05:54:21 UTC (rev 189012)
@@ -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: trunk/Source/_javascript_Core/tests/stress/heap-allocator-allocates-incorrect-size-for-activation.js (0 => 189012)
--- trunk/Source/_javascript_Core/tests/stress/heap-allocator-allocates-incorrect-size-for-activation.js (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/heap-allocator-allocates-incorrect-size-for-activation.js 2015-08-27 05:54:21 UTC (rev 189012)
@@ -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