Skip to content
This repository was archived by the owner on Jun 24, 2022. It is now read-only.

Commit 8eafba5

Browse files
Add more doesGC() assertions.
https://bugs.webkit.org/show_bug.cgi?id=194911 <rdar://problem/48285723> Reviewed by Saam Barati and Yusuke Suzuki. * dfg/DFGOSRExit.cpp: (JSC::DFG::OSRExit::compileOSRExit): - Set expectDoesGC here because we no longer have to worry about missing store barriers in optimized code after this point. This will prevent false positive assertion failures arising from functions called beneath compileOSRExit(). (JSC::DFG::OSRExit::compileExit): - Add a comment to explain why the generated ramp needs to set expectDoesGC even though compileOSRExit() also sets it. Reason: compileOSRExit() is only called for the first OSR from this code origin, the generated ramp is called for many subsequents OSR exits from this code origin. * ftl/FTLOSRExitCompiler.cpp: (JSC::FTL::compileStub): - Added a comment for the equivalent reason to the one above. (JSC::FTL::compileFTLOSRExit): - Set expectDoesGC here because we no longer have to worry about missing store barriers in optimized code after this point. This will prevent false positive assertion failures arising from functions called beneath compileFTLOSRExit(). * heap/CompleteSubspace.cpp: (JSC::CompleteSubspace::tryAllocateSlow): * heap/CompleteSubspaceInlines.h: (JSC::CompleteSubspace::allocateNonVirtual): - assert expectDoesGC. * heap/DeferGC.h: (JSC::DeferGC::~DeferGC): - assert expectDoesGC. - Also added WTF_FORBID_HEAP_ALLOCATION to DeferGC, DeferGCForAWhile, and DisallowGC because all 3 should be stack allocated RAII objects. * heap/GCDeferralContext.h: * heap/GCDeferralContextInlines.h: (JSC::GCDeferralContext::~GCDeferralContext): - Added WTF_FORBID_HEAP_ALLOCATION. - assert expectDoesGC. * heap/Heap.cpp: (JSC::Heap::collectNow): (JSC::Heap::collectAsync): (JSC::Heap::collectSync): (JSC::Heap::stopIfNecessarySlow): (JSC::Heap::collectIfNecessaryOrDefer): * heap/HeapInlines.h: (JSC::Heap::acquireAccess): (JSC::Heap::stopIfNecessary): * heap/LargeAllocation.cpp: (JSC::LargeAllocation::tryCreate): * heap/LocalAllocatorInlines.h: (JSC::LocalAllocator::allocate): - conservatively assert expectDoesGC on these functions that may trigger a GC though they don't always do. * runtime/DisallowScope.h: - DisallowScope should be stack allocated because it's an RAII object. * runtime/JSCellInlines.h: (JSC::tryAllocateCellHelper): - Remove the expectDoesGC assertion because it is now covered by assertions in CompleteSubspace, LargeAllocation, and LocalAllocator. * runtime/RegExpMatchesArray.h: (JSC::createRegExpMatchesArray): - assert expectDoesGC. git-svn-id: http://svn.webkit.org/repository/webkit/trunk@241927 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent 2102834 commit 8eafba5

15 files changed

+159
-12
lines changed

