1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
# Pretty-printers for InterpreterRegs.
import gdb
import mozilla.prettyprinters as prettyprinters
prettyprinters.clear_module_printers(__name__)
from mozilla.prettyprinters import pretty_printer
# Cache information about the Interpreter types for this objfile.
class InterpreterTypeCache(object):
def __init__(self):
self.tValue = gdb.lookup_type('JS::Value')
self.tJSOp = gdb.lookup_type('JSOp')
self.tScriptFrameIterData = gdb.lookup_type('js::ScriptFrameIter::Data')
self.tInterpreterFrame = gdb.lookup_type('js::InterpreterFrame')
self.tBaselineFrame = gdb.lookup_type('js::jit::BaselineFrame')
self.tRematerializedFrame = gdb.lookup_type('js::jit::RematerializedFrame')
@pretty_printer('js::InterpreterRegs')
class InterpreterRegs(object):
def __init__(self, value, cache):
self.value = value
self.cache = cache
if not cache.mod_Interpreter:
cache.mod_Interpreter = InterpreterTypeCache()
self.itc = cache.mod_Interpreter
# There's basically no way to co-operate with 'set print pretty' (how would
# you get the current level of indentation?), so we don't even bother
# trying. No 'children', just 'to_string'.
def to_string(self):
fp_ = 'fp_ = {}'.format(self.value['fp_'])
slots = (self.value['fp_'] + 1).cast(self.itc.tValue.pointer())
sp = 'sp = fp_.slots() + {}'.format(self.value['sp'] - slots)
pc = self.value['pc']
try:
opcode = pc.dereference().cast(self.itc.tJSOp)
except:
opcode = 'bad pc'
pc = 'pc = {} ({})'.format(pc.cast(self.cache.void_ptr_t), opcode)
return '{{ {}, {}, {} }}'.format(fp_, sp, pc)
@pretty_printer('js::AbstractFramePtr')
class AbstractFramePtr(object):
Tag_ScriptFrameIterData = 0x0
Tag_InterpreterFrame = 0x1
Tag_BaselineFrame = 0x2
Tag_RematerializedFrame = 0x3
TagMask = 0x3
def __init__(self, value, cache):
self.value = value
self.cache = cache
if not cache.mod_Interpreter:
cache.mod_Interpreter = InterpreterTypeCache()
self.itc = cache.mod_Interpreter
def to_string(self):
ptr = self.value['ptr_']
tag = ptr & AbstractFramePtr.TagMask
ptr = ptr & ~AbstractFramePtr.TagMask
if tag == AbstractFramePtr.Tag_ScriptFrameIterData:
label = 'js::ScriptFrameIter::Data'
ptr = ptr.cast(self.itc.tScriptFrameIterData.pointer())
if tag == AbstractFramePtr.Tag_InterpreterFrame:
label = 'js::InterpreterFrame'
ptr = ptr.cast(self.itc.tInterpreterFrame.pointer())
if tag == AbstractFramePtr.Tag_BaselineFrame:
label = 'js::jit::BaselineFrame'
ptr = ptr.cast(self.itc.tBaselineFrame.pointer())
if tag == AbstractFramePtr.Tag_RematerializedFrame:
label = 'js::jit::RematerializedFrame'
ptr = ptr.cast(self.itc.tRematerializedFrame.pointer())
return 'AbstractFramePtr (({} *) {})'.format(label, ptr)
# Provide the ptr_ field as a child, so it prints after the pretty string
# provided above.
def children(self):
yield ('ptr_', self.value['ptr_'])
|