Home | History | Annotate | Download | only in tools
      1 # Copyright 2011 the V8 project authors. All rights reserved.
      2 # Redistribution and use in source and binary forms, with or without
      3 # modification, are permitted provided that the following conditions are
      4 # met:
      5 #
      6 #     * Redistributions of source code must retain the above copyright
      7 #       notice, this list of conditions and the following disclaimer.
      8 #     * Redistributions in binary form must reproduce the above
      9 #       copyright notice, this list of conditions and the following
     10 #       disclaimer in the documentation and/or other materials provided
     11 #       with the distribution.
     12 #     * Neither the name of Google Inc. nor the names of its
     13 #       contributors may be used to endorse or promote products derived
     14 #       from this software without specific prior written permission.
     15 #
     16 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 
     29 kSmiTag = 0
     30 kSmiTagSize = 1
     31 kSmiTagMask = (1 << kSmiTagSize) - 1
     32 
     33 
     34 kHeapObjectTag = 1
     35 kHeapObjectTagSize = 2
     36 kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1
     37 
     38 
     39 kFailureTag = 3
     40 kFailureTagSize = 2
     41 kFailureTagMask = (1 << kFailureTagSize) - 1
     42 
     43 
     44 kSmiShiftSize32 = 0
     45 kSmiValueSize32 = 31
     46 kSmiShiftBits32 = kSmiTagSize + kSmiShiftSize32
     47 
     48 
     49 kSmiShiftSize64 = 31
     50 kSmiValueSize64 = 32
     51 kSmiShiftBits64 = kSmiTagSize + kSmiShiftSize64
     52 
     53 
     54 kAllBits = 0xFFFFFFFF
     55 kTopBit32 = 0x80000000
     56 kTopBit64 = 0x8000000000000000
     57 
     58 
     59 t_u32 = gdb.lookup_type('unsigned int')
     60 t_u64 = gdb.lookup_type('unsigned long long')
     61 
     62 
     63 def has_smi_tag(v):
     64   return v & kSmiTagMask == kSmiTag
     65 
     66 
     67 def has_failure_tag(v):
     68   return v & kFailureTagMask == kFailureTag
     69 
     70 
     71 def has_heap_object_tag(v):
     72   return v & kHeapObjectTagMask == kHeapObjectTag
     73 
     74 
     75 def raw_heap_object(v):
     76   return v - kHeapObjectTag
     77 
     78 
     79 def smi_to_int_32(v):
     80   v = v & kAllBits
     81   if (v & kTopBit32) == kTopBit32:
     82     return ((v & kAllBits) >> kSmiShiftBits32) - 2147483648
     83   else:
     84     return (v & kAllBits) >> kSmiShiftBits32
     85 
     86 
     87 def smi_to_int_64(v):
     88   return (v >> kSmiShiftBits64)
     89 
     90 
     91 def decode_v8_value(v, bitness):
     92   base_str = 'v8[%x]' % v
     93   if has_smi_tag(v):
     94     if bitness == 32:
     95       return base_str + (" SMI(%d)" % smi_to_int_32(v))
     96     else:
     97       return base_str + (" SMI(%d)" % smi_to_int_64(v))
     98   elif has_failure_tag(v):
     99     return base_str + " (failure)"
    100   elif has_heap_object_tag(v):
    101     return base_str + (" H(0x%x)" % raw_heap_object(v))
    102   else:
    103     return base_str
    104 
    105 
    106 class V8ValuePrinter(object):
    107   "Print a v8value."
    108   def __init__(self, val):
    109     self.val = val
    110   def to_string(self):
    111     if self.val.type.sizeof == 4:
    112       v_u32 = self.val.cast(t_u32)
    113       return decode_v8_value(int(v_u32), 32)
    114     elif self.val.type.sizeof == 8:
    115       v_u64 = self.val.cast(t_u64)
    116       return decode_v8_value(int(v_u64), 64)
    117     else:
    118       return 'v8value?'
    119   def display_hint(self):
    120     return 'v8value'
    121 
    122 
    123 def v8_pretty_printers(val):
    124   lookup_tag = val.type.tag
    125   if lookup_tag == None:
    126     return None
    127   elif lookup_tag == 'v8value':
    128     return V8ValuePrinter(val)
    129   return None
    130 gdb.pretty_printers.append(v8_pretty_printers)
    131 
    132 
    133 def v8_to_int(v):
    134   if v.type.sizeof == 4:
    135     return int(v.cast(t_u32))
    136   elif v.type.sizeof == 8:
    137     return int(v.cast(t_u64))
    138   else:
    139     return '?'
    140 
    141 
    142 def v8_get_value(vstring):
    143   v = gdb.parse_and_eval(vstring)
    144   return v8_to_int(v)
    145 
    146 
    147 class V8PrintObject (gdb.Command):
    148   """Prints a v8 object."""
    149   def __init__ (self):
    150     super (V8PrintObject, self).__init__ ("v8print", gdb.COMMAND_DATA)
    151   def invoke (self, arg, from_tty):
    152     v = v8_get_value(arg)
    153     gdb.execute('call __gdb_print_v8_object(%d)' % v)
    154 V8PrintObject()
    155