Source/JavaScriptCore/ChangeLog

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,78 @@
1+
2019-02-21 Mark Lam <[email protected]>
2+
3+
Add more doesGC() assertions.
4+
https://bugs.webkit.org/show_bug.cgi?id=194911
5+
<rdar://problem/48285723>
6+
7+
Reviewed by Saam Barati and Yusuke Suzuki.
8+
9+
* dfg/DFGOSRExit.cpp:
10+
(JSC::DFG::OSRExit::compileOSRExit):
11+
- Set expectDoesGC here because we no longer have to worry about missing store
12+
barriers in optimized code after this point. This will prevent false positive
13+
assertion failures arising from functions called beneath compileOSRExit().
14+
15+
(JSC::DFG::OSRExit::compileExit):
16+
- Add a comment to explain why the generated ramp needs to set expectDoesGC even
17+
though compileOSRExit() also sets it. Reason: compileOSRExit() is only called
18+
for the first OSR from this code origin, the generated ramp is called for many
19+
subsequents OSR exits from this code origin.
20+
21+
* ftl/FTLOSRExitCompiler.cpp:
22+
(JSC::FTL::compileStub):
23+
- Added a comment for the equivalent reason to the one above.
24+
25+
(JSC::FTL::compileFTLOSRExit):
26+
- Set expectDoesGC here because we no longer have to worry about missing store
27+
barriers in optimized code after this point. This will prevent false positive
28+
assertion failures arising from functions called beneath compileFTLOSRExit().
29+
30+
* heap/CompleteSubspace.cpp:
31+
(JSC::CompleteSubspace::tryAllocateSlow):
32+
* heap/CompleteSubspaceInlines.h:
33+
(JSC::CompleteSubspace::allocateNonVirtual):
34+
- assert expectDoesGC.
35+
36+
* heap/DeferGC.h:
37+
(JSC::DeferGC::~DeferGC):
38+
- assert expectDoesGC.
39+
- Also added WTF_FORBID_HEAP_ALLOCATION to DeferGC, DeferGCForAWhile, and DisallowGC
40+
because all 3 should be stack allocated RAII objects.
41+
42+
* heap/GCDeferralContext.h:
43+
* heap/GCDeferralContextInlines.h:
44+
(JSC::GCDeferralContext::~GCDeferralContext):
45+
- Added WTF_FORBID_HEAP_ALLOCATION.
46+
- assert expectDoesGC.
47+
48+
* heap/Heap.cpp:
49+
(JSC::Heap::collectNow):
50+
(JSC::Heap::collectAsync):
51+
(JSC::Heap::collectSync):
52+
(JSC::Heap::stopIfNecessarySlow):
53+
(JSC::Heap::collectIfNecessaryOrDefer):
54+
* heap/HeapInlines.h:
55+
(JSC::Heap::acquireAccess):
56+
(JSC::Heap::stopIfNecessary):
57+
* heap/LargeAllocation.cpp:
58+
(JSC::LargeAllocation::tryCreate):
59+
* heap/LocalAllocatorInlines.h:
60+
(JSC::LocalAllocator::allocate):
61+
- conservatively assert expectDoesGC on these functions that may trigger a GC
62+
though they don't always do.
63+
64+
* runtime/DisallowScope.h:
65+
- DisallowScope should be stack allocated because it's an RAII object.
66+
67+
* runtime/JSCellInlines.h:
68+
(JSC::tryAllocateCellHelper):
69+
- Remove the expectDoesGC assertion because it is now covered by assertions in
70+
CompleteSubspace, LargeAllocation, and LocalAllocator.
71+
72+
* runtime/RegExpMatchesArray.h:
73+
(JSC::createRegExpMatchesArray):
74+
- assert expectDoesGC.
75+
176
2019-02-21 Yusuke Suzuki <[email protected]>
277

378
[JSC] Use Fast Malloc as much as possible

Source/JavaScriptCore/dfg/DFGOSRExit.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,12 @@ void JIT_OPERATION OSRExit::compileOSRExit(ExecState* exec)
10151015
VM* vm = &exec->vm();
10161016
auto scope = DECLARE_THROW_SCOPE(*vm);
10171017

1018+
if (validateDFGDoesGC) {
1019+
// We're about to exit optimized code. So, there's no longer any optimized
1020+
// code running that expects no GC.
1021+
vm->heap.setExpectDoesGC(true);
1022+
}
1023+
10181024
if (vm->callFrameForCatch)
10191025
RELEASE_ASSERT(vm->callFrameForCatch == exec);
10201026

@@ -1399,6 +1405,11 @@ void OSRExit::compileExit(CCallHelpers& jit, VM& vm, const OSRExit& exit, const
13991405
// We're about to exit optimized code. So, there's no longer any optimized
14001406
// code running that expects no GC. We need to set this before arguments
14011407
// materialization below (see emitRestoreArguments()).
1408+
1409+
// Even though we set Heap::m_expectDoesGC in compileOSRExit(), we also need
1410+
// to set it here because compileOSRExit() is only called on the first time
1411+
// we exit from this site, but all subsequent exits will take this compiled
1412+
// ramp without calling compileOSRExit() first.
14021413
jit.store8(CCallHelpers::TrustedImm32(true), vm.heap.addressOfExpectDoesGC());
14031414
}
14041415

Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,11 @@ static void compileStub(
248248
// We're about to exit optimized code. So, there's no longer any optimized
249249
// code running that expects no GC. We need to set this before object
250250
// materialization below.
251+
252+
// Even though we set Heap::m_expectDoesGC in compileFTLOSRExit(), we also need
253+
// to set it here because compileFTLOSRExit() is only called on the first time
254+
// we exit from this site, but all subsequent exits will take this compiled
255+
// ramp without calling compileFTLOSRExit() first.
251256
jit.store8(CCallHelpers::TrustedImm32(true), vm->heap.addressOfExpectDoesGC());
252257
}
253258

