summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-10-22 12:50:53 +0100
committerBen Murdoch <benm@google.com>2010-10-22 20:03:06 +0100
commitf87a203d89e1bbb6708282e0b64dbd13d59b723d (patch)
treed7658572059125113d4052a87e2e2c1251419c64 /tools
parent0d5e116f6aee03185f237311a943491bb079a768 (diff)
downloadandroid_external_v8-f87a203d89e1bbb6708282e0b64dbd13d59b723d.tar.gz
android_external_v8-f87a203d89e1bbb6708282e0b64dbd13d59b723d.tar.bz2
android_external_v8-f87a203d89e1bbb6708282e0b64dbd13d59b723d.zip
Update V8 to r5675 as required by WebKit r70209
Change-Id: Ib10adb470d41ca8c109ead5fc893b880e18d489f
Diffstat (limited to 'tools')
-rw-r--r--tools/gyp/v8.gyp7
-rwxr-xr-xtools/ll_prof.py955
-rw-r--r--tools/v8.xcodeproj/project.pbxproj14
-rw-r--r--tools/visual_studio/v8_base.vcproj12
-rw-r--r--tools/visual_studio/v8_base_arm.vcproj12
-rw-r--r--tools/visual_studio/v8_base_x64.vcproj12
6 files changed, 992 insertions, 20 deletions
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index b355fb6f..17d556f1 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -285,6 +285,7 @@
'../../src/builtins.cc',
'../../src/builtins.h',
'../../src/bytecodes-irregexp.h',
+ '../../src/cached-powers.cc',
'../../src/cached-powers.h',
'../../src/char-predicates-inl.h',
'../../src/char-predicates.h',
@@ -402,7 +403,6 @@
'../../src/parser.cc',
'../../src/parser.h',
'../../src/platform.h',
- '../../src/powers-ten.h',
'../../src/prettyprinter.cc',
'../../src/prettyprinter.h',
'../../src/property.cc',
@@ -441,8 +441,12 @@
'../../src/spaces-inl.h',
'../../src/spaces.cc',
'../../src/spaces.h',
+ '../../src/string-search.cc',
+ '../../src/string-search.h',
'../../src/string-stream.cc',
'../../src/string-stream.h',
+ '../../src/strtod.cc',
+ '../../src/strtod.h',
'../../src/stub-cache.cc',
'../../src/stub-cache.h',
'../../src/token.cc',
@@ -472,7 +476,6 @@
'../../src/virtual-frame.cc',
'../../src/virtual-frame.h',
'../../src/vm-state-inl.h',
- '../../src/vm-state.cc',
'../../src/vm-state.h',
'../../src/zone-inl.h',
'../../src/zone.cc',
diff --git a/tools/ll_prof.py b/tools/ll_prof.py
new file mode 100755
index 00000000..563084dd
--- /dev/null
+++ b/tools/ll_prof.py
@@ -0,0 +1,955 @@
+#!/usr/bin/env python
+#
+# Copyright 2010 the V8 project authors. All rights reserved.
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials provided
+# with the distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import bisect
+import collections
+import ctypes
+import mmap
+import optparse
+import os
+import re
+import subprocess
+import sys
+import tempfile
+import time
+
+
+USAGE="""usage: %prog [OPTION]...
+
+Analyses V8 and perf logs to produce profiles.
+
+Perf logs can be collected using a command like:
+ $ perf record -R -e cycles -c 10000 -f -i ./shell bench.js --ll-prof
+ # -R: collect all data
+ # -e cycles: use cpu-cycles event (run "perf list" for details)
+ # -c 10000: write a sample after each 10000 events
+ # -f: force output file overwrite
+ # -i: limit profiling to our process and the kernel
+ # --ll-prof shell flag enables the right V8 logs
+This will produce a binary trace file (perf.data) that %prog can analyse.
+
+Examples:
+ # Print flat profile with annotated disassembly for the 10 top
+ # symbols. Use default log names and include the snapshot log.
+ $ %prog --snapshot --disasm-top=10
+
+ # Print flat profile with annotated disassembly for all used symbols.
+ # Use default log names and include kernel symbols into analysis.
+ $ %prog --disasm-all --kernel
+
+ # Print flat profile. Use custom log names.
+ $ %prog --log=foo.log --snapshot-log=snap-foo.log --trace=foo.data --snapshot
+"""
+
+
+# Must match kGcFakeMmap.
+V8_GC_FAKE_MMAP = "/tmp/__v8_gc__"
+
+JS_ORIGIN = "js"
+JS_SNAPSHOT_ORIGIN = "js-snapshot"
+
+# Avoid using the slow (google-specific) wrapper around objdump.
+OBJDUMP_BIN = "/usr/bin/objdump"
+if not os.path.exists(OBJDUMP_BIN):
+ OBJDUMP_BIN = "objdump"
+
+
+class Code(object):
+ """Code object."""
+
+ _COMMON_DISASM_OPTIONS = ["-M", "intel-mnemonic", "-C"]
+
+ _DISASM_HEADER_RE = re.compile(r"[a-f0-9]+\s+<.*:$")
+ _DISASM_LINE_RE = re.compile(r"\s*([a-f0-9]+):.*")
+
+ # Keys must match constants in Logger::LogCodeInfo.
+ _ARCH_MAP = {
+ "ia32": "-m i386",
+ "x64": "-m i386 -M x86-64",
+ "arm": "-m arm" # Not supported by our objdump build.
+ }
+
+ _id = 0
+
+ def __init__(self, name, start_address, end_address, origin, origin_offset):
+ self.id = Code._id
+ Code._id += 1
+ self.name = name
+ self.other_names = None
+ self.start_address = start_address
+ self.end_address = end_address
+ self.origin = origin
+ self.origin_offset = origin_offset
+ self.self_ticks = 0
+ self.self_ticks_map = None
+ self.callee_ticks = None
+
+ def AddName(self, name):
+ assert self.name != name
+ if self.other_names is None:
+ self.other_names = [name]
+ return
+ if not name in self.other_names:
+ self.other_names.append(name)
+
+ def FullName(self):
+ if self.other_names is None:
+ return self.name
+ self.other_names.sort()
+ return "%s (aka %s)" % (self.name, ", ".join(self.other_names))
+
+ def IsUsed(self):
+ return self.self_ticks > 0 or self.callee_ticks is not None
+
+ def Tick(self, pc):
+ self.self_ticks += 1
+ if self.self_ticks_map is None:
+ self.self_ticks_map = collections.defaultdict(lambda: 0)
+ offset = pc - self.start_address
+ self.self_ticks_map[offset] += 1
+
+ def CalleeTick(self, callee):
+ if self.callee_ticks is None:
+ self.callee_ticks = collections.defaultdict(lambda: 0)
+ self.callee_ticks[callee] += 1
+
+ def PrintAnnotated(self, code_info, options):
+ if self.self_ticks_map is None:
+ ticks_map = []
+ else:
+ ticks_map = self.self_ticks_map.items()
+ # Convert the ticks map to offsets and counts arrays so that later
+ # we can do binary search in the offsets array.
+ ticks_map.sort(key=lambda t: t[0])
+ ticks_offsets = [t[0] for t in ticks_map]
+ ticks_counts = [t[1] for t in ticks_map]
+ # Get a list of disassembled lines and their addresses.
+ lines = []
+ for line in self._GetDisasmLines(code_info, options):
+ match = Code._DISASM_LINE_RE.match(line)
+ if match:
+ line_address = int(match.group(1), 16)
+ lines.append((line_address, line))
+ if len(lines) == 0:
+ return
+ # Print annotated lines.
+ address = lines[0][0]
+ total_count = 0
+ for i in xrange(len(lines)):
+ start_offset = lines[i][0] - address
+ if i == len(lines) - 1:
+ end_offset = self.end_address - self.start_address
+ else:
+ end_offset = lines[i + 1][0] - address
+ # Ticks (reported pc values) are not always precise, i.e. not
+ # necessarily point at instruction starts. So we have to search
+ # for ticks that touch the current instruction line.
+ j = bisect.bisect_left(ticks_offsets, end_offset)
+ count = 0
+ for offset, cnt in reversed(zip(ticks_offsets[:j], ticks_counts[:j])):
+ if offset < start_offset:
+ break
+ count += cnt
+ total_count += count
+ count = 100.0 * count / self.self_ticks
+ if count >= 0.01:
+ print "%15.2f %s" % (count, lines[i][1])
+ else:
+ print "%s %s" % (" " * 15, lines[i][1])
+ print
+ assert total_count == self.self_ticks, \
+ "Lost ticks (%d != %d) in %s" % (total_count, self.self_ticks, self)
+
+ def __str__(self):
+ return "%s [0x%x, 0x%x) size: %d origin: %s" % (
+ self.name,
+ self.start_address,
+ self.end_address,
+ self.end_address - self.start_address,
+ self.origin)
+
+ def _GetDisasmLines(self, code_info, options):
+ tmp_name = None
+ if self.origin == JS_ORIGIN or self.origin == JS_SNAPSHOT_ORIGIN:
+ assert code_info.arch in Code._ARCH_MAP, \
+ "Unsupported architecture '%s'" % arch
+ arch_flags = Code._ARCH_MAP[code_info.arch]
+ # Create a temporary file just with this code object.
+ tmp_name = tempfile.mktemp(".v8code")
+ size = self.end_address - self.start_address
+ command = "dd if=%s.code of=%s bs=1 count=%d skip=%d && " \
+ "%s %s -D -b binary %s %s" % (
+ options.log, tmp_name, size, self.origin_offset,
+ OBJDUMP_BIN, ' '.join(Code._COMMON_DISASM_OPTIONS), arch_flags,
+ tmp_name)
+ else:
+ command = "%s %s --start-address=%d --stop-address=%d -d %s " % (
+ OBJDUMP_BIN, ' '.join(Code._COMMON_DISASM_OPTIONS),
+ self.origin_offset,
+ self.origin_offset + self.end_address - self.start_address,
+ self.origin)
+ process = subprocess.Popen(command,
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ out, err = process.communicate()
+ lines = out.split("\n")
+ header_line = 0
+ for i, line in enumerate(lines):
+ if Code._DISASM_HEADER_RE.match(line):
+ header_line = i
+ break
+ if tmp_name:
+ os.unlink(tmp_name)
+ return lines[header_line + 1:]
+
+
+class CodePage(object):
+ """Group of adjacent code objects."""
+
+ SHIFT = 12 # 4K pages
+ SIZE = (1 << SHIFT)
+ MASK = ~(SIZE - 1)
+
+ @staticmethod
+ def PageAddress(address):
+ return address & CodePage.MASK
+
+ @staticmethod
+ def PageId(address):
+ return address >> CodePage.SHIFT
+
+ @staticmethod
+ def PageAddressFromId(id):
+ return id << CodePage.SHIFT
+
+ def __init__(self, address):
+ self.address = address
+ self.code_objects = []
+
+ def Add(self, code):
+ self.code_objects.append(code)
+
+ def Remove(self, code):
+ self.code_objects.remove(code)
+
+ def Find(self, pc):
+ code_objects = self.code_objects
+ for i, code in enumerate(code_objects):
+ if code.start_address <= pc < code.end_address:
+ code_objects[0], code_objects[i] = code, code_objects[0]
+ return code
+ return None
+
+ def __iter__(self):
+ return self.code_objects.__iter__()
+
+
+class CodeMap(object):
+ """Code object map."""
+
+ def __init__(self):
+ self.pages = {}
+ self.min_address = 1 << 64
+ self.max_address = -1
+
+ def Add(self, code, max_pages=-1):
+ page_id = CodePage.PageId(code.start_address)
+ limit_id = CodePage.PageId(code.end_address + CodePage.SIZE - 1)
+ pages = 0
+ while page_id < limit_id:
+ if max_pages >= 0 and pages > max_pages:
+ print >>sys.stderr, \
+ "Warning: page limit (%d) reached for %s [%s]" % (
+ max_pages, code.name, code.origin)
+ break
+ if page_id in self.pages:
+ page = self.pages[page_id]
+ else:
+ page = CodePage(CodePage.PageAddressFromId(page_id))
+ self.pages[page_id] = page
+ page.Add(code)
+ page_id += 1
+ pages += 1
+ self.min_address = min(self.min_address, code.start_address)
+ self.max_address = max(self.max_address, code.end_address)
+
+ def Remove(self, code):
+ page_id = CodePage.PageId(code.start_address)
+ limit_id = CodePage.PageId(code.end_address + CodePage.SIZE - 1)
+ removed = False
+ while page_id < limit_id:
+ if page_id not in self.pages:
+ page_id += 1
+ continue
+ page = self.pages[page_id]
+ page.Remove(code)
+ removed = True
+ page_id += 1
+ return removed
+
+ def AllCode(self):
+ for page in self.pages.itervalues():
+ for code in page:
+ if CodePage.PageAddress(code.start_address) == page.address:
+ yield code
+
+ def UsedCode(self):
+ for code in self.AllCode():
+ if code.IsUsed():
+ yield code
+
+ def Print(self):
+ for code in self.AllCode():
+ print code
+
+ def Find(self, pc):
+ if pc < self.min_address or pc >= self.max_address:
+ return None
+ page_id = CodePage.PageId(pc)
+ if page_id not in self.pages:
+ return None
+ return self.pages[page_id].Find(pc)
+
+
+class CodeInfo(object):
+ """Generic info about generated code objects."""
+
+ def __init__(self, arch, header_size):
+ self.arch = arch
+ self.header_size = header_size
+
+
+class CodeLogReader(object):
+ """V8 code event log reader."""
+
+ _CODE_INFO_RE = re.compile(
+ r"code-info,([^,]+),(\d+)")
+
+ _CODE_CREATE_RE = re.compile(
+ r"code-creation,([^,]+),(0x[a-f0-9]+),(\d+),\"([^\"]*)\"(?:,(\d+))?")
+
+ _CODE_MOVE_RE = re.compile(
+ r"code-move,(0x[a-f0-9]+),(0x[a-f0-9]+)")
+
+ _CODE_DELETE_RE = re.compile(
+ r"code-delete,(0x[a-f0-9]+)")
+
+ _SNAPSHOT_POS_RE = re.compile(
+ r"snapshot-pos,(0x[a-f0-9]+),(\d+)")
+
+ _CODE_MOVING_GC = "code-moving-gc"
+
+ def __init__(self, log_name, code_map, is_snapshot, snapshot_pos_to_name):
+ self.log = open(log_name, "r")
+ self.code_map = code_map
+ self.is_snapshot = is_snapshot
+ self.snapshot_pos_to_name = snapshot_pos_to_name
+ self.address_to_snapshot_name = {}
+
+ def ReadCodeInfo(self):
+ line = self.log.readline() or ""
+ match = CodeLogReader._CODE_INFO_RE.match(line)
+ assert match, "No code info in log"
+ return CodeInfo(arch=match.group(1), header_size=int(match.group(2)))
+
+ def ReadUpToGC(self, code_info):
+ made_progress = False
+ code_header_size = code_info.header_size
+ while True:
+ line = self.log.readline()
+ if not line:
+ return made_progress
+ made_progress = True
+
+ if line.startswith(CodeLogReader._CODE_MOVING_GC):
+ self.address_to_snapshot_name.clear()
+ return made_progress
+
+ match = CodeLogReader._CODE_CREATE_RE.match(line)
+ if match:
+ start_address = int(match.group(2), 16) + code_header_size
+ end_address = start_address + int(match.group(3)) - code_header_size
+ if start_address in self.address_to_snapshot_name:
+ name = self.address_to_snapshot_name[start_address]
+ origin = JS_SNAPSHOT_ORIGIN
+ else:
+ name = "%s:%s" % (match.group(1), match.group(4))
+ origin = JS_ORIGIN
+ if self.is_snapshot:
+ origin_offset = 0
+ else:
+ origin_offset = int(match.group(5))
+ code = Code(name, start_address, end_address, origin, origin_offset)
+ conficting_code = self.code_map.Find(start_address)
+ if conficting_code:
+ CodeLogReader._HandleCodeConflict(conficting_code, code)
+ # TODO(vitalyr): this warning is too noisy because of our
+ # attempts to reconstruct code log from the snapshot.
+ # print >>sys.stderr, \
+ # "Warning: Skipping duplicate code log entry %s" % code
+ continue
+ self.code_map.Add(code)
+ continue
+
+ match = CodeLogReader._CODE_MOVE_RE.match(line)
+ if match:
+ old_start_address = int(match.group(1), 16) + code_header_size
+ new_start_address = int(match.group(2), 16) + code_header_size
+ if old_start_address == new_start_address:
+ # Skip useless code move entries.
+ continue
+ code = self.code_map.Find(old_start_address)
+ if not code:
+ print >>sys.stderr, "Warning: Not found %x" % old_start_address
+ continue
+ assert code.start_address == old_start_address, \
+ "Inexact move address %x for %s" % (old_start_address, code)
+ self.code_map.Remove(code)
+ size = code.end_address - code.start_address
+ code.start_address = new_start_address
+ code.end_address = new_start_address + size
+ self.code_map.Add(code)
+ continue
+
+ match = CodeLogReader._CODE_DELETE_RE.match(line)
+ if match:
+ old_start_address = int(match.group(1), 16) + code_header_size
+ code = self.code_map.Find(old_start_address)
+ if not code:
+ print >>sys.stderr, "Warning: Not found %x" % old_start_address
+ continue
+ assert code.start_address == old_start_address, \
+ "Inexact delete address %x for %s" % (old_start_address, code)
+ self.code_map.Remove(code)
+ continue
+
+ match = CodeLogReader._SNAPSHOT_POS_RE.match(line)
+ if match:
+ start_address = int(match.group(1), 16) + code_header_size
+ snapshot_pos = int(match.group(2))
+ if self.is_snapshot:
+ code = self.code_map.Find(start_address)
+ if code:
+ assert code.start_address == start_address, \
+ "Inexact snapshot address %x for %s" % (start_address, code)
+ self.snapshot_pos_to_name[snapshot_pos] = code.name
+ else:
+ if snapshot_pos in self.snapshot_pos_to_name:
+ self.address_to_snapshot_name[start_address] = \
+ self.snapshot_pos_to_name[snapshot_pos]
+
+ def Dispose(self):
+ self.log.close()
+
+ @staticmethod
+ def _HandleCodeConflict(old_code, new_code):
+ assert (old_code.start_address == new_code.start_address and
+ old_code.end_address == new_code.end_address), \
+ "Conficting code log entries %s and %s" % (old_code, new_code)
+ CodeLogReader._UpdateNames(old_code, new_code)
+
+ @staticmethod
+ def _UpdateNames(old_code, new_code):
+ if old_code.name == new_code.name:
+ return
+ # Kludge: there are code objects with custom names that don't
+ # match their flags.
+ misnamed_code = set(["Builtin:CpuFeatures::Probe"])
+ if old_code.name in misnamed_code:
+ return
+ # Code object may be shared by a few functions. Collect the full
+ # set of names.
+ old_code.AddName(new_code.name)
+
+
+class Descriptor(object):
+ """Descriptor of a structure in the binary trace log."""
+
+ CTYPE_MAP = {
+ "u16": ctypes.c_uint16,
+ "u32": ctypes.c_uint32,
+ "u64": ctypes.c_uint64
+ }
+
+ def __init__(self, fields):
+ class TraceItem(ctypes.Structure):
+ _fields_ = Descriptor.CtypesFields(fields)
+
+ def __str__(self):
+ return ", ".join("%s: %s" % (field, self.__getattribute__(field))
+ for field, _ in TraceItem._fields_)
+
+ self.ctype = TraceItem
+
+ def Read(self, trace, offset):
+ return self.ctype.from_buffer(trace, offset)
+
+ @staticmethod
+ def CtypesFields(fields):
+ return [(field, Descriptor.CTYPE_MAP[format]) for (field, format) in fields]
+
+
+# Please see http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=tree;f=tools/perf
+# for the gory details.
+
+
+TRACE_HEADER_DESC = Descriptor([
+ ("magic", "u64"),
+ ("size", "u64"),
+ ("attr_size", "u64"),
+ ("attrs_offset", "u64"),
+ ("attrs_size", "u64"),
+ ("data_offset", "u64"),
+ ("data_size", "u64"),
+ ("event_types_offset", "u64"),
+ ("event_types_size", "u64")
+])
+
+
+PERF_EVENT_ATTR_DESC = Descriptor([
+ ("type", "u32"),
+ ("size", "u32"),
+ ("config", "u64"),
+ ("sample_period_or_freq", "u64"),
+ ("sample_type", "u64"),
+ ("read_format", "u64"),
+ ("flags", "u64"),
+ ("wakeup_events_or_watermark", "u32"),
+ ("bt_type", "u32"),
+ ("bp_addr", "u64"),
+ ("bp_len", "u64"),
+])
+
+
+PERF_EVENT_HEADER_DESC = Descriptor([
+ ("type", "u32"),
+ ("misc", "u16"),
+ ("size", "u16")
+])
+
+
+PERF_MMAP_EVENT_BODY_DESC = Descriptor([
+ ("pid", "u32"),
+ ("tid", "u32"),
+ ("addr", "u64"),
+ ("len", "u64"),
+ ("pgoff", "u64")
+])
+
+
+# perf_event_attr.sample_type bits control the set of
+# perf_sample_event fields.
+PERF_SAMPLE_IP = 1 << 0
+PERF_SAMPLE_TID = 1 << 1
+PERF_SAMPLE_TIME = 1 << 2
+PERF_SAMPLE_ADDR = 1 << 3
+PERF_SAMPLE_READ = 1 << 4
+PERF_SAMPLE_CALLCHAIN = 1 << 5
+PERF_SAMPLE_ID = 1 << 6
+PERF_SAMPLE_CPU = 1 << 7
+PERF_SAMPLE_PERIOD = 1 << 8
+PERF_SAMPLE_STREAM_ID = 1 << 9
+PERF_SAMPLE_RAW = 1 << 10
+
+
+PERF_SAMPLE_EVENT_BODY_FIELDS = [
+ ("ip", "u64", PERF_SAMPLE_IP),
+ ("pid", "u32", PERF_SAMPLE_TID),
+ ("tid", "u32", PERF_SAMPLE_TID),
+ ("time", "u64", PERF_SAMPLE_TIME),
+ ("addr", "u64", PERF_SAMPLE_ADDR),
+ ("id", "u64", PERF_SAMPLE_ID),
+ ("stream_id", "u64", PERF_SAMPLE_STREAM_ID),
+ ("cpu", "u32", PERF_SAMPLE_CPU),
+ ("res", "u32", PERF_SAMPLE_CPU),
+ ("period", "u64", PERF_SAMPLE_PERIOD),
+ # Don't want to handle read format that comes after the period and
+ # before the callchain and has variable size.
+ ("nr", "u64", PERF_SAMPLE_CALLCHAIN)
+ # Raw data follows the callchain and is ignored.
+]
+
+
+PERF_SAMPLE_EVENT_IP_FORMAT = "u64"
+
+
+PERF_RECORD_MMAP = 1
+PERF_RECORD_SAMPLE = 9
+
+
+class TraceReader(object):
+ """Perf (linux-2.6/tools/perf) trace file reader."""
+
+ _TRACE_HEADER_MAGIC = 4993446653023372624
+
+ def __init__(self, trace_name):
+ self.trace_file = open(trace_name, "r")
+ self.trace = mmap.mmap(self.trace_file.fileno(), 0, mmap.MAP_PRIVATE)
+ self.trace_header = TRACE_HEADER_DESC.Read(self.trace, 0)
+ if self.trace_header.magic != TraceReader._TRACE_HEADER_MAGIC:
+ print >>sys.stderr, "Warning: unsupported trace header magic"
+ self.offset = self.trace_header.data_offset
+ self.limit = self.trace_header.data_offset + self.trace_header.data_size
+ assert self.limit <= self.trace.size(), \
+ "Trace data limit exceeds trace file size"
+ self.header_size = ctypes.sizeof(PERF_EVENT_HEADER_DESC.ctype)
+ assert self.trace_header.attrs_size != 0, \
+ "No perf event attributes found in the trace"
+ perf_event_attr = PERF_EVENT_ATTR_DESC.Read(self.trace,
+ self.trace_header.attrs_offset)
+ self.sample_event_body_desc = self._SampleEventBodyDesc(
+ perf_event_attr.sample_type)
+ self.callchain_supported = \
+ (perf_event_attr.sample_type & PERF_SAMPLE_CALLCHAIN) != 0
+ if self.callchain_supported:
+ self.ip_struct = Descriptor.CTYPE_MAP[PERF_SAMPLE_EVENT_IP_FORMAT]
+ self.ip_size = ctypes.sizeof(self.ip_struct)
+
+ def ReadEventHeader(self):
+ if self.offset >= self.limit:
+ return None, 0
+ offset = self.offset
+ header = PERF_EVENT_HEADER_DESC.Read(self.trace, self.offset)
+ self.offset += header.size
+ return header, offset
+
+ def ReadMmap(self, header, offset):
+ mmap_info = PERF_MMAP_EVENT_BODY_DESC.Read(self.trace,
+ offset + self.header_size)
+ # Read null-padded filename.
+ filename = self.trace[offset + self.header_size + ctypes.sizeof(mmap_info):
+ offset + header.size].rstrip(chr(0))
+ mmap_info.filename = filename
+ return mmap_info
+
+ def ReadSample(self, header, offset):
+ sample = self.sample_event_body_desc.Read(self.trace,
+ offset + self.header_size)
+ if not self.callchain_supported:
+ return sample
+ sample.ips = []
+ offset += self.header_size + ctypes.sizeof(sample)
+ for _ in xrange(sample.nr):
+ sample.ips.append(
+ self.ip_struct.from_buffer(self.trace, offset).value)
+ offset += self.ip_size
+ return sample
+
+ def Dispose(self):
+ self.trace.close()
+ self.trace_file.close()
+
+ def _SampleEventBodyDesc(self, sample_type):
+ assert (sample_type & PERF_SAMPLE_READ) == 0, \
+ "Can't hande read format in samples"
+ fields = [(field, format)
+ for (field, format, bit) in PERF_SAMPLE_EVENT_BODY_FIELDS
+ if (bit & sample_type) != 0]
+ return Descriptor(fields)
+
+
+OBJDUMP_SECTION_HEADER_RE = re.compile(
+ r"^\s*\d+\s(\.\S+)\s+[a-f0-9]")
+OBJDUMP_SYMBOL_LINE_RE = re.compile(
+ r"^([a-f0-9]+)\s(.{7})\s(\S+)\s+([a-f0-9]+)\s+(?:\.hidden\s+)?(.*)$")
+OBJDUMP_DYNAMIC_SYMBOLS_START_RE = re.compile(
+ r"^DYNAMIC SYMBOL TABLE")
+KERNEL_ALLSYMS_FILE = "/proc/kallsyms"
+PERF_KERNEL_ALLSYMS_RE = re.compile(
+ r".*kallsyms.*")
+KERNEL_ALLSYMS_LINE_RE = re.compile(
+ r"^([a-f0-9]+)\s(?:t|T)\s(\S+)$")
+
+
+class LibraryRepo(object):
+ def __init__(self):
+ self.infos = []
+ self.names = set()
+ self.ticks = {}
+
+ def Load(self, mmap_info, code_map, options):
+ # Skip kernel mmaps when requested using the fact that their tid
+ # is 0.
+ if mmap_info.tid == 0 and not options.kernel:
+ return True
+ if PERF_KERNEL_ALLSYMS_RE.match(mmap_info.filename):
+ return self._LoadKernelSymbols(code_map)
+ self.infos.append(mmap_info)
+ mmap_info.ticks = 0
+ mmap_info.unique_name = self._UniqueMmapName(mmap_info)
+ if not os.path.exists(mmap_info.filename):
+ return True
+ # Request section headers (-h), symbols (-t), and dynamic symbols
+ # (-T) from objdump.
+ # Unfortunately, section headers span two lines, so we have to
+ # keep the just seen section name (from the first line in each
+ # section header) in the after_section variable.
+ process = subprocess.Popen(
+ "%s -h -t -T -C %s" % (OBJDUMP_BIN, mmap_info.filename),
+ shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ pipe = process.stdout
+ after_section = None
+ code_sections = set()
+ reloc_sections = set()
+ dynamic = False
+ try:
+ for line in pipe:
+ if after_section:
+ if line.find("CODE") != -1:
+ code_sections.add(after_section)
+ if line.find("RELOC") != -1:
+ reloc_sections.add(after_section)
+ after_section = None
+ continue
+
+ match = OBJDUMP_SECTION_HEADER_RE.match(line)
+ if match:
+ after_section = match.group(1)
+ continue
+
+ if OBJDUMP_DYNAMIC_SYMBOLS_START_RE.match(line):
+ dynamic = True
+ continue
+
+ match = OBJDUMP_SYMBOL_LINE_RE.match(line)
+ if match:
+ start_address = int(match.group(1), 16)
+ origin_offset = start_address
+ flags = match.group(2)
+ section = match.group(3)
+ if section in code_sections:
+ if dynamic or section in reloc_sections:
+ start_address += mmap_info.addr
+ size = int(match.group(4), 16)
+ name = match.group(5)
+ origin = mmap_info.filename
+ code_map.Add(Code(name, start_address, start_address + size,
+ origin, origin_offset))
+ finally:
+ pipe.close()
+ assert process.wait() == 0, "Failed to objdump %s" % mmap_info.filename
+
+ def Tick(self, pc):
+ for i, mmap_info in enumerate(self.infos):
+ if mmap_info.addr <= pc < (mmap_info.addr + mmap_info.len):
+ mmap_info.ticks += 1
+ self.infos[0], self.infos[i] = mmap_info, self.infos[0]
+ return True
+ return False
+
+ def _UniqueMmapName(self, mmap_info):
+ name = mmap_info.filename
+ index = 1
+ while name in self.names:
+ name = "%s-%d" % (mmap_info.filename, index)
+ index += 1
+ self.names.add(name)
+ return name
+
+ def _LoadKernelSymbols(self, code_map):
+ if not os.path.exists(KERNEL_ALLSYMS_FILE):
+ print >>sys.stderr, "Warning: %s not found" % KERNEL_ALLSYMS_FILE
+ return False
+ kallsyms = open(KERNEL_ALLSYMS_FILE, "r")
+ code = None
+ for line in kallsyms:
+ match = KERNEL_ALLSYMS_LINE_RE.match(line)
+ if match:
+ start_address = int(match.group(1), 16)
+ end_address = start_address
+ name = match.group(2)
+ if code:
+ code.end_address = start_address
+ code_map.Add(code, 16)
+ code = Code(name, start_address, end_address, "kernel", 0)
+ return True
+
+
+def PrintReport(code_map, library_repo, code_info, options):
+ print "Ticks per symbol:"
+ used_code = [code for code in code_map.UsedCode()]
+ used_code.sort(key=lambda x: x.self_ticks, reverse=True)
+ for i, code in enumerate(used_code):
+ print "%10d %s [%s]" % (code.self_ticks, code.FullName(), code.origin)
+ if options.disasm_all or i < options.disasm_top:
+ code.PrintAnnotated(code_info, options)
+ print
+ print "Ticks per library:"
+ mmap_infos = [m for m in library_repo.infos]
+ mmap_infos.sort(key=lambda m: m.ticks, reverse=True)
+ for mmap_info in mmap_infos:
+ print "%10d %s" % (mmap_info.ticks, mmap_info.unique_name)
+
+
+def PrintDot(code_map, options):
+ print "digraph G {"
+ for code in code_map.UsedCode():
+ if code.self_ticks < 10:
+ continue
+ print "n%d [shape=box,label=\"%s\"];" % (code.id, code.name)
+ if code.callee_ticks:
+ for callee, ticks in code.callee_ticks.iteritems():
+ print "n%d -> n%d [label=\"%d\"];" % (code.id, callee.id, ticks)
+ print "}"
+
+
+if __name__ == "__main__":
+ parser = optparse.OptionParser(USAGE)
+ parser.add_option("--snapshot-log",
+ default="obj/release/snapshot.log",
+ help="V8 snapshot log file name [default: %default]")
+ parser.add_option("--log",
+ default="v8.log",
+ help="V8 log file name [default: %default]")
+ parser.add_option("--snapshot",
+ default=False,
+ action="store_true",
+ help="process V8 snapshot log [default: %default]")
+ parser.add_option("--trace",
+ default="perf.data",
+ help="perf trace file name [default: %default]")
+ parser.add_option("--kernel",
+ default=False,
+ action="store_true",
+ help="process kernel entries [default: %default]")
+ parser.add_option("--disasm-top",
+ default=0,
+ type="int",
+ help=("number of top symbols to disassemble and annotate "
+ "[default: %default]"))
+ parser.add_option("--disasm-all",
+ default=False,
+ action="store_true",
+ help=("disassemble and annotate all used symbols "
+ "[default: %default]"))
+ parser.add_option("--dot",
+ default=False,
+ action="store_true",
+ help="produce dot output (WIP) [default: %default]")
+ parser.add_option("--quiet", "-q",
+ default=False,
+ action="store_true",
+ help="no auxiliary messages [default: %default]")
+ options, args = parser.parse_args()
+
+ if not options.quiet:
+ if options.snapshot:
+ print "V8 logs: %s, %s, %s.code" % (options.snapshot_log,
+ options.log,
+ options.log)
+ else:
+ print "V8 log: %s, %s.code (no snapshot)" % (options.log, options.log)
+ print "Perf trace file: %s" % options.trace
+
+ # Stats.
+ events = 0
+ ticks = 0
+ missed_ticks = 0
+ really_missed_ticks = 0
+ mmap_time = 0
+ sample_time = 0
+
+ # Initialize the log reader and get the code info.
+ code_map = CodeMap()
+ snapshot_name_map = {}
+ log_reader = CodeLogReader(log_name=options.log,
+ code_map=code_map,
+ is_snapshot=False,
+ snapshot_pos_to_name=snapshot_name_map)
+ code_info = log_reader.ReadCodeInfo()
+ if not options.quiet:
+ print "Generated code architecture: %s" % code_info.arch
+ print
+
+ # Process the snapshot log to fill the snapshot name map.
+ if options.snapshot:
+ snapshot_log_reader = CodeLogReader(log_name=options.snapshot_log,
+ code_map=CodeMap(),
+ is_snapshot=True,
+ snapshot_pos_to_name=snapshot_name_map)
+ while snapshot_log_reader.ReadUpToGC(code_info):
+ pass
+
+ # Process the code and trace logs.
+ library_repo = LibraryRepo()
+ log_reader.ReadUpToGC(code_info)
+ trace_reader = TraceReader(options.trace)
+ while True:
+ header, offset = trace_reader.ReadEventHeader()
+ if not header:
+ break
+ events += 1
+ if header.type == PERF_RECORD_MMAP:
+ start = time.time()
+ mmap_info = trace_reader.ReadMmap(header, offset)
+ if mmap_info.filename == V8_GC_FAKE_MMAP:
+ log_reader.ReadUpToGC()
+ else:
+ library_repo.Load(mmap_info, code_map, options)
+ mmap_time += time.time() - start
+ elif header.type == PERF_RECORD_SAMPLE:
+ ticks += 1
+ start = time.time()
+ sample = trace_reader.ReadSample(header, offset)
+ code = code_map.Find(sample.ip)
+ if code:
+ code.Tick(sample.ip)
+ else:
+ missed_ticks += 1
+ if not library_repo.Tick(sample.ip) and not code:
+ really_missed_ticks += 1
+ if trace_reader.callchain_supported:
+ for ip in sample.ips:
+ caller_code = code_map.Find(ip)
+ if caller_code:
+ if code:
+ caller_code.CalleeTick(code)
+ code = caller_code
+ sample_time += time.time() - start
+
+ if options.dot:
+ PrintDot(code_map, options)
+ else:
+ PrintReport(code_map, library_repo, code_info, options)
+
+ if not options.quiet:
+ print
+ print "Stats:"
+ print "%10d total trace events" % events
+ print "%10d total ticks" % ticks
+ print "%10d ticks not in symbols" % missed_ticks
+ print "%10d unaccounted ticks" % really_missed_ticks
+ print "%10d total symbols" % len([c for c in code_map.AllCode()])
+ print "%10d used symbols" % len([c for c in code_map.UsedCode()])
+ print "%9.2fs library processing time" % mmap_time
+ print "%9.2fs tick processing time" % sample_time
+
+ log_reader.Dispose()
+ trace_reader.Dispose()
diff --git a/tools/v8.xcodeproj/project.pbxproj b/tools/v8.xcodeproj/project.pbxproj
index 3ebc4584..08558cc5 100644
--- a/tools/v8.xcodeproj/project.pbxproj
+++ b/tools/v8.xcodeproj/project.pbxproj
@@ -122,6 +122,7 @@
89A88E1F0E71A6B40043BA31 /* snapshot-common.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1820E719B8F00D62E90 /* snapshot-common.cc */; };
89A88E200E71A6B60043BA31 /* snapshot-empty.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1830E719B8F00D62E90 /* snapshot-empty.cc */; };
89A88E210E71A6B70043BA31 /* spaces.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1860E719B8F00D62E90 /* spaces.cc */; };
+ 89A88E220E71A6BC0043BA31 /* string-search.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-search.cc */; };
89A88E220E71A6BC0043BA31 /* string-stream.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-stream.cc */; };
89A88E230E71A6BE0043BA31 /* stub-cache-ia32.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18B0E719B8F00D62E90 /* stub-cache-ia32.cc */; };
89A88E240E71A6BF0043BA31 /* stub-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18C0E719B8F00D62E90 /* stub-cache.cc */; };
@@ -183,6 +184,7 @@
89F23C730E78D5B2006B2466 /* snapshot-common.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1820E719B8F00D62E90 /* snapshot-common.cc */; };
89F23C740E78D5B2006B2466 /* snapshot-empty.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1830E719B8F00D62E90 /* snapshot-empty.cc */; };
89F23C750E78D5B2006B2466 /* spaces.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1860E719B8F00D62E90 /* spaces.cc */; };
+ 89F23C760E78D5B2006B2466 /* string-search.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-search.cc */; };
89F23C760E78D5B2006B2466 /* string-stream.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF1880E719B8F00D62E90 /* string-stream.cc */; };
89F23C780E78D5B2006B2466 /* stub-cache.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18C0E719B8F00D62E90 /* stub-cache.cc */; };
89F23C790E78D5B2006B2466 /* token.cc in Sources */ = {isa = PBXBuildFile; fileRef = 897FF18E0E719B8F00D62E90 /* token.cc */; };
@@ -218,8 +220,6 @@
9F73E3B2114E61A100F84A5A /* profile-generator.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F73E3AF114E61A100F84A5A /* profile-generator.cc */; };
9F92FAA90F8F28AD0089F02C /* func-name-inferrer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */; };
9F92FAAA0F8F28AD0089F02C /* func-name-inferrer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9F92FAA70F8F28AD0089F02C /* func-name-inferrer.cc */; };
- 9FA37335116DD9F000C4CD55 /* vm-state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA37333116DD9F000C4CD55 /* vm-state.cc */; };
- 9FA37336116DD9F000C4CD55 /* vm-state.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA37333116DD9F000C4CD55 /* vm-state.cc */; };
9FA38BB31175B2D200C4CD55 /* data-flow.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9C1175B2D200C4CD55 /* data-flow.cc */; };
9FA38BB41175B2D200C4CD55 /* diy-fp.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38B9E1175B2D200C4CD55 /* diy-fp.cc */; };
9FA38BB51175B2D200C4CD55 /* fast-dtoa.cc in Sources */ = {isa = PBXBuildFile; fileRef = 9FA38BA11175B2D200C4CD55 /* fast-dtoa.cc */; };
@@ -502,6 +502,8 @@
897FF1850E719B8F00D62E90 /* spaces-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "spaces-inl.h"; sourceTree = "<group>"; };
897FF1860E719B8F00D62E90 /* spaces.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spaces.cc; sourceTree = "<group>"; };
897FF1870E719B8F00D62E90 /* spaces.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spaces.h; sourceTree = "<group>"; };
+ 897FF1880E719B8F00D62E90 /* string-search.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "string-search.cc"; sourceTree = "<group>"; };
+ 897FF1880E719B8F00D62E90 /* string-search.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "string-search.h"; sourceTree = "<group>"; };
897FF1880E719B8F00D62E90 /* string-stream.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "string-stream.cc"; sourceTree = "<group>"; };
897FF1890E719B8F00D62E90 /* string-stream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "string-stream.h"; sourceTree = "<group>"; };
897FF18A0E719B8F00D62E90 /* stub-cache-arm.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "stub-cache-arm.cc"; path = "arm/stub-cache-arm.cc"; sourceTree = "<group>"; };
@@ -586,7 +588,6 @@
9F92FAA80F8F28AD0089F02C /* func-name-inferrer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "func-name-inferrer.h"; sourceTree = "<group>"; };
9FA36F62116BA26500C4CD55 /* v8-profiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "v8-profiler.h"; sourceTree = "<group>"; };
9FA37332116DD9F000C4CD55 /* vm-state-inl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "vm-state-inl.h"; sourceTree = "<group>"; };
- 9FA37333116DD9F000C4CD55 /* vm-state.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "vm-state.cc"; sourceTree = "<group>"; };
9FA37334116DD9F000C4CD55 /* vm-state.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "vm-state.h"; sourceTree = "<group>"; };
9FA38B9B1175B2D200C4CD55 /* cached-powers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "cached-powers.h"; sourceTree = "<group>"; };
9FA38B9C1175B2D200C4CD55 /* data-flow.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "data-flow.cc"; sourceTree = "<group>"; };
@@ -964,6 +965,8 @@
897FF1870E719B8F00D62E90 /* spaces.h */,
9FA38BAC1175B2D200C4CD55 /* splay-tree-inl.h */,
9FA38BAD1175B2D200C4CD55 /* splay-tree.h */,
+ 897FF1880E719B8F00D62E90 /* string-search.cc */,
+ 897FF1890E719B8F00D62E90 /* string-search.h */,
897FF1880E719B8F00D62E90 /* string-stream.cc */,
897FF1890E719B8F00D62E90 /* string-stream.h */,
897FF18A0E719B8F00D62E90 /* stub-cache-arm.cc */,
@@ -1007,7 +1010,6 @@
58950D5A0F55514900F3E8BA /* virtual-frame.cc */,
58950D5B0F55514900F3E8BA /* virtual-frame.h */,
9FA37332116DD9F000C4CD55 /* vm-state-inl.h */,
- 9FA37333116DD9F000C4CD55 /* vm-state.cc */,
9FA37334116DD9F000C4CD55 /* vm-state.h */,
897FF1A10E719B8F00D62E90 /* zone-inl.h */,
897FF1A20E719B8F00D62E90 /* zone.cc */,
@@ -1353,6 +1355,7 @@
89A88E1F0E71A6B40043BA31 /* snapshot-common.cc in Sources */,
89A88E200E71A6B60043BA31 /* snapshot-empty.cc in Sources */,
89A88E210E71A6B70043BA31 /* spaces.cc in Sources */,
+ 89A88E220E71A6BC0043BA31 /* string-search.cc in Sources */,
89A88E220E71A6BC0043BA31 /* string-stream.cc in Sources */,
89A88E230E71A6BE0043BA31 /* stub-cache-ia32.cc in Sources */,
89A88E240E71A6BF0043BA31 /* stub-cache.cc in Sources */,
@@ -1370,7 +1373,6 @@
9FA38BC71175B2E500C4CD55 /* virtual-frame-ia32.cc in Sources */,
58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
58950D660F5551C200F3E8BA /* virtual-frame.cc in Sources */,
- 9FA37336116DD9F000C4CD55 /* vm-state.cc in Sources */,
89A88E2E0E71A6D60043BA31 /* zone.cc in Sources */,
C68081B112251239001EAFE4 /* code-stubs-ia32.cc in Sources */,
);
@@ -1478,6 +1480,7 @@
89F23C730E78D5B2006B2466 /* snapshot-common.cc in Sources */,
89F23C740E78D5B2006B2466 /* snapshot-empty.cc in Sources */,
89F23C750E78D5B2006B2466 /* spaces.cc in Sources */,
+ 89F23C760E78D5B2006B2466 /* string-search.cc in Sources */,
89F23C760E78D5B2006B2466 /* string-stream.cc in Sources */,
89F23CA00E78D609006B2466 /* stub-cache-arm.cc in Sources */,
89F23C780E78D5B2006B2466 /* stub-cache.cc in Sources */,
@@ -1495,7 +1498,6 @@
58950D690F5551CE00F3E8BA /* virtual-frame-light.cc in Sources */,
58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
58950D680F5551CB00F3E8BA /* virtual-frame.cc in Sources */,
- 9FA37335116DD9F000C4CD55 /* vm-state.cc in Sources */,
89F23C820E78D5B2006B2466 /* zone.cc in Sources */,
C68081AD1225120B001EAFE4 /* code-stubs-arm.cc in Sources */,
);
diff --git a/tools/visual_studio/v8_base.vcproj b/tools/visual_studio/v8_base.vcproj
index 4629b5d3..62d45015 100644
--- a/tools/visual_studio/v8_base.vcproj
+++ b/tools/visual_studio/v8_base.vcproj
@@ -938,6 +938,14 @@
>
</File>
<File
+ RelativePath="..\..\src\string-search.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\string-search.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\string-stream.cc"
>
</File>
@@ -1074,10 +1082,6 @@
>
</File>
<File
- RelativePath="..\..\src\vm-state.cc"
- >
- </File>
- <File
RelativePath="..\..\src\vm-state-inl.h"
>
</File>
diff --git a/tools/visual_studio/v8_base_arm.vcproj b/tools/visual_studio/v8_base_arm.vcproj
index 4848c9bc..4f9ff4ca 100644
--- a/tools/visual_studio/v8_base_arm.vcproj
+++ b/tools/visual_studio/v8_base_arm.vcproj
@@ -912,6 +912,14 @@
>
</File>
<File
+ RelativePath="..\..\src\string-search.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\string-search.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\string-stream.cc"
>
</File>
@@ -1052,10 +1060,6 @@
>
</File>
<File
- RelativePath="..\..\src\vm-state.cc"
- >
- </File>
- <File
RelativePath="..\..\src\vm-state-inl.h"
>
</File>
diff --git a/tools/visual_studio/v8_base_x64.vcproj b/tools/visual_studio/v8_base_x64.vcproj
index e9af65da..c84bce2d 100644
--- a/tools/visual_studio/v8_base_x64.vcproj
+++ b/tools/visual_studio/v8_base_x64.vcproj
@@ -898,6 +898,14 @@
>
</File>
<File
+ RelativePath="..\..\src\string-search.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\string-search.h"
+ >
+ </File>
+ <File
RelativePath="..\..\src\string-stream.cc"
>
</File>
@@ -1034,10 +1042,6 @@
>
</File>
<File
- RelativePath="..\..\src\vm-state.cc"
- >
- </File>
- <File
RelativePath="..\..\src\vm-state-inl.h"
>
</File>