Diff
Modified: branches/safari-607-branch/Source/bmalloc/ChangeLog (246420 => 246421)
--- branches/safari-607-branch/Source/bmalloc/ChangeLog 2019-06-14 02:30:42 UTC (rev 246420)
+++ branches/safari-607-branch/Source/bmalloc/ChangeLog 2019-06-14 02:30:48 UTC (rev 246421)
@@ -1,3 +1,48 @@
+2019-06-13 Kocsen Chung <[email protected]>
+
+ Apply patch. rdar://problem/51656608
+
+ 2019-06-13 Keith Miller <[email protected]>
+
+ IsoHeaps don't notice uncommitted VA becoming the first eligible.
+ https://bugs.webkit.org/show_bug.cgi?id=198301
+
+ Reviewed by Yusuke Suzuki.
+
+ IsoDirectory has a firstEligible member that is used as an
+ optimization to help find the first fit. However if the scavenger
+ decommitted a page before firstEligible then we wouldn't move
+ firstEligible. Thus, if no space is ever freed below firstEligible
+ we will never reused the decommitted memory (e.g. if the VA page
+ is decommitted). The fix is to make IsoDirectory::didDecommit move
+ the firstEligible page back if the decommitted page is smaller
+ than the current firstEligible. As such, this patch renames
+ firstEligible to firstEligibleOrDecommitted.
+
+ Also, this patch changes gigacageEnabledForProcess to check if the
+ process starts with Test rather than just test as TestWTF does.
+
+ Lastly, unbeknownst to me IsoHeaps are dependent on gigacage, so
+ by removing gigacage from arm64 I accidentally disabled
+ IsoHeaps...
+
+ * bmalloc.xcodeproj/project.pbxproj:
+ * bmalloc/IsoDirectory.h:
+ * bmalloc/IsoDirectoryInlines.h:
+ (bmalloc::passedNumPages>::takeFirstEligible):
+ (bmalloc::passedNumPages>::didBecome):
+ (bmalloc::passedNumPages>::didDecommit):
+ * bmalloc/IsoHeapImpl.h:
+ * bmalloc/IsoHeapImplInlines.h:
+ (bmalloc::IsoHeapImpl<Config>::takeFirstEligible):
+ (bmalloc::IsoHeapImpl<Config>::didBecomeEligibleOrDecommited):
+ (bmalloc::IsoHeapImpl<Config>::didCommit):
+ (bmalloc::IsoHeapImpl<Config>::didBecomeEligible): Deleted.
+ * bmalloc/IsoTLS.cpp:
+ (bmalloc::IsoTLS::determineMallocFallbackState):
+ * bmalloc/ProcessCheck.mm:
+ (bmalloc::gigacageEnabledForProcess):
+
2019-01-23 Alan Coon <[email protected]>
Cherry-pick r240193. rdar://problem/47458146
Modified: branches/safari-607-branch/Source/bmalloc/bmalloc/IsoDirectory.h (246420 => 246421)
--- branches/safari-607-branch/Source/bmalloc/bmalloc/IsoDirectory.h 2019-06-14 02:30:42 UTC (rev 246420)
+++ branches/safari-607-branch/Source/bmalloc/bmalloc/IsoDirectory.h 2019-06-14 02:30:48 UTC (rev 246421)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -89,7 +89,7 @@
Bits<numPages> m_empty;
Bits<numPages> m_committed;
std::array<IsoPage<Config>*, numPages> m_pages;
- unsigned m_firstEligible { 0 };
+ unsigned m_firstEligibleOrDecommitted { 0 };
unsigned m_highWatermark { 0 };
};
Modified: branches/safari-607-branch/Source/bmalloc/bmalloc/IsoDirectoryInlines.h (246420 => 246421)
--- branches/safari-607-branch/Source/bmalloc/bmalloc/IsoDirectoryInlines.h 2019-06-14 02:30:42 UTC (rev 246420)
+++ branches/safari-607-branch/Source/bmalloc/bmalloc/IsoDirectoryInlines.h 2019-06-14 02:30:48 UTC (rev 246421)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,8 +46,9 @@
template<typename Config, unsigned passedNumPages>
EligibilityResult<Config> IsoDirectory<Config, passedNumPages>::takeFirstEligible()
{
- unsigned pageIndex = (m_eligible | ~m_committed).findBit(m_firstEligible, true);
- m_firstEligible = pageIndex;
+ unsigned pageIndex = (m_eligible | ~m_committed).findBit(m_firstEligibleOrDecommitted, true);
+ m_firstEligibleOrDecommitted = pageIndex;
+ BASSERT((m_eligible | ~m_committed).findBit(0, true) == pageIndex);
if (pageIndex >= numPages)
return EligibilityKind::Full;
@@ -99,8 +100,8 @@
if (verbose)
fprintf(stderr, "%p: %p did become eligible.\n", this, page);
m_eligible[pageIndex] = true;
- m_firstEligible = std::min(m_firstEligible, pageIndex);
- this->m_heap.didBecomeEligible(this);
+ m_firstEligibleOrDecommitted = std::min(m_firstEligibleOrDecommitted, pageIndex);
+ this->m_heap.didBecomeEligibleOrDecommited(this);
return;
case IsoPageTrigger::Empty:
if (verbose)
@@ -124,6 +125,8 @@
BASSERT(!!m_committed[index]);
this->m_heap.isNoLongerFreeable(m_pages[index], IsoPageBase::pageSize);
m_committed[index] = false;
+ m_firstEligibleOrDecommitted = std::min(m_firstEligibleOrDecommitted, index);
+ this->m_heap.didBecomeEligibleOrDecommited(this);
this->m_heap.didDecommit(m_pages[index], IsoPageBase::pageSize);
}
Modified: branches/safari-607-branch/Source/bmalloc/bmalloc/IsoHeapImpl.h (246420 => 246421)
--- branches/safari-607-branch/Source/bmalloc/bmalloc/IsoHeapImpl.h 2019-06-14 02:30:42 UTC (rev 246420)
+++ branches/safari-607-branch/Source/bmalloc/bmalloc/IsoHeapImpl.h 2019-06-14 02:30:48 UTC (rev 246421)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -68,8 +68,8 @@
EligibilityResult<Config> takeFirstEligible();
// Callbacks from directory.
- void didBecomeEligible(IsoDirectory<Config, numPagesInInlineDirectory>*);
- void didBecomeEligible(IsoDirectory<Config, IsoDirectoryPage<Config>::numPages>*);
+ void didBecomeEligibleOrDecommited(IsoDirectory<Config, numPagesInInlineDirectory>*);
+ void didBecomeEligibleOrDecommited(IsoDirectory<Config, IsoDirectoryPage<Config>::numPages>*);
void scavenge(Vector<DeferredDecommit>&) override;
void scavengeToHighWatermark(Vector<DeferredDecommit>&) override;
@@ -120,8 +120,8 @@
unsigned m_nextDirectoryPageIndex { 1 }; // We start at 1 so that the high water mark being zero means we've only allocated in the inline directory since the last scavenge.
unsigned m_directoryHighWatermark { 0 };
- bool m_isInlineDirectoryEligible { true };
- IsoDirectoryPage<Config>* m_firstEligibleDirectory { nullptr };
+ bool m_isInlineDirectoryEligibleOrDecommitted { true };
+ IsoDirectoryPage<Config>* m_firstEligibleOrDecommitedDirectory { nullptr };
IsoTLSAllocatorEntry<Config> m_allocator;
};
Modified: branches/safari-607-branch/Source/bmalloc/bmalloc/IsoHeapImplInlines.h (246420 => 246421)
--- branches/safari-607-branch/Source/bmalloc/bmalloc/IsoHeapImplInlines.h 2019-06-14 02:30:42 UTC (rev 246420)
+++ branches/safari-607-branch/Source/bmalloc/bmalloc/IsoHeapImplInlines.h 2019-06-14 02:30:48 UTC (rev 246421)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,26 +42,26 @@
template<typename Config>
EligibilityResult<Config> IsoHeapImpl<Config>::takeFirstEligible()
{
- if (m_isInlineDirectoryEligible) {
+ if (m_isInlineDirectoryEligibleOrDecommitted) {
EligibilityResult<Config> result = m_inlineDirectory.takeFirstEligible();
if (result.kind == EligibilityKind::Full)
- m_isInlineDirectoryEligible = false;
+ m_isInlineDirectoryEligibleOrDecommitted = false;
else
return result;
}
- if (!m_firstEligibleDirectory) {
+ if (!m_firstEligibleOrDecommitedDirectory) {
// If nothing is eligible, it can only be because we have no directories. It wouldn't be the end
- // of the world if we broke this invariant. It would only mean that didBecomeEligible() would need
+ // of the world if we broke this invariant. It would only mean that didBecomeEligibleOrDecommited() would need
// a null check.
RELEASE_BASSERT(!m_headDirectory);
RELEASE_BASSERT(!m_tailDirectory);
}
- for (; m_firstEligibleDirectory; m_firstEligibleDirectory = m_firstEligibleDirectory->next) {
- EligibilityResult<Config> result = m_firstEligibleDirectory->payload.takeFirstEligible();
+ for (; m_firstEligibleOrDecommitedDirectory; m_firstEligibleOrDecommitedDirectory = m_firstEligibleOrDecommitedDirectory->next) {
+ EligibilityResult<Config> result = m_firstEligibleOrDecommitedDirectory->payload.takeFirstEligible();
if (result.kind != EligibilityKind::Full) {
- m_directoryHighWatermark = std::max(m_directoryHighWatermark, m_firstEligibleDirectory->index());
+ m_directoryHighWatermark = std::max(m_directoryHighWatermark, m_firstEligibleOrDecommitedDirectory->index());
return result;
}
}
@@ -76,7 +76,7 @@
m_tailDirectory = newDirectory;
}
m_directoryHighWatermark = newDirectory->index();
- m_firstEligibleDirectory = newDirectory;
+ m_firstEligibleOrDecommitedDirectory = newDirectory;
EligibilityResult<Config> result = newDirectory->payload.takeFirstEligible();
RELEASE_BASSERT(result.kind != EligibilityKind::Full);
return result;
@@ -83,19 +83,19 @@
}
template<typename Config>
-void IsoHeapImpl<Config>::didBecomeEligible(IsoDirectory<Config, numPagesInInlineDirectory>* directory)
+void IsoHeapImpl<Config>::didBecomeEligibleOrDecommited(IsoDirectory<Config, numPagesInInlineDirectory>* directory)
{
RELEASE_BASSERT(directory == &m_inlineDirectory);
- m_isInlineDirectoryEligible = true;
+ m_isInlineDirectoryEligibleOrDecommitted = true;
}
template<typename Config>
-void IsoHeapImpl<Config>::didBecomeEligible(IsoDirectory<Config, IsoDirectoryPage<Config>::numPages>* directory)
+void IsoHeapImpl<Config>::didBecomeEligibleOrDecommited(IsoDirectory<Config, IsoDirectoryPage<Config>::numPages>* directory)
{
- RELEASE_BASSERT(m_firstEligibleDirectory);
+ RELEASE_BASSERT(m_firstEligibleOrDecommitedDirectory);
auto* directoryPage = IsoDirectoryPage<Config>::pageFor(directory);
- if (directoryPage->index() < m_firstEligibleDirectory->index())
- m_firstEligibleDirectory = directoryPage;
+ if (directoryPage->index() < m_firstEligibleOrDecommitedDirectory->index())
+ m_firstEligibleOrDecommitedDirectory = directoryPage;
}
template<typename Config>
Modified: branches/safari-607-branch/Source/bmalloc/bmalloc/IsoTLS.cpp (246420 => 246421)
--- branches/safari-607-branch/Source/bmalloc/bmalloc/IsoTLS.cpp 2019-06-14 02:30:42 UTC (rev 246420)
+++ branches/safari-607-branch/Source/bmalloc/bmalloc/IsoTLS.cpp 2019-06-14 02:30:48 UTC (rev 246421)
@@ -205,11 +205,13 @@
if (s_mallocFallbackState != MallocFallbackState::Undecided)
return;
-#if GIGACAGE_ENABLED
+#if GIGACAGE_ENABLED || BCPU(ARM64)
+#if !BCPU(ARM64)
if (!Gigacage::shouldBeEnabled()) {
s_mallocFallbackState = MallocFallbackState::FallBackToMalloc;
return;
}
+#endif
const char* env = getenv("bmalloc_IsoHeap");
if (env && (!strcasecmp(env, "false") || !strcasecmp(env, "no") || !strcmp(env, "0")))
s_mallocFallbackState = MallocFallbackState::FallBackToMalloc;
Modified: branches/safari-607-branch/Source/bmalloc/bmalloc/ProcessCheck.mm (246420 => 246421)
--- branches/safari-607-branch/Source/bmalloc/bmalloc/ProcessCheck.mm 2019-06-14 02:30:42 UTC (rev 246420)
+++ branches/safari-607-branch/Source/bmalloc/bmalloc/ProcessCheck.mm 2019-06-14 02:30:48 UTC (rev 246421)
@@ -46,7 +46,8 @@
bool isOptInBinary = [processName isEqualToString:@"jsc"]
|| [processName isEqualToString:@"DumpRenderTree"]
|| [processName isEqualToString:@"wasm"]
- || [processName hasPrefix:@"test"];
+ || [processName hasPrefix:@"test"]
+ || [processName hasPrefix:@"Test"];
return isOptInBinary;
}
Modified: branches/safari-607-branch/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj (246420 => 246421)
--- branches/safari-607-branch/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj 2019-06-14 02:30:42 UTC (rev 246420)
+++ branches/safari-607-branch/Source/bmalloc/bmalloc.xcodeproj/project.pbxproj 2019-06-14 02:30:48 UTC (rev 246421)
@@ -33,8 +33,6 @@
0F5BF1731F23C5710029D91D /* BExport.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F5BF1721F23C5710029D91D /* BExport.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F74B93E1F89713E00B935D3 /* CryptoRandom.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F74B93C1F89713E00B935D3 /* CryptoRandom.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F74B93F1F89713E00B935D3 /* CryptoRandom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F74B93D1F89713E00B935D3 /* CryptoRandom.cpp */; };
- 0F7EB7F21F95285300F1ABCB /* testbmalloc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F7EB7F11F95285300F1ABCB /* testbmalloc.cpp */; };
- 0F7EB7FA1F95414C00F1ABCB /* libbmalloc.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 14F271BE18EA3963008C152F /* libbmalloc.a */; };
0F7EB8231F9541B000F1ABCB /* EligibilityResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7EB7FC1F9541AD00F1ABCB /* EligibilityResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F7EB8241F9541B000F1ABCB /* IsoHeapImplInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7EB7FD1F9541AD00F1ABCB /* IsoHeapImplInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
0F7EB8251F9541B000F1ABCB /* DeferredTriggerInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F7EB7FE1F9541AD00F1ABCB /* DeferredTriggerInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -143,13 +141,6 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
- 0F7EB7F71F95412900F1ABCB /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 145F6837179DC45F00D65598 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 14F271BD18EA3963008C152F;
- remoteInfo = bmalloc;
- };
0F7EB8551F95505400F1ABCB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 145F6837179DC45F00D65598 /* Project object */;
@@ -166,18 +157,6 @@
};
/* End PBXContainerItemProxy section */
-/* Begin PBXCopyFilesBuildPhase section */
- 0F7EB7ED1F95285300F1ABCB /* CopyFiles */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = /usr/share/man/man1/;
- dstSubfolderSpec = 0;
- files = (
- );
- runOnlyForDeploymentPostprocessing = 1;
- };
-/* End PBXCopyFilesBuildPhase section */
-
/* Begin PBXFileReference section */
0F26A7A42054830D0090A141 /* PerProcess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PerProcess.cpp; path = bmalloc/PerProcess.cpp; sourceTree = "<group>"; };
0F5167731FAD6852008236A8 /* bmalloc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = bmalloc.cpp; path = bmalloc/bmalloc.cpp; sourceTree = "<group>"; };
@@ -191,8 +170,6 @@
0F5BF1721F23C5710029D91D /* BExport.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = BExport.h; path = bmalloc/BExport.h; sourceTree = "<group>"; };
0F74B93C1F89713E00B935D3 /* CryptoRandom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CryptoRandom.h; path = bmalloc/CryptoRandom.h; sourceTree = "<group>"; };
0F74B93D1F89713E00B935D3 /* CryptoRandom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CryptoRandom.cpp; path = bmalloc/CryptoRandom.cpp; sourceTree = "<group>"; };
- 0F7EB7EF1F95285300F1ABCB /* testbmalloc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testbmalloc; sourceTree = BUILT_PRODUCTS_DIR; };
- 0F7EB7F11F95285300F1ABCB /* testbmalloc.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = testbmalloc.cpp; sourceTree = "<group>"; };
0F7EB7FC1F9541AD00F1ABCB /* EligibilityResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EligibilityResult.h; path = bmalloc/EligibilityResult.h; sourceTree = SOURCE_ROOT; };
0F7EB7FD1F9541AD00F1ABCB /* IsoHeapImplInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = IsoHeapImplInlines.h; path = bmalloc/IsoHeapImplInlines.h; sourceTree = SOURCE_ROOT; };
0F7EB7FE1F9541AD00F1ABCB /* DeferredTriggerInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DeferredTriggerInlines.h; path = bmalloc/DeferredTriggerInlines.h; sourceTree = SOURCE_ROOT; };
@@ -306,14 +283,6 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
- 0F7EB7EC1F95285300F1ABCB /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 0F7EB7FA1F95414C00F1ABCB /* libbmalloc.a in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
14CC394118EA8743004AFE34 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -333,14 +302,6 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
- 0F7EB7F01F95285300F1ABCB /* test */ = {
- isa = PBXGroup;
- children = (
- 0F7EB7F11F95285300F1ABCB /* testbmalloc.cpp */,
- );
- path = test;
- sourceTree = "<group>";
- };
0F7EB7F91F95414C00F1ABCB /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -421,7 +382,6 @@
0F7EB7FB1F95416900F1ABCB /* iso */,
145F6840179DC45F00D65598 /* Products */,
14D9DB4F17F2868900EAAB79 /* stdlib */,
- 0F7EB7F01F95285300F1ABCB /* test */,
);
sourceTree = "<group>";
};
@@ -428,7 +388,6 @@
145F6840179DC45F00D65598 /* Products */ = {
isa = PBXGroup;
children = (
- 0F7EB7EF1F95285300F1ABCB /* testbmalloc */,
14F271BE18EA3963008C152F /* libbmalloc.a */,
14CC394418EA8743004AFE34 /* libmbmalloc.dylib */,
);
@@ -665,24 +624,6 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
- 0F7EB7EE1F95285300F1ABCB /* testbmalloc */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 0F7EB7F61F95285300F1ABCB /* Build configuration list for PBXNativeTarget "testbmalloc" */;
- buildPhases = (
- 0F7EB7EB1F95285300F1ABCB /* Sources */,
- 0F7EB7EC1F95285300F1ABCB /* Frameworks */,
- 0F7EB7ED1F95285300F1ABCB /* CopyFiles */,
- );
- buildRules = (
- );
- dependencies = (
- 0F7EB7F81F95412900F1ABCB /* PBXTargetDependency */,
- );
- name = testbmalloc;
- productName = testbmalloc;
- productReference = 0F7EB7EF1F95285300F1ABCB /* testbmalloc */;
- productType = "com.apple.product-type.tool";
- };
14CC394318EA8743004AFE34 /* mbmalloc */ = {
isa = PBXNativeTarget;
buildConfigurationList = 14CC394518EA8743004AFE34 /* Build configuration list for PBXNativeTarget "mbmalloc" */;
@@ -727,10 +668,6 @@
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 1000;
TargetAttributes = {
- 0F7EB7EE1F95285300F1ABCB = {
- CreatedOnToolsVersion = 9.0;
- ProvisioningStyle = Manual;
- };
0F7EB8501F95504B00F1ABCB = {
CreatedOnToolsVersion = 9.0;
ProvisioningStyle = Automatic;
@@ -752,20 +689,11 @@
0F7EB8501F95504B00F1ABCB /* All */,
14F271BD18EA3963008C152F /* bmalloc */,
14CC394318EA8743004AFE34 /* mbmalloc */,
- 0F7EB7EE1F95285300F1ABCB /* testbmalloc */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
- 0F7EB7EB1F95285300F1ABCB /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- 0F7EB7F21F95285300F1ABCB /* testbmalloc.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
14CC394018EA8743004AFE34 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -812,11 +740,6 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
- 0F7EB7F81F95412900F1ABCB /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 14F271BD18EA3963008C152F /* bmalloc */;
- targetProxy = 0F7EB7F71F95412900F1ABCB /* PBXContainerItemProxy */;
- };
0F7EB8561F95505400F1ABCB /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 14F271BD18EA3963008C152F /* bmalloc */;
@@ -830,30 +753,6 @@
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
- 0F7EB7F31F95285300F1ABCB /* Debug */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 14B650C718F39F4800751968 /* DebugRelease.xcconfig */;
- buildSettings = {
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = Debug;
- };
- 0F7EB7F41F95285300F1ABCB /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 14B650C718F39F4800751968 /* DebugRelease.xcconfig */;
- buildSettings = {
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = Release;
- };
- 0F7EB7F51F95285300F1ABCB /* Production */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = 14B650C518F39F4800751968 /* Base.xcconfig */;
- buildSettings = {
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = Production;
- };
0F7EB8521F95504B00F1ABCB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -948,16 +847,6 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
- 0F7EB7F61F95285300F1ABCB /* Build configuration list for PBXNativeTarget "testbmalloc" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 0F7EB7F31F95285300F1ABCB /* Debug */,
- 0F7EB7F41F95285300F1ABCB /* Release */,
- 0F7EB7F51F95285300F1ABCB /* Production */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Production;
- };
0F7EB8511F95504B00F1ABCB /* Build configuration list for PBXAggregateTarget "All" */ = {
isa = XCConfigurationList;
buildConfigurations = (
Deleted: branches/safari-607-branch/Source/bmalloc/test/testbmalloc.cpp (246420 => 246421)
--- branches/safari-607-branch/Source/bmalloc/test/testbmalloc.cpp 2019-06-14 02:30:42 UTC (rev 246420)
+++ branches/safari-607-branch/Source/bmalloc/test/testbmalloc.cpp 2019-06-14 02:30:48 UTC (rev 246421)
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <bmalloc/bmalloc.h>
-#include <bmalloc/Environment.h>
-#include <bmalloc/IsoHeapInlines.h>
-#include <cmath>
-#include <cstdlib>
-#include <set>
-#include <vector>
-
-using namespace bmalloc;
-using namespace bmalloc::api;
-
-// We don't have a NO_RETURN_DUE_TO_EXIT, nor should we. That's ridiculous.
-static bool hiddenTruthBecauseNoReturnIsStupid() { return true; }
-
-static void usage()
-{
- puts("Usage: testb3 [<filter>]");
- if (hiddenTruthBecauseNoReturnIsStupid())
- exit(1);
-}
-
-#define RUN(test) do { \
- if (!shouldRun(#test)) \
- break; \
- puts(#test "..."); \
- test; \
- puts(#test ": OK!"); \
- } while (false)
-
-// Nothing fancy for now; we just use the existing WTF assertion machinery.
-#define CHECK(x) do { \
- if (!!(x)) \
- break; \
- fprintf(stderr, "%s:%d: in %s: assertion %s failed.\n", \
- __FILE__, __LINE__, __PRETTY_FUNCTION__, #x); \
- abort(); \
- } while (false)
-
-static std::set<void*> toptrset(const std::vector<void*>& ptrs)
-{
- std::set<void*> result;
- for (void* ptr : ptrs) {
- if (ptr)
- result.insert(ptr);
- }
- return result;
-}
-
-static void assertEmptyPointerSet(const std::set<void*>& pointers)
-{
- if (PerProcess<Environment>::get()->isDebugHeapEnabled()) {
- printf(" skipping checks because DebugHeap.\n");
- return;
- }
- if (pointers.empty())
- return;
- printf("Pointer set not empty!\n");
- printf("Pointers:");
- for (void* ptr : pointers)
- printf(" %p", ptr);
- printf("\n");
- CHECK(pointers.empty());
-}
-
-template<typename heapType>
-static void assertHasObjects(IsoHeap<heapType>& heap, std::set<void*> pointers)
-{
- if (PerProcess<Environment>::get()->isDebugHeapEnabled()) {
- printf(" skipping checks because DebugHeap.\n");
- return;
- }
- auto& impl = heap.impl();
- std::lock_guard<Mutex> locker(impl.lock);
- impl.forEachLiveObject(
- [&] (void* object) {
- pointers.erase(object);
- });
- assertEmptyPointerSet(pointers);
-}
-
-template<typename heapType>
-static void assertHasOnlyObjects(IsoHeap<heapType>& heap, std::set<void*> pointers)
-{
- if (PerProcess<Environment>::get()->isDebugHeapEnabled()) {
- printf(" skipping checks because DebugHeap.\n");
- return;
- }
- auto& impl = heap.impl();
- std::lock_guard<Mutex> locker(impl.lock);
- impl.forEachLiveObject(
- [&] (void* object) {
- CHECK(pointers.erase(object) == 1);
- });
- assertEmptyPointerSet(pointers);
-}
-
-template<typename heapType>
-static void assertClean(IsoHeap<heapType>& heap)
-{
- scavengeThisThread();
- if (!PerProcess<Environment>::get()->isDebugHeapEnabled()) {
- auto& impl = heap.impl();
- {
- std::lock_guard<Mutex> locker(impl.lock);
- CHECK(!impl.numLiveObjects());
- }
- }
- heap.scavenge();
- if (!PerProcess<Environment>::get()->isDebugHeapEnabled()) {
- auto& impl = heap.impl();
- std::lock_guard<Mutex> locker(impl.lock);
- CHECK(!impl.numCommittedPages());
- }
-}
-
-static void testIsoSimple()
-{
- static IsoHeap<double> heap;
- void* ptr1 = heap.allocate();
- CHECK(ptr1);
- void* ptr2 = heap.allocate();
- CHECK(ptr2);
- CHECK(ptr1 != ptr2);
- CHECK(std::abs(static_cast<char*>(ptr1) - static_cast<char*>(ptr2)) >= 8);
- assertHasObjects(heap, {ptr1, ptr2});
- heap.deallocate(ptr1);
- heap.deallocate(ptr2);
- assertClean(heap);
-}
-
-static void testIsoSimpleScavengeBeforeDealloc()
-{
- static IsoHeap<double> heap;
- void* ptr1 = heap.allocate();
- CHECK(ptr1);
- void* ptr2 = heap.allocate();
- CHECK(ptr2);
- CHECK(ptr1 != ptr2);
- CHECK(std::abs(static_cast<char*>(ptr1) - static_cast<char*>(ptr2)) >= 8);
- scavengeThisThread();
- assertHasOnlyObjects(heap, {ptr1, ptr2});
- heap.deallocate(ptr1);
- heap.deallocate(ptr2);
- assertClean(heap);
-}
-
-static void testIsoFlipFlopFragmentedPages()
-{
- static IsoHeap<double> heap;
- std::vector<void*> ptrs;
- for (unsigned i = 100000; i--;) {
- void* ptr = heap.allocate();
- CHECK(ptr);
- ptrs.push_back(ptr);
- }
- for (unsigned i = 0; i < ptrs.size(); i += 2) {
- heap.deallocate(ptrs[i]);
- ptrs[i] = nullptr;
- }
- for (unsigned i = ptrs.size() / 2; i--;)
- ptrs.push_back(heap.allocate());
- for (void* ptr : ptrs)
- heap.deallocate(ptr);
- assertClean(heap);
-}
-
-static void testIsoFlipFlopFragmentedPagesScavengeInMiddle()
-{
- static IsoHeap<double> heap;
- std::vector<void*> ptrs;
- for (unsigned i = 100000; i--;) {
- void* ptr = heap.allocate();
- CHECK(ptr);
- ptrs.push_back(ptr);
- }
- CHECK(toptrset(ptrs).size() == ptrs.size());
- for (unsigned i = 0; i < ptrs.size(); i += 2) {
- heap.deallocate(ptrs[i]);
- ptrs[i] = nullptr;
- }
- heap.scavenge();
- unsigned numCommittedPagesBefore;
- auto& impl = heap.impl();
- {
- std::lock_guard<Mutex> locker(impl.lock);
- numCommittedPagesBefore = impl.numCommittedPages();
- }
- assertHasOnlyObjects(heap, toptrset(ptrs));
- for (unsigned i = ptrs.size() / 2; i--;)
- ptrs.push_back(heap.allocate());
- {
- std::lock_guard<Mutex> locker(impl.lock);
- CHECK(numCommittedPagesBefore == impl.numCommittedPages());
- }
- for (void* ptr : ptrs)
- heap.deallocate(ptr);
- assertClean(heap);
-}
-
-static void testIsoFlipFlopFragmentedPagesScavengeInMiddle288()
-{
- static IsoHeap<char[288]> heap;
- std::vector<void*> ptrs;
- for (unsigned i = 100000; i--;) {
- void* ptr = heap.allocate();
- CHECK(ptr);
- ptrs.push_back(ptr);
- }
- CHECK(toptrset(ptrs).size() == ptrs.size());
- for (unsigned i = 0; i < ptrs.size(); i += 2) {
- heap.deallocate(ptrs[i]);
- ptrs[i] = nullptr;
- }
- heap.scavenge();
- unsigned numCommittedPagesBefore;
- auto& impl = heap.impl();
- {
- std::lock_guard<Mutex> locker(impl.lock);
- numCommittedPagesBefore = impl.numCommittedPages();
- }
- assertHasOnlyObjects(heap, toptrset(ptrs));
- for (unsigned i = ptrs.size() / 2; i--;)
- ptrs.push_back(heap.allocate());
- {
- std::lock_guard<Mutex> locker(impl.lock);
- CHECK(numCommittedPagesBefore == impl.numCommittedPages());
- }
- for (void* ptr : ptrs)
- heap.deallocate(ptr);
- assertClean(heap);
-}
-
-class BisoMalloced {
- MAKE_BISO_MALLOCED(BisoMalloced);
-public:
- BisoMalloced(int x, float y)
- : x(x)
- , y(y)
- {
- }
-
- int x;
- float y;
-};
-
-MAKE_BISO_MALLOCED_IMPL(BisoMalloced);
-
-static void testBisoMalloced()
-{
- BisoMalloced* ptr = new BisoMalloced(4, 5);
- assertHasObjects(BisoMalloced::bisoHeap(), { ptr });
- delete ptr;
- assertClean(BisoMalloced::bisoHeap());
-}
-
-class BisoMallocedInline {
- MAKE_BISO_MALLOCED_INLINE(BisoMalloced);
-public:
- BisoMallocedInline(int x, float y)
- : x(x)
- , y(y)
- {
- }
-
- int x;
- float y;
-};
-
-static void testBisoMallocedInline()
-{
- BisoMallocedInline* ptr = new BisoMallocedInline(4, 5);
- assertHasObjects(BisoMallocedInline::bisoHeap(), { ptr });
- delete ptr;
- assertClean(BisoMallocedInline::bisoHeap());
-}
-
-static void run(const char* filter)
-{
- auto shouldRun = [&] (const char* testName) -> bool {
- return !filter || !!strcasestr(testName, filter);
- };
-
- RUN(testIsoSimple());
- RUN(testIsoSimpleScavengeBeforeDealloc());
- RUN(testIsoFlipFlopFragmentedPages());
- RUN(testIsoFlipFlopFragmentedPagesScavengeInMiddle());
- RUN(testIsoFlipFlopFragmentedPagesScavengeInMiddle288());
- RUN(testBisoMalloced());
- RUN(testBisoMallocedInline());
-
- puts("Success!");
-}
-
-int main(int argc, char** argv)
-{
- const char* filter = nullptr;
- switch (argc) {
- case 1:
- break;
- case 2:
- filter = argv[1];
- break;
- default:
- usage();
- break;
- }
-
- run(filter);
- return 0;
-}
-
Modified: branches/safari-607-branch/Tools/ChangeLog (246420 => 246421)
--- branches/safari-607-branch/Tools/ChangeLog 2019-06-14 02:30:42 UTC (rev 246420)
+++ branches/safari-607-branch/Tools/ChangeLog 2019-06-14 02:30:48 UTC (rev 246421)
@@ -1,3 +1,20 @@
+2019-06-13 Kocsen Chung <[email protected]>
+
+ Apply patch. rdar://problem/51656608
+
+ 2019-06-13 Keith Miller <[email protected]>
+
+ IsoHeaps don't notice uncommitted VA becoming the first eligible.
+ https://bugs.webkit.org/show_bug.cgi?id=198301
+
+ Reviewed by Yusuke Suzuki.
+
+ Move testbmalloc.cpp to TestWTF so it runs in automation.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WTF/bmalloc/IsoHeap.cpp: Renamed from Source/bmalloc/test/testbmalloc.cpp.
+ (TEST):
+
2019-06-12 Null <[email protected]>
Cherry-pick r243631. rdar://problem/51656612
Modified: branches/safari-607-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (246420 => 246421)
--- branches/safari-607-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2019-06-14 02:30:42 UTC (rev 246420)
+++ branches/safari-607-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2019-06-14 02:30:48 UTC (rev 246421)
@@ -258,6 +258,7 @@
536770341CC8022800D425B1 /* WebScriptObjectDescription.mm in Sources */ = {isa = PBXBuildFile; fileRef = 536770331CC8022800D425B1 /* WebScriptObjectDescription.mm */; };
536770361CC81B6100D425B1 /* WebScriptObjectDescription.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 536770351CC812F900D425B1 /* WebScriptObjectDescription.html */; };
53EC25411E96FD87000831B9 /* PriorityQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53EC253F1E96BC80000831B9 /* PriorityQueue.cpp */; };
+ 53FCDE6B229EFFB900598ECF /* IsoHeap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53FCDE6A229EFFB900598ECF /* IsoHeap.cpp */; };
55226A2F1EBA44B900C36AD0 /* large-red-square-image.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 55226A2E1EB969B600C36AD0 /* large-red-square-image.html */; };
5597F8361D9596C80066BC21 /* SynchronizedFixedQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5597F8341D9596C80066BC21 /* SynchronizedFixedQueue.cpp */; };
55A817FC218100E00004A39A /* AdditionalSupportedImageTypes.mm in Sources */ = {isa = PBXBuildFile; fileRef = 55A817FB218100E00004A39A /* AdditionalSupportedImageTypes.mm */; };
@@ -1639,6 +1640,7 @@
536770331CC8022800D425B1 /* WebScriptObjectDescription.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebScriptObjectDescription.mm; sourceTree = "<group>"; };
536770351CC812F900D425B1 /* WebScriptObjectDescription.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = WebScriptObjectDescription.html; sourceTree = "<group>"; };
53EC253F1E96BC80000831B9 /* PriorityQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PriorityQueue.cpp; sourceTree = "<group>"; };
+ 53FCDE6A229EFFB900598ECF /* IsoHeap.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = IsoHeap.cpp; sourceTree = "<group>"; };
55226A2E1EB969B600C36AD0 /* large-red-square-image.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "large-red-square-image.html"; sourceTree = "<group>"; };
5597F8341D9596C80066BC21 /* SynchronizedFixedQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SynchronizedFixedQueue.cpp; sourceTree = "<group>"; };
55A817FB218100E00004A39A /* AdditionalSupportedImageTypes.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AdditionalSupportedImageTypes.mm; sourceTree = "<group>"; };
@@ -2741,6 +2743,14 @@
path = WebCore;
sourceTree = "<group>";
};
+ 53FCDE69229EFF6800598ECF /* bmalloc */ = {
+ isa = PBXGroup;
+ children = (
+ 53FCDE6A229EFFB900598ECF /* IsoHeap.cpp */,
+ );
+ path = bmalloc;
+ sourceTree = "<group>";
+ };
7560917619259C59009EF06E /* ios */ = {
isa = PBXGroup;
children = (
@@ -3197,6 +3207,7 @@
BC9096461255618900083756 /* WTF */ = {
isa = PBXGroup;
children = (
+ 53FCDE69229EFF6800598ECF /* bmalloc */,
C0991C4F143C7D68007998F2 /* cf */,
E3C21A7821B25C82003B31A3 /* cocoa */,
7CBBA07519BB8A0900BBF025 /* darwin */,
@@ -3832,6 +3843,7 @@
7C83DED21D0A590C00FEBCF3 /* HashMap.cpp in Sources */,
7C83DED41D0A590C00FEBCF3 /* HashSet.cpp in Sources */,
7C83DEE01D0A590C00FEBCF3 /* IntegerToStringConversion.cpp in Sources */,
+ 53FCDE6B229EFFB900598ECF /* IsoHeap.cpp in Sources */,
7A0509411FB9F06400B33FB8 /* JSONValue.cpp in Sources */,
531C1D8E1DF8EF72006E979F /* LEBDecoder.cpp in Sources */,
A57D54F91F3397B400A97AA7 /* LifecycleLogger.cpp in Sources */,
Copied: branches/safari-607-branch/Tools/TestWebKitAPI/Tests/WTF/bmalloc/IsoHeap.cpp (from rev 246420, branches/safari-607-branch/Source/bmalloc/test/testbmalloc.cpp) (0 => 246421)
--- branches/safari-607-branch/Tools/TestWebKitAPI/Tests/WTF/bmalloc/IsoHeap.cpp (rev 0)
+++ branches/safari-607-branch/Tools/TestWebKitAPI/Tests/WTF/bmalloc/IsoHeap.cpp 2019-06-14 02:30:48 UTC (rev 246421)
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2017-2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if !USE(SYSTEM_MALLOC)
+
+#include <bmalloc/bmalloc.h>
+#include <bmalloc/Environment.h>
+#include <bmalloc/IsoHeapInlines.h>
+
+#include <cmath>
+#include <cstdlib>
+#include <set>
+#include <vector>
+
+using namespace bmalloc;
+using namespace bmalloc::api;
+
+#define RUN(test) do { \
+if (!shouldRun(#test)) \
+break; \
+puts(#test "..."); \
+test; \
+puts(#test ": OK!"); \
+} while (false)
+
+// Nothing fancy for now; we just use the existing WTF assertion machinery.
+#define CHECK(x) do { \
+if (!!(x)) \
+break; \
+fprintf(stderr, "%s:%d: in %s: assertion %s failed.\n", \
+__FILE__, __LINE__, __PRETTY_FUNCTION__, #x); \
+abort(); \
+} while (false)
+
+static std::set<void*> toptrset(const std::vector<void*>& ptrs)
+{
+ std::set<void*> result;
+ for (void* ptr : ptrs) {
+ if (ptr)
+ result.insert(ptr);
+ }
+ return result;
+}
+
+static void assertEmptyPointerSet(const std::set<void*>& pointers)
+{
+ if (PerProcess<Environment>::get()->isDebugHeapEnabled()) {
+ printf(" skipping checks because DebugHeap.\n");
+ return;
+ }
+ if (pointers.empty())
+ return;
+ printf("Pointer set not empty!\n");
+ printf("Pointers:");
+ for (void* ptr : pointers)
+ printf(" %p", ptr);
+ printf("\n");
+ CHECK(pointers.empty());
+}
+
+template<typename heapType>
+static void assertHasObjects(IsoHeap<heapType>& heap, std::set<void*> pointers)
+{
+ if (PerProcess<Environment>::get()->isDebugHeapEnabled()) {
+ printf(" skipping checks because DebugHeap.\n");
+ return;
+ }
+ auto& impl = heap.impl();
+ std::lock_guard<Mutex> locker(impl.lock);
+ impl.forEachLiveObject(
+ [&] (void* object) {
+ pointers.erase(object);
+ });
+ assertEmptyPointerSet(pointers);
+}
+
+template<typename heapType>
+static void assertHasOnlyObjects(IsoHeap<heapType>& heap, std::set<void*> pointers)
+{
+ if (PerProcess<Environment>::get()->isDebugHeapEnabled()) {
+ printf(" skipping checks because DebugHeap.\n");
+ return;
+ }
+ auto& impl = heap.impl();
+ std::lock_guard<Mutex> locker(impl.lock);
+ impl.forEachLiveObject(
+ [&] (void* object) {
+ CHECK(pointers.erase(object) == 1);
+ });
+ assertEmptyPointerSet(pointers);
+}
+
+template<typename heapType>
+static void assertClean(IsoHeap<heapType>& heap)
+{
+ scavengeThisThread();
+ if (!PerProcess<Environment>::get()->isDebugHeapEnabled()) {
+ auto& impl = heap.impl();
+ {
+ std::lock_guard<Mutex> locker(impl.lock);
+ CHECK(!impl.numLiveObjects());
+ }
+ }
+ heap.scavenge();
+ if (!PerProcess<Environment>::get()->isDebugHeapEnabled()) {
+ auto& impl = heap.impl();
+ std::lock_guard<Mutex> locker(impl.lock);
+ CHECK(!impl.numCommittedPages());
+ }
+}
+
+TEST(bmalloc, IsoSimple)
+{
+ static IsoHeap<double> heap;
+ void* ptr1 = heap.allocate();
+ CHECK(ptr1);
+ void* ptr2 = heap.allocate();
+ CHECK(ptr2);
+ CHECK(ptr1 != ptr2);
+ CHECK(std::abs(static_cast<char*>(ptr1) - static_cast<char*>(ptr2)) >= 8);
+ assertHasObjects(heap, {ptr1, ptr2});
+ heap.deallocate(ptr1);
+ heap.deallocate(ptr2);
+ assertClean(heap);
+}
+
+TEST(bmalloc, IsoSimpleScavengeBeforeDealloc)
+{
+ static IsoHeap<double> heap;
+ void* ptr1 = heap.allocate();
+ CHECK(ptr1);
+ void* ptr2 = heap.allocate();
+ CHECK(ptr2);
+ CHECK(ptr1 != ptr2);
+ CHECK(std::abs(static_cast<char*>(ptr1) - static_cast<char*>(ptr2)) >= 8);
+ scavengeThisThread();
+ assertHasOnlyObjects(heap, {ptr1, ptr2});
+ heap.deallocate(ptr1);
+ heap.deallocate(ptr2);
+ assertClean(heap);
+}
+
+TEST(bmalloc, IsoFlipFlopFragmentedPages)
+{
+ static IsoHeap<double> heap;
+ std::vector<void*> ptrs;
+ for (unsigned i = 100000; i--;) {
+ void* ptr = heap.allocate();
+ CHECK(ptr);
+ ptrs.push_back(ptr);
+ }
+ for (unsigned i = 0; i < ptrs.size(); i += 2) {
+ heap.deallocate(ptrs[i]);
+ ptrs[i] = nullptr;
+ }
+ for (unsigned i = ptrs.size() / 2; i--;)
+ ptrs.push_back(heap.allocate());
+ for (void* ptr : ptrs)
+ heap.deallocate(ptr);
+ assertClean(heap);
+}
+
+TEST(bmalloc, IsoFlipFlopFragmentedPagesScavengeInMiddle)
+{
+ static IsoHeap<double> heap;
+ std::vector<void*> ptrs;
+ for (unsigned i = 100000; i--;) {
+ void* ptr = heap.allocate();
+ CHECK(ptr);
+ ptrs.push_back(ptr);
+ }
+ CHECK(toptrset(ptrs).size() == ptrs.size());
+ for (unsigned i = 0; i < ptrs.size(); i += 2) {
+ heap.deallocate(ptrs[i]);
+ ptrs[i] = nullptr;
+ }
+ heap.scavenge();
+ unsigned numCommittedPagesBefore;
+ auto& impl = heap.impl();
+ {
+ std::lock_guard<Mutex> locker(impl.lock);
+ numCommittedPagesBefore = impl.numCommittedPages();
+ }
+ assertHasOnlyObjects(heap, toptrset(ptrs));
+ for (unsigned i = ptrs.size() / 2; i--;)
+ ptrs.push_back(heap.allocate());
+ {
+ std::lock_guard<Mutex> locker(impl.lock);
+ CHECK(numCommittedPagesBefore == impl.numCommittedPages());
+ }
+ for (void* ptr : ptrs)
+ heap.deallocate(ptr);
+ assertClean(heap);
+}
+
+TEST(bmalloc, IsoFlipFlopFragmentedPagesScavengeInMiddle288)
+{
+ static IsoHeap<char[288]> heap;
+ std::vector<void*> ptrs;
+ for (unsigned i = 100000; i--;) {
+ void* ptr = heap.allocate();
+ CHECK(ptr);
+ ptrs.push_back(ptr);
+ }
+ CHECK(toptrset(ptrs).size() == ptrs.size());
+ for (unsigned i = 0; i < ptrs.size(); i += 2) {
+ heap.deallocate(ptrs[i]);
+ ptrs[i] = nullptr;
+ }
+ heap.scavenge();
+ unsigned numCommittedPagesBefore;
+ auto& impl = heap.impl();
+ {
+ std::lock_guard<Mutex> locker(impl.lock);
+ numCommittedPagesBefore = impl.numCommittedPages();
+ }
+ assertHasOnlyObjects(heap, toptrset(ptrs));
+ for (unsigned i = ptrs.size() / 2; i--;)
+ ptrs.push_back(heap.allocate());
+ {
+ std::lock_guard<Mutex> locker(impl.lock);
+ CHECK(numCommittedPagesBefore == impl.numCommittedPages());
+ }
+ for (void* ptr : ptrs)
+ heap.deallocate(ptr);
+ assertClean(heap);
+}
+
+class BisoMalloced {
+ MAKE_BISO_MALLOCED(BisoMalloced);
+public:
+ BisoMalloced(int x, float y)
+ : x(x)
+ , y(y)
+ {
+ }
+
+ int x;
+ float y;
+};
+
+MAKE_BISO_MALLOCED_IMPL(BisoMalloced);
+
+TEST(bmalloc, BisoMalloced)
+{
+ BisoMalloced* ptr = new BisoMalloced(4, 5);
+ assertHasObjects(BisoMalloced::bisoHeap(), { ptr });
+ delete ptr;
+ assertClean(BisoMalloced::bisoHeap());
+}
+
+class BisoMallocedInline {
+ MAKE_BISO_MALLOCED_INLINE(BisoMalloced);
+public:
+ BisoMallocedInline(int x, float y)
+ : x(x)
+ , y(y)
+ {
+ }
+
+ int x;
+ float y;
+};
+
+TEST(bmalloc, BisoMallocedInline)
+{
+ BisoMallocedInline* ptr = new BisoMallocedInline(4, 5);
+ assertHasObjects(BisoMallocedInline::bisoHeap(), { ptr });
+ delete ptr;
+ assertClean(BisoMallocedInline::bisoHeap());
+}
+
+
+TEST(bmalloc, ScavengedMemoryShouldBeReused)
+{
+ static IsoHeap<double> heap;
+
+ auto run = [] (unsigned numPagesToCommit) {
+ auto* ptr1 = heap.allocate();
+
+ std::vector<void*> ptrs;
+
+ for (unsigned i = 0; ;i++) {
+ void* ptr = heap.allocate();
+ CHECK(ptr);
+ ptrs.push_back(ptr);
+ if (heap.impl().numCommittedPages() == numPagesToCommit)
+ break;
+ }
+
+ std::set<void*> uniquedPtrs = toptrset(ptrs);
+
+ heap.deallocate(ptr1);
+ for (unsigned i = 0; i < IsoPage<decltype(heap)::Config>::numObjects - 1; i++) {
+ heap.deallocate(ptrs[i]);
+ uniquedPtrs.erase(ptrs[i]);
+ }
+
+ scavenge();
+ assertHasOnlyObjects(heap, uniquedPtrs);
+
+ // FIXME: This only seems to pass when lldb is attached but the scavenger thread isn't running...
+ // see: https://bugs.webkit.org/show_bug.cgi?id=198384
+ // auto* ptr2 = heap.allocate();
+ // CHECK(ptr1 == ptr2);
+ };
+
+ run(2);
+}
+
+#endif