@@ -526,6 +531,13 @@ extern "C" void* compileFTLOSRExit(ExecState* exec, unsigned exitID)
526531
dataLog("Compiling OSR exit with exitID = ", exitID, "\n");
527532

528533
VM& vm = exec->vm();
534+
535+
if (validateDFGDoesGC) {
536+
// We're about to exit optimized code. So, there's no longer any optimized
537+
// code running that expects no GC.
538+
vm.heap.setExpectDoesGC(true);
539+
}
540+
529541
if (vm.callFrameForCatch)
530542
RELEASE_ASSERT(vm.callFrameForCatch == exec);
531543

Source/JavaScriptCore/heap/CompleteSubspace.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2017-2018 Apple Inc. All rights reserved.
2+
* Copyright (C) 2017-2019 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -122,6 +122,9 @@ void* CompleteSubspace::allocateSlow(VM& vm, size_t size, GCDeferralContext* def
122122

123123
void* CompleteSubspace::tryAllocateSlow(VM& vm, size_t size, GCDeferralContext* deferralContext)
124124
{
125+
if (validateDFGDoesGC)
126+
RELEASE_ASSERT(vm.heap.expectDoesGC());
127+
125128
sanitizeStackForVM(&vm);
126129

127130
if (Allocator allocator = allocatorFor(size, AllocatorForMode::EnsureAllocator))

Source/JavaScriptCore/heap/CompleteSubspaceInlines.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2018 Apple Inc. All rights reserved.
2+
* Copyright (C) 2018-2019 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -29,6 +29,9 @@ namespace JSC {
2929

3030
ALWAYS_INLINE void* CompleteSubspace::allocateNonVirtual(VM& vm, size_t size, GCDeferralContext* deferralContext, AllocationFailureMode failureMode)
3131
{
32+
if (validateDFGDoesGC)
33+
RELEASE_ASSERT(vm.heap.expectDoesGC());
34+
3235
if (Allocator allocator = allocatorForNonVirtual(size, AllocatorForMode::AllocatorIfExists))
3336
return allocator.allocate(deferralContext, failureMode);
3437
return allocateSlow(vm, size, deferralContext, failureMode);

Source/JavaScriptCore/heap/DeferGC.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2013-2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2013-2019 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -33,6 +33,7 @@ namespace JSC {
3333

3434
class DeferGC {
3535
WTF_MAKE_NONCOPYABLE(DeferGC);
36+
WTF_FORBID_HEAP_ALLOCATION;
3637
public:
3738
DeferGC(Heap& heap)
3839
: m_heap(heap)
@@ -42,6 +43,8 @@ class DeferGC {
4243

4344
~DeferGC()
4445
{
46+
if (validateDFGDoesGC)
47+
RELEASE_ASSERT(m_heap.expectDoesGC());
4548
m_heap.decrementDeferralDepthAndGCIfNeeded();
4649
}
4750

@@ -51,6 +54,7 @@ class DeferGC {
5154

5255
class DeferGCForAWhile {
5356
WTF_MAKE_NONCOPYABLE(DeferGCForAWhile);
57+
WTF_FORBID_HEAP_ALLOCATION;
5458
public:
5559
DeferGCForAWhile(Heap& heap)
5660
: m_heap(heap)
@@ -69,6 +73,7 @@ class DeferGCForAWhile {
6973

7074
class DisallowGC : public DisallowScope<DisallowGC> {
7175
WTF_MAKE_NONCOPYABLE(DisallowGC);
76+
WTF_FORBID_HEAP_ALLOCATION;
7277
typedef DisallowScope<DisallowGC> Base;
7378
public:
7479
#ifdef NDEBUG

Source/JavaScriptCore/heap/GCDeferralContext.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2016-2018 Apple Inc. All rights reserved.
2+
* Copyright (C) 2016-2019 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -25,13 +25,17 @@
2525

2626
#pragma once
2727

28+
#include <wtf/ForbidHeapAllocation.h>
29+
2830
namespace JSC {
2931

3032
class Heap;
3133
class BlockDirectory;
3234
class LocalAllocator;
3335

3436
class GCDeferralContext {
37+
WTF_FORBID_HEAP_ALLOCATION;
38+
3539
friend class Heap;
3640
friend class BlockDirectory;
3741
friend class LocalAllocator;

Source/JavaScriptCore/heap/GCDeferralContextInlines.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2016-2017 Apple Inc. All rights reserved.
2+
* Copyright (C) 2016-2019 Apple Inc. All rights reserved.
33
*
44
* Redistribution and use in source and binary forms, with or without
55
* modification, are permitted provided that the following conditions
@@ -37,6 +37,9 @@ ALWAYS_INLINE GCDeferralContext::GCDeferralContext(Heap& heap)
3737

3838
ALWAYS_INLINE GCDeferralContext::~GCDeferralContext()
3939
{
40+
if (validateDFGDoesGC)
41+
RELEASE_ASSERT(m_heap.expectDoesGC());
42+
4043
if (UNLIKELY(m_shouldGC))
4144
m_heap.collectIfNecessaryOrDefer();
4245
}

Source/JavaScriptCore/heap/Heap.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2003-2018 Apple Inc. All rights reserved.
2+
* Copyright (C) 2003-2019 Apple Inc. All rights reserved.
33
* Copyright (C) 2007 Eric Seidel <[email protected]>
44
*
55
* This library is free software; you can redistribute it and/or
@@ -1029,6 +1029,9 @@ void Heap::collect(Synchronousness synchronousness, GCRequest request)
10291029

10301030
void Heap::collectNow(Synchronousness synchronousness, GCRequest request)
10311031
{
1032+
if (validateDFGDoesGC)
1033+
RELEASE_ASSERT(expectDoesGC());
1034+
10321035
switch (synchronousness) {
10331036
case Async: {
10341037
collectAsync(request);
@@ -1061,6 +1064,9 @@ void Heap::collectNow(Synchronousness synchronousness, GCRequest request)
10611064

10621065
void Heap::collectAsync(GCRequest request)
10631066
{
1067+
if (validateDFGDoesGC)
1068+
RELEASE_ASSERT(expectDoesGC());
1069+
10641070
if (!m_isSafeToCollect)
10651071
return;
10661072

@@ -1082,9 +1088,12 @@ void Heap::collectAsync(GCRequest request)
10821088

10831089
void Heap::collectSync(GCRequest request)
10841090
{
1091+
if (validateDFGDoesGC)
1092+
RELEASE_ASSERT(expectDoesGC());
1093+
10851094
if (!m_isSafeToCollect)
10861095
return;
1087-
1096+
10881097
waitForCollection(requestCollection(request));
10891098
}
10901099

@@ -1737,6 +1746,9 @@ NEVER_INLINE void Heap::resumeTheMutator()
17371746

17381747
void Heap::stopIfNecessarySlow()
17391748
{
1749+
if (validateDFGDoesGC)
1750+
RELEASE_ASSERT(expectDoesGC());
1751+
17401752
while (stopIfNecessarySlow(m_worldState.load())) { }
17411753

17421754
RELEASE_ASSERT(m_worldState.load() & hasAccessBit);
@@ -1749,6 +1761,9 @@ void Heap::stopIfNecessarySlow()
17491761

17501762
bool Heap::stopIfNecessarySlow(unsigned oldState)
17511763
{
1764+
if (validateDFGDoesGC)
1765+
RELEASE_ASSERT(expectDoesGC());
1766+
17521767
RELEASE_ASSERT(oldState & hasAccessBit);
17531768
RELEASE_ASSERT(!(oldState & stoppedBit));
17541769

@@ -2538,9 +2553,12 @@ void Heap::reportExternalMemoryVisited(size_t size)
25382553
void Heap::collectIfNecessaryOrDefer(GCDeferralContext* deferralContext)
25392554
{
25402555
ASSERT(deferralContext || isDeferred() || !DisallowGC::isInEffectOnCurrentThread());
2556+
if (validateDFGDoesGC)
2557+
RELEASE_ASSERT(expectDoesGC());
25412558

25422559
if (!m_isSafeToCollect)
25432560
return;
2561+
25442562
switch (mutatorState()) {
25452563
case MutatorState::Running:
25462564
case MutatorState::Allocating:

Source/JavaScriptCore/heap/HeapInlines.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,9 @@ inline void Heap::deprecatedReportExtraMemory(size_t size)
238238

239239
inline void Heap::acquireAccess()
240240
{
241+
if (validateDFGDoesGC)
242+
RELEASE_ASSERT(expectDoesGC());
243+
241244
if (m_worldState.compareExchangeWeak(0, hasAccessBit))
242245
return;
243246
acquireAccessSlow();
@@ -262,6 +265,9 @@ inline bool Heap::mayNeedToStop()
262265

263266
inline void Heap::stopIfNecessary()
264267
{
268+
if (validateDFGDoesGC)
269+
RELEASE_ASSERT(expectDoesGC());
270+
265271
if (mayNeedToStop())
266272
stopIfNecessarySlow();
267273
}

0 commit comments

Comments
 (0)