Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Unified Diff: tools/grokdump.py

Issue 12389077: Extend grokdump with support for maps, transition and descriptor arrays. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/grokdump.py
diff --git a/tools/grokdump.py b/tools/grokdump.py
index 603453a852330a8bf30dd04fef4d8791e10f6def..804609b0a953e6579bdb586ecefcfbe53995debf 100755
--- a/tools/grokdump.py
+++ b/tools/grokdump.py
@@ -1145,8 +1145,103 @@ class HeapObject(object):
class Map(HeapObject):
+ def Decode(self, offset, size, value):
+ return (value >> offset) & ((1 << size) - 1)
+
+ # Instance Sizes
+ def InstanceSizesOffset(self):
+ return self.heap.PointerSize()
+
+ def InstanceSizeOffset(self):
+ return self.InstanceSizesOffset()
+
+ def InObjectProperties(self):
+ return self.InstanceSizeOffset() + 1
+
+ def PreAllocatedPropertyFields(self):
+ return self.InObjectProperties() + 1
+
+ def VisitorId(self):
+ return self.PreAllocatedPropertyFields() + 1
+
+ # Instance Attributes
+ def InstanceAttributesOffset(self):
+ return self.InstanceSizesOffset() + self.heap.IntSize()
+
def InstanceTypeOffset(self):
- return self.heap.PointerSize() + self.heap.IntSize()
+ return self.InstanceAttributesOffset()
+
+ def UnusedPropertyFieldsOffset(self):
+ return self.InstanceTypeOffset() + 1
+
+ def BitFieldOffset(self):
+ return self.UnusedPropertyFieldsOffset() + 1
+
+ def BitField2Offset(self):
+ return self.BitFieldOffset() + 1
+
+ # Other fields
+ def PrototypeOffset(self):
+ return self.InstanceAttributesOffset() + self.heap.IntSize()
+
+ def ConstructorOffset(self):
+ return self.PrototypeOffset() + self.heap.PointerSize()
+
+ def TransitionsOrBackPointerOffset(self):
+ return self.ConstructorOffset() + self.heap.PointerSize()
+
+ def DescriptorsOffset(self):
+ return self.TransitionsOrBackPointerOffset() + self.heap.PointerSize()
+
+ def CodeCacheOffset(self):
+ return self.DescriptorsOffset() + self.heap.PointerSize()
+
+ def DependentCodeOffset(self):
+ return self.CodeCacheOffset() + self.heap.PointerSize()
+
+ def BitField3Offset(self):
+ return self.DependentCodeOffset() + self.heap.PointerSize()
+
+ def ReadByte(self, offset):
+ return self.heap.reader.ReadU8(self.address + offset)
+
+ def Print(self):
+ print "Map(%08x)" % (self.address)
+ print "- size: %d, inobject: %d, preallocated: %d, visitor: %d" % (
+ self.ReadByte(self.InstanceSizeOffset()),
+ self.ReadByte(self.InObjectProperties()),
+ self.ReadByte(self.PreAllocatedPropertyFields()),
+ self.VisitorId())
+
+ bitfield = self.ReadByte(self.BitFieldOffset())
+ bitfield2 = self.ReadByte(self.BitField2Offset())
+ print "- %s, unused: %d, bf: %d, bf2: %d" % (
+ INSTANCE_TYPES[self.ReadByte(self.InstanceTypeOffset())],
+ self.ReadByte(self.UnusedPropertyFieldsOffset()),
+ bitfield, bitfield2)
+
+ print "- kind: %s" % (self.Decode(3, 5, bitfield2))
+
+ bitfield3 = self.ObjectField(self.BitField3Offset())
+ print "- EnumLength: %d NumberOfOwnDescriptors: %d OwnsDescriptors: %s" % (
+ self.Decode(0, 11, bitfield3),
+ self.Decode(11, 11, bitfield3),
+ self.Decode(25, 1, bitfield3))
+ print "- IsShared: %s" % (self.Decode(22, 1, bitfield3))
+ print "- FunctionWithPrototype: %s" % (self.Decode(23, 1, bitfield3))
+ print "- DictionaryMap: %s" % (self.Decode(24, 1, bitfield3))
+
+ descriptors = self.ObjectField(self.DescriptorsOffset())
+ if descriptors.__class__ == FixedArray:
+ DescriptorArray(descriptors).Print()
+ else:
+ print "Descriptors: %s" % (descriptors)
+
+ transitions = self.ObjectField(self.TransitionsOrBackPointerOffset())
+ if transitions.__class__ == FixedArray:
+ TransitionArray(transitions).Print()
+ else:
+ print "TransitionsOrBackPointer: %s" % (transitions)
def __init__(self, heap, map, address):
HeapObject.__init__(self, heap, map, address)
@@ -1280,6 +1375,12 @@ class FixedArray(HeapObject):
def ElementsOffset(self):
return self.heap.PointerSize() * 2
+ def MemberOffset(self, i):
+ return self.ElementsOffset() + self.heap.PointerSize() * i
+
+ def Get(self, i):
+ return self.ObjectField(self.MemberOffset(i))
+
def __init__(self, heap, map, address):
HeapObject.__init__(self, heap, map, address)
self.length = self.SmiField(self.LengthOffset())
@@ -1305,6 +1406,111 @@ class FixedArray(HeapObject):
return "FixedArray(%08x, length=%d)" % (self.address, self.length)
+class DescriptorArray(object):
+ def __init__(self, array):
+ self.array = array
+
+ def Length(self):
+ return self.array.Get(0)
+
+ def Decode(self, offset, size, value):
+ return (value >> offset) & ((1 << size) - 1)
+
+ TYPES = [
+ "normal",
+ "field",
+ "function",
+ "callbacks"
+ ]
+
+ def Type(self, value):
+ return DescriptorArray.TYPES[self.Decode(0, 3, value)]
+
+ def Attributes(self, value):
+ attributes = self.Decode(3, 3, value)
+ result = []
+ if (attributes & 0): result += ["ReadOnly"]
+ if (attributes & 1): result += ["DontEnum"]
+ if (attributes & 2): result += ["DontDelete"]
+ return "[" + (",".join(result)) + "]"
+
+ def Deleted(self, value):
+ return self.Decode(6, 1, value) == 1
+
+ def Storage(self, value):
+ return self.Decode(7, 11, value)
+
+ def Pointer(self, value):
+ return self.Decode(18, 11, value)
+
+ def Details(self, di, value):
+ return (
+ di,
+ self.Type(value),
+ self.Attributes(value),
+ self.Storage(value),
+ self.Pointer(value)
+ )
+
+
+ def Print(self):
+ length = self.Length()
+ array = self.array
+
+ print "Descriptors(%08x, length=%d)" % (array.address, length)
+ print "[et] %s" % (array.Get(1))
+
+ for di in xrange(length):
+ i = 2 + di * 3
+ print "0x%x" % (array.address + array.MemberOffset(i))
+ print "[%i] name: %s" % (di, array.Get(i + 0))
+ print "[%i] details: %s %s enum %i pointer %i" % \
+ self.Details(di, array.Get(i + 1))
+ print "[%i] value: %s" % (di, array.Get(i + 2))
+
+ end = self.array.length // 3
+ if length != end:
+ print "[%i-%i] slack descriptors" % (length, end)
+
+
+class TransitionArray(object):
+ def __init__(self, array):
+ self.array = array
+
+ def IsSimpleTransition(self):
+ return self.array.length <= 2
+
+ def Length(self):
+ # SimpleTransition cases
+ if self.IsSimpleTransition():
+ return self.array.length - 1
+ return (self.array.length - 3) // 2
+
+ def Print(self):
+ length = self.Length()
+ array = self.array
+
+ print "Transitions(%08x, length=%d)" % (array.address, length)
+ print "[backpointer] %s" % (array.Get(0))
+ if self.IsSimpleTransition():
+ if length == 1:
+ print "[simple target] %s" % (array.Get(1))
+ return
+
+ elements = array.Get(1)
+ if elements is not None:
+ print "[elements ] %s" % (elements)
+
+ prototype = array.Get(2)
+ if prototype is not None:
+ print "[prototype ] %s" % (prototype)
+
+ for di in xrange(length):
+ i = 3 + di * 2
+ print "[%i] symbol: %s" % (di, array.Get(i + 0))
+ print "[%i] target: %s" % (di, array.Get(i + 1))
+
+
class JSFunction(HeapObject):
def CodeEntryOffset(self):
return 3 * self.heap.PointerSize()
@@ -1720,6 +1926,30 @@ class InspectionShell(cmd.Cmd):
else:
print "Address cannot be interpreted as object!"
+ def do_do_desc(self, address):
+ """
+ Print a descriptor array in a readable format.
+ """
+ start = int(address, 16)
+ if ((start & 1) == 1): start = start + 1
+ DescriptorArray(FixedArray(self.heap, None, start)).Print()
+
+ def do_do_map(self, address):
+ """
+ Print a descriptor array in a readable format.
+ """
+ start = int(address, 16)
+ if ((start & 1) == 1): start = start - 1
+ Map(self.heap, None, start).Print()
+
+ def do_do_trans(self, address):
+ """
+ Print a transition array in a readable format.
+ """
+ start = int(address, 16)
+ if ((start & 1) == 1): start = start - 1
+ TransitionArray(FixedArray(self.heap, None, start)).Print()
+
def do_dp(self, address):
"""
Interpret memory at the given address as being on a V8 heap page
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698