Bug 1470795 Part 3 - Trivial renaming due to API changes, r=froydnj.

--HG--
extra : rebase_source : 95fd379bb385ead70fa241933639e704267229d9
This commit is contained in:
Brian Hackett 2018-07-22 11:57:38 +00:00
Родитель 312bb81dda
Коммит 4f9e9a98ca
11 изменённых файлов: 97 добавлений и 161 удалений

Просмотреть файл

@ -110,12 +110,12 @@ public:
, mCallbackStorage(nullptr) , mCallbackStorage(nullptr)
{ {
// Use AllocateMemory, as the result will have RWX permissions. // Use AllocateMemory, as the result will have RWX permissions.
mCallbackStorage = (uint8_t*) AllocateMemory(CallbackStorageCapacity, TrackedMemoryKind); mCallbackStorage = (uint8_t*) AllocateMemory(CallbackStorageCapacity, MemoryKind::Tracked);
} }
~StableHashTableInfo() { ~StableHashTableInfo() {
MOZ_ASSERT(mHashToKey.empty()); MOZ_ASSERT(mHashToKey.empty());
DeallocateMemory(mCallbackStorage, CallbackStorageCapacity, TrackedMemoryKind); DeallocateMemory(mCallbackStorage, CallbackStorageCapacity, MemoryKind::Tracked);
} }
bool AppearsValid() { bool AppearsValid() {

Просмотреть файл

@ -6,8 +6,7 @@
#include "MemorySnapshot.h" #include "MemorySnapshot.h"
#include "ipc/ChildIPC.h" #include "ipc/ChildInternal.h"
#include "js/ReplayHooks.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "DirtyMemoryHandler.h" #include "DirtyMemoryHandler.h"
#include "InfallibleVector.h" #include "InfallibleVector.h"
@ -161,7 +160,7 @@ struct DirtyPage {
// A set of dirty pages that can be searched quickly. // A set of dirty pages that can be searched quickly.
typedef SplayTree<DirtyPage, DirtyPage::AddressSort, typedef SplayTree<DirtyPage, DirtyPage::AddressSort,
AllocPolicy<UntrackedMemoryKind::SortedDirtyPageSet>, 4> SortedDirtyPageSet; AllocPolicy<MemoryKind::SortedDirtyPageSet>, 4> SortedDirtyPageSet;
// A set of dirty pages associated with some checkpoint. // A set of dirty pages associated with some checkpoint.
struct DirtyPageSet { struct DirtyPageSet {
@ -172,7 +171,7 @@ struct DirtyPageSet {
// thread when all other threads are idle, by the dirty memory handler when // thread when all other threads are idle, by the dirty memory handler when
// it is active and this is the active page set, and by the snapshot thread // it is active and this is the active page set, and by the snapshot thread
// which owns this set. // which owns this set.
InfallibleVector<DirtyPage, 256, AllocPolicy<UntrackedMemoryKind::DirtyPageSet>> mPages; InfallibleVector<DirtyPage, 256, AllocPolicy<MemoryKind::DirtyPageSet>> mPages;
explicit DirtyPageSet(const CheckpointId& aCheckpoint) explicit DirtyPageSet(const CheckpointId& aCheckpoint)
: mCheckpoint(aCheckpoint) : mCheckpoint(aCheckpoint)
@ -189,7 +188,7 @@ struct SnapshotThreadWorklist {
// Sets of pages in the thread's worklist. Each set is for a different diff, // Sets of pages in the thread's worklist. Each set is for a different diff,
// with the oldest checkpoints first. // with the oldest checkpoints first.
InfallibleVector<DirtyPageSet, 256, AllocPolicy<UntrackedMemoryKind::Generic>> mSets; InfallibleVector<DirtyPageSet, 256, AllocPolicy<MemoryKind::Generic>> mSets;
}; };
// Structure used to coordinate activity between the main thread and all // Structure used to coordinate activity between the main thread and all
@ -232,7 +231,7 @@ static const size_t NumSnapshotThreads = 8;
class FreeRegionSet { class FreeRegionSet {
// Kind of memory being managed. This also describes the memory used by the // Kind of memory being managed. This also describes the memory used by the
// set itself. // set itself.
AllocatedMemoryKind mKind; MemoryKind mKind;
// Lock protecting contents of the structure. // Lock protecting contents of the structure.
SpinLock mLock; SpinLock mLock;
@ -277,12 +276,12 @@ class FreeRegionSet {
void* ExtractLockHeld(size_t aSize, AutoSpinLock& aLockHeld); void* ExtractLockHeld(size_t aSize, AutoSpinLock& aLockHeld);
public: public:
explicit FreeRegionSet(AllocatedMemoryKind aKind) explicit FreeRegionSet(MemoryKind aKind)
: mKind(aKind), mRegions(MyAllocPolicy(*this)) : mKind(aKind), mRegions(MyAllocPolicy(*this))
{} {}
// Get the single region set for a given memory kind. // Get the single region set for a given memory kind.
static FreeRegionSet& Get(AllocatedMemoryKind aKind); static FreeRegionSet& Get(MemoryKind aKind);
// Add a free region to the set. // Add a free region to the set.
void Insert(void* aAddress, size_t aSize); void Insert(void* aAddress, size_t aSize);
@ -312,9 +311,9 @@ struct MemoryInfo {
// All tracked memory in the process. This may be updated by any thread while // All tracked memory in the process. This may be updated by any thread while
// holding mTrackedRegionsLock. // holding mTrackedRegionsLock.
SplayTree<AllocatedMemoryRegion, AllocatedMemoryRegion::AddressSort, SplayTree<AllocatedMemoryRegion, AllocatedMemoryRegion::AddressSort,
AllocPolicy<UntrackedMemoryKind::TrackedRegions>, 4> AllocPolicy<MemoryKind::TrackedRegions>, 4>
mTrackedRegions; mTrackedRegions;
InfallibleVector<AllocatedMemoryRegion, 512, AllocPolicy<UntrackedMemoryKind::TrackedRegions>> InfallibleVector<AllocatedMemoryRegion, 512, AllocPolicy<MemoryKind::TrackedRegions>>
mTrackedRegionsByAllocationOrder; mTrackedRegionsByAllocationOrder;
SpinLock mTrackedRegionsLock; SpinLock mTrackedRegionsLock;
@ -347,7 +346,7 @@ struct MemoryInfo {
double mTimeTotals[(size_t) TimerKind::Count]; double mTimeTotals[(size_t) TimerKind::Count];
// Information for memory allocation. // Information for memory allocation.
Atomic<ssize_t, Relaxed, Behavior::DontPreserve> mMemoryBalance[UntrackedMemoryKind::Count]; Atomic<ssize_t, Relaxed, Behavior::DontPreserve> mMemoryBalance[(size_t) MemoryKind::Count];
// Recent dirty memory faults. // Recent dirty memory faults.
void* mDirtyMemoryFaults[50]; void* mDirtyMemoryFaults[50];
@ -360,7 +359,7 @@ struct MemoryInfo {
MemoryInfo() MemoryInfo()
: mMemoryChangesAllowed(true) : mMemoryChangesAllowed(true)
, mFreeUntrackedRegions(UntrackedMemoryKind::FreeRegions) , mFreeUntrackedRegions(MemoryKind::FreeRegions)
, mStartTime(CurrentTime()) , mStartTime(CurrentTime())
, mIntentionalCrashesAllowed(true) , mIntentionalCrashesAllowed(true)
{ {
@ -483,7 +482,7 @@ RecordReplayInterface_InternalRecordReplayDirective(long aDirective)
gMemoryInfo->mCrashSoon = false; gMemoryInfo->mCrashSoon = false;
break; break;
case Directive::AlwaysSaveTemporaryCheckpoints: case Directive::AlwaysSaveTemporaryCheckpoints:
JS::replay::hooks.alwaysSaveTemporaryCheckpoints(); navigation::AlwaysSaveTemporaryCheckpoints();
break; break;
case Directive::AlwaysMarkMajorCheckpoints: case Directive::AlwaysMarkMajorCheckpoints:
child::NotifyAlwaysMarkMajorCheckpoints(); child::NotifyAlwaysMarkMajorCheckpoints();
@ -558,14 +557,14 @@ SnapshotThreadCondition::WaitUntilNoLongerActive()
static uint8_t* static uint8_t*
AllocatePageCopy() AllocatePageCopy()
{ {
return (uint8_t*) AllocateMemory(PageSize, UntrackedMemoryKind::PageCopy); return (uint8_t*) AllocateMemory(PageSize, MemoryKind::PageCopy);
} }
// Free a page allocated by AllocatePageCopy. // Free a page allocated by AllocatePageCopy.
static void static void
FreePageCopy(uint8_t* aPage) FreePageCopy(uint8_t* aPage)
{ {
DeallocateMemory(aPage, PageSize, UntrackedMemoryKind::PageCopy); DeallocateMemory(aPage, PageSize, MemoryKind::PageCopy);
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -875,7 +874,7 @@ ProcessAllInitialMemoryRegions()
// All memory in gMemoryInfo->mTrackedRegions that is not in use at the current // All memory in gMemoryInfo->mTrackedRegions that is not in use at the current
// point in execution. // point in execution.
static FreeRegionSet gFreeRegions(TrackedMemoryKind); static FreeRegionSet gFreeRegions(MemoryKind::Tracked);
// The size of gMemoryInfo->mTrackedRegionsByAllocationOrder we expect to see // The size of gMemoryInfo->mTrackedRegionsByAllocationOrder we expect to see
// at the point of the last saved checkpoint. // at the point of the last saved checkpoint.
@ -902,9 +901,9 @@ FixupFreeRegionsAfterRewind()
} }
/* static */ FreeRegionSet& /* static */ FreeRegionSet&
FreeRegionSet::Get(AllocatedMemoryKind aKind) FreeRegionSet::Get(MemoryKind aKind)
{ {
return (aKind == TrackedMemoryKind) ? gFreeRegions : gMemoryInfo->mFreeUntrackedRegions; return (aKind == MemoryKind::Tracked) ? gFreeRegions : gMemoryInfo->mFreeUntrackedRegions;
} }
void* void*
@ -931,7 +930,7 @@ FreeRegionSet::MaybeRefillNextChunk(AutoSpinLock& aLockHeld)
// Look for a free region we can take the next chunk from. // Look for a free region we can take the next chunk from.
size_t size = ChunkPages * PageSize; size_t size = ChunkPages * PageSize;
gMemoryInfo->mMemoryBalance[mKind] += size; gMemoryInfo->mMemoryBalance[(size_t) mKind] += size;
mNextChunk = ExtractLockHeld(size, aLockHeld); mNextChunk = ExtractLockHeld(size, aLockHeld);
@ -1026,14 +1025,14 @@ FreeRegionSet::Intersects(void* aAddress, size_t aSize)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void void
RegisterAllocatedMemory(void* aBaseAddress, size_t aSize, AllocatedMemoryKind aKind) RegisterAllocatedMemory(void* aBaseAddress, size_t aSize, MemoryKind aKind)
{ {
MOZ_RELEASE_ASSERT(aBaseAddress == PageBase(aBaseAddress)); MOZ_RELEASE_ASSERT(aBaseAddress == PageBase(aBaseAddress));
MOZ_RELEASE_ASSERT(aSize == RoundupSizeToPageBoundary(aSize)); MOZ_RELEASE_ASSERT(aSize == RoundupSizeToPageBoundary(aSize));
uint8_t* aAddress = reinterpret_cast<uint8_t*>(aBaseAddress); uint8_t* aAddress = reinterpret_cast<uint8_t*>(aBaseAddress);
if (aKind != TrackedMemoryKind) { if (aKind != MemoryKind::Tracked) {
if (!HasSavedCheckpoint()) { if (!HasSavedCheckpoint()) {
AddInitialUntrackedMemoryRegion(aAddress, aSize); AddInitialUntrackedMemoryRegion(aAddress, aSize);
} }
@ -1096,13 +1095,13 @@ RestoreWritableFixedMemory(void* aAddress, size_t aSize)
} }
void* void*
AllocateMemoryTryAddress(void* aAddress, size_t aSize, AllocatedMemoryKind aKind) AllocateMemoryTryAddress(void* aAddress, size_t aSize, MemoryKind aKind)
{ {
MOZ_RELEASE_ASSERT(aAddress == PageBase(aAddress)); MOZ_RELEASE_ASSERT(aAddress == PageBase(aAddress));
aSize = RoundupSizeToPageBoundary(aSize); aSize = RoundupSizeToPageBoundary(aSize);
if (gMemoryInfo) { if (gMemoryInfo) {
gMemoryInfo->mMemoryBalance[aKind] += aSize; gMemoryInfo->mMemoryBalance[(size_t) aKind] += aSize;
} }
if (HasSavedCheckpoint()) { if (HasSavedCheckpoint()) {
@ -1116,10 +1115,8 @@ AllocateMemoryTryAddress(void* aAddress, size_t aSize, AllocatedMemoryKind aKind
return res; return res;
} }
extern "C" { void*
AllocateMemory(size_t aSize, MemoryKind aKind)
MOZ_EXPORT void*
RecordReplayInterface_AllocateMemory(size_t aSize, AllocatedMemoryKind aKind)
{ {
if (!IsReplaying()) { if (!IsReplaying()) {
return DirectAllocateMemory(nullptr, aSize); return DirectAllocateMemory(nullptr, aSize);
@ -1127,8 +1124,8 @@ RecordReplayInterface_AllocateMemory(size_t aSize, AllocatedMemoryKind aKind)
return AllocateMemoryTryAddress(nullptr, aSize, aKind); return AllocateMemoryTryAddress(nullptr, aSize, aKind);
} }
MOZ_EXPORT void void
RecordReplayInterface_DeallocateMemory(void* aAddress, size_t aSize, AllocatedMemoryKind aKind) DeallocateMemory(void* aAddress, size_t aSize, MemoryKind aKind)
{ {
// Round the supplied region to the containing page boundaries. // Round the supplied region to the containing page boundaries.
aSize += (uint8_t*) aAddress - PageBase(aAddress); aSize += (uint8_t*) aAddress - PageBase(aAddress);
@ -1140,19 +1137,19 @@ RecordReplayInterface_DeallocateMemory(void* aAddress, size_t aSize, AllocatedMe
} }
if (gMemoryInfo) { if (gMemoryInfo) {
gMemoryInfo->mMemoryBalance[aKind] -= aSize; gMemoryInfo->mMemoryBalance[(size_t) aKind] -= aSize;
} }
// Memory is returned to the system before saving the first checkpoint. // Memory is returned to the system before saving the first checkpoint.
if (!HasSavedCheckpoint()) { if (!HasSavedCheckpoint()) {
if (IsReplaying() && aKind != TrackedMemoryKind) { if (IsReplaying() && aKind != MemoryKind::Tracked) {
RemoveInitialUntrackedRegion((uint8_t*) aAddress, aSize); RemoveInitialUntrackedRegion((uint8_t*) aAddress, aSize);
} }
DirectDeallocateMemory(aAddress, aSize); DirectDeallocateMemory(aAddress, aSize);
return; return;
} }
if (aKind == TrackedMemoryKind) { if (aKind == MemoryKind::Tracked) {
// For simplicity, all free regions must be executable, so ignore deallocated // For simplicity, all free regions must be executable, so ignore deallocated
// memory in regions that are not executable. // memory in regions that are not executable.
bool executable; bool executable;
@ -1167,8 +1164,6 @@ RecordReplayInterface_DeallocateMemory(void* aAddress, size_t aSize, AllocatedMe
FreeRegionSet::Get(aKind).Insert(aAddress, aSize); FreeRegionSet::Get(aKind).Insert(aAddress, aSize);
} }
} // extern "C"
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Snapshot Threads // Snapshot Threads
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -1273,7 +1268,7 @@ void
InitializeMemorySnapshots() InitializeMemorySnapshots()
{ {
MOZ_RELEASE_ASSERT(gMemoryInfo == nullptr); MOZ_RELEASE_ASSERT(gMemoryInfo == nullptr);
void* memory = AllocateMemory(sizeof(MemoryInfo), UntrackedMemoryKind::Generic); void* memory = AllocateMemory(sizeof(MemoryInfo), MemoryKind::Generic);
gMemoryInfo = new(memory) MemoryInfo(); gMemoryInfo = new(memory) MemoryInfo();
// Mark gMemoryInfo as untracked. See AddInitialUntrackedMemoryRegion. // Mark gMemoryInfo as untracked. See AddInitialUntrackedMemoryRegion.

Просмотреть файл

@ -40,11 +40,11 @@ void RestoreWritableFixedMemory(void* aAddress, size_t aSize);
// Allocate memory, trying to use a specific address if provided but only if // Allocate memory, trying to use a specific address if provided but only if
// it is free. // it is free.
void* AllocateMemoryTryAddress(void* aAddress, size_t aSize, AllocatedMemoryKind aKind); void* AllocateMemoryTryAddress(void* aAddress, size_t aSize, MemoryKind aKind);
// Note a range of memory that was just allocated from the system, and the // Note a range of memory that was just allocated from the system, and the
// kind of memory allocation that was performed. // kind of memory allocation that was performed.
void RegisterAllocatedMemory(void* aBaseAddress, size_t aSize, AllocatedMemoryKind aKind); void RegisterAllocatedMemory(void* aBaseAddress, size_t aSize, MemoryKind aKind);
// Initialize the memory snapshots system. // Initialize the memory snapshots system.
void InitializeMemorySnapshots(); void InitializeMemorySnapshots();

Просмотреть файл

@ -6,7 +6,7 @@
#include "ProcessRecordReplay.h" #include "ProcessRecordReplay.h"
#include "ipc/ChildIPC.h" #include "ipc/ChildInternal.h"
#include "mozilla/Compression.h" #include "mozilla/Compression.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "mozilla/Sprintf.h" #include "mozilla/Sprintf.h"
@ -221,7 +221,7 @@ FlushRecording()
MOZ_RELEASE_ASSERT(Thread::CurrentIsMainThread()); MOZ_RELEASE_ASSERT(Thread::CurrentIsMainThread());
// Save the endpoint of the recording. // Save the endpoint of the recording.
JS::replay::ExecutionPoint endpoint = JS::replay::hooks.getRecordingEndpoint(); js::ExecutionPoint endpoint = navigation::GetRecordingEndpoint();
Stream* endpointStream = gRecordingFile->OpenStream(StreamName::Main, 0); Stream* endpointStream = gRecordingFile->OpenStream(StreamName::Main, 0);
endpointStream->WriteScalar(++gNumEndpoints); endpointStream->WriteScalar(++gNumEndpoints);
endpointStream->WriteBytes(&endpoint, sizeof(endpoint)); endpointStream->WriteBytes(&endpoint, sizeof(endpoint));
@ -274,10 +274,10 @@ HitRecordingEndpoint()
// Check if there is a new endpoint in the endpoint data stream. // Check if there is a new endpoint in the endpoint data stream.
Stream* endpointStream = gRecordingFile->OpenStream(StreamName::Main, 0); Stream* endpointStream = gRecordingFile->OpenStream(StreamName::Main, 0);
if (!endpointStream->AtEnd()) { if (!endpointStream->AtEnd()) {
JS::replay::ExecutionPoint endpoint; js::ExecutionPoint endpoint;
size_t index = endpointStream->ReadScalar(); size_t index = endpointStream->ReadScalar();
endpointStream->ReadBytes(&endpoint, sizeof(endpoint)); endpointStream->ReadBytes(&endpoint, sizeof(endpoint));
JS::replay::hooks.setRecordingEndpoint(index, endpoint); navigation::SetRecordingEndpoint(index, endpoint);
return true; return true;
} }
@ -308,16 +308,14 @@ HitEndOfRecording()
} }
} }
extern "C" { bool
SpewEnabled()
MOZ_EXPORT bool
RecordReplayInterface_SpewEnabled()
{ {
return gSpewEnabled; return gSpewEnabled;
} }
MOZ_EXPORT void void
RecordReplayInterface_InternalPrint(const char* aFormat, va_list aArgs) InternalPrint(const char* aFormat, va_list aArgs)
{ {
char buf1[2048]; char buf1[2048];
VsprintfLiteral(buf1, aFormat, aArgs); VsprintfLiteral(buf1, aFormat, aArgs);
@ -326,8 +324,6 @@ RecordReplayInterface_InternalPrint(const char* aFormat, va_list aArgs)
DirectPrint(buf2); DirectPrint(buf2);
} }
} // extern "C"
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Record/Replay Assertions // Record/Replay Assertions
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -638,7 +638,7 @@ RR_mmap(void* aAddress, size_t aSize, int aProt, int aFlags, int aFd, off_t aOff
memory = aAddress; memory = aAddress;
} else { } else {
memory = AllocateMemoryTryAddress(aAddress, RoundupSizeToPageBoundary(aSize), memory = AllocateMemoryTryAddress(aAddress, RoundupSizeToPageBoundary(aSize),
TrackedMemoryKind); MemoryKind::Tracked);
} }
} else { } else {
// We have to call mmap itself, which can change memory protection flags // We have to call mmap itself, which can change memory protection flags
@ -652,7 +652,7 @@ RR_mmap(void* aAddress, size_t aSize, int aProt, int aFlags, int aFd, off_t aOff
MOZ_RELEASE_ASSERT(memory == aAddress); MOZ_RELEASE_ASSERT(memory == aAddress);
RestoreWritableFixedMemory(memory, RoundupSizeToPageBoundary(aSize)); RestoreWritableFixedMemory(memory, RoundupSizeToPageBoundary(aSize));
} else if (memory && memory != (void*)-1) { } else if (memory && memory != (void*)-1) {
RegisterAllocatedMemory(memory, RoundupSizeToPageBoundary(aSize), TrackedMemoryKind); RegisterAllocatedMemory(memory, RoundupSizeToPageBoundary(aSize), MemoryKind::Tracked);
} }
} }
@ -670,7 +670,7 @@ RR_mmap(void* aAddress, size_t aSize, int aProt, int aFlags, int aFd, off_t aOff
static ssize_t static ssize_t
RR_munmap(void* aAddress, size_t aSize) RR_munmap(void* aAddress, size_t aSize)
{ {
DeallocateMemory(aAddress, aSize, TrackedMemoryKind); DeallocateMemory(aAddress, aSize, MemoryKind::Tracked);
return 0; return 0;
} }
@ -1505,14 +1505,14 @@ static kern_return_t
RR_mach_vm_allocate(vm_map_t aTarget, mach_vm_address_t* aAddress, RR_mach_vm_allocate(vm_map_t aTarget, mach_vm_address_t* aAddress,
mach_vm_size_t aSize, int aFlags) mach_vm_size_t aSize, int aFlags)
{ {
*aAddress = (mach_vm_address_t) AllocateMemory(aSize, TrackedMemoryKind); *aAddress = (mach_vm_address_t) AllocateMemory(aSize, MemoryKind::Tracked);
return KERN_SUCCESS; return KERN_SUCCESS;
} }
static kern_return_t static kern_return_t
RR_mach_vm_deallocate(vm_map_t aTarget, mach_vm_address_t aAddress, mach_vm_size_t aSize) RR_mach_vm_deallocate(vm_map_t aTarget, mach_vm_address_t aAddress, mach_vm_size_t aSize)
{ {
DeallocateMemory((void*) aAddress, aSize, TrackedMemoryKind); DeallocateMemory((void*) aAddress, aSize, MemoryKind::Tracked);
return KERN_SUCCESS; return KERN_SUCCESS;
} }

Просмотреть файл

@ -7,6 +7,7 @@
#include "ProcessRewind.h" #include "ProcessRewind.h"
#include "nsString.h" #include "nsString.h"
#include "ipc/ChildInternal.h"
#include "mozilla/dom/ScriptSettings.h" #include "mozilla/dom/ScriptSettings.h"
#include "mozilla/StaticMutex.h" #include "mozilla/StaticMutex.h"
#include "InfallibleVector.h" #include "InfallibleVector.h"
@ -14,10 +15,6 @@
#include "Monitor.h" #include "Monitor.h"
#include "ProcessRecordReplay.h" #include "ProcessRecordReplay.h"
#include "ThreadSnapshot.h" #include "ThreadSnapshot.h"
#include "prcvar.h"
#include <setjmp.h>
#include <sys/time.h>
namespace mozilla { namespace mozilla {
namespace recordreplay { namespace recordreplay {
@ -35,11 +32,11 @@ struct RewindInfo
// Checkpoints which have been saved. This includes only entries from // Checkpoints which have been saved. This includes only entries from
// mShouldSaveCheckpoints, plus all temporary checkpoints. // mShouldSaveCheckpoints, plus all temporary checkpoints.
InfallibleVector<SavedCheckpoint, 1024, AllocPolicy<UntrackedMemoryKind::Generic>> mSavedCheckpoints; InfallibleVector<SavedCheckpoint, 1024, AllocPolicy<MemoryKind::Generic>> mSavedCheckpoints;
// Unsorted list of checkpoints which the middleman has instructed us to // Unsorted list of checkpoints which the middleman has instructed us to
// save. All those equal to or prior to mLastCheckpoint will have been saved. // save. All those equal to or prior to mLastCheckpoint will have been saved.
InfallibleVector<size_t, 1024, AllocPolicy<UntrackedMemoryKind::Generic>> mShouldSaveCheckpoints; InfallibleVector<size_t, 1024, AllocPolicy<MemoryKind::Generic>> mShouldSaveCheckpoints;
}; };
static RewindInfo* gRewindInfo; static RewindInfo* gRewindInfo;
@ -55,7 +52,7 @@ void
InitializeRewindState() InitializeRewindState()
{ {
MOZ_RELEASE_ASSERT(gRewindInfo == nullptr); MOZ_RELEASE_ASSERT(gRewindInfo == nullptr);
void* memory = AllocateMemory(sizeof(RewindInfo), UntrackedMemoryKind::Generic); void* memory = AllocateMemory(sizeof(RewindInfo), MemoryKind::Generic);
gRewindInfo = new(memory) RewindInfo(); gRewindInfo = new(memory) RewindInfo();
gMainThreadCallbackMonitor = new Monitor(); gMainThreadCallbackMonitor = new Monitor();
@ -67,10 +64,8 @@ CheckpointPrecedes(const CheckpointId& aFirst, const CheckpointId& aSecond)
return aFirst.mNormal < aSecond.mNormal || aFirst.mTemporary < aSecond.mTemporary; return aFirst.mNormal < aSecond.mNormal || aFirst.mTemporary < aSecond.mTemporary;
} }
extern "C" { void
RestoreCheckpointAndResume(const CheckpointId& aCheckpoint)
MOZ_EXPORT void
RecordReplayInterface_RestoreCheckpointAndResume(const CheckpointId& aCheckpoint)
{ {
MOZ_RELEASE_ASSERT(IsReplaying()); MOZ_RELEASE_ASSERT(IsReplaying());
MOZ_RELEASE_ASSERT(Thread::CurrentIsMainThread()); MOZ_RELEASE_ASSERT(Thread::CurrentIsMainThread());
@ -115,19 +110,6 @@ RecordReplayInterface_RestoreCheckpointAndResume(const CheckpointId& aCheckpoint
Unreachable(); Unreachable();
} }
static BeforeCheckpointHook gBeforeCheckpointHook;
static AfterCheckpointHook gAfterCheckpointHook;
MOZ_EXPORT void
RecordReplayInterface_SetCheckpointHooks(BeforeCheckpointHook aBeforeCheckpoint,
AfterCheckpointHook aAfterCheckpoint)
{
gBeforeCheckpointHook = aBeforeCheckpoint;
gAfterCheckpointHook = aAfterCheckpoint;
}
} // extern "C"
void void
SetSaveCheckpoint(size_t aCheckpoint, bool aSave) SetSaveCheckpoint(size_t aCheckpoint, bool aSave)
{ {
@ -135,26 +117,17 @@ SetSaveCheckpoint(size_t aCheckpoint, bool aSave)
VectorAddOrRemoveEntry(gRewindInfo->mShouldSaveCheckpoints, aCheckpoint, aSave); VectorAddOrRemoveEntry(gRewindInfo->mShouldSaveCheckpoints, aCheckpoint, aSave);
} }
extern "C" { bool
NewCheckpoint(bool aTemporary)
// Mark a checkpoint, which we might or might not save.
MOZ_EXPORT bool
RecordReplayInterface_NewCheckpoint(bool aTemporary)
{ {
MOZ_RELEASE_ASSERT(Thread::CurrentIsMainThread()); MOZ_RELEASE_ASSERT(Thread::CurrentIsMainThread());
MOZ_RELEASE_ASSERT(!AreThreadEventsPassedThrough()); MOZ_RELEASE_ASSERT(!AreThreadEventsPassedThrough());
MOZ_RELEASE_ASSERT(IsReplaying() || !aTemporary); MOZ_RELEASE_ASSERT(IsReplaying() || !aTemporary);
gBeforeCheckpointHook(); navigation::BeforeCheckpoint();
// Get the ID of the new checkpoint. // Get the ID of the new checkpoint.
CheckpointId checkpoint = gRewindInfo->mLastCheckpoint; CheckpointId checkpoint = gRewindInfo->mLastCheckpoint.NextCheckpoint(aTemporary);
if (aTemporary) {
checkpoint.mTemporary++;
} else {
checkpoint.mNormal++;
checkpoint.mTemporary = 0;
}
// Save all checkpoints the middleman tells us to, and temporary checkpoints // Save all checkpoints the middleman tells us to, and temporary checkpoints
// (which the middleman never knows about). // (which the middleman never knows about).
@ -202,11 +175,7 @@ RecordReplayInterface_NewCheckpoint(bool aTemporary)
gRewindInfo->mLastCheckpoint = checkpoint; gRewindInfo->mLastCheckpoint = checkpoint;
AutoDisallowThreadEvents disallow; navigation::AfterCheckpoint(checkpoint);
dom::AutoJSAPI jsapi;
jsapi.Init();
gAfterCheckpointHook(checkpoint);
return reachedCheckpoint; return reachedCheckpoint;
} }
@ -214,8 +183,8 @@ RecordReplayInterface_NewCheckpoint(bool aTemporary)
static bool gRecordingDiverged; static bool gRecordingDiverged;
static bool gUnhandledDivergeAllowed; static bool gUnhandledDivergeAllowed;
MOZ_EXPORT void void
RecordReplayInterface_DivergeFromRecording() DivergeFromRecording()
{ {
MOZ_RELEASE_ASSERT(Thread::CurrentIsMainThread()); MOZ_RELEASE_ASSERT(Thread::CurrentIsMainThread());
MOZ_RELEASE_ASSERT(IsReplaying()); MOZ_RELEASE_ASSERT(IsReplaying());
@ -223,27 +192,23 @@ RecordReplayInterface_DivergeFromRecording()
gUnhandledDivergeAllowed = true; gUnhandledDivergeAllowed = true;
} }
extern "C" {
MOZ_EXPORT bool MOZ_EXPORT bool
RecordReplayInterface_InternalHasDivergedFromRecording() RecordReplayInterface_InternalHasDivergedFromRecording()
{ {
return Thread::CurrentIsMainThread() && gRecordingDiverged; return Thread::CurrentIsMainThread() && gRecordingDiverged;
} }
MOZ_EXPORT void } // extern "C"
RecordReplayInterface_DisallowUnhandledDivergeFromRecording()
void
DisallowUnhandledDivergeFromRecording()
{ {
MOZ_RELEASE_ASSERT(Thread::CurrentIsMainThread()); MOZ_RELEASE_ASSERT(Thread::CurrentIsMainThread());
gUnhandledDivergeAllowed = false; gUnhandledDivergeAllowed = false;
} }
MFBT_API void
RecordReplayInterface_SaveTemporaryCheckpoint()
{
NewCheckpoint(/* aTemporary = */ true);
}
} // extern "C"
void void
EnsureNotDivergedFromRecording() EnsureNotDivergedFromRecording()
{ {
@ -335,18 +300,14 @@ PauseMainThreadAndInvokeCallback(const std::function<void()>& aCallback)
} }
} }
extern "C" { void
ResumeExecution()
MOZ_EXPORT void
RecordReplayInterface_ResumeExecution()
{ {
MonitorAutoLock lock(*gMainThreadCallbackMonitor); MonitorAutoLock lock(*gMainThreadCallbackMonitor);
gMainThreadShouldPause = false; gMainThreadShouldPause = false;
gMainThreadCallbackMonitor->Notify(); gMainThreadCallbackMonitor->Notify();
} }
} // extern "C"
void void
SetIsActiveChild(bool aActive) SetIsActiveChild(bool aActive)
{ {

Просмотреть файл

@ -57,7 +57,7 @@ void
InitializeThreadSnapshots(size_t aNumThreads) InitializeThreadSnapshots(size_t aNumThreads)
{ {
gThreadState = (ThreadState*) AllocateMemory(aNumThreads * sizeof(ThreadState), gThreadState = (ThreadState*) AllocateMemory(aNumThreads * sizeof(ThreadState),
UntrackedMemoryKind::ThreadSnapshot); MemoryKind::ThreadSnapshot);
jmp_buf buf; jmp_buf buf;
if (setjmp(buf) == 0) { if (setjmp(buf) == 0) {
@ -70,7 +70,7 @@ static void
ClearThreadState(ThreadState* aInfo) ClearThreadState(ThreadState* aInfo)
{ {
MOZ_RELEASE_ASSERT(aInfo->mShouldRestore); MOZ_RELEASE_ASSERT(aInfo->mShouldRestore);
DeallocateMemory(aInfo->mStackContents, aInfo->mStackBytes, UntrackedMemoryKind::ThreadSnapshot); DeallocateMemory(aInfo->mStackContents, aInfo->mStackBytes, MemoryKind::ThreadSnapshot);
aInfo->mShouldRestore = false; aInfo->mShouldRestore = false;
aInfo->mStackContents = nullptr; aInfo->mStackContents = nullptr;
aInfo->mStackBytes = 0; aInfo->mStackBytes = 0;
@ -221,7 +221,7 @@ SaveThreadStack(SavedThreadStack& aStack, size_t aId)
MOZ_RELEASE_ASSERT(stackBytes >= info.mStackTopBytes); MOZ_RELEASE_ASSERT(stackBytes >= info.mStackTopBytes);
aStack.mStack = (uint8_t*) AllocateMemory(stackBytes, UntrackedMemoryKind::ThreadSnapshot); aStack.mStack = (uint8_t*) AllocateMemory(stackBytes, MemoryKind::ThreadSnapshot);
aStack.mStackBytes = stackBytes; aStack.mStackBytes = stackBytes;
MemoryMove(aStack.mStack, info.mStackTop, info.mStackTopBytes); MemoryMove(aStack.mStack, info.mStackTop, info.mStackTopBytes);
@ -241,7 +241,7 @@ RestoreStackForLoadingByThread(const SavedThreadStack& aStack, size_t aId)
info.mStackBytes = aStack.mStackBytes; info.mStackBytes = aStack.mStackBytes;
uint8_t* stackContents = uint8_t* stackContents =
(uint8_t*) AllocateMemory(info.mStackBytes, UntrackedMemoryKind::ThreadSnapshot); (uint8_t*) AllocateMemory(info.mStackBytes, MemoryKind::ThreadSnapshot);
MemoryMove(stackContents, aStack.mStack, aStack.mStackBytes); MemoryMove(stackContents, aStack.mStack, aStack.mStackBytes);
info.mStackContents = stackContents; info.mStackContents = stackContents;
info.mShouldRestore = true; info.mShouldRestore = true;

Просмотреть файл

@ -8,6 +8,7 @@
#define mozilla_recordreplay_ThreadSnapshot_h #define mozilla_recordreplay_ThreadSnapshot_h
#include "File.h" #include "File.h"
#include "ProcessRewind.h"
#include "Thread.h" #include "Thread.h"
namespace mozilla { namespace mozilla {
@ -70,7 +71,7 @@ struct SavedThreadStack
void ReleaseContents() { void ReleaseContents() {
if (mStackBytes) { if (mStackBytes) {
DeallocateMemory(mStack, mStackBytes, UntrackedMemoryKind::ThreadSnapshot); DeallocateMemory(mStack, mStackBytes, MemoryKind::ThreadSnapshot);
} }
} }
}; };

Просмотреть файл

@ -9,11 +9,11 @@
#include "base/process.h" #include "base/process.h"
#include "js/ReplayHooks.h"
#include "mozilla/gfx/Types.h" #include "mozilla/gfx/Types.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "File.h" #include "File.h"
#include "JSControl.h"
#include "Monitor.h" #include "Monitor.h"
namespace mozilla { namespace mozilla {
@ -260,9 +260,9 @@ struct SetBreakpointMessage : public Message
// New position of the breakpoint. If this is invalid then the breakpoint is // New position of the breakpoint. If this is invalid then the breakpoint is
// being cleared. // being cleared.
JS::replay::ExecutionPosition mPosition; js::BreakpointPosition mPosition;
SetBreakpointMessage(size_t aId, const JS::replay::ExecutionPosition& aPosition) SetBreakpointMessage(size_t aId, const js::BreakpointPosition& aPosition)
: Message(MessageType::SetBreakpoint, sizeof(*this)) : Message(MessageType::SetBreakpoint, sizeof(*this))
, mId(aId) , mId(aId)
, mPosition(aPosition) , mPosition(aPosition)
@ -425,7 +425,7 @@ private:
Monitor mMonitor; Monitor mMonitor;
// Buffer for message data received from the other side of the channel. // Buffer for message data received from the other side of the channel.
InfallibleVector<char, 0, AllocPolicy<UntrackedMemoryKind::Generic>> mMessageBuffer; InfallibleVector<char, 0, AllocPolicy<MemoryKind::Generic>> mMessageBuffer;
// The number of bytes of data already in the message buffer. // The number of bytes of data already in the message buffer.
size_t mMessageBytes; size_t mMessageBytes;

Просмотреть файл

@ -133,9 +133,8 @@ ChildProcessInfo::IsPausedAtMatchingBreakpoint(const BreakpointFilter& aFilter)
} }
} }
} }
MOZ_RELEASE_ASSERT(lastSet && MOZ_RELEASE_ASSERT(lastSet && lastSet->mPosition.IsValid());
lastSet->mPosition.kind != JS::replay::ExecutionPosition::Invalid); if (aFilter(lastSet->mPosition.mKind)) {
if (aFilter(lastSet->mPosition.kind)) {
return true; return true;
} }
} }
@ -309,7 +308,7 @@ ChildProcessInfo::Recover(bool aPaused, Message* aPausedMessage, size_t aLastChe
for (Message* msg : mMessages) { for (Message* msg : mMessages) {
if (msg->mType == MessageType::SetBreakpoint) { if (msg->mType == MessageType::SetBreakpoint) {
SetBreakpointMessage* nmsg = static_cast<SetBreakpointMessage*>(msg); SetBreakpointMessage* nmsg = static_cast<SetBreakpointMessage*>(msg);
SendMessageRaw(SetBreakpointMessage(nmsg->mId, JS::replay::ExecutionPosition())); SendMessageRaw(SetBreakpointMessage(nmsg->mId, js::BreakpointPosition()));
} }
free(msg); free(msg);
} }

Просмотреть файл

@ -761,10 +761,10 @@ HasSavedCheckpointsInRange(ChildProcessInfo* aChild, size_t aStart, size_t aEnd)
// child to inspect its state. This excludes breakpoints set for things // child to inspect its state. This excludes breakpoints set for things
// internal to the debugger. // internal to the debugger.
static bool static bool
IsUserBreakpoint(JS::replay::ExecutionPosition::Kind aKind) IsUserBreakpoint(js::BreakpointPosition::Kind aKind)
{ {
MOZ_RELEASE_ASSERT(aKind != JS::replay::ExecutionPosition::Invalid); MOZ_RELEASE_ASSERT(aKind != js::BreakpointPosition::Invalid);
return aKind != JS::replay::ExecutionPosition::NewScript; return aKind != js::BreakpointPosition::NewScript;
} }
static void static void
@ -829,9 +829,6 @@ MainThreadMessageLoop()
return gMainThreadMessageLoop; return gMainThreadMessageLoop;
} }
// Initialize hooks used by the debugger.
static void InitDebuggerHooks();
// Contents of the prefs shmem block that is sent to the child on startup. // Contents of the prefs shmem block that is sent to the child on startup.
static char* gShmemPrefs; static char* gShmemPrefs;
static size_t gShmemPrefsLen; static size_t gShmemPrefsLen;
@ -859,7 +856,6 @@ InitializeMiddleman(int aArgc, char* aArgv[], base::ProcessId aParentPid)
MOZ_RELEASE_ASSERT(gProcessKind == ProcessKind::MiddlemanRecording || MOZ_RELEASE_ASSERT(gProcessKind == ProcessKind::MiddlemanRecording ||
gProcessKind == ProcessKind::MiddlemanReplaying); gProcessKind == ProcessKind::MiddlemanReplaying);
InitDebuggerHooks();
InitializeGraphicsMemory(); InitializeGraphicsMemory();
gMonitor = new Monitor(); gMonitor = new Monitor();
@ -882,19 +878,17 @@ InitializeMiddleman(int aArgc, char* aArgv[], base::ProcessId aParentPid)
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Buffer for receiving the next debugger response. // Buffer for receiving the next debugger response.
static JS::replay::CharBuffer* gResponseBuffer; static js::CharBuffer* gResponseBuffer;
static void static void
RecvDebuggerResponse(const DebuggerResponseMessage& aMsg) RecvDebuggerResponse(const DebuggerResponseMessage& aMsg)
{ {
MOZ_RELEASE_ASSERT(gResponseBuffer && gResponseBuffer->empty()); MOZ_RELEASE_ASSERT(gResponseBuffer && gResponseBuffer->empty());
if (!gResponseBuffer->append(aMsg.Buffer(), aMsg.BufferSize())) { gResponseBuffer->append(aMsg.Buffer(), aMsg.BufferSize());
MOZ_CRASH("RecvDebuggerResponse");
}
} }
static void void
HookDebuggerRequest(const JS::replay::CharBuffer& aBuffer, JS::replay::CharBuffer* aResponse) SendRequest(const js::CharBuffer& aBuffer, js::CharBuffer* aResponse)
{ {
MaybeCreateCheckpointInRecordingChild(); MaybeCreateCheckpointInRecordingChild();
gActiveChild->WaitUntilPaused(); gActiveChild->WaitUntilPaused();
@ -913,8 +907,8 @@ HookDebuggerRequest(const JS::replay::CharBuffer& aBuffer, JS::replay::CharBuffe
gResponseBuffer = nullptr; gResponseBuffer = nullptr;
} }
static void void
HookSetBreakpoint(size_t aId, const JS::replay::ExecutionPosition& aPosition) SetBreakpoint(size_t aId, const js::BreakpointPosition& aPosition)
{ {
MaybeCreateCheckpointInRecordingChild(); MaybeCreateCheckpointInRecordingChild();
gActiveChild->WaitUntilPaused(); gActiveChild->WaitUntilPaused();
@ -938,8 +932,8 @@ static bool gChildExecuteBackward = false;
// main thread. This will continue execution in the preferred direction. // main thread. This will continue execution in the preferred direction.
static bool gResumeForwardOrBackward = false; static bool gResumeForwardOrBackward = false;
static void void
HookResume(bool aForward) Resume(bool aForward)
{ {
gActiveChild->WaitUntilPaused(); gActiveChild->WaitUntilPaused();
@ -1000,8 +994,8 @@ HookResume(bool aForward)
gActiveChild->SendMessage(ResumeMessage(aForward)); gActiveChild->SendMessage(ResumeMessage(aForward));
} }
static void void
HookPause() Pause()
{ {
MaybeCreateCheckpointInRecordingChild(); MaybeCreateCheckpointInRecordingChild();
gActiveChild->WaitUntilPaused(); gActiveChild->WaitUntilPaused();
@ -1020,7 +1014,7 @@ ResumeForwardOrBackward()
MOZ_RELEASE_ASSERT(!gChildExecuteForward || !gChildExecuteBackward); MOZ_RELEASE_ASSERT(!gChildExecuteForward || !gChildExecuteBackward);
if (gResumeForwardOrBackward && (gChildExecuteForward || gChildExecuteBackward)) { if (gResumeForwardOrBackward && (gChildExecuteForward || gChildExecuteBackward)) {
HookResume(gChildExecuteForward); Resume(gChildExecuteForward);
} }
} }
@ -1034,7 +1028,7 @@ RecvHitCheckpoint(const HitCheckpointMessage& aMsg)
// the process to pause. Immediately resume if the main thread is blocked. // the process to pause. Immediately resume if the main thread is blocked.
if (MainThreadIsWaitingForIPDLReply()) { if (MainThreadIsWaitingForIPDLReply()) {
MOZ_RELEASE_ASSERT(gChildExecuteForward); MOZ_RELEASE_ASSERT(gChildExecuteForward);
HookResume(true); Resume(true);
} else if (!gResumeForwardOrBackward) { } else if (!gResumeForwardOrBackward) {
gResumeForwardOrBackward = true; gResumeForwardOrBackward = true;
gMainThreadMessageLoop->PostTask(NewRunnableFunction("ResumeForwardOrBackward", gMainThreadMessageLoop->PostTask(NewRunnableFunction("ResumeForwardOrBackward",
@ -1054,7 +1048,7 @@ HitBreakpoint(uint32_t* aBreakpoints, size_t aNumBreakpoints)
// backward travel. // backward travel.
for (size_t i = 0; i < aNumBreakpoints && gResumeForwardOrBackward; i++) { for (size_t i = 0; i < aNumBreakpoints && gResumeForwardOrBackward; i++) {
AutoSafeJSContext cx; AutoSafeJSContext cx;
if (!JS::replay::hooks.hitBreakpointMiddleman(cx, aBreakpoints[i])) { if (!js::HitBreakpoint(cx, aBreakpoints[i])) {
Print("Warning: hitBreakpoint hook threw an exception.\n"); Print("Warning: hitBreakpoint hook threw an exception.\n");
} }
} }
@ -1077,16 +1071,6 @@ RecvHitBreakpoint(const HitBreakpointMessage& aMsg)
breakpoints, aMsg.NumBreakpoints())); breakpoints, aMsg.NumBreakpoints()));
} }
static void
InitDebuggerHooks()
{
JS::replay::hooks.debugRequestMiddleman = HookDebuggerRequest;
JS::replay::hooks.setBreakpointMiddleman = HookSetBreakpoint;
JS::replay::hooks.resumeMiddleman = HookResume;
JS::replay::hooks.pauseMiddleman = HookPause;
JS::replay::hooks.canRewindMiddleman = CanRewind;
}
} // namespace parent } // namespace parent
} // namespace recordreplay } // namespace recordreplay
} // namespace mozilla } // namespace mozilla