[heap-profiler] Fix use of unordered_map with HeapObjects

This unordered map is mixing code objects and other objects, which makes
operator== unsafe to call with external code space enabled. In case a
heap object and a code object have the same compressed pointer, they
will also have the same hash value and thus must be compared with
EqualSafe.

Bug: v8:13466
Change-Id: I269c46c054d8acd3accb126d2f7d3225ef4bbfde
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4111640
Commit-Queue: Olivier Flückiger <olivf@chromium.org>
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84878}
This commit is contained in:
Olivier Flückiger 2022-12-15 14:17:57 +00:00 committed by V8 LUCI CQ
parent ee1f7bd988
commit ea644a93d0
2 changed files with 10 additions and 8 deletions

View File

@ -2323,7 +2323,8 @@ void V8HeapExplorer::SetGcSubrootReference(Root root, const char* description,
}
HeapEntry* child_entry = GetEntry(child_obj);
if (child_entry == nullptr) return;
const char* name = GetStrongGcSubrootName(child_obj);
auto child_heap_obj = HeapObject::cast(child_obj);
const char* name = GetStrongGcSubrootName(child_heap_obj);
HeapGraphEdge::Type edge_type =
is_weak ? HeapGraphEdge::kWeak : HeapGraphEdge::kInternal;
if (name != nullptr) {
@ -2341,9 +2342,9 @@ void V8HeapExplorer::SetGcSubrootReference(Root root, const char* description,
// Add a shortcut to JS global object reference at snapshot root.
// That allows the user to easily find global objects. They are
// also used as starting points in distance calculations.
if (is_weak || !child_obj.IsNativeContext()) return;
if (is_weak || !child_heap_obj.IsNativeContext()) return;
JSGlobalObject global = Context::cast(child_obj).global_object();
JSGlobalObject global = Context::cast(child_heap_obj).global_object();
if (!global.IsJSGlobalObject()) return;
if (!user_roots_.insert(global).second) return;
@ -2351,13 +2352,15 @@ void V8HeapExplorer::SetGcSubrootReference(Root root, const char* description,
SetUserGlobalReference(global);
}
const char* V8HeapExplorer::GetStrongGcSubrootName(Object object) {
const char* V8HeapExplorer::GetStrongGcSubrootName(HeapObject object) {
if (strong_gc_subroot_names_.empty()) {
Isolate* isolate = Isolate::FromHeap(heap_);
for (RootIndex root_index = RootIndex::kFirstStrongOrReadOnlyRoot;
root_index <= RootIndex::kLastStrongOrReadOnlyRoot; ++root_index) {
const char* name = RootsTable::name(root_index);
strong_gc_subroot_names_.emplace(isolate->root(root_index), name);
Object root = isolate->root(root_index);
CHECK(!root.IsSmi());
strong_gc_subroot_names_.emplace(HeapObject::cast(root), name);
}
CHECK(!strong_gc_subroot_names_.empty());
}

View File

@ -500,7 +500,7 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
void SetGcRootsReference(Root root);
void SetGcSubrootReference(Root root, const char* description, bool is_weak,
Object child);
const char* GetStrongGcSubrootName(Object object);
const char* GetStrongGcSubrootName(HeapObject object);
void TagObject(Object obj, const char* tag,
base::Optional<HeapEntry::Type> type = {});
void RecursivelyTagConstantPool(Object obj, const char* tag,
@ -518,8 +518,7 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
global_object_tag_pairs_;
std::unordered_map<JSGlobalObject, const char*, Object::Hasher>
global_object_tag_map_;
std::unordered_map<Object, const char*, Object::Hasher>
strong_gc_subroot_names_;
UnorderedHeapObjectMap<const char*> strong_gc_subroot_names_;
std::unordered_set<JSGlobalObject, Object::Hasher> user_roots_;
v8::HeapProfiler::ObjectNameResolver* global_object_name_resolver_;