forked from mirrors/gecko-dev
Backed out changeset e8fcfc7f8108 (bug 1811850) Backed out changeset f8950d716c9e (bug 1811850) Backed out changeset f650123cc188 (bug 1811850) Backed out changeset d96f90c2c58b (bug 1811850) Backed out changeset c3b0f9666183 (bug 1811850)
124 lines
4.6 KiB
Python
124 lines
4.6 KiB
Python
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
# Pretty-printers for GCCellPtr values.
|
|
|
|
import gdb
|
|
import mozilla.prettyprinters
|
|
from mozilla.prettyprinters import pretty_printer
|
|
|
|
# Forget any printers from previous loads of this module.
|
|
mozilla.prettyprinters.clear_module_printers(__name__)
|
|
|
|
# Cache information about the types for this objfile.
|
|
|
|
|
|
class GCCellPtrTypeCache(object):
|
|
def __init__(self, cache):
|
|
self.TraceKind_t = gdb.lookup_type("JS::TraceKind")
|
|
self.AllocKind_t = gdb.lookup_type("js::gc::AllocKind")
|
|
self.Arena_t = gdb.lookup_type("js::gc::Arena")
|
|
self.Cell_t = gdb.lookup_type("js::gc::Cell")
|
|
self.TenuredCell_t = gdb.lookup_type("js::gc::TenuredCell")
|
|
|
|
trace_kinds = gdb.types.make_enum_dict(self.TraceKind_t)
|
|
alloc_kinds = gdb.types.make_enum_dict(self.AllocKind_t)
|
|
|
|
def trace_kind(k):
|
|
return trace_kinds["JS::TraceKind::" + k]
|
|
|
|
def alloc_kind(k):
|
|
return alloc_kinds["js::gc::AllocKind::" + k]
|
|
|
|
# Build a mapping from TraceKind enum values to the types they denote.
|
|
trace_map = {
|
|
# Inline types.
|
|
"Object": "JSObject",
|
|
"BigInt": "JS::BigInt",
|
|
"String": "JSString",
|
|
"Symbol": "JS::Symbol",
|
|
"Shape": "js::Shape",
|
|
"BaseShape": "js::BaseShape",
|
|
"Null": "std::nullptr_t",
|
|
# Out-of-line types.
|
|
"JitCode": "js::jit::JitCode",
|
|
"Script": "js::BaseScript",
|
|
"Scope": "js::Scope",
|
|
"RegExpShared": "js::RegExpShared",
|
|
"GetterSetter": "js::GetterSetter",
|
|
"PropMap": "js::PropMap",
|
|
}
|
|
|
|
# Map from AllocKind to TraceKind for out-of-line types.
|
|
alloc_map = {
|
|
"JITCODE": "JitCode",
|
|
"SCRIPT": "Script",
|
|
"SCOPE": "Scope",
|
|
"REGEXP_SHARED": "RegExpShared",
|
|
"GETTER_SETTER": "GetterSetter",
|
|
"COMPACT_PROP_MAP": "PropMap",
|
|
"NORMAL_PROP_MAP": "PropMap",
|
|
"DICT_PROP_MAP": "PropMap",
|
|
}
|
|
|
|
self.trace_kind_to_type = {
|
|
trace_kind(k): gdb.lookup_type(v) for k, v in trace_map.items()
|
|
}
|
|
self.alloc_kind_to_trace_kind = {
|
|
alloc_kind(k): trace_kind(v) for k, v in alloc_map.items()
|
|
}
|
|
|
|
self.Null = trace_kind("Null")
|
|
self.tracekind_mask = gdb.parse_and_eval("JS::OutOfLineTraceKindMask")
|
|
self.arena_mask = gdb.parse_and_eval("js::gc::ArenaMask")
|
|
|
|
|
|
@pretty_printer("JS::GCCellPtr")
|
|
class GCCellPtr(object):
|
|
def __init__(self, value, cache):
|
|
self.value = value
|
|
if not cache.mod_GCCellPtr:
|
|
cache.mod_GCCellPtr = GCCellPtrTypeCache(cache)
|
|
self.cache = cache
|
|
|
|
def to_string(self):
|
|
ptr = self.value["ptr"]
|
|
kind = ptr & self.cache.mod_GCCellPtr.tracekind_mask
|
|
if kind == self.cache.mod_GCCellPtr.Null:
|
|
return "JS::GCCellPtr(nullptr)"
|
|
if kind == self.cache.mod_GCCellPtr.tracekind_mask:
|
|
# Out-of-line trace kinds.
|
|
#
|
|
# Compute the underlying type for out-of-line kinds by
|
|
# reimplementing the GCCellPtr::outOfLineKind() method.
|
|
#
|
|
# The extra casts below are only present to make it easier to
|
|
# compare this code against the C++ implementation.
|
|
|
|
# GCCellPtr::asCell()
|
|
cell_ptr = ptr & ~self.cache.mod_GCCellPtr.tracekind_mask
|
|
cell = cell_ptr.reinterpret_cast(self.cache.mod_GCCellPtr.Cell_t.pointer())
|
|
|
|
# Cell::asTenured()
|
|
tenured = cell.cast(self.cache.mod_GCCellPtr.TenuredCell_t.pointer())
|
|
|
|
# TenuredCell::arena()
|
|
addr = int(tenured)
|
|
arena_ptr = addr & ~self.cache.mod_GCCellPtr.arena_mask
|
|
arena = arena_ptr.reinterpret_cast(
|
|
self.cache.mod_GCCellPtr.Arena_t.pointer()
|
|
)
|
|
|
|
# Arena::getAllocKind()
|
|
alloc_kind = arena["allocKind"].cast(self.cache.mod_GCCellPtr.AllocKind_t)
|
|
alloc_idx = int(
|
|
alloc_kind.cast(self.cache.mod_GCCellPtr.AllocKind_t.target())
|
|
)
|
|
|
|
# Map the AllocKind to a TraceKind.
|
|
kind = self.cache.mod_GCCellPtr.alloc_kind_to_trace_kind[alloc_idx]
|
|
type_name = self.cache.mod_GCCellPtr.trace_kind_to_type[int(kind)]
|
|
return "JS::GCCellPtr(({}*) {})".format(
|
|
type_name, ptr.cast(self.cache.void_ptr_t)
|
|
)
|