#include <ctype.h>
#include <memory>
#include <optional>
#include <vector>
#include "include/v8-function.h"
#include "include/v8-json.h"
#include "include/v8-profiler.h"
#include "src/api/api-inl.h"
#include "src/base/hashmap.h"
#include "src/base/logging.h"
#include "src/base/strings.h"
#include "src/codegen/assembler-inl.h"
#include "src/debug/debug.h"
#include "src/handles/global-handles.h"
#include "src/heap/heap-inl.h"
#include "src/heap/pretenuring-handler.h"
#include "src/objects/objects-inl.h"
#include "src/profiler/allocation-tracker.h"
#include "src/profiler/heap-profiler.h"
#include "src/profiler/heap-snapshot-generator-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/collector.h"
#include "test/cctest/heap/heap-utils.h"
#include "test/cctest/jsonstream-helper.h"
#if V8_ENABLE_WEBASSEMBLY
#include "src/wasm/wasm-module-builder.h"
#endif
AllocationTraceNode;
AllocationTraceTree;
AllocationTracker;
EntrySourceLocation;
GrowNewSpaceToMaximumCapacity;
optional;
ArrayVector;
OS;
Vector;
VectorOf;
namespace {
class NamedEntriesDetector { … };
}
static const v8::HeapGraphNode* GetGlobalObject(
const v8::HeapSnapshot* snapshot) { … }
static const char* GetName(const v8::HeapGraphNode* node) { … }
static const char* GetName(const v8::HeapGraphEdge* edge) { … }
static size_t GetSize(const v8::HeapGraphNode* node) { … }
static const v8::HeapGraphNode* GetChildByName(const v8::HeapGraphNode* node,
const char* name) { … }
static const v8::HeapGraphEdge* GetEdgeByChildName(
const v8::HeapGraphNode* node, const char* name) { … }
static const v8::HeapGraphNode* GetRootChild(const v8::HeapSnapshot* snapshot,
const char* name) { … }
static optional<EntrySourceLocation> GetLocation(
const v8::HeapSnapshot* s, const v8::HeapGraphNode* node) { … }
static const v8::HeapGraphNode* GetProperty(v8::Isolate* isolate,
const v8::HeapGraphNode* node,
v8::HeapGraphEdge::Type type,
const char* name) { … }
#if V8_ENABLE_WEBASSEMBLY
static const std::vector<std::string> GetProperties(
v8::Isolate* isolate, const v8::HeapGraphNode* node) { … }
static void CheckProperties(
v8::Isolate* isolate, const v8::HeapGraphNode* node,
std::initializer_list<std::string> expected_properties) { … }
#endif
static bool HasString(v8::Isolate* isolate, const v8::HeapGraphNode* node,
const char* contents) { … }
static void EnsureNoUninstrumentedInternals(v8::Isolate* isolate,
const v8::HeapGraphNode* node) { … }
static bool ValidateSnapshot(const v8::HeapSnapshot* snapshot, int depth = 3) { … }
bool EndsWith(const char* a, const char* b) { … }
TEST(HeapSnapshot) { … }
TEST(HeapSnapshotLocations) { … }
TEST(HeapSnapshotObjectSizes) { … }
TEST(BoundFunctionInSnapshot) { … }
TEST(HeapSnapshotEntryChildren) { … }
TEST(HeapSnapshotCodeObjects) { … }
TEST(HeapSnapshotHeapNumbers) { … }
TEST(HeapSnapshotHeapNumbersCaptureNumericValue) { … }
TEST(HeapSnapshotHeapBigInts) { … }
TEST(HeapSnapshotSlicedString) { … }
START_ALLOW_USE_DEPRECATED(…)
TEST(HeapSnapshotConsString) { … }
END_ALLOW_USE_DEPRECATED(…)
TEST(HeapSnapshotSymbol) { … }
TEST(HeapSnapshotWeakCollection) { … }
TEST(HeapSnapshotCollection) { … }
TEST(HeapSnapshotMap) { … }
START_ALLOW_USE_DEPRECATED(…)
TEST(HeapSnapshotInternalReferences) { … }
END_ALLOW_USE_DEPRECATED(…)
TEST(HeapSnapshotEphemeron) { … }
TEST(HeapSnapshotAddressReuse) { … }
TEST(HeapEntryIdsAndArrayShift) { … }
TEST(HeapEntryIdsAndGC) { … }
TEST(HeapSnapshotJSONSerialization) { … }
TEST(HeapSnapshotJSONSerializationAborting) { … }
namespace {
class TestStatsStream : public v8::OutputStream { … };
}
static TestStatsStream GetHeapStatsUpdate(
v8::HeapProfiler* heap_profiler,
v8::SnapshotObjectId* object_id = nullptr) { … }
TEST(HeapSnapshotObjectsStats) { … }
TEST(HeapObjectIds) { … }
static void CheckChildrenIds(const v8::HeapSnapshot* snapshot,
const v8::HeapGraphNode* node,
int level, int max_level) { … }
TEST(HeapSnapshotGetNodeById) { … }
TEST(HeapSnapshotGetSnapshotObjectId) { … }
TEST(HeapSnapshotUnknownSnapshotObjectId) { … }
namespace {
class TestActivityControl : public v8::ActivityControl { … };
}
TEST(TakeHeapSnapshotAborting) { … }
TEST(TakeHeapSnapshotReportFinishOnce) { … }
namespace {
class EmbedderGraphBuilder : public v8::PersistentHandleVisitor { … };
}
static const v8::HeapGraphNode* GetNode(const v8::HeapGraphNode* parent,
v8::HeapGraphNode::Type type,
const char* name) { … }
TEST(HeapSnapshotRetainedObjectInfo) { … }
namespace {
class EmbedderGraphBuilderForNativeSnapshotObjectId final { … };
}
TEST(NativeSnapshotObjectId) { … }
TEST(NativeSnapshotObjectIdMoving) { … }
TEST(DeleteAllHeapSnapshots) { … }
static bool FindHeapSnapshot(v8::HeapProfiler* profiler,
const v8::HeapSnapshot* snapshot) { … }
TEST(DeleteHeapSnapshot) { … }
class NameResolver : public v8::HeapProfiler::ObjectNameResolver { … };
TEST(GlobalObjectName) { … }
TEST(GlobalObjectFields) { … }
TEST(NoHandleLeaks) { … }
TEST(NodesIteration) { … }
START_ALLOW_USE_DEPRECATED(…)
TEST(GetHeapValueForNode) { … }
TEST(GetHeapValueForDeletedObject) { … }
static int StringCmp(const char* ref, i::Tagged<i::String> act) { … }
TEST(GetConstructor) { … }
TEST(GetConstructorName) { … }
END_ALLOW_USE_DEPRECATED(…)
TEST(FastCaseAccessors) { … }
START_ALLOW_USE_DEPRECATED(…)
TEST(FastCaseRedefinedAccessors) { … }
END_ALLOW_USE_DEPRECATED(…)
TEST(SlowCaseAccessors) { … }
TEST(HiddenPropertiesFastCase) { … }
TEST(SymbolsAndPrivateClassFields) { … }
TEST(AccessorInfo) { … }
TEST(JSGeneratorObject) { … }
bool HasWeakEdge(const v8::HeapGraphNode* node) { … }
bool HasWeakGlobalHandle() { … }
TEST(WeakGlobalHandle) { … }
TEST(SfiAndJsFunctionWeakRefs) { … }
TEST(AllStrongGcRootsHaveNames) { … }
TEST(NoRefsToNonEssentialEntries) { … }
TEST(MapHasDescriptorsAndTransitions) { … }
TEST(ManyLocalsInSharedContext) { … }
TEST(AllocationSitesAreVisible) { … }
TEST(JSFunctionHasCodeLink) { … }
static const v8::HeapGraphNode* GetNodeByPath(v8::Isolate* isolate,
const v8::HeapSnapshot* snapshot,
const char* path[], int depth) { … }
TEST(CheckCodeNames) { … }
static const char* record_trace_tree_source = …;
static AllocationTraceNode* FindNode(AllocationTracker* tracker,
v8::base::Vector<const char*> names) { … }
TEST(ArrayGrowLeftTrim) { … }
TEST(TrackHeapAllocationsWithInlining) { … }
TEST(TrackHeapAllocationsWithoutInlining) { … }
static const char* inline_heap_allocation_source = …;
TEST(TrackBumpPointerAllocations) { … }
TEST(TrackV8ApiAllocation) { … }
TEST(ArrayBufferAndArrayBufferView) { … }
static int GetRetainersCount(const v8::HeapSnapshot* snapshot,
const v8::HeapGraphNode* node) { … }
TEST(ArrayBufferSharedBackingStore) { … }
TEST(WeakContainers) { … }
TEST(JSPromise) { … }
TEST(HeapSnapshotScriptContext) { … }
class EmbedderNode : public v8::EmbedderGraph::Node { … };
class EmbedderRootNode : public EmbedderNode { … };
v8::Local<v8::Value>* global_object_pointer;
void BuildEmbedderGraph(v8::Isolate* v8_isolate, v8::EmbedderGraph* graph,
void* data) { … }
void CheckEmbedderGraphSnapshot(v8::Isolate* isolate,
const v8::HeapSnapshot* snapshot) { … }
TEST(EmbedderGraph) { … }
void BuildEmbedderGraphWithNamedEdges(v8::Isolate* v8_isolate,
v8::EmbedderGraph* graph, void* data) { … }
void CheckEmbedderGraphWithNamedEdges(v8::Isolate* isolate,
const v8::HeapSnapshot* snapshot) { … }
TEST(EmbedderGraphWithNamedEdges) { … }
struct GraphBuildingContext { … };
void CheckEmbedderGraphSnapshotWithContext(
v8::Isolate* isolate, const v8::HeapSnapshot* snapshot,
const GraphBuildingContext* context) { … }
void BuildEmbedderGraphWithContext(v8::Isolate* v8_isolate,
v8::EmbedderGraph* graph, void* data) { … }
TEST(EmbedderGraphMultipleCallbacks) { … }
TEST(StrongHandleAnnotation) { … }
void BuildEmbedderGraphWithWrapperNode(v8::Isolate* v8_isolate,
v8::EmbedderGraph* graph, void* data) { … }
TEST(EmbedderGraphWithWrapperNode) { … }
class EmbedderNodeWithPrefix : public v8::EmbedderGraph::Node { … };
void BuildEmbedderGraphWithPrefix(v8::Isolate* v8_isolate,
v8::EmbedderGraph* graph, void* data) { … }
TEST(EmbedderGraphWithPrefix) { … }
static inline i::Address ToAddress(int n) { … }
TEST(AddressToTraceMap) { … }
static const v8::AllocationProfile::Node* FindAllocationProfileNode(
v8::Isolate* isolate, v8::AllocationProfile* profile,
v8::base::Vector<const char*> names) { … }
static void CheckNoZeroCountNodes(v8::AllocationProfile::Node* node) { … }
static int NumberOfAllocations(const v8::AllocationProfile::Node* node) { … }
static const char* simple_sampling_heap_profiler_script = …;
TEST(SamplingHeapProfiler) { … }
TEST(SamplingHeapProfilerRateAgnosticEstimates) { … }
TEST(SamplingHeapProfilerApiAllocation) { … }
TEST(SamplingHeapProfilerApiSamples) { … }
TEST(SamplingHeapProfilerLeftTrimming) { … }
TEST(SamplingHeapProfilerPretenuredInlineAllocations) { … }
TEST(SamplingHeapProfilerLargeInterval) { … }
TEST(HeapSnapshotPrototypeNotJSReceiver) { … }
TEST(SamplingHeapProfilerSampleDuringDeopt) { … }
namespace {
class TestQueryObjectPredicate : public v8::QueryObjectPredicate { … };
class IncludeAllQueryObjectPredicate : public v8::QueryObjectPredicate { … };
}
TEST(QueryObjects) { … }
TEST(WeakReference) { … }
TEST(Bug8373_1) { … }
TEST(Bug8373_2) { … }
TEST(HeapSnapshotDeleteDuringTakeSnapshot) { … }
TEST(ObjectRetainedInHandle) { … }
TEST(ObjectRetainedInDirectHandle) { … }
#if V8_ENABLE_WEBASSEMBLY
TEST(HeapSnapshotWithWasmInstance) { … }
#endif