mustang 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -0
- data/Isolate +9 -0
- data/README.md +6 -12
- data/Rakefile +30 -4
- data/TODO.md +9 -0
- data/ext/v8/extconf.rb +56 -0
- data/ext/v8/v8.cpp +37 -0
- data/ext/v8/v8_array.cpp +161 -0
- data/ext/v8/v8_array.h +17 -0
- data/ext/v8/v8_base.cpp +147 -0
- data/ext/v8/v8_base.h +23 -0
- data/ext/v8/v8_cast.cpp +151 -0
- data/ext/v8/v8_cast.h +64 -0
- data/ext/v8/v8_context.cpp +174 -0
- data/ext/v8/v8_context.h +12 -0
- data/ext/v8/v8_date.cpp +61 -0
- data/ext/v8/v8_date.h +16 -0
- data/ext/v8/v8_errors.cpp +147 -0
- data/ext/v8/v8_errors.h +19 -0
- data/ext/v8/v8_external.cpp +66 -0
- data/ext/v8/v8_external.h +16 -0
- data/ext/v8/v8_function.cpp +182 -0
- data/ext/v8/v8_function.h +14 -0
- data/ext/v8/v8_integer.cpp +70 -0
- data/ext/v8/v8_integer.h +16 -0
- data/ext/v8/v8_macros.h +30 -0
- data/ext/v8/v8_main.cpp +53 -0
- data/ext/v8/v8_main.h +13 -0
- data/ext/v8/v8_number.cpp +62 -0
- data/ext/v8/v8_number.h +16 -0
- data/ext/v8/v8_object.cpp +172 -0
- data/ext/v8/v8_object.h +17 -0
- data/ext/v8/v8_ref.cpp +72 -0
- data/ext/v8/v8_ref.h +43 -0
- data/ext/v8/v8_regexp.cpp +148 -0
- data/ext/v8/v8_regexp.h +16 -0
- data/ext/v8/v8_string.cpp +78 -0
- data/ext/v8/v8_string.h +16 -0
- data/ext/v8/v8_value.cpp +370 -0
- data/ext/v8/v8_value.h +19 -0
- data/gemspec.yml +2 -1
- data/lib/core_ext/class.rb +14 -0
- data/lib/core_ext/object.rb +12 -0
- data/lib/core_ext/symbol.rb +23 -0
- data/lib/mustang.rb +44 -0
- data/lib/mustang/context.rb +69 -0
- data/lib/mustang/errors.rb +36 -0
- data/lib/support/delegated.rb +25 -0
- data/lib/v8/array.rb +21 -0
- data/lib/v8/context.rb +13 -0
- data/lib/v8/date.rb +20 -0
- data/lib/v8/error.rb +15 -0
- data/lib/v8/external.rb +16 -0
- data/lib/v8/function.rb +11 -0
- data/lib/v8/integer.rb +16 -0
- data/lib/v8/number.rb +16 -0
- data/lib/v8/object.rb +66 -0
- data/lib/v8/regexp.rb +23 -0
- data/lib/v8/string.rb +27 -0
- data/mustang.gemspec +3 -0
- data/spec/core_ext/class_spec.rb +19 -0
- data/spec/core_ext/object_spec.rb +19 -0
- data/spec/core_ext/symbol_spec.rb +27 -0
- data/spec/fixtures/test1.js +2 -0
- data/spec/fixtures/test2.js +2 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/v8/array_spec.rb +88 -0
- data/spec/v8/cast_spec.rb +151 -0
- data/spec/v8/context_spec.rb +78 -0
- data/spec/v8/data_spec.rb +39 -0
- data/spec/v8/date_spec.rb +45 -0
- data/spec/v8/empty_spec.rb +27 -0
- data/spec/v8/errors_spec.rb +142 -0
- data/spec/v8/external_spec.rb +44 -0
- data/spec/v8/function_spec.rb +170 -0
- data/spec/v8/integer_spec.rb +41 -0
- data/spec/v8/main_spec.rb +18 -0
- data/spec/v8/null_spec.rb +27 -0
- data/spec/v8/number_spec.rb +40 -0
- data/spec/v8/object_spec.rb +79 -0
- data/spec/v8/primitive_spec.rb +9 -0
- data/spec/v8/regexp_spec.rb +65 -0
- data/spec/v8/string_spec.rb +48 -0
- data/spec/v8/undefined_spec.rb +27 -0
- data/spec/v8/value_spec.rb +215 -0
- data/vendor/v8/.gitignore +2 -0
- data/vendor/v8/AUTHORS +3 -1
- data/vendor/v8/ChangeLog +117 -0
- data/vendor/v8/SConstruct +334 -53
- data/vendor/v8/include/v8-debug.h +21 -11
- data/vendor/v8/include/v8-preparser.h +1 -1
- data/vendor/v8/include/v8-profiler.h +122 -43
- data/vendor/v8/include/v8-testing.h +5 -0
- data/vendor/v8/include/v8.h +171 -17
- data/vendor/v8/preparser/SConscript +38 -0
- data/vendor/v8/preparser/preparser-process.cc +77 -114
- data/vendor/v8/samples/shell.cc +232 -46
- data/vendor/v8/src/SConscript +29 -5
- data/vendor/v8/src/accessors.cc +70 -211
- data/vendor/v8/{test/cctest/test-mips.cc → src/allocation-inl.h} +15 -18
- data/vendor/v8/src/allocation.cc +0 -82
- data/vendor/v8/src/allocation.h +9 -42
- data/vendor/v8/src/api.cc +1645 -1156
- data/vendor/v8/src/api.h +76 -12
- data/vendor/v8/src/apiutils.h +0 -7
- data/vendor/v8/src/arguments.h +15 -4
- data/vendor/v8/src/arm/assembler-arm-inl.h +10 -9
- data/vendor/v8/src/arm/assembler-arm.cc +62 -23
- data/vendor/v8/src/arm/assembler-arm.h +76 -11
- data/vendor/v8/src/arm/builtins-arm.cc +39 -33
- data/vendor/v8/src/arm/code-stubs-arm.cc +1182 -402
- data/vendor/v8/src/arm/code-stubs-arm.h +20 -54
- data/vendor/v8/src/arm/codegen-arm.cc +159 -106
- data/vendor/v8/src/arm/codegen-arm.h +6 -6
- data/vendor/v8/src/arm/constants-arm.h +16 -1
- data/vendor/v8/src/arm/cpu-arm.cc +7 -5
- data/vendor/v8/src/arm/debug-arm.cc +6 -4
- data/vendor/v8/src/arm/deoptimizer-arm.cc +51 -14
- data/vendor/v8/src/arm/disasm-arm.cc +47 -15
- data/vendor/v8/src/arm/frames-arm.h +1 -1
- data/vendor/v8/src/arm/full-codegen-arm.cc +724 -408
- data/vendor/v8/src/arm/ic-arm.cc +90 -85
- data/vendor/v8/src/arm/lithium-arm.cc +140 -69
- data/vendor/v8/src/arm/lithium-arm.h +161 -46
- data/vendor/v8/src/arm/lithium-codegen-arm.cc +567 -297
- data/vendor/v8/src/arm/lithium-codegen-arm.h +21 -9
- data/vendor/v8/src/arm/lithium-gap-resolver-arm.cc +2 -0
- data/vendor/v8/src/arm/macro-assembler-arm.cc +457 -96
- data/vendor/v8/src/arm/macro-assembler-arm.h +115 -18
- data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +20 -13
- data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +1 -0
- data/vendor/v8/src/arm/simulator-arm.cc +184 -101
- data/vendor/v8/src/arm/simulator-arm.h +26 -21
- data/vendor/v8/src/arm/stub-cache-arm.cc +450 -467
- data/vendor/v8/src/arm/virtual-frame-arm.cc +14 -12
- data/vendor/v8/src/arm/virtual-frame-arm.h +11 -8
- data/vendor/v8/src/array.js +35 -18
- data/vendor/v8/src/assembler.cc +186 -92
- data/vendor/v8/src/assembler.h +106 -69
- data/vendor/v8/src/ast-inl.h +5 -0
- data/vendor/v8/src/ast.cc +46 -35
- data/vendor/v8/src/ast.h +107 -50
- data/vendor/v8/src/atomicops.h +2 -0
- data/vendor/v8/src/atomicops_internals_mips_gcc.h +169 -0
- data/vendor/v8/src/bootstrapper.cc +649 -399
- data/vendor/v8/src/bootstrapper.h +94 -27
- data/vendor/v8/src/builtins.cc +359 -227
- data/vendor/v8/src/builtins.h +157 -123
- data/vendor/v8/src/checks.cc +2 -2
- data/vendor/v8/src/checks.h +4 -0
- data/vendor/v8/src/code-stubs.cc +27 -17
- data/vendor/v8/src/code-stubs.h +38 -17
- data/vendor/v8/src/codegen-inl.h +5 -1
- data/vendor/v8/src/codegen.cc +27 -17
- data/vendor/v8/src/codegen.h +9 -9
- data/vendor/v8/src/compilation-cache.cc +92 -206
- data/vendor/v8/src/compilation-cache.h +205 -30
- data/vendor/v8/src/compiler.cc +107 -120
- data/vendor/v8/src/compiler.h +17 -2
- data/vendor/v8/src/contexts.cc +22 -15
- data/vendor/v8/src/contexts.h +14 -8
- data/vendor/v8/src/conversions.cc +86 -30
- data/vendor/v8/src/counters.cc +19 -4
- data/vendor/v8/src/counters.h +28 -16
- data/vendor/v8/src/cpu-profiler-inl.h +4 -3
- data/vendor/v8/src/cpu-profiler.cc +123 -72
- data/vendor/v8/src/cpu-profiler.h +33 -19
- data/vendor/v8/src/cpu.h +2 -0
- data/vendor/v8/src/d8-debug.cc +3 -3
- data/vendor/v8/src/d8-debug.h +7 -6
- data/vendor/v8/src/d8-posix.cc +2 -0
- data/vendor/v8/src/d8.cc +22 -12
- data/vendor/v8/src/d8.gyp +3 -0
- data/vendor/v8/src/d8.js +618 -0
- data/vendor/v8/src/data-flow.h +3 -3
- data/vendor/v8/src/dateparser.h +4 -2
- data/vendor/v8/src/debug-agent.cc +10 -9
- data/vendor/v8/src/debug-agent.h +9 -11
- data/vendor/v8/src/debug-debugger.js +121 -0
- data/vendor/v8/src/debug.cc +331 -227
- data/vendor/v8/src/debug.h +248 -219
- data/vendor/v8/src/deoptimizer.cc +173 -62
- data/vendor/v8/src/deoptimizer.h +119 -19
- data/vendor/v8/src/disasm.h +3 -0
- data/vendor/v8/src/disassembler.cc +10 -9
- data/vendor/v8/src/execution.cc +185 -129
- data/vendor/v8/src/execution.h +47 -78
- data/vendor/v8/src/extensions/experimental/break-iterator.cc +250 -0
- data/vendor/v8/src/extensions/experimental/break-iterator.h +89 -0
- data/vendor/v8/src/extensions/experimental/experimental.gyp +2 -0
- data/vendor/v8/src/extensions/experimental/i18n-extension.cc +22 -2
- data/vendor/v8/src/extensions/externalize-string-extension.cc +2 -2
- data/vendor/v8/src/extensions/gc-extension.cc +1 -1
- data/vendor/v8/src/factory.cc +261 -154
- data/vendor/v8/src/factory.h +162 -158
- data/vendor/v8/src/flag-definitions.h +17 -11
- data/vendor/v8/src/frame-element.cc +0 -5
- data/vendor/v8/src/frame-element.h +9 -13
- data/vendor/v8/src/frames-inl.h +7 -0
- data/vendor/v8/src/frames.cc +56 -46
- data/vendor/v8/src/frames.h +36 -25
- data/vendor/v8/src/full-codegen.cc +15 -24
- data/vendor/v8/src/full-codegen.h +13 -41
- data/vendor/v8/src/func-name-inferrer.cc +7 -6
- data/vendor/v8/src/func-name-inferrer.h +1 -1
- data/vendor/v8/src/gdb-jit.cc +1 -0
- data/vendor/v8/src/global-handles.cc +118 -56
- data/vendor/v8/src/global-handles.h +98 -40
- data/vendor/v8/src/globals.h +2 -2
- data/vendor/v8/src/handles-inl.h +106 -9
- data/vendor/v8/src/handles.cc +220 -157
- data/vendor/v8/src/handles.h +38 -59
- data/vendor/v8/src/hashmap.h +3 -3
- data/vendor/v8/src/heap-inl.h +141 -25
- data/vendor/v8/src/heap-profiler.cc +117 -63
- data/vendor/v8/src/heap-profiler.h +38 -21
- data/vendor/v8/src/heap.cc +805 -564
- data/vendor/v8/src/heap.h +640 -594
- data/vendor/v8/src/hydrogen-instructions.cc +216 -73
- data/vendor/v8/src/hydrogen-instructions.h +259 -124
- data/vendor/v8/src/hydrogen.cc +996 -1171
- data/vendor/v8/src/hydrogen.h +163 -144
- data/vendor/v8/src/ia32/assembler-ia32-inl.h +12 -11
- data/vendor/v8/src/ia32/assembler-ia32.cc +85 -39
- data/vendor/v8/src/ia32/assembler-ia32.h +82 -16
- data/vendor/v8/src/ia32/builtins-ia32.cc +64 -58
- data/vendor/v8/src/ia32/code-stubs-ia32.cc +248 -324
- data/vendor/v8/src/ia32/code-stubs-ia32.h +3 -44
- data/vendor/v8/src/ia32/codegen-ia32.cc +217 -165
- data/vendor/v8/src/ia32/codegen-ia32.h +3 -0
- data/vendor/v8/src/ia32/cpu-ia32.cc +6 -5
- data/vendor/v8/src/ia32/debug-ia32.cc +8 -5
- data/vendor/v8/src/ia32/deoptimizer-ia32.cc +124 -14
- data/vendor/v8/src/ia32/disasm-ia32.cc +85 -62
- data/vendor/v8/src/ia32/frames-ia32.h +1 -1
- data/vendor/v8/src/ia32/full-codegen-ia32.cc +348 -435
- data/vendor/v8/src/ia32/ic-ia32.cc +91 -91
- data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +500 -255
- data/vendor/v8/src/ia32/lithium-codegen-ia32.h +13 -4
- data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.cc +6 -0
- data/vendor/v8/src/ia32/lithium-ia32.cc +122 -45
- data/vendor/v8/src/ia32/lithium-ia32.h +128 -41
- data/vendor/v8/src/ia32/macro-assembler-ia32.cc +109 -84
- data/vendor/v8/src/ia32/macro-assembler-ia32.h +18 -9
- data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +26 -15
- data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +1 -0
- data/vendor/v8/src/ia32/register-allocator-ia32.cc +30 -30
- data/vendor/v8/src/ia32/simulator-ia32.h +4 -4
- data/vendor/v8/src/ia32/stub-cache-ia32.cc +383 -400
- data/vendor/v8/src/ia32/virtual-frame-ia32.cc +36 -13
- data/vendor/v8/src/ia32/virtual-frame-ia32.h +11 -5
- data/vendor/v8/src/ic-inl.h +12 -2
- data/vendor/v8/src/ic.cc +304 -221
- data/vendor/v8/src/ic.h +115 -58
- data/vendor/v8/src/interpreter-irregexp.cc +25 -21
- data/vendor/v8/src/interpreter-irregexp.h +2 -1
- data/vendor/v8/src/isolate.cc +883 -0
- data/vendor/v8/src/isolate.h +1304 -0
- data/vendor/v8/src/json.js +10 -10
- data/vendor/v8/src/jsregexp.cc +111 -80
- data/vendor/v8/src/jsregexp.h +6 -7
- data/vendor/v8/src/jump-target-heavy.cc +5 -8
- data/vendor/v8/src/jump-target-heavy.h +0 -6
- data/vendor/v8/src/jump-target-inl.h +1 -1
- data/vendor/v8/src/jump-target-light.cc +3 -3
- data/vendor/v8/src/lithium-allocator-inl.h +2 -0
- data/vendor/v8/src/lithium-allocator.cc +42 -30
- data/vendor/v8/src/lithium-allocator.h +8 -22
- data/vendor/v8/src/lithium.cc +1 -0
- data/vendor/v8/src/liveedit.cc +141 -99
- data/vendor/v8/src/liveedit.h +7 -2
- data/vendor/v8/src/liveobjectlist-inl.h +90 -0
- data/vendor/v8/src/liveobjectlist.cc +2537 -1
- data/vendor/v8/src/liveobjectlist.h +245 -35
- data/vendor/v8/src/log-utils.cc +122 -35
- data/vendor/v8/src/log-utils.h +33 -36
- data/vendor/v8/src/log.cc +299 -241
- data/vendor/v8/src/log.h +177 -110
- data/vendor/v8/src/mark-compact.cc +612 -470
- data/vendor/v8/src/mark-compact.h +153 -80
- data/vendor/v8/src/messages.cc +16 -14
- data/vendor/v8/src/messages.js +30 -7
- data/vendor/v8/src/mips/assembler-mips-inl.h +155 -35
- data/vendor/v8/src/mips/assembler-mips.cc +1093 -219
- data/vendor/v8/src/mips/assembler-mips.h +552 -153
- data/vendor/v8/src/mips/builtins-mips.cc +43 -100
- data/vendor/v8/src/mips/code-stubs-mips.cc +752 -0
- data/vendor/v8/src/mips/code-stubs-mips.h +511 -0
- data/vendor/v8/src/mips/codegen-mips-inl.h +8 -14
- data/vendor/v8/src/mips/codegen-mips.cc +672 -896
- data/vendor/v8/src/mips/codegen-mips.h +271 -69
- data/vendor/v8/src/mips/constants-mips.cc +44 -20
- data/vendor/v8/src/mips/constants-mips.h +238 -40
- data/vendor/v8/src/mips/cpu-mips.cc +20 -3
- data/vendor/v8/src/mips/debug-mips.cc +35 -7
- data/vendor/v8/src/mips/deoptimizer-mips.cc +91 -0
- data/vendor/v8/src/mips/disasm-mips.cc +329 -93
- data/vendor/v8/src/mips/frames-mips.cc +2 -50
- data/vendor/v8/src/mips/frames-mips.h +24 -9
- data/vendor/v8/src/mips/full-codegen-mips.cc +473 -23
- data/vendor/v8/src/mips/ic-mips.cc +81 -45
- data/vendor/v8/src/mips/jump-target-mips.cc +11 -106
- data/vendor/v8/src/mips/lithium-codegen-mips.h +65 -0
- data/vendor/v8/src/mips/lithium-mips.h +304 -0
- data/vendor/v8/src/mips/macro-assembler-mips.cc +2391 -390
- data/vendor/v8/src/mips/macro-assembler-mips.h +718 -121
- data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +478 -0
- data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +250 -0
- data/vendor/v8/src/mips/register-allocator-mips-inl.h +0 -3
- data/vendor/v8/src/mips/register-allocator-mips.h +3 -2
- data/vendor/v8/src/mips/simulator-mips.cc +1009 -221
- data/vendor/v8/src/mips/simulator-mips.h +119 -36
- data/vendor/v8/src/mips/stub-cache-mips.cc +331 -148
- data/vendor/v8/src/mips/{fast-codegen-mips.cc → virtual-frame-mips-inl.h} +11 -30
- data/vendor/v8/src/mips/virtual-frame-mips.cc +137 -149
- data/vendor/v8/src/mips/virtual-frame-mips.h +294 -312
- data/vendor/v8/src/mirror-debugger.js +9 -8
- data/vendor/v8/src/mksnapshot.cc +2 -2
- data/vendor/v8/src/objects-debug.cc +16 -16
- data/vendor/v8/src/objects-inl.h +421 -195
- data/vendor/v8/src/objects-printer.cc +7 -7
- data/vendor/v8/src/objects-visiting.cc +1 -1
- data/vendor/v8/src/objects-visiting.h +33 -12
- data/vendor/v8/src/objects.cc +935 -658
- data/vendor/v8/src/objects.h +234 -139
- data/vendor/v8/src/parser.cc +484 -439
- data/vendor/v8/src/parser.h +35 -14
- data/vendor/v8/src/platform-cygwin.cc +173 -107
- data/vendor/v8/src/platform-freebsd.cc +224 -72
- data/vendor/v8/src/platform-linux.cc +234 -95
- data/vendor/v8/src/platform-macos.cc +215 -82
- data/vendor/v8/src/platform-nullos.cc +9 -3
- data/vendor/v8/src/platform-openbsd.cc +22 -7
- data/vendor/v8/src/platform-posix.cc +30 -5
- data/vendor/v8/src/platform-solaris.cc +120 -38
- data/vendor/v8/src/platform-tls-mac.h +62 -0
- data/vendor/v8/src/platform-tls-win32.h +62 -0
- data/vendor/v8/src/platform-tls.h +50 -0
- data/vendor/v8/src/platform-win32.cc +195 -97
- data/vendor/v8/src/platform.h +72 -15
- data/vendor/v8/src/preparse-data.cc +2 -0
- data/vendor/v8/src/preparser-api.cc +8 -2
- data/vendor/v8/src/preparser.cc +1 -1
- data/vendor/v8/src/prettyprinter.cc +43 -52
- data/vendor/v8/src/prettyprinter.h +1 -1
- data/vendor/v8/src/profile-generator-inl.h +0 -28
- data/vendor/v8/src/profile-generator.cc +942 -685
- data/vendor/v8/src/profile-generator.h +210 -176
- data/vendor/v8/src/property.cc +6 -0
- data/vendor/v8/src/property.h +14 -3
- data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +1 -1
- data/vendor/v8/src/regexp-macro-assembler.cc +28 -19
- data/vendor/v8/src/regexp-macro-assembler.h +11 -6
- data/vendor/v8/src/regexp-stack.cc +18 -10
- data/vendor/v8/src/regexp-stack.h +45 -21
- data/vendor/v8/src/regexp.js +3 -3
- data/vendor/v8/src/register-allocator-inl.h +3 -3
- data/vendor/v8/src/register-allocator.cc +1 -7
- data/vendor/v8/src/register-allocator.h +5 -15
- data/vendor/v8/src/rewriter.cc +2 -1
- data/vendor/v8/src/runtime-profiler.cc +158 -128
- data/vendor/v8/src/runtime-profiler.h +131 -15
- data/vendor/v8/src/runtime.cc +2409 -1692
- data/vendor/v8/src/runtime.h +93 -17
- data/vendor/v8/src/safepoint-table.cc +3 -0
- data/vendor/v8/src/safepoint-table.h +9 -3
- data/vendor/v8/src/scanner-base.cc +21 -28
- data/vendor/v8/src/scanner-base.h +22 -11
- data/vendor/v8/src/scanner.cc +3 -5
- data/vendor/v8/src/scanner.h +4 -2
- data/vendor/v8/src/scopeinfo.cc +11 -16
- data/vendor/v8/src/scopeinfo.h +26 -15
- data/vendor/v8/src/scopes.cc +67 -37
- data/vendor/v8/src/scopes.h +26 -12
- data/vendor/v8/src/serialize.cc +193 -154
- data/vendor/v8/src/serialize.h +41 -36
- data/vendor/v8/src/small-pointer-list.h +163 -0
- data/vendor/v8/src/snapshot-common.cc +1 -1
- data/vendor/v8/src/snapshot.h +3 -1
- data/vendor/v8/src/spaces-inl.h +30 -25
- data/vendor/v8/src/spaces.cc +263 -370
- data/vendor/v8/src/spaces.h +178 -166
- data/vendor/v8/src/string-search.cc +4 -3
- data/vendor/v8/src/string-search.h +21 -20
- data/vendor/v8/src/string-stream.cc +32 -24
- data/vendor/v8/src/string.js +7 -7
- data/vendor/v8/src/stub-cache.cc +324 -248
- data/vendor/v8/src/stub-cache.h +181 -155
- data/vendor/v8/src/token.cc +3 -3
- data/vendor/v8/src/token.h +3 -3
- data/vendor/v8/src/top.cc +218 -390
- data/vendor/v8/src/type-info.cc +98 -32
- data/vendor/v8/src/type-info.h +10 -3
- data/vendor/v8/src/unicode.cc +1 -1
- data/vendor/v8/src/unicode.h +1 -1
- data/vendor/v8/src/utils.h +3 -0
- data/vendor/v8/src/v8-counters.cc +18 -11
- data/vendor/v8/src/v8-counters.h +34 -13
- data/vendor/v8/src/v8.cc +66 -121
- data/vendor/v8/src/v8.h +7 -4
- data/vendor/v8/src/v8globals.h +18 -12
- data/vendor/v8/src/{memory.h → v8memory.h} +0 -0
- data/vendor/v8/src/v8natives.js +59 -18
- data/vendor/v8/src/v8threads.cc +127 -114
- data/vendor/v8/src/v8threads.h +42 -35
- data/vendor/v8/src/v8utils.h +2 -39
- data/vendor/v8/src/variables.h +1 -1
- data/vendor/v8/src/version.cc +26 -5
- data/vendor/v8/src/version.h +4 -0
- data/vendor/v8/src/virtual-frame-heavy-inl.h +2 -4
- data/vendor/v8/src/virtual-frame-light-inl.h +5 -4
- data/vendor/v8/src/vm-state-inl.h +21 -17
- data/vendor/v8/src/vm-state.h +7 -5
- data/vendor/v8/src/win32-headers.h +1 -0
- data/vendor/v8/src/x64/assembler-x64-inl.h +12 -11
- data/vendor/v8/src/x64/assembler-x64.cc +80 -40
- data/vendor/v8/src/x64/assembler-x64.h +67 -17
- data/vendor/v8/src/x64/builtins-x64.cc +34 -33
- data/vendor/v8/src/x64/code-stubs-x64.cc +636 -377
- data/vendor/v8/src/x64/code-stubs-x64.h +14 -48
- data/vendor/v8/src/x64/codegen-x64-inl.h +1 -1
- data/vendor/v8/src/x64/codegen-x64.cc +158 -136
- data/vendor/v8/src/x64/codegen-x64.h +4 -1
- data/vendor/v8/src/x64/cpu-x64.cc +7 -5
- data/vendor/v8/src/x64/debug-x64.cc +8 -6
- data/vendor/v8/src/x64/deoptimizer-x64.cc +195 -20
- data/vendor/v8/src/x64/disasm-x64.cc +42 -23
- data/vendor/v8/src/x64/frames-x64.cc +1 -1
- data/vendor/v8/src/x64/frames-x64.h +2 -2
- data/vendor/v8/src/x64/full-codegen-x64.cc +780 -218
- data/vendor/v8/src/x64/ic-x64.cc +77 -79
- data/vendor/v8/src/x64/jump-target-x64.cc +1 -1
- data/vendor/v8/src/x64/lithium-codegen-x64.cc +698 -181
- data/vendor/v8/src/x64/lithium-codegen-x64.h +31 -6
- data/vendor/v8/src/x64/lithium-x64.cc +136 -54
- data/vendor/v8/src/x64/lithium-x64.h +142 -51
- data/vendor/v8/src/x64/macro-assembler-x64.cc +456 -187
- data/vendor/v8/src/x64/macro-assembler-x64.h +166 -34
- data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +44 -28
- data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +8 -4
- data/vendor/v8/src/x64/register-allocator-x64-inl.h +3 -3
- data/vendor/v8/src/x64/register-allocator-x64.cc +12 -8
- data/vendor/v8/src/x64/simulator-x64.h +5 -5
- data/vendor/v8/src/x64/stub-cache-x64.cc +299 -344
- data/vendor/v8/src/x64/virtual-frame-x64.cc +37 -13
- data/vendor/v8/src/x64/virtual-frame-x64.h +13 -7
- data/vendor/v8/src/zone-inl.h +49 -3
- data/vendor/v8/src/zone.cc +42 -41
- data/vendor/v8/src/zone.h +37 -34
- data/vendor/v8/test/benchmarks/testcfg.py +100 -0
- data/vendor/v8/test/cctest/SConscript +5 -4
- data/vendor/v8/test/cctest/cctest.h +3 -2
- data/vendor/v8/test/cctest/cctest.status +6 -11
- data/vendor/v8/test/cctest/test-accessors.cc +3 -3
- data/vendor/v8/test/cctest/test-alloc.cc +39 -33
- data/vendor/v8/test/cctest/test-api.cc +1092 -205
- data/vendor/v8/test/cctest/test-assembler-arm.cc +39 -25
- data/vendor/v8/test/cctest/test-assembler-ia32.cc +36 -37
- data/vendor/v8/test/cctest/test-assembler-mips.cc +1098 -40
- data/vendor/v8/test/cctest/test-assembler-x64.cc +32 -25
- data/vendor/v8/test/cctest/test-ast.cc +1 -0
- data/vendor/v8/test/cctest/test-circular-queue.cc +8 -5
- data/vendor/v8/test/cctest/test-compiler.cc +24 -24
- data/vendor/v8/test/cctest/test-cpu-profiler.cc +140 -5
- data/vendor/v8/test/cctest/test-dataflow.cc +1 -0
- data/vendor/v8/test/cctest/test-debug.cc +136 -77
- data/vendor/v8/test/cctest/test-decls.cc +1 -1
- data/vendor/v8/test/cctest/test-deoptimization.cc +25 -24
- data/vendor/v8/test/cctest/test-disasm-arm.cc +9 -4
- data/vendor/v8/test/cctest/test-disasm-ia32.cc +10 -8
- data/vendor/v8/test/cctest/test-func-name-inference.cc +10 -4
- data/vendor/v8/test/cctest/test-heap-profiler.cc +226 -164
- data/vendor/v8/test/cctest/test-heap.cc +240 -217
- data/vendor/v8/test/cctest/test-liveedit.cc +1 -0
- data/vendor/v8/test/cctest/test-log-stack-tracer.cc +18 -20
- data/vendor/v8/test/cctest/test-log.cc +114 -108
- data/vendor/v8/test/cctest/test-macro-assembler-x64.cc +247 -177
- data/vendor/v8/test/cctest/test-mark-compact.cc +129 -90
- data/vendor/v8/test/cctest/test-parsing.cc +15 -14
- data/vendor/v8/test/cctest/test-platform-linux.cc +1 -0
- data/vendor/v8/test/cctest/test-platform-tls.cc +66 -0
- data/vendor/v8/test/cctest/test-platform-win32.cc +1 -0
- data/vendor/v8/test/cctest/test-profile-generator.cc +1 -1
- data/vendor/v8/test/cctest/test-regexp.cc +53 -41
- data/vendor/v8/test/cctest/test-reloc-info.cc +18 -11
- data/vendor/v8/test/cctest/test-serialize.cc +44 -43
- data/vendor/v8/test/cctest/test-sockets.cc +8 -3
- data/vendor/v8/test/cctest/test-spaces.cc +47 -29
- data/vendor/v8/test/cctest/test-strings.cc +20 -20
- data/vendor/v8/test/cctest/test-thread-termination.cc +8 -3
- data/vendor/v8/test/cctest/test-threads.cc +5 -3
- data/vendor/v8/test/cctest/test-utils.cc +5 -4
- data/vendor/v8/test/cctest/testcfg.py +7 -3
- data/vendor/v8/test/es5conform/es5conform.status +2 -77
- data/vendor/v8/test/es5conform/testcfg.py +1 -1
- data/vendor/v8/test/message/testcfg.py +1 -1
- data/vendor/v8/test/mjsunit/accessors-on-global-object.js +3 -3
- data/vendor/v8/test/mjsunit/array-concat.js +43 -1
- data/vendor/v8/test/mjsunit/array-join.js +25 -0
- data/vendor/v8/test/mjsunit/bitops-info.js +7 -1
- data/vendor/v8/test/mjsunit/compiler/array-length.js +2 -2
- data/vendor/v8/test/mjsunit/compiler/global-accessors.js +47 -0
- data/vendor/v8/test/mjsunit/compiler/pic.js +1 -1
- data/vendor/v8/test/mjsunit/compiler/regress-loadfield.js +65 -0
- data/vendor/v8/test/mjsunit/math-sqrt.js +5 -1
- data/vendor/v8/test/mjsunit/mjsunit.js +59 -8
- data/vendor/v8/test/mjsunit/mjsunit.status +0 -12
- data/vendor/v8/test/mjsunit/mul-exhaustive.js +129 -11
- data/vendor/v8/test/mjsunit/negate-zero.js +1 -1
- data/vendor/v8/test/mjsunit/object-freeze.js +5 -13
- data/vendor/v8/test/mjsunit/object-prevent-extensions.js +9 -50
- data/vendor/v8/test/mjsunit/object-seal.js +4 -13
- data/vendor/v8/test/mjsunit/override-eval-with-non-function.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-1145.js +54 -0
- data/vendor/v8/test/mjsunit/regress/regress-1172-bis.js +37 -0
- data/vendor/v8/test/mjsunit/regress/regress-1181.js +54 -0
- data/vendor/v8/test/mjsunit/regress/regress-1207.js +35 -0
- data/vendor/v8/test/mjsunit/regress/regress-1209.js +34 -0
- data/vendor/v8/test/mjsunit/regress/regress-1210.js +48 -0
- data/vendor/v8/test/mjsunit/regress/regress-1213.js +43 -0
- data/vendor/v8/test/mjsunit/regress/regress-1218.js +29 -0
- data/vendor/v8/test/mjsunit/regress/regress-1229.js +79 -0
- data/vendor/v8/test/mjsunit/regress/regress-1233.js +47 -0
- data/vendor/v8/test/mjsunit/regress/regress-1236.js +34 -0
- data/vendor/v8/test/mjsunit/regress/regress-1237.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-1240.js +39 -0
- data/vendor/v8/test/mjsunit/regress/regress-1257.js +58 -0
- data/vendor/v8/test/mjsunit/regress/regress-1278.js +69 -0
- data/vendor/v8/test/mjsunit/regress/regress-create-exception.js +1 -0
- data/vendor/v8/test/mjsunit/regress/regress-lazy-deopt-reloc.js +52 -0
- data/vendor/v8/test/mjsunit/sin-cos.js +15 -10
- data/vendor/v8/test/mjsunit/smi-negative-zero.js +2 -2
- data/vendor/v8/test/mjsunit/str-to-num.js +1 -1
- data/vendor/v8/test/mjsunit/strict-mode.js +435 -0
- data/vendor/v8/test/mjsunit/testcfg.py +23 -6
- data/vendor/v8/test/mozilla/mozilla.status +0 -2
- data/vendor/v8/test/mozilla/testcfg.py +1 -1
- data/vendor/v8/test/preparser/empty.js +28 -0
- data/vendor/v8/test/preparser/functions-only.js +38 -0
- data/vendor/v8/test/preparser/non-alphanum.js +34 -0
- data/vendor/v8/test/preparser/symbols-only.js +49 -0
- data/vendor/v8/test/preparser/testcfg.py +90 -0
- data/vendor/v8/test/sputnik/testcfg.py +1 -1
- data/vendor/v8/test/test262/README +16 -0
- data/vendor/v8/test/test262/harness-adapt.js +80 -0
- data/vendor/v8/test/test262/test262.status +1506 -0
- data/vendor/v8/test/test262/testcfg.py +123 -0
- data/vendor/v8/tools/freebsd-tick-processor +10 -0
- data/vendor/v8/tools/gyp/v8.gyp +8 -33
- data/vendor/v8/tools/linux-tick-processor +5 -3
- data/vendor/v8/tools/test.py +37 -14
- data/vendor/v8/tools/tickprocessor.js +22 -8
- data/vendor/v8/tools/visual_studio/v8_base.vcproj +13 -1
- data/vendor/v8/tools/visual_studio/v8_base_arm.vcproj +5 -1
- data/vendor/v8/tools/visual_studio/v8_base_x64.vcproj +5 -1
- data/vendor/v8/tools/visual_studio/x64.vsprops +1 -0
- metadata +1495 -1341
- data/ext/extconf.rb +0 -22
- data/ext/mustang.cpp +0 -58
- data/vendor/v8/src/top.h +0 -608
@@ -121,34 +121,6 @@ uint64_t HeapEntry::id() {
|
|
121
121
|
return id_adaptor.returned_id;
|
122
122
|
}
|
123
123
|
|
124
|
-
|
125
|
-
template<class Visitor>
|
126
|
-
void HeapEntriesMap::UpdateEntries(Visitor* visitor) {
|
127
|
-
for (HashMap::Entry* p = entries_.Start();
|
128
|
-
p != NULL;
|
129
|
-
p = entries_.Next(p)) {
|
130
|
-
EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(p->value);
|
131
|
-
entry_info->entry = visitor->GetEntry(
|
132
|
-
reinterpret_cast<HeapObject*>(p->key),
|
133
|
-
entry_info->children_count,
|
134
|
-
entry_info->retainers_count);
|
135
|
-
entry_info->children_count = 0;
|
136
|
-
entry_info->retainers_count = 0;
|
137
|
-
}
|
138
|
-
}
|
139
|
-
|
140
|
-
|
141
|
-
bool HeapSnapshotGenerator::ReportProgress(bool force) {
|
142
|
-
const int kProgressReportGranularity = 10000;
|
143
|
-
if (control_ != NULL
|
144
|
-
&& (force || progress_counter_ % kProgressReportGranularity == 0)) {
|
145
|
-
return
|
146
|
-
control_->ReportProgressValue(progress_counter_, progress_total_) ==
|
147
|
-
v8::ActivityControl::kContinue;
|
148
|
-
}
|
149
|
-
return true;
|
150
|
-
}
|
151
|
-
|
152
124
|
} } // namespace v8::internal
|
153
125
|
|
154
126
|
#endif // ENABLE_LOGGING_AND_PROFILING
|
@@ -29,8 +29,8 @@
|
|
29
29
|
|
30
30
|
#include "v8.h"
|
31
31
|
#include "global-handles.h"
|
32
|
+
#include "heap-profiler.h"
|
32
33
|
#include "scopeinfo.h"
|
33
|
-
#include "top.h"
|
34
34
|
#include "unicode.h"
|
35
35
|
#include "zone-inl.h"
|
36
36
|
|
@@ -47,24 +47,27 @@ TokenEnumerator::TokenEnumerator()
|
|
47
47
|
|
48
48
|
|
49
49
|
TokenEnumerator::~TokenEnumerator() {
|
50
|
+
Isolate* isolate = Isolate::Current();
|
50
51
|
for (int i = 0; i < token_locations_.length(); ++i) {
|
51
52
|
if (!token_removed_[i]) {
|
52
|
-
|
53
|
-
|
53
|
+
isolate->global_handles()->ClearWeakness(token_locations_[i]);
|
54
|
+
isolate->global_handles()->Destroy(token_locations_[i]);
|
54
55
|
}
|
55
56
|
}
|
56
57
|
}
|
57
58
|
|
58
59
|
|
59
60
|
int TokenEnumerator::GetTokenId(Object* token) {
|
61
|
+
Isolate* isolate = Isolate::Current();
|
60
62
|
if (token == NULL) return TokenEnumerator::kNoSecurityToken;
|
61
63
|
for (int i = 0; i < token_locations_.length(); ++i) {
|
62
64
|
if (*token_locations_[i] == token && !token_removed_[i]) return i;
|
63
65
|
}
|
64
|
-
Handle<Object> handle =
|
66
|
+
Handle<Object> handle = isolate->global_handles()->Create(token);
|
65
67
|
// handle.location() points to a memory cell holding a pointer
|
66
68
|
// to a token object in the V8's heap.
|
67
|
-
|
69
|
+
isolate->global_handles()->MakeWeak(handle.location(), this,
|
70
|
+
TokenRemovedCallback);
|
68
71
|
token_locations_.Add(handle.location());
|
69
72
|
token_removed_.Add(false);
|
70
73
|
return token_locations_.length() - 1;
|
@@ -94,55 +97,74 @@ StringsStorage::StringsStorage()
|
|
94
97
|
}
|
95
98
|
|
96
99
|
|
97
|
-
static void DeleteIndexName(char** name_ptr) {
|
98
|
-
DeleteArray(*name_ptr);
|
99
|
-
}
|
100
|
-
|
101
|
-
|
102
100
|
StringsStorage::~StringsStorage() {
|
103
101
|
for (HashMap::Entry* p = names_.Start();
|
104
102
|
p != NULL;
|
105
103
|
p = names_.Next(p)) {
|
106
104
|
DeleteArray(reinterpret_cast<const char*>(p->value));
|
107
105
|
}
|
108
|
-
|
106
|
+
}
|
107
|
+
|
108
|
+
|
109
|
+
const char* StringsStorage::GetCopy(const char* src) {
|
110
|
+
int len = static_cast<int>(strlen(src));
|
111
|
+
Vector<char> dst = Vector<char>::New(len + 1);
|
112
|
+
OS::StrNCpy(dst, src, len);
|
113
|
+
dst[len] = '\0';
|
114
|
+
uint32_t hash = HashSequentialString(dst.start(), len);
|
115
|
+
return AddOrDisposeString(dst.start(), hash);
|
116
|
+
}
|
117
|
+
|
118
|
+
|
119
|
+
const char* StringsStorage::GetFormatted(const char* format, ...) {
|
120
|
+
va_list args;
|
121
|
+
va_start(args, format);
|
122
|
+
const char* result = GetVFormatted(format, args);
|
123
|
+
va_end(args);
|
124
|
+
return result;
|
125
|
+
}
|
126
|
+
|
127
|
+
|
128
|
+
const char* StringsStorage::AddOrDisposeString(char* str, uint32_t hash) {
|
129
|
+
HashMap::Entry* cache_entry = names_.Lookup(str, hash, true);
|
130
|
+
if (cache_entry->value == NULL) {
|
131
|
+
// New entry added.
|
132
|
+
cache_entry->value = str;
|
133
|
+
} else {
|
134
|
+
DeleteArray(str);
|
135
|
+
}
|
136
|
+
return reinterpret_cast<const char*>(cache_entry->value);
|
137
|
+
}
|
138
|
+
|
139
|
+
|
140
|
+
const char* StringsStorage::GetVFormatted(const char* format, va_list args) {
|
141
|
+
Vector<char> str = Vector<char>::New(1024);
|
142
|
+
int len = OS::VSNPrintF(str, format, args);
|
143
|
+
if (len == -1) {
|
144
|
+
DeleteArray(str.start());
|
145
|
+
return format;
|
146
|
+
}
|
147
|
+
uint32_t hash = HashSequentialString(str.start(), len);
|
148
|
+
return AddOrDisposeString(str.start(), hash);
|
109
149
|
}
|
110
150
|
|
111
151
|
|
112
152
|
const char* StringsStorage::GetName(String* name) {
|
113
153
|
if (name->IsString()) {
|
114
|
-
|
115
|
-
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).Detach()
|
116
|
-
|
117
|
-
if (cache_entry->value == NULL) {
|
118
|
-
// New entry added.
|
119
|
-
cache_entry->value = c_name;
|
120
|
-
} else {
|
121
|
-
DeleteArray(c_name);
|
122
|
-
}
|
123
|
-
return reinterpret_cast<const char*>(cache_entry->value);
|
154
|
+
return AddOrDisposeString(
|
155
|
+
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).Detach(),
|
156
|
+
name->Hash());
|
124
157
|
}
|
125
158
|
return "";
|
126
159
|
}
|
127
160
|
|
128
161
|
|
129
162
|
const char* StringsStorage::GetName(int index) {
|
130
|
-
|
131
|
-
if (index_names_.length() <= index) {
|
132
|
-
index_names_.AddBlock(
|
133
|
-
NULL, index - index_names_.length() + 1);
|
134
|
-
}
|
135
|
-
if (index_names_[index] == NULL) {
|
136
|
-
const int kMaximumNameLength = 32;
|
137
|
-
char* name = NewArray<char>(kMaximumNameLength);
|
138
|
-
OS::SNPrintF(Vector<char>(name, kMaximumNameLength), "%d", index);
|
139
|
-
index_names_[index] = name;
|
140
|
-
}
|
141
|
-
return index_names_[index];
|
163
|
+
return GetFormatted("%d", index);
|
142
164
|
}
|
143
165
|
|
144
166
|
|
145
|
-
const char* CodeEntry::kEmptyNamePrefix = "";
|
167
|
+
const char* const CodeEntry::kEmptyNamePrefix = "";
|
146
168
|
|
147
169
|
|
148
170
|
void CodeEntry::CopyData(const CodeEntry& source) {
|
@@ -298,7 +320,7 @@ struct NodesPair {
|
|
298
320
|
|
299
321
|
class FilteredCloneCallback {
|
300
322
|
public:
|
301
|
-
|
323
|
+
FilteredCloneCallback(ProfileNode* dst_root, int security_token_id)
|
302
324
|
: stack_(10),
|
303
325
|
security_token_id_(security_token_id) {
|
304
326
|
stack_.Add(NodesPair(NULL, dst_root));
|
@@ -465,7 +487,7 @@ void CpuProfile::Print() {
|
|
465
487
|
}
|
466
488
|
|
467
489
|
|
468
|
-
CodeEntry* const CodeMap::
|
490
|
+
CodeEntry* const CodeMap::kSharedFunctionCodeEntry = NULL;
|
469
491
|
const CodeMap::CodeTreeConfig::Key CodeMap::CodeTreeConfig::kNoKey = NULL;
|
470
492
|
const CodeMap::CodeTreeConfig::Value CodeMap::CodeTreeConfig::kNoValue =
|
471
493
|
CodeMap::CodeEntryInfo(NULL, 0);
|
@@ -483,18 +505,18 @@ CodeEntry* CodeMap::FindEntry(Address addr) {
|
|
483
505
|
}
|
484
506
|
|
485
507
|
|
486
|
-
int CodeMap::
|
508
|
+
int CodeMap::GetSharedId(Address addr) {
|
487
509
|
CodeTree::Locator locator;
|
488
|
-
// For
|
510
|
+
// For shared function entries, 'size' field is used to store their IDs.
|
489
511
|
if (tree_.Find(addr, &locator)) {
|
490
512
|
const CodeEntryInfo& entry = locator.value();
|
491
|
-
ASSERT(entry.entry ==
|
513
|
+
ASSERT(entry.entry == kSharedFunctionCodeEntry);
|
492
514
|
return entry.size;
|
493
515
|
} else {
|
494
516
|
tree_.Insert(addr, &locator);
|
495
|
-
int
|
496
|
-
locator.set_value(CodeEntryInfo(
|
497
|
-
return
|
517
|
+
int id = next_shared_id_++;
|
518
|
+
locator.set_value(CodeEntryInfo(kSharedFunctionCodeEntry, id));
|
519
|
+
return id;
|
498
520
|
}
|
499
521
|
}
|
500
522
|
|
@@ -528,13 +550,16 @@ static void DeleteCpuProfile(CpuProfile** profile_ptr) {
|
|
528
550
|
}
|
529
551
|
|
530
552
|
static void DeleteProfilesList(List<CpuProfile*>** list_ptr) {
|
531
|
-
(*list_ptr)
|
532
|
-
|
553
|
+
if (*list_ptr != NULL) {
|
554
|
+
(*list_ptr)->Iterate(DeleteCpuProfile);
|
555
|
+
delete *list_ptr;
|
556
|
+
}
|
533
557
|
}
|
534
558
|
|
535
559
|
CpuProfilesCollection::~CpuProfilesCollection() {
|
536
560
|
delete current_profiles_semaphore_;
|
537
561
|
current_profiles_.Iterate(DeleteCpuProfile);
|
562
|
+
detached_profiles_.Iterate(DeleteCpuProfile);
|
538
563
|
profiles_by_token_.Iterate(DeleteProfilesList);
|
539
564
|
code_entries_.Iterate(DeleteCodeEntry);
|
540
565
|
}
|
@@ -599,15 +624,8 @@ CpuProfile* CpuProfilesCollection::StopProfiling(int security_token_id,
|
|
599
624
|
|
600
625
|
CpuProfile* CpuProfilesCollection::GetProfile(int security_token_id,
|
601
626
|
unsigned uid) {
|
602
|
-
|
603
|
-
|
604
|
-
false);
|
605
|
-
int index;
|
606
|
-
if (entry != NULL) {
|
607
|
-
index = static_cast<int>(reinterpret_cast<intptr_t>(entry->value));
|
608
|
-
} else {
|
609
|
-
return NULL;
|
610
|
-
}
|
627
|
+
int index = GetProfileIndex(uid);
|
628
|
+
if (index < 0) return NULL;
|
611
629
|
List<CpuProfile*>* unabridged_list =
|
612
630
|
profiles_by_token_[TokenToIndex(TokenEnumerator::kNoSecurityToken)];
|
613
631
|
if (security_token_id == TokenEnumerator::kNoSecurityToken) {
|
@@ -622,6 +640,15 @@ CpuProfile* CpuProfilesCollection::GetProfile(int security_token_id,
|
|
622
640
|
}
|
623
641
|
|
624
642
|
|
643
|
+
int CpuProfilesCollection::GetProfileIndex(unsigned uid) {
|
644
|
+
HashMap::Entry* entry = profiles_uids_.Lookup(reinterpret_cast<void*>(uid),
|
645
|
+
static_cast<uint32_t>(uid),
|
646
|
+
false);
|
647
|
+
return entry != NULL ?
|
648
|
+
static_cast<int>(reinterpret_cast<intptr_t>(entry->value)) : -1;
|
649
|
+
}
|
650
|
+
|
651
|
+
|
625
652
|
bool CpuProfilesCollection::IsLastProfile(const char* title) {
|
626
653
|
// Called from VM thread, and only it can mutate the list,
|
627
654
|
// so no locking is needed here.
|
@@ -631,6 +658,39 @@ bool CpuProfilesCollection::IsLastProfile(const char* title) {
|
|
631
658
|
}
|
632
659
|
|
633
660
|
|
661
|
+
void CpuProfilesCollection::RemoveProfile(CpuProfile* profile) {
|
662
|
+
// Called from VM thread for a completed profile.
|
663
|
+
unsigned uid = profile->uid();
|
664
|
+
int index = GetProfileIndex(uid);
|
665
|
+
if (index < 0) {
|
666
|
+
detached_profiles_.RemoveElement(profile);
|
667
|
+
return;
|
668
|
+
}
|
669
|
+
profiles_uids_.Remove(reinterpret_cast<void*>(uid),
|
670
|
+
static_cast<uint32_t>(uid));
|
671
|
+
// Decrement all indexes above the deleted one.
|
672
|
+
for (HashMap::Entry* p = profiles_uids_.Start();
|
673
|
+
p != NULL;
|
674
|
+
p = profiles_uids_.Next(p)) {
|
675
|
+
intptr_t p_index = reinterpret_cast<intptr_t>(p->value);
|
676
|
+
if (p_index > index) {
|
677
|
+
p->value = reinterpret_cast<void*>(p_index - 1);
|
678
|
+
}
|
679
|
+
}
|
680
|
+
for (int i = 0; i < profiles_by_token_.length(); ++i) {
|
681
|
+
List<CpuProfile*>* list = profiles_by_token_[i];
|
682
|
+
if (list != NULL && index < list->length()) {
|
683
|
+
// Move all filtered clones into detached_profiles_,
|
684
|
+
// so we can know that they are still in use.
|
685
|
+
CpuProfile* cloned_profile = list->Remove(index);
|
686
|
+
if (cloned_profile != NULL && cloned_profile != profile) {
|
687
|
+
detached_profiles_.Add(cloned_profile);
|
688
|
+
}
|
689
|
+
}
|
690
|
+
}
|
691
|
+
}
|
692
|
+
|
693
|
+
|
634
694
|
int CpuProfilesCollection::TokenToIndex(int security_token_id) {
|
635
695
|
ASSERT(TokenEnumerator::kNoSecurityToken == -1);
|
636
696
|
return security_token_id + 1; // kNoSecurityToken -> 0, 0 -> 1, ...
|
@@ -763,10 +823,12 @@ void SampleRateCalculator::UpdateMeasurements(double current_time) {
|
|
763
823
|
}
|
764
824
|
|
765
825
|
|
766
|
-
const char* ProfileGenerator::kAnonymousFunctionName =
|
767
|
-
|
768
|
-
const char* ProfileGenerator::
|
769
|
-
|
826
|
+
const char* const ProfileGenerator::kAnonymousFunctionName =
|
827
|
+
"(anonymous function)";
|
828
|
+
const char* const ProfileGenerator::kProgramEntryName =
|
829
|
+
"(program)";
|
830
|
+
const char* const ProfileGenerator::kGarbageCollectorEntryName =
|
831
|
+
"(garbage collector)";
|
770
832
|
|
771
833
|
|
772
834
|
ProfileGenerator::ProfileGenerator(CpuProfilesCollection* profiles)
|
@@ -789,7 +851,15 @@ void ProfileGenerator::RecordTickSample(const TickSample& sample) {
|
|
789
851
|
if (sample.pc != NULL) {
|
790
852
|
*entry++ = code_map_.FindEntry(sample.pc);
|
791
853
|
|
792
|
-
if (sample.
|
854
|
+
if (sample.has_external_callback) {
|
855
|
+
// Don't use PC when in external callback code, as it can point
|
856
|
+
// inside callback's code, and we will erroneously report
|
857
|
+
// that a callback calls itself.
|
858
|
+
*(entries.start()) = NULL;
|
859
|
+
*entry++ = code_map_.FindEntry(sample.external_callback);
|
860
|
+
} else if (sample.tos != NULL) {
|
861
|
+
// Find out, if top of stack was pointing inside a JS function
|
862
|
+
// meaning that we have encountered a frameless invocation.
|
793
863
|
*entry = code_map_.FindEntry(sample.tos);
|
794
864
|
if (*entry != NULL && !(*entry)->is_js_function()) {
|
795
865
|
*entry = NULL;
|
@@ -914,11 +984,6 @@ int HeapEntry::RetainedSize(bool exact) {
|
|
914
984
|
}
|
915
985
|
|
916
986
|
|
917
|
-
List<HeapGraphPath*>* HeapEntry::GetRetainingPaths() {
|
918
|
-
return snapshot_->GetRetainingPaths(this);
|
919
|
-
}
|
920
|
-
|
921
|
-
|
922
987
|
template<class Visitor>
|
923
988
|
void HeapEntry::ApplyAndPaintAllReachable(Visitor* visitor) {
|
924
989
|
List<HeapEntry*> list(10);
|
@@ -1009,6 +1074,7 @@ const char* HeapEntry::TypeAsString() {
|
|
1009
1074
|
case kArray: return "/array/";
|
1010
1075
|
case kRegExp: return "/regexp/";
|
1011
1076
|
case kHeapNumber: return "/number/";
|
1077
|
+
case kNative: return "/native/";
|
1012
1078
|
default: return "???";
|
1013
1079
|
}
|
1014
1080
|
}
|
@@ -1076,113 +1142,6 @@ void HeapEntry::CalculateExactRetainedSize() {
|
|
1076
1142
|
}
|
1077
1143
|
|
1078
1144
|
|
1079
|
-
class CachedHeapGraphPath {
|
1080
|
-
public:
|
1081
|
-
CachedHeapGraphPath()
|
1082
|
-
: nodes_(NodesMatch) { }
|
1083
|
-
CachedHeapGraphPath(const CachedHeapGraphPath& src)
|
1084
|
-
: nodes_(NodesMatch, &HashMap::DefaultAllocator, src.nodes_.capacity()),
|
1085
|
-
path_(src.path_.length() + 1) {
|
1086
|
-
for (HashMap::Entry* p = src.nodes_.Start();
|
1087
|
-
p != NULL;
|
1088
|
-
p = src.nodes_.Next(p)) {
|
1089
|
-
nodes_.Lookup(p->key, p->hash, true);
|
1090
|
-
}
|
1091
|
-
path_.AddAll(src.path_);
|
1092
|
-
}
|
1093
|
-
void Add(HeapGraphEdge* edge) {
|
1094
|
-
nodes_.Lookup(edge->to(), Hash(edge->to()), true);
|
1095
|
-
path_.Add(edge);
|
1096
|
-
}
|
1097
|
-
bool ContainsNode(HeapEntry* node) {
|
1098
|
-
return nodes_.Lookup(node, Hash(node), false) != NULL;
|
1099
|
-
}
|
1100
|
-
const List<HeapGraphEdge*>* path() const { return &path_; }
|
1101
|
-
|
1102
|
-
private:
|
1103
|
-
static uint32_t Hash(HeapEntry* entry) {
|
1104
|
-
return static_cast<uint32_t>(reinterpret_cast<intptr_t>(entry));
|
1105
|
-
}
|
1106
|
-
static bool NodesMatch(void* key1, void* key2) { return key1 == key2; }
|
1107
|
-
|
1108
|
-
HashMap nodes_;
|
1109
|
-
List<HeapGraphEdge*> path_;
|
1110
|
-
};
|
1111
|
-
|
1112
|
-
|
1113
|
-
List<HeapGraphPath*>* HeapEntry::CalculateRetainingPaths() {
|
1114
|
-
List<HeapGraphPath*>* retaining_paths = new List<HeapGraphPath*>(4);
|
1115
|
-
CachedHeapGraphPath path;
|
1116
|
-
FindRetainingPaths(&path, retaining_paths);
|
1117
|
-
return retaining_paths;
|
1118
|
-
}
|
1119
|
-
|
1120
|
-
|
1121
|
-
void HeapEntry::FindRetainingPaths(CachedHeapGraphPath* prev_path,
|
1122
|
-
List<HeapGraphPath*>* retaining_paths) {
|
1123
|
-
Vector<HeapGraphEdge*> rets = retainers();
|
1124
|
-
for (int i = 0; i < rets.length(); ++i) {
|
1125
|
-
HeapGraphEdge* ret_edge = rets[i];
|
1126
|
-
if (prev_path->ContainsNode(ret_edge->From())) continue;
|
1127
|
-
if (ret_edge->From() != snapshot()->root()) {
|
1128
|
-
CachedHeapGraphPath path(*prev_path);
|
1129
|
-
path.Add(ret_edge);
|
1130
|
-
ret_edge->From()->FindRetainingPaths(&path, retaining_paths);
|
1131
|
-
} else {
|
1132
|
-
HeapGraphPath* ret_path = new HeapGraphPath(*prev_path->path());
|
1133
|
-
ret_path->Set(0, ret_edge);
|
1134
|
-
retaining_paths->Add(ret_path);
|
1135
|
-
}
|
1136
|
-
}
|
1137
|
-
}
|
1138
|
-
|
1139
|
-
|
1140
|
-
HeapGraphPath::HeapGraphPath(const List<HeapGraphEdge*>& path)
|
1141
|
-
: path_(path.length() + 1) {
|
1142
|
-
Add(NULL);
|
1143
|
-
for (int i = path.length() - 1; i >= 0; --i) {
|
1144
|
-
Add(path[i]);
|
1145
|
-
}
|
1146
|
-
}
|
1147
|
-
|
1148
|
-
|
1149
|
-
void HeapGraphPath::Print() {
|
1150
|
-
path_[0]->From()->Print(1, 0);
|
1151
|
-
for (int i = 0; i < path_.length(); ++i) {
|
1152
|
-
OS::Print(" -> ");
|
1153
|
-
HeapGraphEdge* edge = path_[i];
|
1154
|
-
switch (edge->type()) {
|
1155
|
-
case HeapGraphEdge::kContextVariable:
|
1156
|
-
OS::Print("[#%s] ", edge->name());
|
1157
|
-
break;
|
1158
|
-
case HeapGraphEdge::kElement:
|
1159
|
-
case HeapGraphEdge::kHidden:
|
1160
|
-
OS::Print("[%d] ", edge->index());
|
1161
|
-
break;
|
1162
|
-
case HeapGraphEdge::kInternal:
|
1163
|
-
OS::Print("[$%s] ", edge->name());
|
1164
|
-
break;
|
1165
|
-
case HeapGraphEdge::kProperty:
|
1166
|
-
OS::Print("[%s] ", edge->name());
|
1167
|
-
break;
|
1168
|
-
case HeapGraphEdge::kShortcut:
|
1169
|
-
OS::Print("[^%s] ", edge->name());
|
1170
|
-
break;
|
1171
|
-
default:
|
1172
|
-
OS::Print("!!! unknown edge type: %d ", edge->type());
|
1173
|
-
}
|
1174
|
-
edge->to()->Print(1, 0);
|
1175
|
-
}
|
1176
|
-
OS::Print("\n");
|
1177
|
-
}
|
1178
|
-
|
1179
|
-
|
1180
|
-
HeapObject *const HeapSnapshot::kInternalRootObject =
|
1181
|
-
reinterpret_cast<HeapObject*>(1);
|
1182
|
-
HeapObject *const HeapSnapshot::kGcRootsObject =
|
1183
|
-
reinterpret_cast<HeapObject*>(2);
|
1184
|
-
|
1185
|
-
|
1186
1145
|
// It is very important to keep objects that form a heap snapshot
|
1187
1146
|
// as small as possible.
|
1188
1147
|
namespace { // Avoid littering the global namespace.
|
@@ -1211,9 +1170,9 @@ HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection,
|
|
1211
1170
|
uid_(uid),
|
1212
1171
|
root_entry_(NULL),
|
1213
1172
|
gc_roots_entry_(NULL),
|
1173
|
+
natives_root_entry_(NULL),
|
1214
1174
|
raw_entries_(NULL),
|
1215
|
-
entries_sorted_(false)
|
1216
|
-
retaining_paths_(HeapEntry::Match) {
|
1175
|
+
entries_sorted_(false) {
|
1217
1176
|
STATIC_ASSERT(
|
1218
1177
|
sizeof(HeapGraphEdge) ==
|
1219
1178
|
SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapGraphEdgeSize); // NOLINT
|
@@ -1222,21 +1181,14 @@ HeapSnapshot::HeapSnapshot(HeapSnapshotsCollection* collection,
|
|
1222
1181
|
SnapshotSizeConstants<sizeof(void*)>::kExpectedHeapEntrySize); // NOLINT
|
1223
1182
|
}
|
1224
1183
|
|
1225
|
-
|
1226
|
-
static void DeleteHeapGraphPath(HeapGraphPath** path_ptr) {
|
1227
|
-
delete *path_ptr;
|
1228
|
-
}
|
1229
|
-
|
1230
1184
|
HeapSnapshot::~HeapSnapshot() {
|
1231
1185
|
DeleteArray(raw_entries_);
|
1232
|
-
|
1233
|
-
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
delete list;
|
1239
|
-
}
|
1186
|
+
}
|
1187
|
+
|
1188
|
+
|
1189
|
+
void HeapSnapshot::Delete() {
|
1190
|
+
collection_->RemoveSnapshot(this);
|
1191
|
+
delete this;
|
1240
1192
|
}
|
1241
1193
|
|
1242
1194
|
|
@@ -1253,96 +1205,6 @@ void HeapSnapshot::AllocateEntries(int entries_count,
|
|
1253
1205
|
}
|
1254
1206
|
|
1255
1207
|
|
1256
|
-
HeapEntry* HeapSnapshot::AddEntry(HeapObject* object,
|
1257
|
-
int children_count,
|
1258
|
-
int retainers_count) {
|
1259
|
-
if (object == kInternalRootObject) {
|
1260
|
-
ASSERT(root_entry_ == NULL);
|
1261
|
-
ASSERT(retainers_count == 0);
|
1262
|
-
return (root_entry_ = AddEntry(HeapEntry::kObject,
|
1263
|
-
"",
|
1264
|
-
HeapObjectsMap::kInternalRootObjectId,
|
1265
|
-
0,
|
1266
|
-
children_count,
|
1267
|
-
retainers_count));
|
1268
|
-
} else if (object == kGcRootsObject) {
|
1269
|
-
ASSERT(gc_roots_entry_ == NULL);
|
1270
|
-
return (gc_roots_entry_ = AddEntry(HeapEntry::kObject,
|
1271
|
-
"(GC roots)",
|
1272
|
-
HeapObjectsMap::kGcRootsObjectId,
|
1273
|
-
0,
|
1274
|
-
children_count,
|
1275
|
-
retainers_count));
|
1276
|
-
} else if (object->IsJSFunction()) {
|
1277
|
-
JSFunction* func = JSFunction::cast(object);
|
1278
|
-
SharedFunctionInfo* shared = func->shared();
|
1279
|
-
return AddEntry(object,
|
1280
|
-
HeapEntry::kClosure,
|
1281
|
-
collection_->GetName(String::cast(shared->name())),
|
1282
|
-
children_count,
|
1283
|
-
retainers_count);
|
1284
|
-
} else if (object->IsJSRegExp()) {
|
1285
|
-
JSRegExp* re = JSRegExp::cast(object);
|
1286
|
-
return AddEntry(object,
|
1287
|
-
HeapEntry::kRegExp,
|
1288
|
-
collection_->GetName(re->Pattern()),
|
1289
|
-
children_count,
|
1290
|
-
retainers_count);
|
1291
|
-
} else if (object->IsJSObject()) {
|
1292
|
-
return AddEntry(object,
|
1293
|
-
HeapEntry::kObject,
|
1294
|
-
collection_->GetName(GetConstructorNameForHeapProfile(
|
1295
|
-
JSObject::cast(object))),
|
1296
|
-
children_count,
|
1297
|
-
retainers_count);
|
1298
|
-
} else if (object->IsString()) {
|
1299
|
-
return AddEntry(object,
|
1300
|
-
HeapEntry::kString,
|
1301
|
-
collection_->GetName(String::cast(object)),
|
1302
|
-
children_count,
|
1303
|
-
retainers_count);
|
1304
|
-
} else if (object->IsCode()) {
|
1305
|
-
return AddEntry(object,
|
1306
|
-
HeapEntry::kCode,
|
1307
|
-
"",
|
1308
|
-
children_count,
|
1309
|
-
retainers_count);
|
1310
|
-
} else if (object->IsSharedFunctionInfo()) {
|
1311
|
-
SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
|
1312
|
-
return AddEntry(object,
|
1313
|
-
HeapEntry::kCode,
|
1314
|
-
collection_->GetName(String::cast(shared->name())),
|
1315
|
-
children_count,
|
1316
|
-
retainers_count);
|
1317
|
-
} else if (object->IsScript()) {
|
1318
|
-
Script* script = Script::cast(object);
|
1319
|
-
return AddEntry(object,
|
1320
|
-
HeapEntry::kCode,
|
1321
|
-
script->name()->IsString() ?
|
1322
|
-
collection_->GetName(String::cast(script->name())) : "",
|
1323
|
-
children_count,
|
1324
|
-
retainers_count);
|
1325
|
-
} else if (object->IsFixedArray()) {
|
1326
|
-
return AddEntry(object,
|
1327
|
-
HeapEntry::kArray,
|
1328
|
-
"",
|
1329
|
-
children_count,
|
1330
|
-
retainers_count);
|
1331
|
-
} else if (object->IsHeapNumber()) {
|
1332
|
-
return AddEntry(object,
|
1333
|
-
HeapEntry::kHeapNumber,
|
1334
|
-
"number",
|
1335
|
-
children_count,
|
1336
|
-
retainers_count);
|
1337
|
-
}
|
1338
|
-
return AddEntry(object,
|
1339
|
-
HeapEntry::kHidden,
|
1340
|
-
"system",
|
1341
|
-
children_count,
|
1342
|
-
retainers_count);
|
1343
|
-
}
|
1344
|
-
|
1345
|
-
|
1346
1208
|
static void HeapEntryClearPaint(HeapEntry** entry_ptr) {
|
1347
1209
|
(*entry_ptr)->clear_paint();
|
1348
1210
|
}
|
@@ -1352,17 +1214,39 @@ void HeapSnapshot::ClearPaint() {
|
|
1352
1214
|
}
|
1353
1215
|
|
1354
1216
|
|
1355
|
-
HeapEntry* HeapSnapshot::
|
1356
|
-
|
1357
|
-
|
1358
|
-
|
1359
|
-
|
1360
|
-
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
1365
|
-
|
1217
|
+
HeapEntry* HeapSnapshot::AddRootEntry(int children_count) {
|
1218
|
+
ASSERT(root_entry_ == NULL);
|
1219
|
+
return (root_entry_ = AddEntry(HeapEntry::kObject,
|
1220
|
+
"",
|
1221
|
+
HeapObjectsMap::kInternalRootObjectId,
|
1222
|
+
0,
|
1223
|
+
children_count,
|
1224
|
+
0));
|
1225
|
+
}
|
1226
|
+
|
1227
|
+
|
1228
|
+
HeapEntry* HeapSnapshot::AddGcRootsEntry(int children_count,
|
1229
|
+
int retainers_count) {
|
1230
|
+
ASSERT(gc_roots_entry_ == NULL);
|
1231
|
+
return (gc_roots_entry_ = AddEntry(HeapEntry::kObject,
|
1232
|
+
"(GC roots)",
|
1233
|
+
HeapObjectsMap::kGcRootsObjectId,
|
1234
|
+
0,
|
1235
|
+
children_count,
|
1236
|
+
retainers_count));
|
1237
|
+
}
|
1238
|
+
|
1239
|
+
|
1240
|
+
HeapEntry* HeapSnapshot::AddNativesRootEntry(int children_count,
|
1241
|
+
int retainers_count) {
|
1242
|
+
ASSERT(natives_root_entry_ == NULL);
|
1243
|
+
return (natives_root_entry_ = AddEntry(
|
1244
|
+
HeapEntry::kObject,
|
1245
|
+
"(Native objects)",
|
1246
|
+
HeapObjectsMap::kNativesRootObjectId,
|
1247
|
+
0,
|
1248
|
+
children_count,
|
1249
|
+
retainers_count));
|
1366
1250
|
}
|
1367
1251
|
|
1368
1252
|
|
@@ -1400,14 +1284,7 @@ HeapEntry* HeapSnapshot::GetNextEntryToInit() {
|
|
1400
1284
|
}
|
1401
1285
|
|
1402
1286
|
|
1403
|
-
HeapSnapshotsDiff* HeapSnapshot::CompareWith(HeapSnapshot* snapshot) {
|
1404
|
-
return collection_->CompareSnapshots(this, snapshot);
|
1405
|
-
}
|
1406
|
-
|
1407
|
-
|
1408
1287
|
HeapEntry* HeapSnapshot::GetEntryById(uint64_t id) {
|
1409
|
-
// GetSortedEntriesList is used in diff algorithm and sorts
|
1410
|
-
// entries by their id.
|
1411
1288
|
List<HeapEntry*>* entries_by_id = GetSortedEntriesList();
|
1412
1289
|
|
1413
1290
|
// Perform a binary search by id.
|
@@ -1428,16 +1305,6 @@ HeapEntry* HeapSnapshot::GetEntryById(uint64_t id) {
|
|
1428
1305
|
}
|
1429
1306
|
|
1430
1307
|
|
1431
|
-
List<HeapGraphPath*>* HeapSnapshot::GetRetainingPaths(HeapEntry* entry) {
|
1432
|
-
HashMap::Entry* p =
|
1433
|
-
retaining_paths_.Lookup(entry, HeapEntry::Hash(entry), true);
|
1434
|
-
if (p->value == NULL) {
|
1435
|
-
p->value = entry->CalculateRetainingPaths();
|
1436
|
-
}
|
1437
|
-
return reinterpret_cast<List<HeapGraphPath*>*>(p->value);
|
1438
|
-
}
|
1439
|
-
|
1440
|
-
|
1441
1308
|
template<class T>
|
1442
1309
|
static int SortByIds(const T* entry1_ptr,
|
1443
1310
|
const T* entry2_ptr) {
|
@@ -1459,10 +1326,13 @@ void HeapSnapshot::Print(int max_depth) {
|
|
1459
1326
|
}
|
1460
1327
|
|
1461
1328
|
|
1462
|
-
|
1463
|
-
|
1329
|
+
// We split IDs on evens for embedder objects (see
|
1330
|
+
// HeapObjectsMap::GenerateId) and odds for native objects.
|
1331
|
+
const uint64_t HeapObjectsMap::kInternalRootObjectId = 1;
|
1332
|
+
const uint64_t HeapObjectsMap::kGcRootsObjectId = 3;
|
1333
|
+
const uint64_t HeapObjectsMap::kNativesRootObjectId = 5;
|
1464
1334
|
// Increase kFirstAvailableObjectId if new 'special' objects appear.
|
1465
|
-
const uint64_t HeapObjectsMap::kFirstAvailableObjectId =
|
1335
|
+
const uint64_t HeapObjectsMap::kFirstAvailableObjectId = 7;
|
1466
1336
|
|
1467
1337
|
HeapObjectsMap::HeapObjectsMap()
|
1468
1338
|
: initial_fill_mode_(true),
|
@@ -1487,7 +1357,8 @@ uint64_t HeapObjectsMap::FindObject(Address addr) {
|
|
1487
1357
|
uint64_t existing = FindEntry(addr);
|
1488
1358
|
if (existing != 0) return existing;
|
1489
1359
|
}
|
1490
|
-
uint64_t id = next_id_
|
1360
|
+
uint64_t id = next_id_;
|
1361
|
+
next_id_ += 2;
|
1491
1362
|
AddEntry(addr, id);
|
1492
1363
|
return id;
|
1493
1364
|
}
|
@@ -1555,6 +1426,17 @@ void HeapObjectsMap::RemoveDeadEntries() {
|
|
1555
1426
|
}
|
1556
1427
|
|
1557
1428
|
|
1429
|
+
uint64_t HeapObjectsMap::GenerateId(v8::RetainedObjectInfo* info) {
|
1430
|
+
uint64_t id = static_cast<uint64_t>(info->GetHash());
|
1431
|
+
const char* label = info->GetLabel();
|
1432
|
+
id ^= HashSequentialString(label, static_cast<int>(strlen(label)));
|
1433
|
+
intptr_t element_count = info->GetElementCount();
|
1434
|
+
if (element_count != -1)
|
1435
|
+
id ^= ComputeIntegerHash(static_cast<uint32_t>(element_count));
|
1436
|
+
return id << 1;
|
1437
|
+
}
|
1438
|
+
|
1439
|
+
|
1558
1440
|
HeapSnapshotsCollection::HeapSnapshotsCollection()
|
1559
1441
|
: is_tracking_objects_(false),
|
1560
1442
|
snapshots_uids_(HeapSnapshotsMatch),
|
@@ -1604,10 +1486,11 @@ HeapSnapshot* HeapSnapshotsCollection::GetSnapshot(unsigned uid) {
|
|
1604
1486
|
}
|
1605
1487
|
|
1606
1488
|
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1489
|
+
void HeapSnapshotsCollection::RemoveSnapshot(HeapSnapshot* snapshot) {
|
1490
|
+
snapshots_.RemoveElement(snapshot);
|
1491
|
+
unsigned uid = snapshot->uid();
|
1492
|
+
snapshots_uids_.Remove(reinterpret_cast<void*>(uid),
|
1493
|
+
static_cast<uint32_t>(uid));
|
1611
1494
|
}
|
1612
1495
|
|
1613
1496
|
|
@@ -1615,7 +1498,7 @@ HeapEntry *const HeapEntriesMap::kHeapEntryPlaceholder =
|
|
1615
1498
|
reinterpret_cast<HeapEntry*>(1);
|
1616
1499
|
|
1617
1500
|
HeapEntriesMap::HeapEntriesMap()
|
1618
|
-
: entries_(
|
1501
|
+
: entries_(HeapThingsMatch),
|
1619
1502
|
entries_count_(0),
|
1620
1503
|
total_children_count_(0),
|
1621
1504
|
total_retainers_count_(0) {
|
@@ -1629,8 +1512,25 @@ HeapEntriesMap::~HeapEntriesMap() {
|
|
1629
1512
|
}
|
1630
1513
|
|
1631
1514
|
|
1632
|
-
|
1633
|
-
HashMap::Entry*
|
1515
|
+
void HeapEntriesMap::AllocateEntries() {
|
1516
|
+
for (HashMap::Entry* p = entries_.Start();
|
1517
|
+
p != NULL;
|
1518
|
+
p = entries_.Next(p)) {
|
1519
|
+
EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(p->value);
|
1520
|
+
entry_info->entry = entry_info->allocator->AllocateEntry(
|
1521
|
+
p->key,
|
1522
|
+
entry_info->children_count,
|
1523
|
+
entry_info->retainers_count);
|
1524
|
+
ASSERT(entry_info->entry != NULL);
|
1525
|
+
ASSERT(entry_info->entry != kHeapEntryPlaceholder);
|
1526
|
+
entry_info->children_count = 0;
|
1527
|
+
entry_info->retainers_count = 0;
|
1528
|
+
}
|
1529
|
+
}
|
1530
|
+
|
1531
|
+
|
1532
|
+
HeapEntry* HeapEntriesMap::Map(HeapThing thing) {
|
1533
|
+
HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), false);
|
1634
1534
|
if (cache_entry != NULL) {
|
1635
1535
|
EntryInfo* entry_info = reinterpret_cast<EntryInfo*>(cache_entry->value);
|
1636
1536
|
return entry_info->entry;
|
@@ -1640,15 +1540,16 @@ HeapEntry* HeapEntriesMap::Map(HeapObject* object) {
|
|
1640
1540
|
}
|
1641
1541
|
|
1642
1542
|
|
1643
|
-
void HeapEntriesMap::Pair(
|
1644
|
-
|
1543
|
+
void HeapEntriesMap::Pair(
|
1544
|
+
HeapThing thing, HeapEntriesAllocator* allocator, HeapEntry* entry) {
|
1545
|
+
HashMap::Entry* cache_entry = entries_.Lookup(thing, Hash(thing), true);
|
1645
1546
|
ASSERT(cache_entry->value == NULL);
|
1646
|
-
cache_entry->value = new EntryInfo(entry);
|
1547
|
+
cache_entry->value = new EntryInfo(entry, allocator);
|
1647
1548
|
++entries_count_;
|
1648
1549
|
}
|
1649
1550
|
|
1650
1551
|
|
1651
|
-
void HeapEntriesMap::CountReference(
|
1552
|
+
void HeapEntriesMap::CountReference(HeapThing from, HeapThing to,
|
1652
1553
|
int* prev_children_count,
|
1653
1554
|
int* prev_retainers_count) {
|
1654
1555
|
HashMap::Entry* from_cache_entry = entries_.Lookup(from, Hash(from), false);
|
@@ -1671,7 +1572,7 @@ void HeapEntriesMap::CountReference(HeapObject* from, HeapObject* to,
|
|
1671
1572
|
|
1672
1573
|
|
1673
1574
|
HeapObjectsSet::HeapObjectsSet()
|
1674
|
-
: entries_(HeapEntriesMap::
|
1575
|
+
: entries_(HeapEntriesMap::HeapThingsMatch) {
|
1675
1576
|
}
|
1676
1577
|
|
1677
1578
|
|
@@ -1700,242 +1601,212 @@ void HeapObjectsSet::Insert(Object* obj) {
|
|
1700
1601
|
}
|
1701
1602
|
|
1702
1603
|
|
1703
|
-
|
1704
|
-
|
1604
|
+
HeapObject *const V8HeapExplorer::kInternalRootObject =
|
1605
|
+
reinterpret_cast<HeapObject*>(
|
1606
|
+
static_cast<intptr_t>(HeapObjectsMap::kInternalRootObjectId));
|
1607
|
+
HeapObject *const V8HeapExplorer::kGcRootsObject =
|
1608
|
+
reinterpret_cast<HeapObject*>(
|
1609
|
+
static_cast<intptr_t>(HeapObjectsMap::kGcRootsObjectId));
|
1610
|
+
|
1611
|
+
|
1612
|
+
V8HeapExplorer::V8HeapExplorer(
|
1613
|
+
HeapSnapshot* snapshot,
|
1614
|
+
SnapshottingProgressReportingInterface* progress)
|
1705
1615
|
: snapshot_(snapshot),
|
1706
|
-
|
1707
|
-
|
1616
|
+
collection_(snapshot_->collection()),
|
1617
|
+
progress_(progress),
|
1708
1618
|
filler_(NULL) {
|
1709
1619
|
}
|
1710
1620
|
|
1711
|
-
class SnapshotCounter : public HeapSnapshotGenerator::SnapshotFillerInterface {
|
1712
|
-
public:
|
1713
|
-
explicit SnapshotCounter(HeapEntriesMap* entries)
|
1714
|
-
: entries_(entries) { }
|
1715
|
-
HeapEntry* AddEntry(HeapObject* obj) {
|
1716
|
-
entries_->Pair(obj, HeapEntriesMap::kHeapEntryPlaceholder);
|
1717
|
-
return HeapEntriesMap::kHeapEntryPlaceholder;
|
1718
|
-
}
|
1719
|
-
void SetIndexedReference(HeapGraphEdge::Type,
|
1720
|
-
HeapObject* parent_obj,
|
1721
|
-
HeapEntry*,
|
1722
|
-
int,
|
1723
|
-
Object* child_obj,
|
1724
|
-
HeapEntry*) {
|
1725
|
-
entries_->CountReference(parent_obj, HeapObject::cast(child_obj));
|
1726
|
-
}
|
1727
|
-
void SetNamedReference(HeapGraphEdge::Type,
|
1728
|
-
HeapObject* parent_obj,
|
1729
|
-
HeapEntry*,
|
1730
|
-
const char*,
|
1731
|
-
Object* child_obj,
|
1732
|
-
HeapEntry*) {
|
1733
|
-
entries_->CountReference(parent_obj, HeapObject::cast(child_obj));
|
1734
|
-
}
|
1735
|
-
void SetRootShortcutReference(Object* child_obj, HeapEntry*) {
|
1736
|
-
entries_->CountReference(
|
1737
|
-
HeapSnapshot::kInternalRootObject, HeapObject::cast(child_obj));
|
1738
|
-
}
|
1739
|
-
void SetRootGcRootsReference() {
|
1740
|
-
entries_->CountReference(
|
1741
|
-
HeapSnapshot::kInternalRootObject, HeapSnapshot::kGcRootsObject);
|
1742
|
-
}
|
1743
|
-
void SetStrongRootReference(Object* child_obj, HeapEntry*) {
|
1744
|
-
entries_->CountReference(
|
1745
|
-
HeapSnapshot::kGcRootsObject, HeapObject::cast(child_obj));
|
1746
|
-
}
|
1747
|
-
private:
|
1748
|
-
HeapEntriesMap* entries_;
|
1749
|
-
};
|
1750
1621
|
|
1622
|
+
V8HeapExplorer::~V8HeapExplorer() {
|
1623
|
+
}
|
1751
1624
|
|
1752
|
-
class SnapshotFiller : public HeapSnapshotGenerator::SnapshotFillerInterface {
|
1753
|
-
public:
|
1754
|
-
explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
|
1755
|
-
: snapshot_(snapshot),
|
1756
|
-
collection_(snapshot->collection()),
|
1757
|
-
entries_(entries) { }
|
1758
|
-
HeapEntry* AddEntry(HeapObject* obj) {
|
1759
|
-
UNREACHABLE();
|
1760
|
-
return NULL;
|
1761
|
-
}
|
1762
|
-
void SetIndexedReference(HeapGraphEdge::Type type,
|
1763
|
-
HeapObject* parent_obj,
|
1764
|
-
HeapEntry* parent_entry,
|
1765
|
-
int index,
|
1766
|
-
Object* child_obj,
|
1767
|
-
HeapEntry* child_entry) {
|
1768
|
-
int child_index, retainer_index;
|
1769
|
-
entries_->CountReference(parent_obj,
|
1770
|
-
HeapObject::cast(child_obj),
|
1771
|
-
&child_index,
|
1772
|
-
&retainer_index);
|
1773
|
-
parent_entry->SetIndexedReference(
|
1774
|
-
type, child_index, index, child_entry, retainer_index);
|
1775
|
-
}
|
1776
|
-
void SetNamedReference(HeapGraphEdge::Type type,
|
1777
|
-
HeapObject* parent_obj,
|
1778
|
-
HeapEntry* parent_entry,
|
1779
|
-
const char* reference_name,
|
1780
|
-
Object* child_obj,
|
1781
|
-
HeapEntry* child_entry) {
|
1782
|
-
int child_index, retainer_index;
|
1783
|
-
entries_->CountReference(parent_obj, HeapObject::cast(child_obj),
|
1784
|
-
&child_index, &retainer_index);
|
1785
|
-
parent_entry->SetNamedReference(type,
|
1786
|
-
child_index,
|
1787
|
-
reference_name,
|
1788
|
-
child_entry,
|
1789
|
-
retainer_index);
|
1790
|
-
}
|
1791
|
-
void SetRootGcRootsReference() {
|
1792
|
-
int child_index, retainer_index;
|
1793
|
-
entries_->CountReference(HeapSnapshot::kInternalRootObject,
|
1794
|
-
HeapSnapshot::kGcRootsObject,
|
1795
|
-
&child_index,
|
1796
|
-
&retainer_index);
|
1797
|
-
snapshot_->root()->SetIndexedReference(HeapGraphEdge::kElement,
|
1798
|
-
child_index,
|
1799
|
-
child_index + 1,
|
1800
|
-
snapshot_->gc_roots(),
|
1801
|
-
retainer_index);
|
1802
|
-
}
|
1803
|
-
void SetRootShortcutReference(Object* child_obj,
|
1804
|
-
HeapEntry* child_entry) {
|
1805
|
-
int child_index, retainer_index;
|
1806
|
-
entries_->CountReference(HeapSnapshot::kInternalRootObject,
|
1807
|
-
HeapObject::cast(child_obj),
|
1808
|
-
&child_index,
|
1809
|
-
&retainer_index);
|
1810
|
-
snapshot_->root()->SetNamedReference(HeapGraphEdge::kShortcut,
|
1811
|
-
child_index,
|
1812
|
-
collection_->GetName(child_index + 1),
|
1813
|
-
child_entry,
|
1814
|
-
retainer_index);
|
1815
|
-
}
|
1816
|
-
void SetStrongRootReference(Object* child_obj,
|
1817
|
-
HeapEntry* child_entry) {
|
1818
|
-
int child_index, retainer_index;
|
1819
|
-
entries_->CountReference(HeapSnapshot::kGcRootsObject,
|
1820
|
-
HeapObject::cast(child_obj),
|
1821
|
-
&child_index,
|
1822
|
-
&retainer_index);
|
1823
|
-
snapshot_->gc_roots()->SetIndexedReference(HeapGraphEdge::kElement,
|
1824
|
-
child_index,
|
1825
|
-
child_index + 1,
|
1826
|
-
child_entry,
|
1827
|
-
retainer_index);
|
1828
|
-
}
|
1829
|
-
private:
|
1830
|
-
HeapSnapshot* snapshot_;
|
1831
|
-
HeapSnapshotsCollection* collection_;
|
1832
|
-
HeapEntriesMap* entries_;
|
1833
|
-
};
|
1834
1625
|
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
HeapObject* obj, int children_count, int retainers_count) {
|
1841
|
-
HeapEntry* entry =
|
1842
|
-
snapshot_->AddEntry(obj, children_count, retainers_count);
|
1843
|
-
ASSERT(entry != NULL);
|
1844
|
-
return entry;
|
1845
|
-
}
|
1846
|
-
private:
|
1847
|
-
HeapSnapshot* snapshot_;
|
1848
|
-
};
|
1849
|
-
|
1850
|
-
class RootsReferencesExtractor : public ObjectVisitor {
|
1851
|
-
public:
|
1852
|
-
explicit RootsReferencesExtractor(HeapSnapshotGenerator* generator)
|
1853
|
-
: generator_(generator) {
|
1854
|
-
}
|
1855
|
-
void VisitPointers(Object** start, Object** end) {
|
1856
|
-
for (Object** p = start; p < end; p++) generator_->SetGcRootsReference(*p);
|
1857
|
-
}
|
1858
|
-
private:
|
1859
|
-
HeapSnapshotGenerator* generator_;
|
1860
|
-
};
|
1626
|
+
HeapEntry* V8HeapExplorer::AllocateEntry(
|
1627
|
+
HeapThing ptr, int children_count, int retainers_count) {
|
1628
|
+
return AddEntry(
|
1629
|
+
reinterpret_cast<HeapObject*>(ptr), children_count, retainers_count);
|
1630
|
+
}
|
1861
1631
|
|
1862
1632
|
|
1863
|
-
|
1864
|
-
|
1633
|
+
HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
|
1634
|
+
int children_count,
|
1635
|
+
int retainers_count) {
|
1636
|
+
if (object == kInternalRootObject) {
|
1637
|
+
ASSERT(retainers_count == 0);
|
1638
|
+
return snapshot_->AddRootEntry(children_count);
|
1639
|
+
} else if (object == kGcRootsObject) {
|
1640
|
+
return snapshot_->AddGcRootsEntry(children_count, retainers_count);
|
1641
|
+
} else if (object->IsJSFunction()) {
|
1642
|
+
JSFunction* func = JSFunction::cast(object);
|
1643
|
+
SharedFunctionInfo* shared = func->shared();
|
1644
|
+
return AddEntry(object,
|
1645
|
+
HeapEntry::kClosure,
|
1646
|
+
collection_->names()->GetName(String::cast(shared->name())),
|
1647
|
+
children_count,
|
1648
|
+
retainers_count);
|
1649
|
+
} else if (object->IsJSRegExp()) {
|
1650
|
+
JSRegExp* re = JSRegExp::cast(object);
|
1651
|
+
return AddEntry(object,
|
1652
|
+
HeapEntry::kRegExp,
|
1653
|
+
collection_->names()->GetName(re->Pattern()),
|
1654
|
+
children_count,
|
1655
|
+
retainers_count);
|
1656
|
+
} else if (object->IsJSObject()) {
|
1657
|
+
return AddEntry(object,
|
1658
|
+
HeapEntry::kObject,
|
1659
|
+
collection_->names()->GetName(
|
1660
|
+
GetConstructorNameForHeapProfile(
|
1661
|
+
JSObject::cast(object))),
|
1662
|
+
children_count,
|
1663
|
+
retainers_count);
|
1664
|
+
} else if (object->IsString()) {
|
1665
|
+
return AddEntry(object,
|
1666
|
+
HeapEntry::kString,
|
1667
|
+
collection_->names()->GetName(String::cast(object)),
|
1668
|
+
children_count,
|
1669
|
+
retainers_count);
|
1670
|
+
} else if (object->IsCode()) {
|
1671
|
+
return AddEntry(object,
|
1672
|
+
HeapEntry::kCode,
|
1673
|
+
"",
|
1674
|
+
children_count,
|
1675
|
+
retainers_count);
|
1676
|
+
} else if (object->IsSharedFunctionInfo()) {
|
1677
|
+
SharedFunctionInfo* shared = SharedFunctionInfo::cast(object);
|
1678
|
+
return AddEntry(object,
|
1679
|
+
HeapEntry::kCode,
|
1680
|
+
collection_->names()->GetName(String::cast(shared->name())),
|
1681
|
+
children_count,
|
1682
|
+
retainers_count);
|
1683
|
+
} else if (object->IsScript()) {
|
1684
|
+
Script* script = Script::cast(object);
|
1685
|
+
return AddEntry(object,
|
1686
|
+
HeapEntry::kCode,
|
1687
|
+
script->name()->IsString() ?
|
1688
|
+
collection_->names()->GetName(
|
1689
|
+
String::cast(script->name()))
|
1690
|
+
: "",
|
1691
|
+
children_count,
|
1692
|
+
retainers_count);
|
1693
|
+
} else if (object->IsFixedArray() || object->IsByteArray()) {
|
1694
|
+
return AddEntry(object,
|
1695
|
+
HeapEntry::kArray,
|
1696
|
+
"",
|
1697
|
+
children_count,
|
1698
|
+
retainers_count);
|
1699
|
+
} else if (object->IsHeapNumber()) {
|
1700
|
+
return AddEntry(object,
|
1701
|
+
HeapEntry::kHeapNumber,
|
1702
|
+
"number",
|
1703
|
+
children_count,
|
1704
|
+
retainers_count);
|
1705
|
+
}
|
1706
|
+
return AddEntry(object,
|
1707
|
+
HeapEntry::kHidden,
|
1708
|
+
GetSystemEntryName(object),
|
1709
|
+
children_count,
|
1710
|
+
retainers_count);
|
1711
|
+
}
|
1865
1712
|
|
1866
|
-
SetProgressTotal(4); // 2 passes + dominators + sizes.
|
1867
1713
|
|
1868
|
-
|
1869
|
-
|
1714
|
+
HeapEntry* V8HeapExplorer::AddEntry(HeapObject* object,
|
1715
|
+
HeapEntry::Type type,
|
1716
|
+
const char* name,
|
1717
|
+
int children_count,
|
1718
|
+
int retainers_count) {
|
1719
|
+
return snapshot_->AddEntry(type,
|
1720
|
+
name,
|
1721
|
+
collection_->GetObjectId(object->address()),
|
1722
|
+
object->Size(),
|
1723
|
+
children_count,
|
1724
|
+
retainers_count);
|
1725
|
+
}
|
1870
1726
|
|
1871
|
-
// Allocate and fill entries in the snapshot, allocate references.
|
1872
|
-
snapshot_->AllocateEntries(entries_.entries_count(),
|
1873
|
-
entries_.total_children_count(),
|
1874
|
-
entries_.total_retainers_count());
|
1875
|
-
SnapshotAllocator allocator(snapshot_);
|
1876
|
-
entries_.UpdateEntries(&allocator);
|
1877
1727
|
|
1878
|
-
|
1879
|
-
|
1728
|
+
void V8HeapExplorer::AddRootEntries(SnapshotFillerInterface* filler) {
|
1729
|
+
filler->AddEntry(kInternalRootObject, this);
|
1730
|
+
filler->AddEntry(kGcRootsObject, this);
|
1731
|
+
}
|
1880
1732
|
|
1881
|
-
if (!SetEntriesDominators()) return false;
|
1882
|
-
if (!ApproximateRetainedSizes()) return false;
|
1883
1733
|
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1734
|
+
const char* V8HeapExplorer::GetSystemEntryName(HeapObject* object) {
|
1735
|
+
switch (object->map()->instance_type()) {
|
1736
|
+
case MAP_TYPE: return "system / Map";
|
1737
|
+
case JS_GLOBAL_PROPERTY_CELL_TYPE: return "system / JSGlobalPropertyCell";
|
1738
|
+
case PROXY_TYPE: return "system / Proxy";
|
1739
|
+
case ODDBALL_TYPE: return "system / Oddball";
|
1740
|
+
#define MAKE_STRUCT_CASE(NAME, Name, name) \
|
1741
|
+
case NAME##_TYPE: return "system / "#Name;
|
1742
|
+
STRUCT_LIST(MAKE_STRUCT_CASE)
|
1743
|
+
#undef MAKE_STRUCT_CASE
|
1744
|
+
default: return "system";
|
1745
|
+
}
|
1887
1746
|
}
|
1888
1747
|
|
1889
1748
|
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1895
|
-
|
1896
|
-
return
|
1749
|
+
int V8HeapExplorer::EstimateObjectsCount() {
|
1750
|
+
HeapIterator iterator(HeapIterator::kFilterUnreachable);
|
1751
|
+
int objects_count = 0;
|
1752
|
+
for (HeapObject* obj = iterator.next();
|
1753
|
+
obj != NULL;
|
1754
|
+
obj = iterator.next(), ++objects_count) {}
|
1755
|
+
return objects_count;
|
1897
1756
|
}
|
1898
1757
|
|
1899
1758
|
|
1900
1759
|
class IndexedReferencesExtractor : public ObjectVisitor {
|
1901
1760
|
public:
|
1902
|
-
IndexedReferencesExtractor(
|
1761
|
+
IndexedReferencesExtractor(V8HeapExplorer* generator,
|
1903
1762
|
HeapObject* parent_obj,
|
1904
|
-
HeapEntry* parent_entry
|
1905
|
-
HeapObjectsSet* known_references = NULL)
|
1763
|
+
HeapEntry* parent_entry)
|
1906
1764
|
: generator_(generator),
|
1907
1765
|
parent_obj_(parent_obj),
|
1908
1766
|
parent_(parent_entry),
|
1909
|
-
known_references_(known_references),
|
1910
1767
|
next_index_(1) {
|
1911
1768
|
}
|
1912
1769
|
void VisitPointers(Object** start, Object** end) {
|
1913
1770
|
for (Object** p = start; p < end; p++) {
|
1914
|
-
if (
|
1915
|
-
|
1916
|
-
}
|
1771
|
+
if (CheckVisitedAndUnmark(p)) continue;
|
1772
|
+
generator_->SetHiddenReference(parent_obj_, parent_, next_index_++, *p);
|
1917
1773
|
}
|
1918
1774
|
}
|
1775
|
+
static void MarkVisitedField(HeapObject* obj, int offset) {
|
1776
|
+
if (offset < 0) return;
|
1777
|
+
Address field = obj->address() + offset;
|
1778
|
+
ASSERT(!Memory::Object_at(field)->IsFailure());
|
1779
|
+
ASSERT(Memory::Object_at(field)->IsHeapObject());
|
1780
|
+
*field |= kFailureTag;
|
1781
|
+
}
|
1919
1782
|
private:
|
1920
|
-
|
1783
|
+
bool CheckVisitedAndUnmark(Object** field) {
|
1784
|
+
if ((*field)->IsFailure()) {
|
1785
|
+
intptr_t untagged = reinterpret_cast<intptr_t>(*field) & ~kFailureTagMask;
|
1786
|
+
*field = reinterpret_cast<Object*>(untagged | kHeapObjectTag);
|
1787
|
+
ASSERT((*field)->IsHeapObject());
|
1788
|
+
return true;
|
1789
|
+
}
|
1790
|
+
return false;
|
1791
|
+
}
|
1792
|
+
V8HeapExplorer* generator_;
|
1921
1793
|
HeapObject* parent_obj_;
|
1922
1794
|
HeapEntry* parent_;
|
1923
|
-
HeapObjectsSet* known_references_;
|
1924
1795
|
int next_index_;
|
1925
1796
|
};
|
1926
1797
|
|
1927
1798
|
|
1928
|
-
void
|
1799
|
+
void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
|
1929
1800
|
HeapEntry* entry = GetEntry(obj);
|
1930
1801
|
if (entry == NULL) return; // No interest in this object.
|
1931
1802
|
|
1932
|
-
known_references_.Clear();
|
1933
1803
|
if (obj->IsJSGlobalProxy()) {
|
1934
1804
|
// We need to reference JS global objects from snapshot's root.
|
1935
1805
|
// We use JSGlobalProxy because this is what embedder (e.g. browser)
|
1936
1806
|
// uses for the global object.
|
1937
1807
|
JSGlobalProxy* proxy = JSGlobalProxy::cast(obj);
|
1938
1808
|
SetRootShortcutReference(proxy->map()->prototype());
|
1809
|
+
SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
|
1939
1810
|
IndexedReferencesExtractor refs_extractor(this, obj, entry);
|
1940
1811
|
obj->Iterate(&refs_extractor);
|
1941
1812
|
} else if (obj->IsJSObject()) {
|
@@ -1945,16 +1816,40 @@ void HeapSnapshotGenerator::ExtractReferences(HeapObject* obj) {
|
|
1945
1816
|
ExtractElementReferences(js_obj, entry);
|
1946
1817
|
ExtractInternalReferences(js_obj, entry);
|
1947
1818
|
SetPropertyReference(
|
1948
|
-
obj, entry,
|
1819
|
+
obj, entry, HEAP->Proto_symbol(), js_obj->GetPrototype());
|
1949
1820
|
if (obj->IsJSFunction()) {
|
1950
|
-
JSFunction* js_fun = JSFunction::cast(
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1821
|
+
JSFunction* js_fun = JSFunction::cast(js_obj);
|
1822
|
+
Object* proto_or_map = js_fun->prototype_or_initial_map();
|
1823
|
+
if (!proto_or_map->IsTheHole()) {
|
1824
|
+
if (!proto_or_map->IsMap()) {
|
1825
|
+
SetPropertyReference(
|
1826
|
+
obj, entry,
|
1827
|
+
HEAP->prototype_symbol(), proto_or_map,
|
1828
|
+
JSFunction::kPrototypeOrInitialMapOffset);
|
1829
|
+
} else {
|
1830
|
+
SetPropertyReference(
|
1831
|
+
obj, entry,
|
1832
|
+
HEAP->prototype_symbol(), js_fun->prototype());
|
1833
|
+
}
|
1954
1834
|
}
|
1835
|
+
SetInternalReference(js_fun, entry,
|
1836
|
+
"shared", js_fun->shared(),
|
1837
|
+
JSFunction::kSharedFunctionInfoOffset);
|
1838
|
+
SetInternalReference(js_fun, entry,
|
1839
|
+
"context", js_fun->unchecked_context(),
|
1840
|
+
JSFunction::kContextOffset);
|
1841
|
+
SetInternalReference(js_fun, entry,
|
1842
|
+
"literals", js_fun->literals(),
|
1843
|
+
JSFunction::kLiteralsOffset);
|
1955
1844
|
}
|
1956
|
-
|
1957
|
-
|
1845
|
+
SetInternalReference(obj, entry,
|
1846
|
+
"properties", js_obj->properties(),
|
1847
|
+
JSObject::kPropertiesOffset);
|
1848
|
+
SetInternalReference(obj, entry,
|
1849
|
+
"elements", js_obj->elements(),
|
1850
|
+
JSObject::kElementsOffset);
|
1851
|
+
SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
|
1852
|
+
IndexedReferencesExtractor refs_extractor(this, obj, entry);
|
1958
1853
|
obj->Iterate(&refs_extractor);
|
1959
1854
|
} else if (obj->IsString()) {
|
1960
1855
|
if (obj->IsConsString()) {
|
@@ -1962,15 +1857,49 @@ void HeapSnapshotGenerator::ExtractReferences(HeapObject* obj) {
|
|
1962
1857
|
SetInternalReference(obj, entry, 1, cs->first());
|
1963
1858
|
SetInternalReference(obj, entry, 2, cs->second());
|
1964
1859
|
}
|
1860
|
+
} else if (obj->IsMap()) {
|
1861
|
+
Map* map = Map::cast(obj);
|
1862
|
+
SetInternalReference(obj, entry,
|
1863
|
+
"prototype", map->prototype(), Map::kPrototypeOffset);
|
1864
|
+
SetInternalReference(obj, entry,
|
1865
|
+
"constructor", map->constructor(),
|
1866
|
+
Map::kConstructorOffset);
|
1867
|
+
SetInternalReference(obj, entry,
|
1868
|
+
"descriptors", map->instance_descriptors(),
|
1869
|
+
Map::kInstanceDescriptorsOffset);
|
1870
|
+
SetInternalReference(obj, entry,
|
1871
|
+
"code_cache", map->code_cache(),
|
1872
|
+
Map::kCodeCacheOffset);
|
1873
|
+
SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
|
1874
|
+
IndexedReferencesExtractor refs_extractor(this, obj, entry);
|
1875
|
+
obj->Iterate(&refs_extractor);
|
1876
|
+
} else if (obj->IsSharedFunctionInfo()) {
|
1877
|
+
SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
|
1878
|
+
SetInternalReference(obj, entry,
|
1879
|
+
"name", shared->name(),
|
1880
|
+
SharedFunctionInfo::kNameOffset);
|
1881
|
+
SetInternalReference(obj, entry,
|
1882
|
+
"code", shared->unchecked_code(),
|
1883
|
+
SharedFunctionInfo::kCodeOffset);
|
1884
|
+
SetInternalReference(obj, entry,
|
1885
|
+
"instance_class_name", shared->instance_class_name(),
|
1886
|
+
SharedFunctionInfo::kInstanceClassNameOffset);
|
1887
|
+
SetInternalReference(obj, entry,
|
1888
|
+
"script", shared->script(),
|
1889
|
+
SharedFunctionInfo::kScriptOffset);
|
1890
|
+
SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
|
1891
|
+
IndexedReferencesExtractor refs_extractor(this, obj, entry);
|
1892
|
+
obj->Iterate(&refs_extractor);
|
1965
1893
|
} else {
|
1894
|
+
SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
|
1966
1895
|
IndexedReferencesExtractor refs_extractor(this, obj, entry);
|
1967
1896
|
obj->Iterate(&refs_extractor);
|
1968
1897
|
}
|
1969
1898
|
}
|
1970
1899
|
|
1971
1900
|
|
1972
|
-
void
|
1973
|
-
|
1901
|
+
void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj,
|
1902
|
+
HeapEntry* entry) {
|
1974
1903
|
if (js_obj->IsJSFunction()) {
|
1975
1904
|
HandleScope hs;
|
1976
1905
|
JSFunction* func = JSFunction::cast(js_obj);
|
@@ -1987,26 +1916,34 @@ void HeapSnapshotGenerator::ExtractClosureReferences(JSObject* js_obj,
|
|
1987
1916
|
SetClosureReference(js_obj, entry, local_name, context->get(idx));
|
1988
1917
|
}
|
1989
1918
|
}
|
1990
|
-
SetInternalReference(js_obj, entry, "code", func->shared());
|
1991
1919
|
}
|
1992
1920
|
}
|
1993
1921
|
|
1994
1922
|
|
1995
|
-
void
|
1996
|
-
|
1923
|
+
void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj,
|
1924
|
+
HeapEntry* entry) {
|
1997
1925
|
if (js_obj->HasFastProperties()) {
|
1998
1926
|
DescriptorArray* descs = js_obj->map()->instance_descriptors();
|
1999
1927
|
for (int i = 0; i < descs->number_of_descriptors(); i++) {
|
2000
1928
|
switch (descs->GetType(i)) {
|
2001
1929
|
case FIELD: {
|
2002
1930
|
int index = descs->GetFieldIndex(i);
|
2003
|
-
|
2004
|
-
|
1931
|
+
if (index < js_obj->map()->inobject_properties()) {
|
1932
|
+
SetPropertyReference(
|
1933
|
+
js_obj, entry,
|
1934
|
+
descs->GetKey(i), js_obj->InObjectPropertyAt(index),
|
1935
|
+
js_obj->GetInObjectPropertyOffset(index));
|
1936
|
+
} else {
|
1937
|
+
SetPropertyReference(
|
1938
|
+
js_obj, entry,
|
1939
|
+
descs->GetKey(i), js_obj->FastPropertyAt(index));
|
1940
|
+
}
|
2005
1941
|
break;
|
2006
1942
|
}
|
2007
1943
|
case CONSTANT_FUNCTION:
|
2008
1944
|
SetPropertyReference(
|
2009
|
-
js_obj, entry,
|
1945
|
+
js_obj, entry,
|
1946
|
+
descs->GetKey(i), descs->GetConstantFunction(i));
|
2010
1947
|
break;
|
2011
1948
|
default: ;
|
2012
1949
|
}
|
@@ -2034,8 +1971,8 @@ void HeapSnapshotGenerator::ExtractPropertyReferences(JSObject* js_obj,
|
|
2034
1971
|
}
|
2035
1972
|
|
2036
1973
|
|
2037
|
-
void
|
2038
|
-
|
1974
|
+
void V8HeapExplorer::ExtractElementReferences(JSObject* js_obj,
|
1975
|
+
HeapEntry* entry) {
|
2039
1976
|
if (js_obj->HasFastElements()) {
|
2040
1977
|
FixedArray* elements = FixedArray::cast(js_obj->elements());
|
2041
1978
|
int length = js_obj->IsJSArray() ?
|
@@ -2061,37 +1998,82 @@ void HeapSnapshotGenerator::ExtractElementReferences(JSObject* js_obj,
|
|
2061
1998
|
}
|
2062
1999
|
|
2063
2000
|
|
2064
|
-
void
|
2065
|
-
|
2001
|
+
void V8HeapExplorer::ExtractInternalReferences(JSObject* js_obj,
|
2002
|
+
HeapEntry* entry) {
|
2066
2003
|
int length = js_obj->GetInternalFieldCount();
|
2067
2004
|
for (int i = 0; i < length; ++i) {
|
2068
2005
|
Object* o = js_obj->GetInternalField(i);
|
2069
|
-
SetInternalReference(
|
2006
|
+
SetInternalReference(
|
2007
|
+
js_obj, entry, i, o, js_obj->GetInternalFieldOffset(i));
|
2070
2008
|
}
|
2071
2009
|
}
|
2072
2010
|
|
2073
2011
|
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2012
|
+
HeapEntry* V8HeapExplorer::GetEntry(Object* obj) {
|
2013
|
+
if (!obj->IsHeapObject()) return NULL;
|
2014
|
+
return filler_->FindOrAddEntry(obj, this);
|
2015
|
+
}
|
2016
|
+
|
2017
|
+
|
2018
|
+
class RootsReferencesExtractor : public ObjectVisitor {
|
2019
|
+
public:
|
2020
|
+
explicit RootsReferencesExtractor(V8HeapExplorer* explorer)
|
2021
|
+
: explorer_(explorer) {
|
2022
|
+
}
|
2023
|
+
void VisitPointers(Object** start, Object** end) {
|
2024
|
+
for (Object** p = start; p < end; p++) explorer_->SetGcRootsReference(*p);
|
2025
|
+
}
|
2026
|
+
private:
|
2027
|
+
V8HeapExplorer* explorer_;
|
2028
|
+
};
|
2029
|
+
|
2030
|
+
|
2031
|
+
bool V8HeapExplorer::IterateAndExtractReferences(
|
2032
|
+
SnapshotFillerInterface* filler) {
|
2033
|
+
filler_ = filler;
|
2034
|
+
HeapIterator iterator(HeapIterator::kFilterUnreachable);
|
2035
|
+
bool interrupted = false;
|
2036
|
+
// Heap iteration with filtering must be finished in any case.
|
2037
|
+
for (HeapObject* obj = iterator.next();
|
2038
|
+
obj != NULL;
|
2039
|
+
obj = iterator.next(), progress_->ProgressStep()) {
|
2040
|
+
if (!interrupted) {
|
2041
|
+
ExtractReferences(obj);
|
2042
|
+
if (!progress_->ProgressReport(false)) interrupted = true;
|
2043
|
+
}
|
2044
|
+
}
|
2045
|
+
if (interrupted) {
|
2046
|
+
filler_ = NULL;
|
2047
|
+
return false;
|
2048
|
+
}
|
2049
|
+
SetRootGcRootsReference();
|
2050
|
+
RootsReferencesExtractor extractor(this);
|
2051
|
+
HEAP->IterateRoots(&extractor, VISIT_ALL);
|
2052
|
+
filler_ = NULL;
|
2053
|
+
return progress_->ProgressReport(false);
|
2054
|
+
}
|
2055
|
+
|
2056
|
+
|
2057
|
+
void V8HeapExplorer::SetClosureReference(HeapObject* parent_obj,
|
2058
|
+
HeapEntry* parent_entry,
|
2059
|
+
String* reference_name,
|
2060
|
+
Object* child_obj) {
|
2078
2061
|
HeapEntry* child_entry = GetEntry(child_obj);
|
2079
2062
|
if (child_entry != NULL) {
|
2080
2063
|
filler_->SetNamedReference(HeapGraphEdge::kContextVariable,
|
2081
2064
|
parent_obj,
|
2082
2065
|
parent_entry,
|
2083
|
-
collection_->GetName(reference_name),
|
2066
|
+
collection_->names()->GetName(reference_name),
|
2084
2067
|
child_obj,
|
2085
2068
|
child_entry);
|
2086
|
-
known_references_.Insert(child_obj);
|
2087
2069
|
}
|
2088
2070
|
}
|
2089
2071
|
|
2090
2072
|
|
2091
|
-
void
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2073
|
+
void V8HeapExplorer::SetElementReference(HeapObject* parent_obj,
|
2074
|
+
HeapEntry* parent_entry,
|
2075
|
+
int index,
|
2076
|
+
Object* child_obj) {
|
2095
2077
|
HeapEntry* child_entry = GetEntry(child_obj);
|
2096
2078
|
if (child_entry != NULL) {
|
2097
2079
|
filler_->SetIndexedReference(HeapGraphEdge::kElement,
|
@@ -2100,15 +2082,15 @@ void HeapSnapshotGenerator::SetElementReference(HeapObject* parent_obj,
|
|
2100
2082
|
index,
|
2101
2083
|
child_obj,
|
2102
2084
|
child_entry);
|
2103
|
-
known_references_.Insert(child_obj);
|
2104
2085
|
}
|
2105
2086
|
}
|
2106
2087
|
|
2107
2088
|
|
2108
|
-
void
|
2109
|
-
|
2110
|
-
|
2111
|
-
|
2089
|
+
void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
|
2090
|
+
HeapEntry* parent_entry,
|
2091
|
+
const char* reference_name,
|
2092
|
+
Object* child_obj,
|
2093
|
+
int field_offset) {
|
2112
2094
|
HeapEntry* child_entry = GetEntry(child_obj);
|
2113
2095
|
if (child_entry != NULL) {
|
2114
2096
|
filler_->SetNamedReference(HeapGraphEdge::kInternal,
|
@@ -2117,32 +2099,33 @@ void HeapSnapshotGenerator::SetInternalReference(HeapObject* parent_obj,
|
|
2117
2099
|
reference_name,
|
2118
2100
|
child_obj,
|
2119
2101
|
child_entry);
|
2120
|
-
|
2102
|
+
IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
|
2121
2103
|
}
|
2122
2104
|
}
|
2123
2105
|
|
2124
2106
|
|
2125
|
-
void
|
2126
|
-
|
2127
|
-
|
2128
|
-
|
2107
|
+
void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
|
2108
|
+
HeapEntry* parent_entry,
|
2109
|
+
int index,
|
2110
|
+
Object* child_obj,
|
2111
|
+
int field_offset) {
|
2129
2112
|
HeapEntry* child_entry = GetEntry(child_obj);
|
2130
2113
|
if (child_entry != NULL) {
|
2131
2114
|
filler_->SetNamedReference(HeapGraphEdge::kInternal,
|
2132
2115
|
parent_obj,
|
2133
2116
|
parent_entry,
|
2134
|
-
collection_->GetName(index),
|
2117
|
+
collection_->names()->GetName(index),
|
2135
2118
|
child_obj,
|
2136
2119
|
child_entry);
|
2137
|
-
|
2120
|
+
IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
|
2138
2121
|
}
|
2139
2122
|
}
|
2140
2123
|
|
2141
2124
|
|
2142
|
-
void
|
2143
|
-
|
2144
|
-
|
2145
|
-
|
2125
|
+
void V8HeapExplorer::SetHiddenReference(HeapObject* parent_obj,
|
2126
|
+
HeapEntry* parent_entry,
|
2127
|
+
int index,
|
2128
|
+
Object* child_obj) {
|
2146
2129
|
HeapEntry* child_entry = GetEntry(child_obj);
|
2147
2130
|
if (child_entry != NULL) {
|
2148
2131
|
filler_->SetIndexedReference(HeapGraphEdge::kHidden,
|
@@ -2155,10 +2138,11 @@ void HeapSnapshotGenerator::SetHiddenReference(HeapObject* parent_obj,
|
|
2155
2138
|
}
|
2156
2139
|
|
2157
2140
|
|
2158
|
-
void
|
2159
|
-
|
2160
|
-
|
2161
|
-
|
2141
|
+
void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
|
2142
|
+
HeapEntry* parent_entry,
|
2143
|
+
String* reference_name,
|
2144
|
+
Object* child_obj,
|
2145
|
+
int field_offset) {
|
2162
2146
|
HeapEntry* child_entry = GetEntry(child_obj);
|
2163
2147
|
if (child_entry != NULL) {
|
2164
2148
|
HeapGraphEdge::Type type = reference_name->length() > 0 ?
|
@@ -2166,77 +2150,446 @@ void HeapSnapshotGenerator::SetPropertyReference(HeapObject* parent_obj,
|
|
2166
2150
|
filler_->SetNamedReference(type,
|
2167
2151
|
parent_obj,
|
2168
2152
|
parent_entry,
|
2169
|
-
collection_->GetName(reference_name),
|
2153
|
+
collection_->names()->GetName(reference_name),
|
2170
2154
|
child_obj,
|
2171
2155
|
child_entry);
|
2172
|
-
|
2156
|
+
IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
|
2173
2157
|
}
|
2174
2158
|
}
|
2175
2159
|
|
2176
2160
|
|
2177
|
-
void
|
2178
|
-
|
2179
|
-
|
2180
|
-
|
2181
|
-
Object* child_obj) {
|
2161
|
+
void V8HeapExplorer::SetPropertyShortcutReference(HeapObject* parent_obj,
|
2162
|
+
HeapEntry* parent_entry,
|
2163
|
+
String* reference_name,
|
2164
|
+
Object* child_obj) {
|
2182
2165
|
HeapEntry* child_entry = GetEntry(child_obj);
|
2183
2166
|
if (child_entry != NULL) {
|
2184
2167
|
filler_->SetNamedReference(HeapGraphEdge::kShortcut,
|
2185
2168
|
parent_obj,
|
2186
2169
|
parent_entry,
|
2187
|
-
collection_->GetName(reference_name),
|
2170
|
+
collection_->names()->GetName(reference_name),
|
2188
2171
|
child_obj,
|
2189
2172
|
child_entry);
|
2190
2173
|
}
|
2191
2174
|
}
|
2192
2175
|
|
2193
2176
|
|
2194
|
-
void
|
2195
|
-
filler_->
|
2177
|
+
void V8HeapExplorer::SetRootGcRootsReference() {
|
2178
|
+
filler_->SetIndexedAutoIndexReference(
|
2179
|
+
HeapGraphEdge::kElement,
|
2180
|
+
kInternalRootObject, snapshot_->root(),
|
2181
|
+
kGcRootsObject, snapshot_->gc_roots());
|
2196
2182
|
}
|
2197
2183
|
|
2198
2184
|
|
2199
|
-
void
|
2185
|
+
void V8HeapExplorer::SetRootShortcutReference(Object* child_obj) {
|
2200
2186
|
HeapEntry* child_entry = GetEntry(child_obj);
|
2201
2187
|
ASSERT(child_entry != NULL);
|
2202
|
-
filler_->
|
2188
|
+
filler_->SetNamedAutoIndexReference(
|
2189
|
+
HeapGraphEdge::kShortcut,
|
2190
|
+
kInternalRootObject, snapshot_->root(),
|
2191
|
+
child_obj, child_entry);
|
2203
2192
|
}
|
2204
2193
|
|
2205
2194
|
|
2206
|
-
void
|
2195
|
+
void V8HeapExplorer::SetGcRootsReference(Object* child_obj) {
|
2207
2196
|
HeapEntry* child_entry = GetEntry(child_obj);
|
2208
2197
|
if (child_entry != NULL) {
|
2209
|
-
filler_->
|
2198
|
+
filler_->SetIndexedAutoIndexReference(
|
2199
|
+
HeapGraphEdge::kElement,
|
2200
|
+
kGcRootsObject, snapshot_->gc_roots(),
|
2201
|
+
child_obj, child_entry);
|
2202
|
+
}
|
2203
|
+
}
|
2204
|
+
|
2205
|
+
|
2206
|
+
class GlobalHandlesExtractor : public ObjectVisitor {
|
2207
|
+
public:
|
2208
|
+
explicit GlobalHandlesExtractor(NativeObjectsExplorer* explorer)
|
2209
|
+
: explorer_(explorer) {}
|
2210
|
+
virtual ~GlobalHandlesExtractor() {}
|
2211
|
+
virtual void VisitPointers(Object** start, Object** end) {
|
2212
|
+
UNREACHABLE();
|
2213
|
+
}
|
2214
|
+
virtual void VisitEmbedderReference(Object** p, uint16_t class_id) {
|
2215
|
+
explorer_->VisitSubtreeWrapper(p, class_id);
|
2216
|
+
}
|
2217
|
+
private:
|
2218
|
+
NativeObjectsExplorer* explorer_;
|
2219
|
+
};
|
2220
|
+
|
2221
|
+
HeapThing const NativeObjectsExplorer::kNativesRootObject =
|
2222
|
+
reinterpret_cast<HeapThing>(
|
2223
|
+
static_cast<intptr_t>(HeapObjectsMap::kNativesRootObjectId));
|
2224
|
+
|
2225
|
+
|
2226
|
+
NativeObjectsExplorer::NativeObjectsExplorer(
|
2227
|
+
HeapSnapshot* snapshot, SnapshottingProgressReportingInterface* progress)
|
2228
|
+
: snapshot_(snapshot),
|
2229
|
+
collection_(snapshot_->collection()),
|
2230
|
+
progress_(progress),
|
2231
|
+
embedder_queried_(false),
|
2232
|
+
objects_by_info_(RetainedInfosMatch),
|
2233
|
+
filler_(NULL) {
|
2234
|
+
}
|
2235
|
+
|
2236
|
+
|
2237
|
+
NativeObjectsExplorer::~NativeObjectsExplorer() {
|
2238
|
+
for (HashMap::Entry* p = objects_by_info_.Start();
|
2239
|
+
p != NULL;
|
2240
|
+
p = objects_by_info_.Next(p)) {
|
2241
|
+
v8::RetainedObjectInfo* info =
|
2242
|
+
reinterpret_cast<v8::RetainedObjectInfo*>(p->key);
|
2243
|
+
info->Dispose();
|
2244
|
+
List<HeapObject*>* objects =
|
2245
|
+
reinterpret_cast<List<HeapObject*>* >(p->value);
|
2246
|
+
delete objects;
|
2247
|
+
}
|
2248
|
+
}
|
2249
|
+
|
2250
|
+
|
2251
|
+
HeapEntry* NativeObjectsExplorer::AllocateEntry(
|
2252
|
+
HeapThing ptr, int children_count, int retainers_count) {
|
2253
|
+
if (ptr == kNativesRootObject) {
|
2254
|
+
return snapshot_->AddNativesRootEntry(children_count, retainers_count);
|
2255
|
+
} else {
|
2256
|
+
v8::RetainedObjectInfo* info =
|
2257
|
+
reinterpret_cast<v8::RetainedObjectInfo*>(ptr);
|
2258
|
+
intptr_t elements = info->GetElementCount();
|
2259
|
+
intptr_t size = info->GetSizeInBytes();
|
2260
|
+
return snapshot_->AddEntry(
|
2261
|
+
HeapEntry::kNative,
|
2262
|
+
elements != -1 ?
|
2263
|
+
collection_->names()->GetFormatted(
|
2264
|
+
"%s / %" V8_PTR_PREFIX "d entries",
|
2265
|
+
info->GetLabel(),
|
2266
|
+
info->GetElementCount()) :
|
2267
|
+
collection_->names()->GetCopy(info->GetLabel()),
|
2268
|
+
HeapObjectsMap::GenerateId(info),
|
2269
|
+
size != -1 ? static_cast<int>(size) : 0,
|
2270
|
+
children_count,
|
2271
|
+
retainers_count);
|
2272
|
+
}
|
2273
|
+
}
|
2274
|
+
|
2275
|
+
|
2276
|
+
void NativeObjectsExplorer::AddRootEntries(SnapshotFillerInterface* filler) {
|
2277
|
+
if (EstimateObjectsCount() <= 0) return;
|
2278
|
+
filler->AddEntry(kNativesRootObject, this);
|
2279
|
+
}
|
2280
|
+
|
2281
|
+
|
2282
|
+
int NativeObjectsExplorer::EstimateObjectsCount() {
|
2283
|
+
FillRetainedObjects();
|
2284
|
+
return objects_by_info_.occupancy();
|
2285
|
+
}
|
2286
|
+
|
2287
|
+
|
2288
|
+
void NativeObjectsExplorer::FillRetainedObjects() {
|
2289
|
+
if (embedder_queried_) return;
|
2290
|
+
Isolate* isolate = Isolate::Current();
|
2291
|
+
// Record objects that are joined into ObjectGroups.
|
2292
|
+
isolate->heap()->CallGlobalGCPrologueCallback();
|
2293
|
+
List<ObjectGroup*>* groups = isolate->global_handles()->object_groups();
|
2294
|
+
for (int i = 0; i < groups->length(); ++i) {
|
2295
|
+
ObjectGroup* group = groups->at(i);
|
2296
|
+
if (group->info_ == NULL) continue;
|
2297
|
+
List<HeapObject*>* list = GetListMaybeDisposeInfo(group->info_);
|
2298
|
+
for (int j = 0; j < group->objects_.length(); ++j) {
|
2299
|
+
HeapObject* obj = HeapObject::cast(*group->objects_[j]);
|
2300
|
+
list->Add(obj);
|
2301
|
+
in_groups_.Insert(obj);
|
2302
|
+
}
|
2303
|
+
group->info_ = NULL; // Acquire info object ownership.
|
2304
|
+
}
|
2305
|
+
isolate->global_handles()->RemoveObjectGroups();
|
2306
|
+
isolate->heap()->CallGlobalGCEpilogueCallback();
|
2307
|
+
// Record objects that are not in ObjectGroups, but have class ID.
|
2308
|
+
GlobalHandlesExtractor extractor(this);
|
2309
|
+
isolate->global_handles()->IterateAllRootsWithClassIds(&extractor);
|
2310
|
+
embedder_queried_ = true;
|
2311
|
+
}
|
2312
|
+
|
2313
|
+
|
2314
|
+
List<HeapObject*>* NativeObjectsExplorer::GetListMaybeDisposeInfo(
|
2315
|
+
v8::RetainedObjectInfo* info) {
|
2316
|
+
HashMap::Entry* entry =
|
2317
|
+
objects_by_info_.Lookup(info, InfoHash(info), true);
|
2318
|
+
if (entry->value != NULL) {
|
2319
|
+
info->Dispose();
|
2320
|
+
} else {
|
2321
|
+
entry->value = new List<HeapObject*>(4);
|
2322
|
+
}
|
2323
|
+
return reinterpret_cast<List<HeapObject*>* >(entry->value);
|
2324
|
+
}
|
2325
|
+
|
2326
|
+
|
2327
|
+
bool NativeObjectsExplorer::IterateAndExtractReferences(
|
2328
|
+
SnapshotFillerInterface* filler) {
|
2329
|
+
if (EstimateObjectsCount() <= 0) return true;
|
2330
|
+
filler_ = filler;
|
2331
|
+
FillRetainedObjects();
|
2332
|
+
for (HashMap::Entry* p = objects_by_info_.Start();
|
2333
|
+
p != NULL;
|
2334
|
+
p = objects_by_info_.Next(p)) {
|
2335
|
+
v8::RetainedObjectInfo* info =
|
2336
|
+
reinterpret_cast<v8::RetainedObjectInfo*>(p->key);
|
2337
|
+
SetNativeRootReference(info);
|
2338
|
+
List<HeapObject*>* objects =
|
2339
|
+
reinterpret_cast<List<HeapObject*>* >(p->value);
|
2340
|
+
for (int i = 0; i < objects->length(); ++i) {
|
2341
|
+
SetWrapperNativeReferences(objects->at(i), info);
|
2342
|
+
}
|
2343
|
+
}
|
2344
|
+
SetRootNativesRootReference();
|
2345
|
+
filler_ = NULL;
|
2346
|
+
return true;
|
2347
|
+
}
|
2348
|
+
|
2349
|
+
|
2350
|
+
void NativeObjectsExplorer::SetNativeRootReference(
|
2351
|
+
v8::RetainedObjectInfo* info) {
|
2352
|
+
HeapEntry* child_entry = filler_->FindOrAddEntry(info, this);
|
2353
|
+
ASSERT(child_entry != NULL);
|
2354
|
+
filler_->SetIndexedAutoIndexReference(
|
2355
|
+
HeapGraphEdge::kElement,
|
2356
|
+
kNativesRootObject, snapshot_->natives_root(),
|
2357
|
+
info, child_entry);
|
2358
|
+
}
|
2359
|
+
|
2360
|
+
|
2361
|
+
void NativeObjectsExplorer::SetWrapperNativeReferences(
|
2362
|
+
HeapObject* wrapper, v8::RetainedObjectInfo* info) {
|
2363
|
+
HeapEntry* wrapper_entry = filler_->FindEntry(wrapper);
|
2364
|
+
ASSERT(wrapper_entry != NULL);
|
2365
|
+
HeapEntry* info_entry = filler_->FindOrAddEntry(info, this);
|
2366
|
+
ASSERT(info_entry != NULL);
|
2367
|
+
filler_->SetNamedReference(HeapGraphEdge::kInternal,
|
2368
|
+
wrapper, wrapper_entry,
|
2369
|
+
"native",
|
2370
|
+
info, info_entry);
|
2371
|
+
filler_->SetIndexedAutoIndexReference(HeapGraphEdge::kElement,
|
2372
|
+
info, info_entry,
|
2373
|
+
wrapper, wrapper_entry);
|
2374
|
+
}
|
2375
|
+
|
2376
|
+
|
2377
|
+
void NativeObjectsExplorer::SetRootNativesRootReference() {
|
2378
|
+
filler_->SetIndexedAutoIndexReference(
|
2379
|
+
HeapGraphEdge::kElement,
|
2380
|
+
V8HeapExplorer::kInternalRootObject, snapshot_->root(),
|
2381
|
+
kNativesRootObject, snapshot_->natives_root());
|
2382
|
+
}
|
2383
|
+
|
2384
|
+
|
2385
|
+
void NativeObjectsExplorer::VisitSubtreeWrapper(Object** p, uint16_t class_id) {
|
2386
|
+
if (in_groups_.Contains(*p)) return;
|
2387
|
+
Isolate* isolate = Isolate::Current();
|
2388
|
+
v8::RetainedObjectInfo* info =
|
2389
|
+
isolate->heap_profiler()->ExecuteWrapperClassCallback(class_id, p);
|
2390
|
+
if (info == NULL) return;
|
2391
|
+
GetListMaybeDisposeInfo(info)->Add(HeapObject::cast(*p));
|
2392
|
+
}
|
2393
|
+
|
2394
|
+
|
2395
|
+
HeapSnapshotGenerator::HeapSnapshotGenerator(HeapSnapshot* snapshot,
|
2396
|
+
v8::ActivityControl* control)
|
2397
|
+
: snapshot_(snapshot),
|
2398
|
+
control_(control),
|
2399
|
+
v8_heap_explorer_(snapshot_, this),
|
2400
|
+
dom_explorer_(snapshot_, this) {
|
2401
|
+
}
|
2402
|
+
|
2403
|
+
|
2404
|
+
class SnapshotCounter : public SnapshotFillerInterface {
|
2405
|
+
public:
|
2406
|
+
explicit SnapshotCounter(HeapEntriesMap* entries) : entries_(entries) { }
|
2407
|
+
HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
|
2408
|
+
entries_->Pair(ptr, allocator, HeapEntriesMap::kHeapEntryPlaceholder);
|
2409
|
+
return HeapEntriesMap::kHeapEntryPlaceholder;
|
2410
|
+
}
|
2411
|
+
HeapEntry* FindEntry(HeapThing ptr) {
|
2412
|
+
return entries_->Map(ptr);
|
2413
|
+
}
|
2414
|
+
HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
|
2415
|
+
HeapEntry* entry = FindEntry(ptr);
|
2416
|
+
return entry != NULL ? entry : AddEntry(ptr, allocator);
|
2417
|
+
}
|
2418
|
+
void SetIndexedReference(HeapGraphEdge::Type,
|
2419
|
+
HeapThing parent_ptr,
|
2420
|
+
HeapEntry*,
|
2421
|
+
int,
|
2422
|
+
HeapThing child_ptr,
|
2423
|
+
HeapEntry*) {
|
2424
|
+
entries_->CountReference(parent_ptr, child_ptr);
|
2425
|
+
}
|
2426
|
+
void SetIndexedAutoIndexReference(HeapGraphEdge::Type,
|
2427
|
+
HeapThing parent_ptr,
|
2428
|
+
HeapEntry*,
|
2429
|
+
HeapThing child_ptr,
|
2430
|
+
HeapEntry*) {
|
2431
|
+
entries_->CountReference(parent_ptr, child_ptr);
|
2432
|
+
}
|
2433
|
+
void SetNamedReference(HeapGraphEdge::Type,
|
2434
|
+
HeapThing parent_ptr,
|
2435
|
+
HeapEntry*,
|
2436
|
+
const char*,
|
2437
|
+
HeapThing child_ptr,
|
2438
|
+
HeapEntry*) {
|
2439
|
+
entries_->CountReference(parent_ptr, child_ptr);
|
2440
|
+
}
|
2441
|
+
void SetNamedAutoIndexReference(HeapGraphEdge::Type,
|
2442
|
+
HeapThing parent_ptr,
|
2443
|
+
HeapEntry*,
|
2444
|
+
HeapThing child_ptr,
|
2445
|
+
HeapEntry*) {
|
2446
|
+
entries_->CountReference(parent_ptr, child_ptr);
|
2447
|
+
}
|
2448
|
+
private:
|
2449
|
+
HeapEntriesMap* entries_;
|
2450
|
+
};
|
2451
|
+
|
2452
|
+
|
2453
|
+
class SnapshotFiller : public SnapshotFillerInterface {
|
2454
|
+
public:
|
2455
|
+
explicit SnapshotFiller(HeapSnapshot* snapshot, HeapEntriesMap* entries)
|
2456
|
+
: snapshot_(snapshot),
|
2457
|
+
collection_(snapshot->collection()),
|
2458
|
+
entries_(entries) { }
|
2459
|
+
HeapEntry* AddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
|
2460
|
+
UNREACHABLE();
|
2461
|
+
return NULL;
|
2462
|
+
}
|
2463
|
+
HeapEntry* FindEntry(HeapThing ptr) {
|
2464
|
+
return entries_->Map(ptr);
|
2465
|
+
}
|
2466
|
+
HeapEntry* FindOrAddEntry(HeapThing ptr, HeapEntriesAllocator* allocator) {
|
2467
|
+
HeapEntry* entry = FindEntry(ptr);
|
2468
|
+
return entry != NULL ? entry : AddEntry(ptr, allocator);
|
2469
|
+
}
|
2470
|
+
void SetIndexedReference(HeapGraphEdge::Type type,
|
2471
|
+
HeapThing parent_ptr,
|
2472
|
+
HeapEntry* parent_entry,
|
2473
|
+
int index,
|
2474
|
+
HeapThing child_ptr,
|
2475
|
+
HeapEntry* child_entry) {
|
2476
|
+
int child_index, retainer_index;
|
2477
|
+
entries_->CountReference(
|
2478
|
+
parent_ptr, child_ptr, &child_index, &retainer_index);
|
2479
|
+
parent_entry->SetIndexedReference(
|
2480
|
+
type, child_index, index, child_entry, retainer_index);
|
2481
|
+
}
|
2482
|
+
void SetIndexedAutoIndexReference(HeapGraphEdge::Type type,
|
2483
|
+
HeapThing parent_ptr,
|
2484
|
+
HeapEntry* parent_entry,
|
2485
|
+
HeapThing child_ptr,
|
2486
|
+
HeapEntry* child_entry) {
|
2487
|
+
int child_index, retainer_index;
|
2488
|
+
entries_->CountReference(
|
2489
|
+
parent_ptr, child_ptr, &child_index, &retainer_index);
|
2490
|
+
parent_entry->SetIndexedReference(
|
2491
|
+
type, child_index, child_index + 1, child_entry, retainer_index);
|
2492
|
+
}
|
2493
|
+
void SetNamedReference(HeapGraphEdge::Type type,
|
2494
|
+
HeapThing parent_ptr,
|
2495
|
+
HeapEntry* parent_entry,
|
2496
|
+
const char* reference_name,
|
2497
|
+
HeapThing child_ptr,
|
2498
|
+
HeapEntry* child_entry) {
|
2499
|
+
int child_index, retainer_index;
|
2500
|
+
entries_->CountReference(
|
2501
|
+
parent_ptr, child_ptr, &child_index, &retainer_index);
|
2502
|
+
parent_entry->SetNamedReference(
|
2503
|
+
type, child_index, reference_name, child_entry, retainer_index);
|
2504
|
+
}
|
2505
|
+
void SetNamedAutoIndexReference(HeapGraphEdge::Type type,
|
2506
|
+
HeapThing parent_ptr,
|
2507
|
+
HeapEntry* parent_entry,
|
2508
|
+
HeapThing child_ptr,
|
2509
|
+
HeapEntry* child_entry) {
|
2510
|
+
int child_index, retainer_index;
|
2511
|
+
entries_->CountReference(
|
2512
|
+
parent_ptr, child_ptr, &child_index, &retainer_index);
|
2513
|
+
parent_entry->SetNamedReference(type,
|
2514
|
+
child_index,
|
2515
|
+
collection_->names()->GetName(child_index + 1),
|
2516
|
+
child_entry,
|
2517
|
+
retainer_index);
|
2210
2518
|
}
|
2519
|
+
private:
|
2520
|
+
HeapSnapshot* snapshot_;
|
2521
|
+
HeapSnapshotsCollection* collection_;
|
2522
|
+
HeapEntriesMap* entries_;
|
2523
|
+
};
|
2524
|
+
|
2525
|
+
|
2526
|
+
bool HeapSnapshotGenerator::GenerateSnapshot() {
|
2527
|
+
AssertNoAllocation no_alloc;
|
2528
|
+
|
2529
|
+
SetProgressTotal(4); // 2 passes + dominators + sizes.
|
2530
|
+
|
2531
|
+
// Pass 1. Iterate heap contents to count entries and references.
|
2532
|
+
if (!CountEntriesAndReferences()) return false;
|
2533
|
+
|
2534
|
+
// Allocate and fill entries in the snapshot, allocate references.
|
2535
|
+
snapshot_->AllocateEntries(entries_.entries_count(),
|
2536
|
+
entries_.total_children_count(),
|
2537
|
+
entries_.total_retainers_count());
|
2538
|
+
entries_.AllocateEntries();
|
2539
|
+
|
2540
|
+
// Pass 2. Fill references.
|
2541
|
+
if (!FillReferences()) return false;
|
2542
|
+
|
2543
|
+
if (!SetEntriesDominators()) return false;
|
2544
|
+
if (!ApproximateRetainedSizes()) return false;
|
2545
|
+
|
2546
|
+
progress_counter_ = progress_total_;
|
2547
|
+
if (!ProgressReport(true)) return false;
|
2548
|
+
return true;
|
2549
|
+
}
|
2550
|
+
|
2551
|
+
|
2552
|
+
void HeapSnapshotGenerator::ProgressStep() {
|
2553
|
+
++progress_counter_;
|
2554
|
+
}
|
2555
|
+
|
2556
|
+
|
2557
|
+
bool HeapSnapshotGenerator::ProgressReport(bool force) {
|
2558
|
+
const int kProgressReportGranularity = 10000;
|
2559
|
+
if (control_ != NULL
|
2560
|
+
&& (force || progress_counter_ % kProgressReportGranularity == 0)) {
|
2561
|
+
return
|
2562
|
+
control_->ReportProgressValue(progress_counter_, progress_total_) ==
|
2563
|
+
v8::ActivityControl::kContinue;
|
2564
|
+
}
|
2565
|
+
return true;
|
2211
2566
|
}
|
2212
2567
|
|
2213
2568
|
|
2214
2569
|
void HeapSnapshotGenerator::SetProgressTotal(int iterations_count) {
|
2215
2570
|
if (control_ == NULL) return;
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
2219
|
-
for (HeapObject* obj = iterator.next();
|
2220
|
-
obj != NULL;
|
2221
|
-
obj = iterator.next(), ++objects_count) {}
|
2222
|
-
progress_total_ = objects_count * iterations_count;
|
2571
|
+
progress_total_ = (
|
2572
|
+
v8_heap_explorer_.EstimateObjectsCount() +
|
2573
|
+
dom_explorer_.EstimateObjectsCount()) * iterations_count;
|
2223
2574
|
progress_counter_ = 0;
|
2224
2575
|
}
|
2225
2576
|
|
2226
2577
|
|
2227
2578
|
bool HeapSnapshotGenerator::CountEntriesAndReferences() {
|
2228
2579
|
SnapshotCounter counter(&entries_);
|
2229
|
-
|
2230
|
-
|
2231
|
-
|
2232
|
-
|
2580
|
+
v8_heap_explorer_.AddRootEntries(&counter);
|
2581
|
+
dom_explorer_.AddRootEntries(&counter);
|
2582
|
+
return
|
2583
|
+
v8_heap_explorer_.IterateAndExtractReferences(&counter) &&
|
2584
|
+
dom_explorer_.IterateAndExtractReferences(&counter);
|
2233
2585
|
}
|
2234
2586
|
|
2235
2587
|
|
2236
2588
|
bool HeapSnapshotGenerator::FillReferences() {
|
2237
2589
|
SnapshotFiller filler(snapshot_, &entries_);
|
2238
|
-
|
2239
|
-
|
2590
|
+
return
|
2591
|
+
v8_heap_explorer_.IterateAndExtractReferences(&filler) &&
|
2592
|
+
dom_explorer_.IterateAndExtractReferences(&filler);
|
2240
2593
|
}
|
2241
2594
|
|
2242
2595
|
|
@@ -2322,7 +2675,7 @@ bool HeapSnapshotGenerator::BuildDominatorTree(
|
|
2322
2675
|
int remaining = entries_length - changed;
|
2323
2676
|
if (remaining < 0) remaining = 0;
|
2324
2677
|
progress_counter_ = base_progress_counter + remaining;
|
2325
|
-
if (!
|
2678
|
+
if (!ProgressReport(true)) return false;
|
2326
2679
|
}
|
2327
2680
|
return true;
|
2328
2681
|
}
|
@@ -2352,7 +2705,7 @@ bool HeapSnapshotGenerator::ApproximateRetainedSizes() {
|
|
2352
2705
|
}
|
2353
2706
|
for (int i = 0;
|
2354
2707
|
i < snapshot_->entries()->length();
|
2355
|
-
++i,
|
2708
|
+
++i, ProgressStep()) {
|
2356
2709
|
HeapEntry* entry = snapshot_->entries()->at(i);
|
2357
2710
|
int entry_size = entry->self_size();
|
2358
2711
|
for (HeapEntry* dominator = entry->dominator();
|
@@ -2360,109 +2713,12 @@ bool HeapSnapshotGenerator::ApproximateRetainedSizes() {
|
|
2360
2713
|
entry = dominator, dominator = entry->dominator()) {
|
2361
2714
|
dominator->add_retained_size(entry_size);
|
2362
2715
|
}
|
2363
|
-
if (!
|
2716
|
+
if (!ProgressReport()) return false;
|
2364
2717
|
}
|
2365
2718
|
return true;
|
2366
2719
|
}
|
2367
2720
|
|
2368
2721
|
|
2369
|
-
bool HeapSnapshotGenerator::IterateAndExtractReferences() {
|
2370
|
-
HeapIterator iterator(HeapIterator::kFilterUnreachable);
|
2371
|
-
bool interrupted = false;
|
2372
|
-
// Heap iteration with filtering must be finished in any case.
|
2373
|
-
for (HeapObject* obj = iterator.next();
|
2374
|
-
obj != NULL;
|
2375
|
-
obj = iterator.next(), IncProgressCounter()) {
|
2376
|
-
if (!interrupted) {
|
2377
|
-
ExtractReferences(obj);
|
2378
|
-
if (!ReportProgress()) interrupted = true;
|
2379
|
-
}
|
2380
|
-
}
|
2381
|
-
if (interrupted) return false;
|
2382
|
-
SetRootGcRootsReference();
|
2383
|
-
RootsReferencesExtractor extractor(this);
|
2384
|
-
Heap::IterateRoots(&extractor, VISIT_ALL);
|
2385
|
-
return ReportProgress();
|
2386
|
-
}
|
2387
|
-
|
2388
|
-
|
2389
|
-
void HeapSnapshotsDiff::CreateRoots(int additions_count, int deletions_count) {
|
2390
|
-
raw_additions_root_ =
|
2391
|
-
NewArray<char>(HeapEntry::EntriesSize(1, additions_count, 0));
|
2392
|
-
additions_root()->Init(
|
2393
|
-
snapshot2_, HeapEntry::kHidden, "", 0, 0, additions_count, 0);
|
2394
|
-
raw_deletions_root_ =
|
2395
|
-
NewArray<char>(HeapEntry::EntriesSize(1, deletions_count, 0));
|
2396
|
-
deletions_root()->Init(
|
2397
|
-
snapshot1_, HeapEntry::kHidden, "", 0, 0, deletions_count, 0);
|
2398
|
-
}
|
2399
|
-
|
2400
|
-
|
2401
|
-
static void DeleteHeapSnapshotsDiff(HeapSnapshotsDiff** diff_ptr) {
|
2402
|
-
delete *diff_ptr;
|
2403
|
-
}
|
2404
|
-
|
2405
|
-
HeapSnapshotsComparator::~HeapSnapshotsComparator() {
|
2406
|
-
diffs_.Iterate(DeleteHeapSnapshotsDiff);
|
2407
|
-
}
|
2408
|
-
|
2409
|
-
|
2410
|
-
HeapSnapshotsDiff* HeapSnapshotsComparator::Compare(HeapSnapshot* snapshot1,
|
2411
|
-
HeapSnapshot* snapshot2) {
|
2412
|
-
snapshot1->ClearPaint();
|
2413
|
-
snapshot1->root()->PaintAllReachable();
|
2414
|
-
snapshot2->ClearPaint();
|
2415
|
-
snapshot2->root()->PaintAllReachable();
|
2416
|
-
|
2417
|
-
List<HeapEntry*>* entries1 = snapshot1->GetSortedEntriesList();
|
2418
|
-
List<HeapEntry*>* entries2 = snapshot2->GetSortedEntriesList();
|
2419
|
-
int i = 0, j = 0;
|
2420
|
-
List<HeapEntry*> added_entries, deleted_entries;
|
2421
|
-
while (i < entries1->length() && j < entries2->length()) {
|
2422
|
-
uint64_t id1 = entries1->at(i)->id();
|
2423
|
-
uint64_t id2 = entries2->at(j)->id();
|
2424
|
-
if (id1 == id2) {
|
2425
|
-
HeapEntry* entry1 = entries1->at(i++);
|
2426
|
-
HeapEntry* entry2 = entries2->at(j++);
|
2427
|
-
if (entry1->painted_reachable() != entry2->painted_reachable()) {
|
2428
|
-
if (entry1->painted_reachable())
|
2429
|
-
deleted_entries.Add(entry1);
|
2430
|
-
else
|
2431
|
-
added_entries.Add(entry2);
|
2432
|
-
}
|
2433
|
-
} else if (id1 < id2) {
|
2434
|
-
HeapEntry* entry = entries1->at(i++);
|
2435
|
-
deleted_entries.Add(entry);
|
2436
|
-
} else {
|
2437
|
-
HeapEntry* entry = entries2->at(j++);
|
2438
|
-
added_entries.Add(entry);
|
2439
|
-
}
|
2440
|
-
}
|
2441
|
-
while (i < entries1->length()) {
|
2442
|
-
HeapEntry* entry = entries1->at(i++);
|
2443
|
-
deleted_entries.Add(entry);
|
2444
|
-
}
|
2445
|
-
while (j < entries2->length()) {
|
2446
|
-
HeapEntry* entry = entries2->at(j++);
|
2447
|
-
added_entries.Add(entry);
|
2448
|
-
}
|
2449
|
-
|
2450
|
-
HeapSnapshotsDiff* diff = new HeapSnapshotsDiff(snapshot1, snapshot2);
|
2451
|
-
diffs_.Add(diff);
|
2452
|
-
diff->CreateRoots(added_entries.length(), deleted_entries.length());
|
2453
|
-
|
2454
|
-
for (int i = 0; i < deleted_entries.length(); ++i) {
|
2455
|
-
HeapEntry* entry = deleted_entries[i];
|
2456
|
-
diff->AddDeletedEntry(i, i + 1, entry);
|
2457
|
-
}
|
2458
|
-
for (int i = 0; i < added_entries.length(); ++i) {
|
2459
|
-
HeapEntry* entry = added_entries[i];
|
2460
|
-
diff->AddAddedEntry(i, i + 1, entry);
|
2461
|
-
}
|
2462
|
-
return diff;
|
2463
|
-
}
|
2464
|
-
|
2465
|
-
|
2466
2722
|
class OutputStreamWriter {
|
2467
2723
|
public:
|
2468
2724
|
explicit OutputStreamWriter(v8::OutputStream* stream)
|
@@ -2674,7 +2930,8 @@ void HeapSnapshotJSONSerializer::SerializeNodes() {
|
|
2674
2930
|
"," JSON_S("code")
|
2675
2931
|
"," JSON_S("closure")
|
2676
2932
|
"," JSON_S("regexp")
|
2677
|
-
"," JSON_S("number")
|
2933
|
+
"," JSON_S("number")
|
2934
|
+
"," JSON_S("native"))
|
2678
2935
|
"," JSON_S("string")
|
2679
2936
|
"," JSON_S("number")
|
2680
2937
|
"," JSON_S("number")
|
@@ -2829,7 +3086,7 @@ void HeapSnapshotJSONSerializer::SortHashMap(
|
|
2829
3086
|
|
2830
3087
|
|
2831
3088
|
String* GetConstructorNameForHeapProfile(JSObject* object) {
|
2832
|
-
if (object->IsJSFunction()) return
|
3089
|
+
if (object->IsJSFunction()) return HEAP->closure_symbol();
|
2833
3090
|
return object->constructor_name();
|
2834
3091
|
}
|
2835
3092
|
|