肉碱是什么| 白带什么样子| 中度肠化是什么意思| 导是什么意思| 这是什么表情包| 今年是什么生肖年| 秘辛是什么意思| 水鱼煲鸡汤放什么药材| 脾五行属什么| it是什么行业| 知了猴是什么东西| 什么可以美白| 肌酐高是什么引起的| rush是什么意思| 梦见吃药是什么意思| 3的倒数是什么| 颈椎病吃什么药效果好| 胸推是什么意思| 为什么美国支持以色列| 桥本甲状腺炎吃什么药| 小肚子左边疼是什么原因| 岔气吃什么药| 鞋底md是什么材质| 十二年义务教育什么时候实行| 今年三十岁属什么生肖| 乙肝阳性是什么意思| 三维彩超主要检查什么| 绝交是什么意思| 细菌感染有什么症状表现| 液基薄层细胞学检查是什么| 拔罐对身体有什么好处和坏处| 时兴是什么意思| 激素吃多了对身体有什么副作用| 孙权和孙策是什么关系| 吊销驾驶证是什么意思| 深圳居住证有什么用| 血清胃功能检测是什么| 吃完饭打嗝是什么原因| 姗字五行属什么| mrn是什么意思| 吃什么食物可以补充雌激素| 胆汁是什么颜色| 表情是什么意思| 为什么眼睛有红血丝| 眼睛总有眼屎是什么原因| 下午一点是什么时辰| 恩师是什么意思| 64属什么| 嗓子有痰是什么原因引起的| 胃反流吃什么药效果好| 座是什么结构| 慢性阑尾炎吃什么消炎药| 打狂犬疫苗后注意什么| 为什么叫韩国人棒子| 沙果是什么水果| 他克莫司软膏治疗什么| 什么叫脂溢性脱发| 甘油三酯高吃什么| 退烧药吃多了有什么副作用| 疲软是什么意思| 西梅什么时候成熟| 梦见别人怀孕了是什么意思| 衢是什么意思| 孕妇尿路感染吃什么药| 什么地望着| st是什么意思| 明矾是什么东西| cooc香水是什么牌子的| 大圣归来2什么时候上映| 副词什么意思| 右眉毛跳是什么预兆| 经常出鼻血是什么原因| 什么是高脂血症| 为什么泡完脚后非常痒| 用什么回奶最快最有效| 什么于怀| 我想成为一个什么样的人| 男性早泄吃什么药| 什么是打飞机| 1966年属什么今年多大| 来大姨妈血块多是什么原因| 低血糖有什么危害| 种生基是什么意思| aml是什么意思| 高姓和什么姓是世仇| 龟毛的性格指什么性格| 慎什么意思| 牵牛花什么时候开花| 幻视是什么意思| 纤维瘤挂什么科| 早上喝蜂蜜水有什么好处| 5月25日什么星座| 企鹅吃什么食物| 曲奇是什么意思| 什么是全运会| b3是什么维生素| 女人手心痒是什么征兆| 上嘴唇长痘痘是什么原因| 小孩经常尿床是什么原因| 日本旅游买什么东西最划算| 3月7日是什么星座| 病毒性感冒咳嗽吃什么药效果好| 吃什么长内膜| 尿隐血十1是什么意思| c3是什么驾驶证| 宫颈息肉有什么症状| 李元霸为什么怕罗士信| 白包是什么意思| 211大学是什么意思| cpr什么意思| 肾囊肿是什么原因引起的| 裂纹舌是什么原因| 上眼皮突然肿了是什么原因| 泡面吃多了有什么危害| 金牛座后面是什么星座| 新加坡为什么说中文| 举足轻重什么意思| 绿萝叶子发黄是什么原因| 脚底疼是什么原因引起的| 肾阴虚是什么症状| 老农民韩美丽结局是什么| 什么是静脉| 亿字五行属什么| 牙龈发紫是什么原因| 过期的钙片有什么用途| 高血压能喝什么饮料| 左眼跳代表什么| 中性粒细胞比率偏低是什么意思| 梦见经血是什么预兆| 兼职是什么| 十字架代表什么| pola是什么牌子| 喝冰糖水有什么好处和坏处| 海淘是什么意思啊| 士加一笔是什么字| 感冒嗓子疼吃什么药| 断桥铝是什么意思| 蛋白质是什么食物| 宫内囊性回声代表什么| 头好出汗是什么原因| 花名册是什么意思| 1014是什么星座| 舌头发黄是什么原因| 鱼的五行属什么| 175是什么码| 小青龙是什么龙虾| 凤梨不能和什么一起吃| 血压偏高吃什么药| 慢性胃炎能吃什么水果| 脂肪瘤是什么原因引起的| 下压高是什么原因引起的| 梦见喝水是什么意思| 偶发室上性早搏是什么意思| 吃黑米有什么好处和坏处| 四物汤什么时候喝最好| 腹泻拉稀水吃什么药| 胃左边疼是什么原因| 韩红什么军衔| 炭疽病是什么病| 字如其人什么意思| 五指毛桃有什么作用| 梦见朋友离婚了是什么意思| 元气大伤什么意思| 同比和环比是什么意思| 甲状腺是什么病严重吗| 天天睡觉做梦是什么原因| 意大利全称是什么| 龟苓膏不能和什么一起吃| 返祖现象什么意思| 每天一杯蜂蜜水有什么好处| 什么时候跑步减肥效果最好| 广州有什么美食| 内科查什么| gg 是什么意思| 经血逆流的症状是什么| 梦见亲嘴是什么意思| 牙结石有什么危害| 手机越狱什么意思| 手脱皮擦什么药膏| 上火吃什么消炎药| 血压太低有什么危害| 喝红枣水有什么好处和坏处| 衡水老白干是什么香型| hiit是什么意思| 双肾尿盐结晶是什么| 夏天喝什么茶比较好| 尿酸偏高是什么病| 哺乳期妈妈感冒了可以吃什么药| 请人原谅说什么| 五金是什么| 洋葱不能和什么食物一起吃| 什么时候喝牛奶效果最佳| 健康管理是什么| 梦到吃梨是什么意思| loft是什么意思| 肿大淋巴结是什么意思| 鸡蛋散黄是什么原因| 尿酸高喝什么水最好| 肝素帽是什么| ug是什么单位| 怎么判断脸上是什么斑| 131是什么意思| 北极熊代表什么生肖| 睫角守宫吃什么| 壁虎吃什么| 一带一路是指什么| 喝酒肚子疼是什么原因| 常流鼻血是什么原因| 眼疲劳用什么眼药水| 妊娠囊是什么| 自尊是什么意思| 尿细菌高是什么原因| 文献是什么| 狗为什么会咬人| 中午喜鹊叫有什么预兆| 雷替斯和优甲乐有什么区别| 蚂蚁为什么要搬家| 事不过三是什么意思| 老年人腿无力是什么原因导致的| 糖化高是什么意思| 贴水是什么意思| 减肥吃什么菜最好| 口腔溃疡什么症状| 为什么开空调没蚊子| 胃疼的人吃什么最养胃| 大寒是什么意思| 巾帼是指什么| 肝郁化火吃什么药| 寄托是什么意思| 顾影自怜是什么意思| 妇科炎症吃什么消炎药效果好| 2013属什么生肖| 赛博朋克什么意思| 手臂长痘痘是什么原因| 血压低有什么危害| 蒲公英有什么好处| 巴旦木是什么树的果实| 四环素片主要治什么病| 男人左眼跳是什么意思| 喜悦之情溢于言表什么意思| 安全监察是一种带有什么的监督| 冬天吃什么水果| 呼吸衰竭是什么意思| 女人盗汗吃什么好得快| 俄罗斯是什么洲| 319是什么星座| 龙傲天是什么意思| 明太鱼是什么鱼| 18号来月经什么时候是排卵期| 装清高是什么意思| 武五行属什么| 原点是什么| 胸疼是什么原因| 5.4是什么星座| 胖大海是什么| 95年的猪是什么命| 粗枝大叶是什么意思| 阴囊湿疹用什么药| 逆时针是什么方向| 阔以是什么意思| 抖s什么意思| 破壁机是干什么用的| 腱鞘炎在什么位置| 有情人终成眷属是什么意思| 百度
blob: 0daccb64f54781080d804fa3bfbcef26a723f7fb [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2019 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""A tool to extract size information for chrome.
For a list of command-line options, call this script with '--help'.
This script uses Python 2 due to dependence on tracing.value.
"""
from __future__ import print_function
import argparse
import errno
import glob
import json
import platform
import os
import re
import stat
import subprocess
import sys
import tempfile
SRC_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..'))
# Add Catapult to the path so we can import the chartjson-histogramset
# conversion.
sys.path.append(os.path.join(SRC_DIR, 'third_party', 'catapult', 'tracing'))
from tracing.value import convert_chart_json
sys.path.insert(0, os.path.join(SRC_DIR, 'build', 'util'))
from lib.results import result_sink
from lib.results import result_types
class ResultsCollector:
def __init__(self):
self.results = {}
def add_result(self, name, identifier, value, units):
assert name not in self.results
self.results[name] = {
'identifier': identifier,
'value': int(value),
'units': units
}
# Legacy printing, previously used for parsing the text logs.
print('RESULT %s: %s= %s %s' % (name, identifier, value, units))
def get_size(filename):
return os.stat(filename)[stat.ST_SIZE]
def get_linux_stripped_size(filename):
# Assumes |filename| is in out/Release
src_dir = os.path.dirname(os.path.dirname(os.path.dirname(filename)))
llvm_strip_path = os.path.join(src_dir, 'third_party', 'llvm-build',
'Release+Asserts', 'bin', 'llvm-strip')
with tempfile.NamedTemporaryFile() as stripped_file:
strip_cmd = [
llvm_strip_path, '--strip-unneeded', '--strip-debug', '-o',
stripped_file.name, filename
]
result = 0
result, _ = run_process(result, strip_cmd)
if result != 0:
return (result, 0)
return (result, get_size(stripped_file.name))
def run_process(result, command):
p = subprocess.Popen(command, stdout=subprocess.PIPE)
stdout = p.communicate()[0].decode()
if p.returncode != 0:
print('ERROR from command "%s": %d' % (' '.join(command), p.returncode))
if result == 0:
result = p.returncode
return result, stdout
def main_mac(output_directory, results_collector, size_path):
"""Print appropriate size information about built Mac targets.
Returns the first non-zero exit status of any command it executes,
or zero on success.
"""
result = 0
# Work with either build type.
base_names = ('Chromium', 'Google Chrome')
for base_name in base_names:
app_bundle = base_name + '.app'
framework_name = base_name + ' Framework'
framework_bundle = framework_name + '.framework'
framework_dsym_bundle = framework_name + '.dSYM'
chromium_app_dir = os.path.join(output_directory, app_bundle)
chromium_executable = os.path.join(chromium_app_dir, 'Contents', 'MacOS',
base_name)
chromium_framework_dir = os.path.join(output_directory, framework_bundle)
chromium_framework_executable = os.path.join(chromium_framework_dir,
framework_name)
chromium_framework_dsym_dir = os.path.join(output_directory,
framework_dsym_bundle)
chromium_framework_dsym = os.path.join(chromium_framework_dsym_dir,
'Contents', 'Resources', 'DWARF',
framework_name)
if os.path.exists(chromium_executable):
print_dict = {
# Remove spaces in the names so any downstream processing is less
# likely to choke.
'app_name': re.sub(r'\s', '', base_name),
'app_bundle': re.sub(r'\s', '', app_bundle),
'framework_name': re.sub(r'\s', '', framework_name),
'framework_bundle': re.sub(r'\s', '', framework_bundle),
'app_size': get_size(chromium_executable),
'framework_size': get_size(chromium_framework_executable),
'framework_dsym_name': re.sub(r'\s', '', framework_name) + 'Dsym',
'framework_dsym_size': get_size(chromium_framework_dsym),
}
# Collect the segment info out of the App
result, stdout = run_process(result, [size_path, chromium_executable])
print_dict['app_text'], print_dict['app_data'], print_dict['app_objc'] = \
re.search(r'(\d+)\s+(\d+)\s+(\d+)', stdout).groups()
# Collect the segment info out of the Framework
result, stdout = run_process(result,
[size_path, chromium_framework_executable])
print_dict['framework_text'], print_dict['framework_data'], \
print_dict['framework_objc'] = \
re.search(r'(\d+)\s+(\d+)\s+(\d+)', stdout).groups()
# Collect the whole size of the App bundle on disk (include the framework)
whole_size = 0
for root_dir, _, filenames in os.walk(chromium_app_dir,
followlinks=False):
for filename in filenames:
full_path = os.path.join(root_dir, filename)
if not os.path.islink(full_path):
whole_size += get_size(full_path)
print_dict['app_bundle_size'] = whole_size
results_collector.add_result(print_dict['app_name'],
print_dict['app_name'],
print_dict['app_size'], 'bytes')
results_collector.add_result('%s-__TEXT' % print_dict['app_name'],
'__TEXT', print_dict['app_text'], 'bytes')
results_collector.add_result('%s-__DATA' % print_dict['app_name'],
'__DATA', print_dict['app_data'], 'bytes')
results_collector.add_result('%s-__OBJC' % print_dict['app_name'],
'__OBJC', print_dict['app_objc'], 'bytes')
results_collector.add_result(print_dict['framework_name'],
print_dict['framework_name'],
print_dict['framework_size'], 'bytes')
results_collector.add_result('%s-__TEXT' % print_dict['framework_name'],
'__TEXT', print_dict['framework_text'],
'bytes')
results_collector.add_result('%s-__DATA' % print_dict['framework_name'],
'__DATA', print_dict['framework_data'],
'bytes')
results_collector.add_result('%s-__OBJC' % print_dict['framework_name'],
'__OBJC', print_dict['framework_objc'],
'bytes')
results_collector.add_result(print_dict['app_bundle'],
print_dict['app_bundle'],
print_dict['app_bundle_size'], 'bytes')
results_collector.add_result(print_dict['framework_dsym_name'],
print_dict['framework_dsym_name'],
print_dict['framework_dsym_size'], 'bytes')
# Found a match, don't check the other base_names.
return result
# If no base_names matched, fail script.
return 66
def check_linux_binary(binary_name, output_directory):
"""Collect appropriate size information about the built Linux binary given.
Returns a tuple (result, sizes). result is the first non-zero exit
status of any command it executes, or zero on success. sizes is a list
of tuples (name, identifier, totals_identifier, value, units).
The printed line looks like:
name: identifier= value units
When this same data is used for totals across all the binaries, then
totals_identifier is the identifier to use, or '' to just use identifier.
"""
binary_file = os.path.join(output_directory, binary_name)
if not os.path.exists(binary_file):
# Don't print anything for missing files.
return 0, []
result = 0
sizes = []
sizes.append((binary_name, binary_name, 'size', get_size(binary_file),
'bytes'))
result, stripped_size = get_linux_stripped_size(binary_file)
sizes.append((binary_name + '-stripped', 'stripped', 'stripped',
stripped_size, 'bytes'))
result, stdout = run_process(result, ['size', binary_file])
text, data, bss = re.search(r'(\d+)\s+(\d+)\s+(\d+)', stdout).groups()
sizes += [
(binary_name + '-text', 'text', '', text, 'bytes'),
(binary_name + '-data', 'data', '', data, 'bytes'),
(binary_name + '-bss', 'bss', '', bss, 'bytes'),
]
# Determine if the binary has the DT_TEXTREL marker.
result, stdout = run_process(result, ['readelf', '-Wd', binary_file])
if re.search(r'\bTEXTREL\b', stdout) is None:
# Nope, so the count is zero.
count = 0
else:
# There are some, so count them.
result, stdout = run_process(result, ['eu-findtextrel', binary_file])
count = stdout.count('\n')
sizes.append((binary_name + '-textrel', 'textrel', '', count, 'relocs'))
return result, sizes
def main_linux(output_directory, results_collector, size_path):
"""Print appropriate size information about built Linux targets.
Returns the first non-zero exit status of any command it executes,
or zero on success.
"""
assert size_path is None
binaries = [
'chrome',
'nacl_helper',
'nacl_helper_bootstrap',
'libffmpegsumo.so',
'libgcflashplayer.so',
'libppGoogleNaClPluginChrome.so',
]
result = 0
totals = {}
for binary in binaries:
this_result, this_sizes = check_linux_binary(binary, output_directory)
if result == 0:
result = this_result
for name, identifier, totals_id, value, units in this_sizes:
results_collector.add_result(name, identifier, value, units)
totals_id = totals_id or identifier, units
totals[totals_id] = totals.get(totals_id, 0) + int(value)
files = [
'nacl_irt_x86_64.nexe',
'resources.pak',
]
for filename in files:
path = os.path.join(output_directory, filename)
try:
size = get_size(path)
except OSError as e:
if e.errno == errno.ENOENT:
continue # Don't print anything for missing files.
raise
results_collector.add_result(filename, filename, size, 'bytes')
totals['size', 'bytes'] += size
# TODO(mcgrathr): This should all be refactored so the mac and win flavors
# also deliver data structures rather than printing, and the logic for
# the printing and the summing totals is shared across all three flavors.
for (identifier, units), value in sorted(totals.items()):
results_collector.add_result('totals-%s' % identifier, identifier, value,
units)
return result
def check_android_binaries(binaries,
output_directory,
results_collector,
binaries_to_print=None):
"""Common method for printing size information for Android targets.
Prints size information for each element of binaries in the output
directory. If binaries_to_print is specified, the name of each binary from
binaries is replaced with corresponding element of binaries_to_print
in output. Returns the first non-zero exit status of any command it
executes, or zero on success.
"""
result = 0
if not binaries_to_print:
binaries_to_print = binaries
for (binary, binary_to_print) in zip(binaries, binaries_to_print):
this_result, this_sizes = check_linux_binary(binary, output_directory)
if result == 0:
result = this_result
for name, identifier, _, value, units in this_sizes:
name = name.replace('/', '_').replace(binary, binary_to_print)
identifier = identifier.replace(binary, binary_to_print)
results_collector.add_result(name, identifier, value, units)
return result
def main_android(output_directory, results_collector, size_path):
"""Print appropriate size information about built Android targets.
Returns the first non-zero exit status of any command it executes,
or zero on success.
"""
assert size_path is None
binaries = [
'chrome_public_apk/libs/armeabi-v7a/libchrome.so',
'lib/libchrome.so',
'libchrome.so',
]
return check_android_binaries(binaries, output_directory, results_collector)
def main_android_cronet(output_directory, results_collector, size_path):
"""Print appropriate size information about Android Cronet targets.
Returns the first non-zero exit status of any command it executes,
or zero on success.
"""
assert size_path is None
# Use version in binary file name, but not in printed output.
binaries_with_paths = glob.glob(
os.path.join(output_directory, 'libcronet.*.so'))
num_binaries = len(binaries_with_paths)
assert num_binaries == 1, "Got %d binaries: %s" % (
num_binaries, ', '.join(binaries_with_paths))
binaries = [os.path.basename(binaries_with_paths[0])]
binaries_to_print = ['libcronet.so']
return check_android_binaries(binaries, output_directory, results_collector,
binaries_to_print)
def main_win(output_directory, results_collector, size_path):
"""Print appropriate size information about built Windows targets.
Returns the first non-zero exit status of any command it executes,
or zero on success.
"""
assert size_path is None
files = [
'chrome.dll',
'chrome.dll.pdb',
'chrome.exe',
'chrome_child.dll',
'chrome_child.dll.pdb',
'chrome_elf.dll',
'chrome_proxy.exe',
'chrome_watcher.dll',
'elevated_tracing_service.exe',
'elevation_service.exe',
'libEGL.dll',
'libGLESv2.dll',
'mini_installer.exe',
'notification_helper.exe',
'resources.pak',
'setup.exe',
'WidevineCdm\\_platform_specific\\win_arm64\\widevinecdm.dll',
'WidevineCdm\\_platform_specific\\win_x64\\widevinecdm.dll',
'WidevineCdm\\_platform_specific\\win_x86\\widevinecdm.dll',
]
for f in files:
p = os.path.join(output_directory, f)
if os.path.isfile(p):
results_collector.add_result(f, f, get_size(p), 'bytes')
return 0
def format_for_histograms_conversion(data):
# We need to do two things to the provided data to make it compatible with the
# conversion script:
# 1. Add a top-level "benchmark_name" key.
# 2. Pull out the "identifier" value to be the story name.
formatted_data = {}
for metric, metric_data in data.items():
story = metric_data['identifier']
formatted_data[metric] = {story: metric_data.copy()}
del formatted_data[metric][story]['identifier']
return {'benchmark_name': 'sizes', 'charts': formatted_data}
def main():
if sys.platform in ('win32', 'cygwin'):
default_platform = 'win'
elif sys.platform.startswith('darwin'):
default_platform = 'mac'
elif sys.platform.startswith('linux'):
default_platform = 'linux'
else:
default_platform = None
main_map = {
'android': main_android,
'android-cronet': main_android_cronet,
'linux': main_linux,
'mac': main_mac,
'win': main_win,
}
platforms = sorted(main_map.keys())
parser = argparse.ArgumentParser()
parser.add_argument(
'--output-directory',
type=os.path.realpath,
help='Chromium output directory, e.g. /path/to/src/out/Debug')
parser.add_argument(
'--platform',
default=default_platform,
help='specify platform (%s) [default: %%(default)s]' %
', '.join(platforms))
parser.add_argument('--size-path', default=None, help='Path to size binary')
# Accepted to conform to the isolated script interface, but ignored.
parser.add_argument('--isolated-script-test-filter', help=argparse.SUPPRESS)
parser.add_argument(
'--isolated-script-test-perf-output', help=argparse.SUPPRESS)
parser.add_argument('--isolated-script-test-repeat', help=argparse.SUPPRESS)
parser.add_argument('--isolated-script-test-launcher-retry-limit',
help=argparse.SUPPRESS)
parser.add_argument(
'--isolated-script-test-output',
type=os.path.realpath,
help='File to which simplified JSON results will be written.')
args = parser.parse_args()
real_main = main_map.get(args.platform)
if not real_main:
if args.platform is None:
sys.stderr.write('Unsupported sys.platform %s.\n' % repr(sys.platform))
else:
sys.stderr.write('Unknown platform %s.\n' % repr(args.platform))
msg = 'Use the --platform= option to specify a supported platform:\n'
sys.stderr.write(msg + ' ' + ' '.join(platforms) + '\n')
return 2
isolated_script_output = {
'valid': False,
'failures': [],
'version': 'simplified'
}
test_name = 'sizes'
results_directory = None
if args.isolated_script_test_output:
results_directory = os.path.join(
os.path.dirname(args.isolated_script_test_output), test_name)
if not os.path.exists(results_directory):
os.makedirs(results_directory)
results_collector = ResultsCollector()
result_sink_client = result_sink.TryInitClient()
try:
rc = real_main(args.output_directory, results_collector, args.size_path)
isolated_script_output = {
'valid': True,
'failures': [test_name] if rc else [],
'version': 'simplified',
}
finally:
if results_directory:
results_path = os.path.join(results_directory, 'test_results.json')
with open(results_path, 'w') as output_file:
json.dump(isolated_script_output, output_file)
histogram_path = os.path.join(results_directory, 'perf_results.json')
# We need to add a bit more data to the results and rearrange some things,
# otherwise the conversion fails due to the provided data being malformed.
updated_results = format_for_histograms_conversion(
results_collector.results)
with open(histogram_path, 'w') as f:
json.dump(updated_results, f)
histogram_result = convert_chart_json.ConvertChartJson(histogram_path)
if histogram_result.returncode != 0:
sys.stderr.write(
'chartjson conversion failed: %s\n' % histogram_result.stdout)
rc = rc or histogram_result.returncode
else:
with open(histogram_path, 'wb') as f:
f.write(histogram_result.stdout)
if result_sink_client:
status = result_types.PASS
if not isolated_script_output['valid']:
status = result_types.UNKNOWN
elif isolated_script_output['failures']:
status = result_types.FAIL
result_sink_client.Post(test_name, status, None, None, None)
return rc
if '__main__' == __name__:
sys.exit(main())
肚子咕噜响是什么原因 珊五行属什么 中元节是什么节日 黄水疮用什么药膏最快 眼睛模糊用什么药好
汉字最多笔画是什么字 一阵什么 手抖是什么原因造成的 吃什么菜减肥最快 肾衰竭吃什么水果好
胆结石吃什么水果好 4s店是什么意思 附件炎吃什么药最好 幼儿急疹为什么不能碰水 电风扇什么牌子好
爆裂性骨折什么意思 犒劳是什么意思 白细胞低是什么原因引起的 本能是什么意思 溥仪为什么没有后代
小舅子是什么关系xjhesheng.com 臀疗是什么gysmod.com 冰箱冷藏室结冰是什么原因hcv8jop8ns4r.cn 寂灭是什么意思chuanglingweilai.com 刚做了人流适合吃什么好hcv8jop4ns1r.cn
肺炎支原体抗体阴性是什么意思hcv8jop6ns9r.cn 倒卖是什么意思hkuteam.com 乳牙是什么hcv8jop9ns7r.cn 佛系是什么意思啊hcv7jop4ns8r.cn 痛经吃什么水果能缓解疼痛hcv9jop6ns6r.cn
中国什么时候解放kuyehao.com 肠胃炎适合吃什么食物hcv8jop2ns3r.cn 耳根有痣代表什么hcv9jop3ns6r.cn 变化无穷是什么生肖weuuu.com 菜花是什么hcv8jop9ns5r.cn
心肌炎吃什么食物最好hcv9jop2ns7r.cn edv是什么意思hcv9jop5ns1r.cn 梦见大蜈蚣是什么预兆hcv9jop3ns9r.cn 朝鲜说什么语言hcv9jop0ns0r.cn 脑白质疏松是什么意思hcv8jop4ns0r.cn
百度