mustang 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
data/vendor/v8/src/heap.cc
CHANGED
@@ -49,119 +49,114 @@
|
|
49
49
|
#include "regexp-macro-assembler.h"
|
50
50
|
#include "arm/regexp-macro-assembler-arm.h"
|
51
51
|
#endif
|
52
|
-
|
52
|
+
#if V8_TARGET_ARCH_MIPS && !V8_INTERPRETED_REGEXP
|
53
|
+
#include "regexp-macro-assembler.h"
|
54
|
+
#include "mips/regexp-macro-assembler-mips.h"
|
55
|
+
#endif
|
53
56
|
|
54
57
|
namespace v8 {
|
55
58
|
namespace internal {
|
56
59
|
|
57
60
|
|
58
|
-
String* Heap::hidden_symbol_;
|
59
|
-
Object* Heap::roots_[Heap::kRootListLength];
|
60
|
-
Object* Heap::global_contexts_list_;
|
61
|
-
|
62
|
-
|
63
|
-
NewSpace Heap::new_space_;
|
64
|
-
OldSpace* Heap::old_pointer_space_ = NULL;
|
65
|
-
OldSpace* Heap::old_data_space_ = NULL;
|
66
|
-
OldSpace* Heap::code_space_ = NULL;
|
67
|
-
MapSpace* Heap::map_space_ = NULL;
|
68
|
-
CellSpace* Heap::cell_space_ = NULL;
|
69
|
-
LargeObjectSpace* Heap::lo_space_ = NULL;
|
70
|
-
|
71
61
|
static const intptr_t kMinimumPromotionLimit = 2 * MB;
|
72
62
|
static const intptr_t kMinimumAllocationLimit = 8 * MB;
|
73
63
|
|
74
|
-
intptr_t Heap::old_gen_promotion_limit_ = kMinimumPromotionLimit;
|
75
|
-
intptr_t Heap::old_gen_allocation_limit_ = kMinimumAllocationLimit;
|
76
64
|
|
77
|
-
|
65
|
+
static Mutex* gc_initializer_mutex = OS::CreateMutex();
|
78
66
|
|
79
|
-
int Heap::amount_of_external_allocated_memory_ = 0;
|
80
|
-
int Heap::amount_of_external_allocated_memory_at_last_global_gc_ = 0;
|
81
67
|
|
68
|
+
Heap::Heap()
|
69
|
+
: isolate_(NULL),
|
82
70
|
// semispace_size_ should be a power of 2 and old_generation_size_ should be
|
83
71
|
// a multiple of Page::kPageSize.
|
84
72
|
#if defined(ANDROID)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
73
|
+
reserved_semispace_size_(2*MB),
|
74
|
+
max_semispace_size_(2*MB),
|
75
|
+
initial_semispace_size_(128*KB),
|
76
|
+
max_old_generation_size_(192*MB),
|
77
|
+
max_executable_size_(max_old_generation_size_),
|
78
|
+
code_range_size_(0),
|
90
79
|
#elif defined(V8_TARGET_ARCH_X64)
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
static const int default_max_semispace_size_ = 8*MB;
|
98
|
-
intptr_t Heap::max_old_generation_size_ = 512*MB;
|
99
|
-
int Heap::initial_semispace_size_ = 512*KB;
|
100
|
-
intptr_t Heap::code_range_size_ = 0;
|
101
|
-
intptr_t Heap::max_executable_size_ = 128*MB;
|
102
|
-
#endif
|
103
|
-
|
104
|
-
// Allow build-time customization of the max semispace size. Building
|
105
|
-
// V8 with snapshots and a non-default max semispace size is much
|
106
|
-
// easier if you can define it as part of the build environment.
|
107
|
-
#if defined(V8_MAX_SEMISPACE_SIZE)
|
108
|
-
int Heap::max_semispace_size_ = V8_MAX_SEMISPACE_SIZE;
|
80
|
+
reserved_semispace_size_(16*MB),
|
81
|
+
max_semispace_size_(16*MB),
|
82
|
+
initial_semispace_size_(1*MB),
|
83
|
+
max_old_generation_size_(1*GB),
|
84
|
+
max_executable_size_(256*MB),
|
85
|
+
code_range_size_(512*MB),
|
109
86
|
#else
|
110
|
-
|
87
|
+
reserved_semispace_size_(8*MB),
|
88
|
+
max_semispace_size_(8*MB),
|
89
|
+
initial_semispace_size_(512*KB),
|
90
|
+
max_old_generation_size_(512*MB),
|
91
|
+
max_executable_size_(128*MB),
|
92
|
+
code_range_size_(0),
|
111
93
|
#endif
|
112
|
-
|
113
|
-
// The snapshot semispace size will be the default semispace size if
|
114
|
-
// snapshotting is used and will be the requested semispace size as
|
115
|
-
// set up by ConfigureHeap otherwise.
|
116
|
-
int Heap::reserved_semispace_size_ = Heap::max_semispace_size_;
|
117
|
-
|
118
|
-
List<Heap::GCPrologueCallbackPair> Heap::gc_prologue_callbacks_;
|
119
|
-
List<Heap::GCEpilogueCallbackPair> Heap::gc_epilogue_callbacks_;
|
120
|
-
|
121
|
-
GCCallback Heap::global_gc_prologue_callback_ = NULL;
|
122
|
-
GCCallback Heap::global_gc_epilogue_callback_ = NULL;
|
123
|
-
HeapObjectCallback Heap::gc_safe_size_of_old_object_ = NULL;
|
124
|
-
|
125
94
|
// Variables set based on semispace_size_ and old_generation_size_ in
|
126
|
-
// ConfigureHeap
|
127
|
-
|
95
|
+
// ConfigureHeap (survived_since_last_expansion_, external_allocation_limit_)
|
128
96
|
// Will be 4 * reserved_semispace_size_ to ensure that young
|
129
97
|
// generation can be aligned to its size.
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
int Heap::young_survivors_after_last_gc_ = 0;
|
148
|
-
int Heap::high_survival_rate_period_length_ = 0;
|
149
|
-
double Heap::survival_rate_ = 0;
|
150
|
-
Heap::SurvivalRateTrend Heap::previous_survival_rate_trend_ = Heap::STABLE;
|
151
|
-
Heap::SurvivalRateTrend Heap::survival_rate_trend_ = Heap::STABLE;
|
152
|
-
|
98
|
+
survived_since_last_expansion_(0),
|
99
|
+
always_allocate_scope_depth_(0),
|
100
|
+
linear_allocation_scope_depth_(0),
|
101
|
+
contexts_disposed_(0),
|
102
|
+
new_space_(this),
|
103
|
+
old_pointer_space_(NULL),
|
104
|
+
old_data_space_(NULL),
|
105
|
+
code_space_(NULL),
|
106
|
+
map_space_(NULL),
|
107
|
+
cell_space_(NULL),
|
108
|
+
lo_space_(NULL),
|
109
|
+
gc_state_(NOT_IN_GC),
|
110
|
+
mc_count_(0),
|
111
|
+
ms_count_(0),
|
112
|
+
gc_count_(0),
|
113
|
+
unflattened_strings_length_(0),
|
153
114
|
#ifdef DEBUG
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
115
|
+
allocation_allowed_(true),
|
116
|
+
allocation_timeout_(0),
|
117
|
+
disallow_allocation_failure_(false),
|
118
|
+
debug_utils_(NULL),
|
158
119
|
#endif // DEBUG
|
120
|
+
old_gen_promotion_limit_(kMinimumPromotionLimit),
|
121
|
+
old_gen_allocation_limit_(kMinimumAllocationLimit),
|
122
|
+
external_allocation_limit_(0),
|
123
|
+
amount_of_external_allocated_memory_(0),
|
124
|
+
amount_of_external_allocated_memory_at_last_global_gc_(0),
|
125
|
+
old_gen_exhausted_(false),
|
126
|
+
hidden_symbol_(NULL),
|
127
|
+
global_gc_prologue_callback_(NULL),
|
128
|
+
global_gc_epilogue_callback_(NULL),
|
129
|
+
gc_safe_size_of_old_object_(NULL),
|
130
|
+
tracer_(NULL),
|
131
|
+
young_survivors_after_last_gc_(0),
|
132
|
+
high_survival_rate_period_length_(0),
|
133
|
+
survival_rate_(0),
|
134
|
+
previous_survival_rate_trend_(Heap::STABLE),
|
135
|
+
survival_rate_trend_(Heap::STABLE),
|
136
|
+
max_gc_pause_(0),
|
137
|
+
max_alive_after_gc_(0),
|
138
|
+
min_in_mutator_(kMaxInt),
|
139
|
+
alive_after_last_gc_(0),
|
140
|
+
last_gc_end_timestamp_(0.0),
|
141
|
+
page_watermark_invalidated_mark_(1 << Page::WATERMARK_INVALIDATED),
|
142
|
+
number_idle_notifications_(0),
|
143
|
+
last_idle_notification_gc_count_(0),
|
144
|
+
last_idle_notification_gc_count_init_(false),
|
145
|
+
configured_(false),
|
146
|
+
is_safe_to_read_maps_(true) {
|
147
|
+
// Allow build-time customization of the max semispace size. Building
|
148
|
+
// V8 with snapshots and a non-default max semispace size is much
|
149
|
+
// easier if you can define it as part of the build environment.
|
150
|
+
#if defined(V8_MAX_SEMISPACE_SIZE)
|
151
|
+
max_semispace_size_ = reserved_semispace_size_ = V8_MAX_SEMISPACE_SIZE;
|
152
|
+
#endif
|
153
|
+
|
154
|
+
memset(roots_, 0, sizeof(roots_[0]) * kRootListLength);
|
155
|
+
global_contexts_list_ = NULL;
|
156
|
+
mark_compact_collector_.heap_ = this;
|
157
|
+
external_string_table_.heap_ = this;
|
158
|
+
}
|
159
159
|
|
160
|
-
intptr_t GCTracer::alive_after_last_gc_ = 0;
|
161
|
-
double GCTracer::last_gc_end_timestamp_ = 0.0;
|
162
|
-
int GCTracer::max_gc_pause_ = 0;
|
163
|
-
intptr_t GCTracer::max_alive_after_gc_ = 0;
|
164
|
-
int GCTracer::min_in_mutator_ = kMaxInt;
|
165
160
|
|
166
161
|
intptr_t Heap::Capacity() {
|
167
162
|
if (!HasBeenSetup()) return 0;
|
@@ -190,7 +185,7 @@ intptr_t Heap::CommittedMemory() {
|
|
190
185
|
intptr_t Heap::CommittedMemoryExecutable() {
|
191
186
|
if (!HasBeenSetup()) return 0;
|
192
187
|
|
193
|
-
return
|
188
|
+
return isolate()->memory_allocator()->SizeExecutable();
|
194
189
|
}
|
195
190
|
|
196
191
|
|
@@ -217,8 +212,8 @@ bool Heap::HasBeenSetup() {
|
|
217
212
|
|
218
213
|
|
219
214
|
int Heap::GcSafeSizeOfOldObject(HeapObject* object) {
|
220
|
-
ASSERT(!
|
221
|
-
ASSERT(!
|
215
|
+
ASSERT(!HEAP->InNewSpace(object)); // Code only works for old objects.
|
216
|
+
ASSERT(!HEAP->mark_compact_collector()->are_map_pointers_encoded());
|
222
217
|
MapWord map_word = object->map_word();
|
223
218
|
map_word.ClearMark();
|
224
219
|
map_word.ClearOverflow();
|
@@ -227,8 +222,8 @@ int Heap::GcSafeSizeOfOldObject(HeapObject* object) {
|
|
227
222
|
|
228
223
|
|
229
224
|
int Heap::GcSafeSizeOfOldObjectWithEncodedMap(HeapObject* object) {
|
230
|
-
ASSERT(!
|
231
|
-
ASSERT(
|
225
|
+
ASSERT(!HEAP->InNewSpace(object)); // Code only works for old objects.
|
226
|
+
ASSERT(HEAP->mark_compact_collector()->are_map_pointers_encoded());
|
232
227
|
uint32_t marker = Memory::uint32_at(object->address());
|
233
228
|
if (marker == MarkCompactCollector::kSingleFreeEncoding) {
|
234
229
|
return kIntSize;
|
@@ -236,7 +231,7 @@ int Heap::GcSafeSizeOfOldObjectWithEncodedMap(HeapObject* object) {
|
|
236
231
|
return Memory::int_at(object->address() + kIntSize);
|
237
232
|
} else {
|
238
233
|
MapWord map_word = object->map_word();
|
239
|
-
Address map_address = map_word.DecodeMapAddress(
|
234
|
+
Address map_address = map_word.DecodeMapAddress(HEAP->map_space());
|
240
235
|
Map* map = reinterpret_cast<Map*>(HeapObject::FromAddress(map_address));
|
241
236
|
return object->SizeFromMap(map);
|
242
237
|
}
|
@@ -246,19 +241,20 @@ int Heap::GcSafeSizeOfOldObjectWithEncodedMap(HeapObject* object) {
|
|
246
241
|
GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space) {
|
247
242
|
// Is global GC requested?
|
248
243
|
if (space != NEW_SPACE || FLAG_gc_global) {
|
249
|
-
|
244
|
+
isolate_->counters()->gc_compactor_caused_by_request()->Increment();
|
250
245
|
return MARK_COMPACTOR;
|
251
246
|
}
|
252
247
|
|
253
248
|
// Is enough data promoted to justify a global GC?
|
254
249
|
if (OldGenerationPromotionLimitReached()) {
|
255
|
-
|
250
|
+
isolate_->counters()->gc_compactor_caused_by_promoted_data()->Increment();
|
256
251
|
return MARK_COMPACTOR;
|
257
252
|
}
|
258
253
|
|
259
254
|
// Have allocation in OLD and LO failed?
|
260
255
|
if (old_gen_exhausted_) {
|
261
|
-
|
256
|
+
isolate_->counters()->
|
257
|
+
gc_compactor_caused_by_oldspace_exhaustion()->Increment();
|
262
258
|
return MARK_COMPACTOR;
|
263
259
|
}
|
264
260
|
|
@@ -271,8 +267,9 @@ GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space) {
|
|
271
267
|
// and does not count available bytes already in the old space or code
|
272
268
|
// space. Undercounting is safe---we may get an unrequested full GC when
|
273
269
|
// a scavenge would have succeeded.
|
274
|
-
if (
|
275
|
-
|
270
|
+
if (isolate_->memory_allocator()->MaxAvailable() <= new_space_.Size()) {
|
271
|
+
isolate_->counters()->
|
272
|
+
gc_compactor_caused_by_oldspace_exhaustion()->Increment();
|
276
273
|
return MARK_COMPACTOR;
|
277
274
|
}
|
278
275
|
|
@@ -317,8 +314,8 @@ void Heap::PrintShortHeapStatistics() {
|
|
317
314
|
if (!FLAG_trace_gc_verbose) return;
|
318
315
|
PrintF("Memory allocator, used: %8" V8_PTR_PREFIX "d"
|
319
316
|
", available: %8" V8_PTR_PREFIX "d\n",
|
320
|
-
|
321
|
-
|
317
|
+
isolate_->memory_allocator()->Size(),
|
318
|
+
isolate_->memory_allocator()->Available());
|
322
319
|
PrintF("New space, used: %8" V8_PTR_PREFIX "d"
|
323
320
|
", available: %8" V8_PTR_PREFIX "d\n",
|
324
321
|
Heap::new_space_.Size(),
|
@@ -383,7 +380,7 @@ void Heap::ReportStatisticsAfterGC() {
|
|
383
380
|
|
384
381
|
|
385
382
|
void Heap::GarbageCollectionPrologue() {
|
386
|
-
|
383
|
+
isolate_->transcendental_cache()->Clear();
|
387
384
|
ClearJSFunctionResultCaches();
|
388
385
|
gc_count_++;
|
389
386
|
unflattened_strings_length_ = 0;
|
@@ -424,21 +421,24 @@ void Heap::GarbageCollectionEpilogue() {
|
|
424
421
|
Verify();
|
425
422
|
}
|
426
423
|
|
427
|
-
if (FLAG_print_global_handles)
|
424
|
+
if (FLAG_print_global_handles) isolate_->global_handles()->Print();
|
428
425
|
if (FLAG_print_handles) PrintHandles();
|
429
426
|
if (FLAG_gc_verbose) Print();
|
430
427
|
if (FLAG_code_stats) ReportCodeStatistics("After GC");
|
431
428
|
#endif
|
432
429
|
|
433
|
-
|
430
|
+
isolate_->counters()->alive_after_last_gc()->Set(
|
431
|
+
static_cast<int>(SizeOfObjects()));
|
434
432
|
|
435
|
-
|
436
|
-
|
433
|
+
isolate_->counters()->symbol_table_capacity()->Set(
|
434
|
+
symbol_table()->Capacity());
|
435
|
+
isolate_->counters()->number_of_symbols()->Set(
|
436
|
+
symbol_table()->NumberOfElements());
|
437
437
|
#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
|
438
438
|
ReportStatisticsAfterGC();
|
439
439
|
#endif
|
440
440
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
441
|
-
|
441
|
+
isolate_->debug()->AfterGarbageCollection();
|
442
442
|
#endif
|
443
443
|
}
|
444
444
|
|
@@ -447,9 +447,9 @@ void Heap::CollectAllGarbage(bool force_compaction) {
|
|
447
447
|
// Since we are ignoring the return value, the exact choice of space does
|
448
448
|
// not matter, so long as we do not specify NEW_SPACE, which would not
|
449
449
|
// cause a full GC.
|
450
|
-
|
450
|
+
mark_compact_collector_.SetForceCompaction(force_compaction);
|
451
451
|
CollectGarbage(OLD_POINTER_SPACE);
|
452
|
-
|
452
|
+
mark_compact_collector_.SetForceCompaction(false);
|
453
453
|
}
|
454
454
|
|
455
455
|
|
@@ -457,7 +457,7 @@ void Heap::CollectAllAvailableGarbage() {
|
|
457
457
|
// Since we are ignoring the return value, the exact choice of space does
|
458
458
|
// not matter, so long as we do not specify NEW_SPACE, which would not
|
459
459
|
// cause a full GC.
|
460
|
-
|
460
|
+
mark_compact_collector()->SetForceCompaction(true);
|
461
461
|
|
462
462
|
// Major GC would invoke weak handle callbacks on weakly reachable
|
463
463
|
// handles, but won't collect weakly reachable objects until next
|
@@ -473,13 +473,13 @@ void Heap::CollectAllAvailableGarbage() {
|
|
473
473
|
break;
|
474
474
|
}
|
475
475
|
}
|
476
|
-
|
476
|
+
mark_compact_collector()->SetForceCompaction(false);
|
477
477
|
}
|
478
478
|
|
479
479
|
|
480
480
|
bool Heap::CollectGarbage(AllocationSpace space, GarbageCollector collector) {
|
481
481
|
// The VM is in the GC state until exiting this function.
|
482
|
-
VMState state(GC);
|
482
|
+
VMState state(isolate_, GC);
|
483
483
|
|
484
484
|
#ifdef DEBUG
|
485
485
|
// Reset the allocation timeout to the GC interval, but make sure to
|
@@ -492,7 +492,7 @@ bool Heap::CollectGarbage(AllocationSpace space, GarbageCollector collector) {
|
|
492
492
|
|
493
493
|
bool next_gc_likely_to_collect_more = false;
|
494
494
|
|
495
|
-
{ GCTracer tracer;
|
495
|
+
{ GCTracer tracer(this);
|
496
496
|
GarbageCollectionPrologue();
|
497
497
|
// The GC count was incremented in the prologue. Tell the tracer about
|
498
498
|
// it.
|
@@ -502,8 +502,8 @@ bool Heap::CollectGarbage(AllocationSpace space, GarbageCollector collector) {
|
|
502
502
|
tracer.set_collector(collector);
|
503
503
|
|
504
504
|
HistogramTimer* rate = (collector == SCAVENGER)
|
505
|
-
?
|
506
|
-
:
|
505
|
+
? isolate_->counters()->gc_scavenger()
|
506
|
+
: isolate_->counters()->gc_compactor();
|
507
507
|
rate->Start();
|
508
508
|
next_gc_likely_to_collect_more =
|
509
509
|
PerformGarbageCollection(collector, &tracer);
|
@@ -522,7 +522,7 @@ bool Heap::CollectGarbage(AllocationSpace space, GarbageCollector collector) {
|
|
522
522
|
|
523
523
|
|
524
524
|
void Heap::PerformScavenge() {
|
525
|
-
GCTracer tracer;
|
525
|
+
GCTracer tracer(this);
|
526
526
|
PerformGarbageCollection(SCAVENGER, &tracer);
|
527
527
|
}
|
528
528
|
|
@@ -531,7 +531,6 @@ void Heap::PerformScavenge() {
|
|
531
531
|
// Helper class for verifying the symbol table.
|
532
532
|
class SymbolTableVerifier : public ObjectVisitor {
|
533
533
|
public:
|
534
|
-
SymbolTableVerifier() { }
|
535
534
|
void VisitPointers(Object** start, Object** end) {
|
536
535
|
// Visit all HeapObject pointers in [start, end).
|
537
536
|
for (Object** p = start; p < end; p++) {
|
@@ -548,7 +547,7 @@ class SymbolTableVerifier : public ObjectVisitor {
|
|
548
547
|
static void VerifySymbolTable() {
|
549
548
|
#ifdef DEBUG
|
550
549
|
SymbolTableVerifier verifier;
|
551
|
-
|
550
|
+
HEAP->symbol_table()->IterateElements(&verifier);
|
552
551
|
#endif // DEBUG
|
553
552
|
}
|
554
553
|
|
@@ -633,7 +632,7 @@ void Heap::EnsureFromSpaceIsCommitted() {
|
|
633
632
|
|
634
633
|
|
635
634
|
void Heap::ClearJSFunctionResultCaches() {
|
636
|
-
if (
|
635
|
+
if (isolate_->bootstrapper()->IsActive()) return;
|
637
636
|
|
638
637
|
Object* context = global_contexts_list_;
|
639
638
|
while (!context->IsUndefined()) {
|
@@ -651,8 +650,9 @@ void Heap::ClearJSFunctionResultCaches() {
|
|
651
650
|
}
|
652
651
|
|
653
652
|
|
653
|
+
|
654
654
|
void Heap::ClearNormalizedMapCaches() {
|
655
|
-
if (
|
655
|
+
if (isolate_->bootstrapper()->IsActive()) return;
|
656
656
|
|
657
657
|
Object* context = global_contexts_list_;
|
658
658
|
while (!context->IsUndefined()) {
|
@@ -709,7 +709,7 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
|
|
709
709
|
bool next_gc_likely_to_collect_more = false;
|
710
710
|
|
711
711
|
if (collector != SCAVENGER) {
|
712
|
-
PROFILE(CodeMovingGCEvent());
|
712
|
+
PROFILE(isolate_, CodeMovingGCEvent());
|
713
713
|
}
|
714
714
|
|
715
715
|
VerifySymbolTable();
|
@@ -768,13 +768,13 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
|
|
768
768
|
UpdateSurvivalRateTrend(start_new_space_size);
|
769
769
|
}
|
770
770
|
|
771
|
-
|
771
|
+
isolate_->counters()->objs_since_last_young()->Set(0);
|
772
772
|
|
773
773
|
if (collector == MARK_COMPACTOR) {
|
774
774
|
DisableAssertNoAllocation allow_allocation;
|
775
775
|
GCTracer::Scope scope(tracer, GCTracer::Scope::EXTERNAL);
|
776
776
|
next_gc_likely_to_collect_more =
|
777
|
-
|
777
|
+
isolate_->global_handles()->PostGarbageCollectionProcessing();
|
778
778
|
}
|
779
779
|
|
780
780
|
// Update relocatables.
|
@@ -808,11 +808,11 @@ bool Heap::PerformGarbageCollection(GarbageCollector collector,
|
|
808
808
|
|
809
809
|
void Heap::MarkCompact(GCTracer* tracer) {
|
810
810
|
gc_state_ = MARK_COMPACT;
|
811
|
-
LOG(ResourceEvent("markcompact", "begin"));
|
811
|
+
LOG(isolate_, ResourceEvent("markcompact", "begin"));
|
812
812
|
|
813
|
-
|
813
|
+
mark_compact_collector_.Prepare(tracer);
|
814
814
|
|
815
|
-
bool is_compacting =
|
815
|
+
bool is_compacting = mark_compact_collector_.IsCompacting();
|
816
816
|
|
817
817
|
if (is_compacting) {
|
818
818
|
mc_count_++;
|
@@ -823,15 +823,17 @@ void Heap::MarkCompact(GCTracer* tracer) {
|
|
823
823
|
|
824
824
|
MarkCompactPrologue(is_compacting);
|
825
825
|
|
826
|
-
|
826
|
+
is_safe_to_read_maps_ = false;
|
827
|
+
mark_compact_collector_.CollectGarbage();
|
828
|
+
is_safe_to_read_maps_ = true;
|
827
829
|
|
828
|
-
LOG(ResourceEvent("markcompact", "end"));
|
830
|
+
LOG(isolate_, ResourceEvent("markcompact", "end"));
|
829
831
|
|
830
832
|
gc_state_ = NOT_IN_GC;
|
831
833
|
|
832
834
|
Shrink();
|
833
835
|
|
834
|
-
|
836
|
+
isolate_->counters()->objs_since_last_full()->Set(0);
|
835
837
|
|
836
838
|
contexts_disposed_ = 0;
|
837
839
|
}
|
@@ -840,13 +842,11 @@ void Heap::MarkCompact(GCTracer* tracer) {
|
|
840
842
|
void Heap::MarkCompactPrologue(bool is_compacting) {
|
841
843
|
// At any old GC clear the keyed lookup cache to enable collection of unused
|
842
844
|
// maps.
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
RuntimeProfiler::MarkCompactPrologue(is_compacting);
|
845
|
+
isolate_->keyed_lookup_cache()->Clear();
|
846
|
+
isolate_->context_slot_cache()->Clear();
|
847
|
+
isolate_->descriptor_lookup_cache()->Clear();
|
848
848
|
|
849
|
-
|
849
|
+
isolate_->compilation_cache()->MarkCompactPrologue();
|
850
850
|
|
851
851
|
CompletelyClearInstanceofCache();
|
852
852
|
|
@@ -870,6 +870,7 @@ Object* Heap::FindCodeObject(Address a) {
|
|
870
870
|
// Helper class for copying HeapObjects
|
871
871
|
class ScavengeVisitor: public ObjectVisitor {
|
872
872
|
public:
|
873
|
+
explicit ScavengeVisitor(Heap* heap) : heap_(heap) {}
|
873
874
|
|
874
875
|
void VisitPointer(Object** p) { ScavengePointer(p); }
|
875
876
|
|
@@ -881,48 +882,15 @@ class ScavengeVisitor: public ObjectVisitor {
|
|
881
882
|
private:
|
882
883
|
void ScavengePointer(Object** p) {
|
883
884
|
Object* object = *p;
|
884
|
-
if (!
|
885
|
+
if (!heap_->InNewSpace(object)) return;
|
885
886
|
Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p),
|
886
887
|
reinterpret_cast<HeapObject*>(object));
|
887
888
|
}
|
888
|
-
};
|
889
|
-
|
890
|
-
|
891
|
-
// A queue of objects promoted during scavenge. Each object is accompanied
|
892
|
-
// by it's size to avoid dereferencing a map pointer for scanning.
|
893
|
-
class PromotionQueue {
|
894
|
-
public:
|
895
|
-
void Initialize(Address start_address) {
|
896
|
-
front_ = rear_ = reinterpret_cast<intptr_t*>(start_address);
|
897
|
-
}
|
898
889
|
|
899
|
-
|
900
|
-
|
901
|
-
void insert(HeapObject* target, int size) {
|
902
|
-
*(--rear_) = reinterpret_cast<intptr_t>(target);
|
903
|
-
*(--rear_) = size;
|
904
|
-
// Assert no overflow into live objects.
|
905
|
-
ASSERT(reinterpret_cast<Address>(rear_) >= Heap::new_space()->top());
|
906
|
-
}
|
907
|
-
|
908
|
-
void remove(HeapObject** target, int* size) {
|
909
|
-
*target = reinterpret_cast<HeapObject*>(*(--front_));
|
910
|
-
*size = static_cast<int>(*(--front_));
|
911
|
-
// Assert no underflow.
|
912
|
-
ASSERT(front_ >= rear_);
|
913
|
-
}
|
914
|
-
|
915
|
-
private:
|
916
|
-
// The front of the queue is higher in memory than the rear.
|
917
|
-
intptr_t* front_;
|
918
|
-
intptr_t* rear_;
|
890
|
+
Heap* heap_;
|
919
891
|
};
|
920
892
|
|
921
893
|
|
922
|
-
// Shared state read by the scavenge collector and set by ScavengeObject.
|
923
|
-
static PromotionQueue promotion_queue;
|
924
|
-
|
925
|
-
|
926
894
|
#ifdef DEBUG
|
927
895
|
// Visitor class to verify pointers in code or data space do not point into
|
928
896
|
// new space.
|
@@ -931,7 +899,7 @@ class VerifyNonPointerSpacePointersVisitor: public ObjectVisitor {
|
|
931
899
|
void VisitPointers(Object** start, Object**end) {
|
932
900
|
for (Object** current = start; current < end; current++) {
|
933
901
|
if ((*current)->IsHeapObject()) {
|
934
|
-
ASSERT(!
|
902
|
+
ASSERT(!HEAP->InNewSpace(HeapObject::cast(*current)));
|
935
903
|
}
|
936
904
|
}
|
937
905
|
}
|
@@ -942,12 +910,12 @@ static void VerifyNonPointerSpacePointers() {
|
|
942
910
|
// Verify that there are no pointers to new space in spaces where we
|
943
911
|
// do not expect them.
|
944
912
|
VerifyNonPointerSpacePointersVisitor v;
|
945
|
-
HeapObjectIterator code_it(
|
913
|
+
HeapObjectIterator code_it(HEAP->code_space());
|
946
914
|
for (HeapObject* object = code_it.next();
|
947
915
|
object != NULL; object = code_it.next())
|
948
916
|
object->Iterate(&v);
|
949
917
|
|
950
|
-
HeapObjectIterator data_it(
|
918
|
+
HeapObjectIterator data_it(HEAP->old_data_space());
|
951
919
|
for (HeapObject* object = data_it.next();
|
952
920
|
object != NULL; object = data_it.next())
|
953
921
|
object->Iterate(&v);
|
@@ -973,7 +941,9 @@ void Heap::Scavenge() {
|
|
973
941
|
|
974
942
|
gc_state_ = SCAVENGE;
|
975
943
|
|
976
|
-
|
944
|
+
SwitchScavengingVisitorsTableIfProfilingWasEnabled();
|
945
|
+
|
946
|
+
Page::FlipMeaningOfInvalidatedWatermarkFlag(this);
|
977
947
|
#ifdef DEBUG
|
978
948
|
VerifyPageWatermarkValidity(old_pointer_space_, ALL_VALID);
|
979
949
|
VerifyPageWatermarkValidity(map_space_, ALL_VALID);
|
@@ -988,10 +958,10 @@ void Heap::Scavenge() {
|
|
988
958
|
map_space_->FlushTopPageWatermark();
|
989
959
|
|
990
960
|
// Implements Cheney's copying algorithm
|
991
|
-
LOG(ResourceEvent("scavenge", "begin"));
|
961
|
+
LOG(isolate_, ResourceEvent("scavenge", "begin"));
|
992
962
|
|
993
963
|
// Clear descriptor cache.
|
994
|
-
|
964
|
+
isolate_->descriptor_lookup_cache()->Clear();
|
995
965
|
|
996
966
|
// Used for updating survived_since_last_expansion_ at function end.
|
997
967
|
intptr_t survived_watermark = PromotedSpaceSize();
|
@@ -1021,16 +991,17 @@ void Heap::Scavenge() {
|
|
1021
991
|
// frees up its size in bytes from the top of the new space, and
|
1022
992
|
// objects are at least one pointer in size.
|
1023
993
|
Address new_space_front = new_space_.ToSpaceLow();
|
1024
|
-
|
994
|
+
promotion_queue_.Initialize(new_space_.ToSpaceHigh());
|
1025
995
|
|
1026
|
-
|
996
|
+
is_safe_to_read_maps_ = false;
|
997
|
+
ScavengeVisitor scavenge_visitor(this);
|
1027
998
|
// Copy roots.
|
1028
999
|
IterateRoots(&scavenge_visitor, VISIT_ALL_IN_SCAVENGE);
|
1029
1000
|
|
1030
1001
|
// Copy objects reachable from the old generation. By definition,
|
1031
1002
|
// there are no intergenerational pointers in code or data spaces.
|
1032
1003
|
IterateDirtyRegions(old_pointer_space_,
|
1033
|
-
&IteratePointersInDirtyRegion,
|
1004
|
+
&Heap::IteratePointersInDirtyRegion,
|
1034
1005
|
&ScavengePointer,
|
1035
1006
|
WATERMARK_CAN_BE_INVALID);
|
1036
1007
|
|
@@ -1056,23 +1027,18 @@ void Heap::Scavenge() {
|
|
1056
1027
|
// Scavenge object reachable from the global contexts list directly.
|
1057
1028
|
scavenge_visitor.VisitPointer(BitCast<Object**>(&global_contexts_list_));
|
1058
1029
|
|
1059
|
-
// Scavenge objects reachable from the runtime-profiler sampler
|
1060
|
-
// window directly.
|
1061
|
-
Object** sampler_window_address = RuntimeProfiler::SamplerWindowAddress();
|
1062
|
-
int sampler_window_size = RuntimeProfiler::SamplerWindowSize();
|
1063
|
-
scavenge_visitor.VisitPointers(
|
1064
|
-
sampler_window_address,
|
1065
|
-
sampler_window_address + sampler_window_size);
|
1066
|
-
|
1067
1030
|
new_space_front = DoScavenge(&scavenge_visitor, new_space_front);
|
1068
1031
|
|
1069
1032
|
UpdateNewSpaceReferencesInExternalStringTable(
|
1070
1033
|
&UpdateNewSpaceReferenceInExternalStringTableEntry);
|
1071
1034
|
|
1072
1035
|
LiveObjectList::UpdateReferencesForScavengeGC();
|
1036
|
+
isolate()->runtime_profiler()->UpdateSamplesAfterScavenge();
|
1073
1037
|
|
1074
1038
|
ASSERT(new_space_front == new_space_.top());
|
1075
1039
|
|
1040
|
+
is_safe_to_read_maps_ = true;
|
1041
|
+
|
1076
1042
|
// Set age mark.
|
1077
1043
|
new_space_.set_age_mark(new_space_.top());
|
1078
1044
|
|
@@ -1080,18 +1046,19 @@ void Heap::Scavenge() {
|
|
1080
1046
|
IncrementYoungSurvivorsCounter(static_cast<int>(
|
1081
1047
|
(PromotedSpaceSize() - survived_watermark) + new_space_.Size()));
|
1082
1048
|
|
1083
|
-
LOG(ResourceEvent("scavenge", "end"));
|
1049
|
+
LOG(isolate_, ResourceEvent("scavenge", "end"));
|
1084
1050
|
|
1085
1051
|
gc_state_ = NOT_IN_GC;
|
1086
1052
|
}
|
1087
1053
|
|
1088
1054
|
|
1089
|
-
String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(
|
1055
|
+
String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Heap* heap,
|
1056
|
+
Object** p) {
|
1090
1057
|
MapWord first_word = HeapObject::cast(*p)->map_word();
|
1091
1058
|
|
1092
1059
|
if (!first_word.IsForwardingAddress()) {
|
1093
1060
|
// Unreachable external string can be finalized.
|
1094
|
-
FinalizeExternalString(String::cast(*p));
|
1061
|
+
heap->FinalizeExternalString(String::cast(*p));
|
1095
1062
|
return NULL;
|
1096
1063
|
}
|
1097
1064
|
|
@@ -1102,48 +1069,49 @@ String* Heap::UpdateNewSpaceReferenceInExternalStringTableEntry(Object** p) {
|
|
1102
1069
|
|
1103
1070
|
void Heap::UpdateNewSpaceReferencesInExternalStringTable(
|
1104
1071
|
ExternalStringTableUpdaterCallback updater_func) {
|
1105
|
-
|
1072
|
+
external_string_table_.Verify();
|
1106
1073
|
|
1107
|
-
if (
|
1074
|
+
if (external_string_table_.new_space_strings_.is_empty()) return;
|
1108
1075
|
|
1109
|
-
Object** start = &
|
1110
|
-
Object** end = start +
|
1076
|
+
Object** start = &external_string_table_.new_space_strings_[0];
|
1077
|
+
Object** end = start + external_string_table_.new_space_strings_.length();
|
1111
1078
|
Object** last = start;
|
1112
1079
|
|
1113
1080
|
for (Object** p = start; p < end; ++p) {
|
1114
|
-
ASSERT(
|
1115
|
-
String* target = updater_func(p);
|
1081
|
+
ASSERT(InFromSpace(*p));
|
1082
|
+
String* target = updater_func(this, p);
|
1116
1083
|
|
1117
1084
|
if (target == NULL) continue;
|
1118
1085
|
|
1119
1086
|
ASSERT(target->IsExternalString());
|
1120
1087
|
|
1121
|
-
if (
|
1088
|
+
if (InNewSpace(target)) {
|
1122
1089
|
// String is still in new space. Update the table entry.
|
1123
1090
|
*last = target;
|
1124
1091
|
++last;
|
1125
1092
|
} else {
|
1126
1093
|
// String got promoted. Move it to the old string list.
|
1127
|
-
|
1094
|
+
external_string_table_.AddOldString(target);
|
1128
1095
|
}
|
1129
1096
|
}
|
1130
1097
|
|
1131
1098
|
ASSERT(last <= end);
|
1132
|
-
|
1099
|
+
external_string_table_.ShrinkNewStrings(static_cast<int>(last - start));
|
1133
1100
|
}
|
1134
1101
|
|
1135
1102
|
|
1136
|
-
static Object* ProcessFunctionWeakReferences(
|
1103
|
+
static Object* ProcessFunctionWeakReferences(Heap* heap,
|
1104
|
+
Object* function,
|
1137
1105
|
WeakObjectRetainer* retainer) {
|
1138
|
-
Object* head =
|
1106
|
+
Object* head = heap->undefined_value();
|
1139
1107
|
JSFunction* tail = NULL;
|
1140
1108
|
Object* candidate = function;
|
1141
|
-
while (
|
1109
|
+
while (candidate != heap->undefined_value()) {
|
1142
1110
|
// Check whether to keep the candidate in the list.
|
1143
1111
|
JSFunction* candidate_function = reinterpret_cast<JSFunction*>(candidate);
|
1144
1112
|
Object* retain = retainer->RetainAs(candidate);
|
1145
1113
|
if (retain != NULL) {
|
1146
|
-
if (head->
|
1114
|
+
if (head == heap->undefined_value()) {
|
1147
1115
|
// First element in the list.
|
1148
1116
|
head = candidate_function;
|
1149
1117
|
} else {
|
@@ -1160,7 +1128,7 @@ static Object* ProcessFunctionWeakReferences(Object* function,
|
|
1160
1128
|
|
1161
1129
|
// Terminate the list if there is one or more elements.
|
1162
1130
|
if (tail != NULL) {
|
1163
|
-
tail->set_next_function_link(
|
1131
|
+
tail->set_next_function_link(heap->undefined_value());
|
1164
1132
|
}
|
1165
1133
|
|
1166
1134
|
return head;
|
@@ -1171,18 +1139,19 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
|
|
1171
1139
|
Object* head = undefined_value();
|
1172
1140
|
Context* tail = NULL;
|
1173
1141
|
Object* candidate = global_contexts_list_;
|
1174
|
-
while (
|
1142
|
+
while (candidate != undefined_value()) {
|
1175
1143
|
// Check whether to keep the candidate in the list.
|
1176
1144
|
Context* candidate_context = reinterpret_cast<Context*>(candidate);
|
1177
1145
|
Object* retain = retainer->RetainAs(candidate);
|
1178
1146
|
if (retain != NULL) {
|
1179
|
-
if (head
|
1147
|
+
if (head == undefined_value()) {
|
1180
1148
|
// First element in the list.
|
1181
1149
|
head = candidate_context;
|
1182
1150
|
} else {
|
1183
1151
|
// Subsequent elements in the list.
|
1184
1152
|
ASSERT(tail != NULL);
|
1185
|
-
tail->set_unchecked(
|
1153
|
+
tail->set_unchecked(this,
|
1154
|
+
Context::NEXT_CONTEXT_LINK,
|
1186
1155
|
candidate_context,
|
1187
1156
|
UPDATE_WRITE_BARRIER);
|
1188
1157
|
}
|
@@ -1192,9 +1161,11 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
|
|
1192
1161
|
// Process the weak list of optimized functions for the context.
|
1193
1162
|
Object* function_list_head =
|
1194
1163
|
ProcessFunctionWeakReferences(
|
1164
|
+
this,
|
1195
1165
|
candidate_context->get(Context::OPTIMIZED_FUNCTIONS_LIST),
|
1196
1166
|
retainer);
|
1197
|
-
candidate_context->set_unchecked(
|
1167
|
+
candidate_context->set_unchecked(this,
|
1168
|
+
Context::OPTIMIZED_FUNCTIONS_LIST,
|
1198
1169
|
function_list_head,
|
1199
1170
|
UPDATE_WRITE_BARRIER);
|
1200
1171
|
}
|
@@ -1204,21 +1175,22 @@ void Heap::ProcessWeakReferences(WeakObjectRetainer* retainer) {
|
|
1204
1175
|
|
1205
1176
|
// Terminate the list if there is one or more elements.
|
1206
1177
|
if (tail != NULL) {
|
1207
|
-
tail->set_unchecked(
|
1178
|
+
tail->set_unchecked(this,
|
1179
|
+
Context::NEXT_CONTEXT_LINK,
|
1208
1180
|
Heap::undefined_value(),
|
1209
1181
|
UPDATE_WRITE_BARRIER);
|
1210
1182
|
}
|
1211
1183
|
|
1212
1184
|
// Update the head of the list of contexts.
|
1213
|
-
|
1185
|
+
global_contexts_list_ = head;
|
1214
1186
|
}
|
1215
1187
|
|
1216
1188
|
|
1217
1189
|
class NewSpaceScavenger : public StaticNewSpaceVisitor<NewSpaceScavenger> {
|
1218
1190
|
public:
|
1219
|
-
static inline void VisitPointer(Object** p) {
|
1191
|
+
static inline void VisitPointer(Heap* heap, Object** p) {
|
1220
1192
|
Object* object = *p;
|
1221
|
-
if (!
|
1193
|
+
if (!heap->InNewSpace(object)) return;
|
1222
1194
|
Heap::ScavengeObject(reinterpret_cast<HeapObject**>(p),
|
1223
1195
|
reinterpret_cast<HeapObject*>(object));
|
1224
1196
|
}
|
@@ -1239,10 +1211,10 @@ Address Heap::DoScavenge(ObjectVisitor* scavenge_visitor,
|
|
1239
1211
|
}
|
1240
1212
|
|
1241
1213
|
// Promote and process all the to-be-promoted objects.
|
1242
|
-
while (!
|
1214
|
+
while (!promotion_queue_.is_empty()) {
|
1243
1215
|
HeapObject* target;
|
1244
1216
|
int size;
|
1245
|
-
|
1217
|
+
promotion_queue_.remove(&target, &size);
|
1246
1218
|
|
1247
1219
|
// Promoted object might be already partially visited
|
1248
1220
|
// during dirty regions iteration. Thus we search specificly
|
@@ -1262,6 +1234,32 @@ Address Heap::DoScavenge(ObjectVisitor* scavenge_visitor,
|
|
1262
1234
|
}
|
1263
1235
|
|
1264
1236
|
|
1237
|
+
enum LoggingAndProfiling {
|
1238
|
+
LOGGING_AND_PROFILING_ENABLED,
|
1239
|
+
LOGGING_AND_PROFILING_DISABLED
|
1240
|
+
};
|
1241
|
+
|
1242
|
+
|
1243
|
+
typedef void (*ScavengingCallback)(Map* map,
|
1244
|
+
HeapObject** slot,
|
1245
|
+
HeapObject* object);
|
1246
|
+
|
1247
|
+
|
1248
|
+
static Atomic32 scavenging_visitors_table_mode_;
|
1249
|
+
static VisitorDispatchTable<ScavengingCallback> scavenging_visitors_table_;
|
1250
|
+
|
1251
|
+
|
1252
|
+
INLINE(static void DoScavengeObject(Map* map,
|
1253
|
+
HeapObject** slot,
|
1254
|
+
HeapObject* obj));
|
1255
|
+
|
1256
|
+
|
1257
|
+
void DoScavengeObject(Map* map, HeapObject** slot, HeapObject* obj) {
|
1258
|
+
scavenging_visitors_table_.GetVisitor(map)(map, slot, obj);
|
1259
|
+
}
|
1260
|
+
|
1261
|
+
|
1262
|
+
template<LoggingAndProfiling logging_and_profiling_mode>
|
1265
1263
|
class ScavengingVisitor : public StaticVisitorBase {
|
1266
1264
|
public:
|
1267
1265
|
static void Initialize() {
|
@@ -1270,23 +1268,22 @@ class ScavengingVisitor : public StaticVisitorBase {
|
|
1270
1268
|
table_.Register(kVisitShortcutCandidate, &EvacuateShortcutCandidate);
|
1271
1269
|
table_.Register(kVisitByteArray, &EvacuateByteArray);
|
1272
1270
|
table_.Register(kVisitFixedArray, &EvacuateFixedArray);
|
1271
|
+
|
1273
1272
|
table_.Register(kVisitGlobalContext,
|
1274
1273
|
&ObjectEvacuationStrategy<POINTER_OBJECT>::
|
1275
|
-
VisitSpecialized<Context::kSize>);
|
1276
|
-
|
1277
|
-
typedef ObjectEvacuationStrategy<POINTER_OBJECT> PointerObject;
|
1274
|
+
template VisitSpecialized<Context::kSize>);
|
1278
1275
|
|
1279
1276
|
table_.Register(kVisitConsString,
|
1280
1277
|
&ObjectEvacuationStrategy<POINTER_OBJECT>::
|
1281
|
-
VisitSpecialized<ConsString::kSize>);
|
1278
|
+
template VisitSpecialized<ConsString::kSize>);
|
1282
1279
|
|
1283
1280
|
table_.Register(kVisitSharedFunctionInfo,
|
1284
1281
|
&ObjectEvacuationStrategy<POINTER_OBJECT>::
|
1285
|
-
VisitSpecialized<SharedFunctionInfo::kSize>);
|
1282
|
+
template VisitSpecialized<SharedFunctionInfo::kSize>);
|
1286
1283
|
|
1287
1284
|
table_.Register(kVisitJSFunction,
|
1288
1285
|
&ObjectEvacuationStrategy<POINTER_OBJECT>::
|
1289
|
-
|
1286
|
+
template VisitSpecialized<JSFunction::kSize>);
|
1290
1287
|
|
1291
1288
|
table_.RegisterSpecializations<ObjectEvacuationStrategy<DATA_OBJECT>,
|
1292
1289
|
kVisitDataObject,
|
@@ -1301,18 +1298,16 @@ class ScavengingVisitor : public StaticVisitorBase {
|
|
1301
1298
|
kVisitStructGeneric>();
|
1302
1299
|
}
|
1303
1300
|
|
1304
|
-
|
1305
|
-
|
1306
|
-
table_.GetVisitor(map)(map, slot, obj);
|
1301
|
+
static VisitorDispatchTable<ScavengingCallback>* GetTable() {
|
1302
|
+
return &table_;
|
1307
1303
|
}
|
1308
1304
|
|
1309
|
-
|
1310
1305
|
private:
|
1311
1306
|
enum ObjectContents { DATA_OBJECT, POINTER_OBJECT };
|
1312
1307
|
enum SizeRestriction { SMALL, UNKNOWN_SIZE };
|
1313
1308
|
|
1314
1309
|
#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
|
1315
|
-
static void RecordCopiedObject(HeapObject* obj) {
|
1310
|
+
static void RecordCopiedObject(Heap* heap, HeapObject* obj) {
|
1316
1311
|
bool should_record = false;
|
1317
1312
|
#ifdef DEBUG
|
1318
1313
|
should_record = FLAG_heap_stats;
|
@@ -1321,10 +1316,10 @@ class ScavengingVisitor : public StaticVisitorBase {
|
|
1321
1316
|
should_record = should_record || FLAG_log_gc;
|
1322
1317
|
#endif
|
1323
1318
|
if (should_record) {
|
1324
|
-
if (
|
1325
|
-
|
1319
|
+
if (heap->new_space()->Contains(obj)) {
|
1320
|
+
heap->new_space()->RecordAllocation(obj);
|
1326
1321
|
} else {
|
1327
|
-
|
1322
|
+
heap->new_space()->RecordPromotion(obj);
|
1328
1323
|
}
|
1329
1324
|
}
|
1330
1325
|
}
|
@@ -1333,27 +1328,34 @@ class ScavengingVisitor : public StaticVisitorBase {
|
|
1333
1328
|
// Helper function used by CopyObject to copy a source object to an
|
1334
1329
|
// allocated target object and update the forwarding pointer in the source
|
1335
1330
|
// object. Returns the target object.
|
1336
|
-
INLINE(static HeapObject* MigrateObject(
|
1331
|
+
INLINE(static HeapObject* MigrateObject(Heap* heap,
|
1332
|
+
HeapObject* source,
|
1337
1333
|
HeapObject* target,
|
1338
1334
|
int size)) {
|
1339
1335
|
// Copy the content of source to target.
|
1340
|
-
|
1336
|
+
heap->CopyBlock(target->address(), source->address(), size);
|
1341
1337
|
|
1342
1338
|
// Set the forwarding address.
|
1343
1339
|
source->set_map_word(MapWord::FromForwardingAddress(target));
|
1344
1340
|
|
1341
|
+
if (logging_and_profiling_mode == LOGGING_AND_PROFILING_ENABLED) {
|
1345
1342
|
#if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
|
1346
|
-
|
1347
|
-
|
1343
|
+
// Update NewSpace stats if necessary.
|
1344
|
+
RecordCopiedObject(heap, target);
|
1348
1345
|
#endif
|
1349
|
-
|
1346
|
+
HEAP_PROFILE(heap, ObjectMoveEvent(source->address(), target->address()));
|
1350
1347
|
#if defined(ENABLE_LOGGING_AND_PROFILING)
|
1351
|
-
|
1352
|
-
if (
|
1353
|
-
|
1348
|
+
Isolate* isolate = heap->isolate();
|
1349
|
+
if (isolate->logger()->is_logging() ||
|
1350
|
+
isolate->cpu_profiler()->is_profiling()) {
|
1351
|
+
if (target->IsSharedFunctionInfo()) {
|
1352
|
+
PROFILE(isolate, SharedFunctionInfoMoveEvent(
|
1353
|
+
source->address(), target->address()));
|
1354
|
+
}
|
1354
1355
|
}
|
1355
|
-
}
|
1356
1356
|
#endif
|
1357
|
+
}
|
1358
|
+
|
1357
1359
|
return target;
|
1358
1360
|
}
|
1359
1361
|
|
@@ -1367,36 +1369,37 @@ class ScavengingVisitor : public StaticVisitorBase {
|
|
1367
1369
|
(object_size <= Page::kMaxHeapObjectSize));
|
1368
1370
|
ASSERT(object->Size() == object_size);
|
1369
1371
|
|
1370
|
-
|
1372
|
+
Heap* heap = map->heap();
|
1373
|
+
if (heap->ShouldBePromoted(object->address(), object_size)) {
|
1371
1374
|
MaybeObject* maybe_result;
|
1372
1375
|
|
1373
1376
|
if ((size_restriction != SMALL) &&
|
1374
1377
|
(object_size > Page::kMaxHeapObjectSize)) {
|
1375
|
-
maybe_result =
|
1378
|
+
maybe_result = heap->lo_space()->AllocateRawFixedArray(object_size);
|
1376
1379
|
} else {
|
1377
1380
|
if (object_contents == DATA_OBJECT) {
|
1378
|
-
maybe_result =
|
1381
|
+
maybe_result = heap->old_data_space()->AllocateRaw(object_size);
|
1379
1382
|
} else {
|
1380
|
-
maybe_result =
|
1383
|
+
maybe_result = heap->old_pointer_space()->AllocateRaw(object_size);
|
1381
1384
|
}
|
1382
1385
|
}
|
1383
1386
|
|
1384
1387
|
Object* result = NULL; // Initialization to please compiler.
|
1385
1388
|
if (maybe_result->ToObject(&result)) {
|
1386
1389
|
HeapObject* target = HeapObject::cast(result);
|
1387
|
-
*slot = MigrateObject(object, target, object_size);
|
1390
|
+
*slot = MigrateObject(heap, object , target, object_size);
|
1388
1391
|
|
1389
1392
|
if (object_contents == POINTER_OBJECT) {
|
1390
|
-
promotion_queue
|
1393
|
+
heap->promotion_queue()->insert(target, object_size);
|
1391
1394
|
}
|
1392
1395
|
|
1393
|
-
|
1396
|
+
heap->tracer()->increment_promoted_objects_size(object_size);
|
1394
1397
|
return;
|
1395
1398
|
}
|
1396
1399
|
}
|
1397
1400
|
Object* result =
|
1398
|
-
|
1399
|
-
*slot = MigrateObject(object, HeapObject::cast(result), object_size);
|
1401
|
+
heap->new_space()->AllocateRaw(object_size)->ToObjectUnchecked();
|
1402
|
+
*slot = MigrateObject(heap, object, HeapObject::cast(result), object_size);
|
1400
1403
|
return;
|
1401
1404
|
}
|
1402
1405
|
|
@@ -1447,13 +1450,14 @@ class ScavengingVisitor : public StaticVisitorBase {
|
|
1447
1450
|
HeapObject* object) {
|
1448
1451
|
ASSERT(IsShortcutCandidate(map->instance_type()));
|
1449
1452
|
|
1450
|
-
if (ConsString::cast(object)->unchecked_second() ==
|
1453
|
+
if (ConsString::cast(object)->unchecked_second() ==
|
1454
|
+
map->heap()->empty_string()) {
|
1451
1455
|
HeapObject* first =
|
1452
1456
|
HeapObject::cast(ConsString::cast(object)->unchecked_first());
|
1453
1457
|
|
1454
1458
|
*slot = first;
|
1455
1459
|
|
1456
|
-
if (!
|
1460
|
+
if (!map->heap()->InNewSpace(first)) {
|
1457
1461
|
object->set_map_word(MapWord::FromForwardingAddress(first));
|
1458
1462
|
return;
|
1459
1463
|
}
|
@@ -1467,7 +1471,7 @@ class ScavengingVisitor : public StaticVisitorBase {
|
|
1467
1471
|
return;
|
1468
1472
|
}
|
1469
1473
|
|
1470
|
-
|
1474
|
+
DoScavengeObject(first->map(), slot, first);
|
1471
1475
|
object->set_map_word(MapWord::FromForwardingAddress(*slot));
|
1472
1476
|
return;
|
1473
1477
|
}
|
@@ -1494,26 +1498,59 @@ class ScavengingVisitor : public StaticVisitorBase {
|
|
1494
1498
|
}
|
1495
1499
|
};
|
1496
1500
|
|
1497
|
-
|
1498
|
-
|
1499
|
-
static VisitorDispatchTable<Callback> table_;
|
1501
|
+
static VisitorDispatchTable<ScavengingCallback> table_;
|
1500
1502
|
};
|
1501
1503
|
|
1502
1504
|
|
1503
|
-
|
1505
|
+
template<LoggingAndProfiling logging_and_profiling_mode>
|
1506
|
+
VisitorDispatchTable<ScavengingCallback>
|
1507
|
+
ScavengingVisitor<logging_and_profiling_mode>::table_;
|
1508
|
+
|
1509
|
+
|
1510
|
+
static void InitializeScavengingVisitorsTables() {
|
1511
|
+
ScavengingVisitor<LOGGING_AND_PROFILING_DISABLED>::Initialize();
|
1512
|
+
ScavengingVisitor<LOGGING_AND_PROFILING_ENABLED>::Initialize();
|
1513
|
+
scavenging_visitors_table_.CopyFrom(
|
1514
|
+
ScavengingVisitor<LOGGING_AND_PROFILING_DISABLED>::GetTable());
|
1515
|
+
scavenging_visitors_table_mode_ = LOGGING_AND_PROFILING_DISABLED;
|
1516
|
+
}
|
1517
|
+
|
1518
|
+
|
1519
|
+
void Heap::SwitchScavengingVisitorsTableIfProfilingWasEnabled() {
|
1520
|
+
if (scavenging_visitors_table_mode_ == LOGGING_AND_PROFILING_ENABLED) {
|
1521
|
+
// Table was already updated by some isolate.
|
1522
|
+
return;
|
1523
|
+
}
|
1524
|
+
|
1525
|
+
if (isolate()->logger()->is_logging() ||
|
1526
|
+
isolate()->cpu_profiler()->is_profiling() ||
|
1527
|
+
(isolate()->heap_profiler() != NULL &&
|
1528
|
+
isolate()->heap_profiler()->is_profiling())) {
|
1529
|
+
// If one of the isolates is doing scavenge at this moment of time
|
1530
|
+
// it might see this table in an inconsitent state when
|
1531
|
+
// some of the callbacks point to
|
1532
|
+
// ScavengingVisitor<LOGGING_AND_PROFILING_ENABLED> and others
|
1533
|
+
// to ScavengingVisitor<LOGGING_AND_PROFILING_DISABLED>.
|
1534
|
+
// However this does not lead to any bugs as such isolate does not have
|
1535
|
+
// profiling enabled and any isolate with enabled profiling is guaranteed
|
1536
|
+
// to see the table in the consistent state.
|
1537
|
+
scavenging_visitors_table_.CopyFrom(
|
1538
|
+
ScavengingVisitor<LOGGING_AND_PROFILING_ENABLED>::GetTable());
|
1539
|
+
|
1540
|
+
// We use Release_Store to prevent reordering of this write before writes
|
1541
|
+
// to the table.
|
1542
|
+
Release_Store(&scavenging_visitors_table_mode_,
|
1543
|
+
LOGGING_AND_PROFILING_ENABLED);
|
1544
|
+
}
|
1545
|
+
}
|
1504
1546
|
|
1505
1547
|
|
1506
1548
|
void Heap::ScavengeObjectSlow(HeapObject** p, HeapObject* object) {
|
1507
|
-
ASSERT(InFromSpace(object));
|
1549
|
+
ASSERT(HEAP->InFromSpace(object));
|
1508
1550
|
MapWord first_word = object->map_word();
|
1509
1551
|
ASSERT(!first_word.IsForwardingAddress());
|
1510
1552
|
Map* map = first_word.ToMap();
|
1511
|
-
|
1512
|
-
}
|
1513
|
-
|
1514
|
-
|
1515
|
-
void Heap::ScavengePointer(HeapObject** p) {
|
1516
|
-
ScavengeObject(p, *p);
|
1553
|
+
DoScavengeObject(map, p, object);
|
1517
1554
|
}
|
1518
1555
|
|
1519
1556
|
|
@@ -1528,9 +1565,8 @@ MaybeObject* Heap::AllocatePartialMap(InstanceType instance_type,
|
|
1528
1565
|
reinterpret_cast<Map*>(result)->set_map(raw_unchecked_meta_map());
|
1529
1566
|
reinterpret_cast<Map*>(result)->set_instance_type(instance_type);
|
1530
1567
|
reinterpret_cast<Map*>(result)->set_instance_size(instance_size);
|
1531
|
-
reinterpret_cast<Map*>(result)->
|
1532
|
-
|
1533
|
-
StaticVisitorBase::GetVisitorId(instance_type, instance_size));
|
1568
|
+
reinterpret_cast<Map*>(result)->set_visitor_id(
|
1569
|
+
StaticVisitorBase::GetVisitorId(instance_type, instance_size));
|
1534
1570
|
reinterpret_cast<Map*>(result)->set_inobject_properties(0);
|
1535
1571
|
reinterpret_cast<Map*>(result)->set_pre_allocated_property_fields(0);
|
1536
1572
|
reinterpret_cast<Map*>(result)->set_unused_property_fields(0);
|
@@ -1639,6 +1675,7 @@ bool Heap::CreateInitialMaps() {
|
|
1639
1675
|
if (!maybe_obj->ToObject(&obj)) return false;
|
1640
1676
|
}
|
1641
1677
|
set_null_value(obj);
|
1678
|
+
Oddball::cast(obj)->set_kind(Oddball::kNull);
|
1642
1679
|
|
1643
1680
|
// Allocate the empty descriptor array.
|
1644
1681
|
{ MaybeObject* maybe_obj = AllocateEmptyFixedArray();
|
@@ -1716,10 +1753,10 @@ bool Heap::CreateInitialMaps() {
|
|
1716
1753
|
set_empty_byte_array(ByteArray::cast(obj));
|
1717
1754
|
|
1718
1755
|
{ MaybeObject* maybe_obj =
|
1719
|
-
AllocateMap(
|
1756
|
+
AllocateMap(EXTERNAL_PIXEL_ARRAY_TYPE, ExternalArray::kAlignedSize);
|
1720
1757
|
if (!maybe_obj->ToObject(&obj)) return false;
|
1721
1758
|
}
|
1722
|
-
|
1759
|
+
set_external_pixel_array_map(Map::cast(obj));
|
1723
1760
|
|
1724
1761
|
{ MaybeObject* maybe_obj = AllocateMap(EXTERNAL_BYTE_ARRAY_TYPE,
|
1725
1762
|
ExternalArray::kAlignedSize);
|
@@ -1830,7 +1867,7 @@ bool Heap::CreateInitialMaps() {
|
|
1830
1867
|
}
|
1831
1868
|
set_message_object_map(Map::cast(obj));
|
1832
1869
|
|
1833
|
-
ASSERT(!
|
1870
|
+
ASSERT(!InNewSpace(empty_fixed_array()));
|
1834
1871
|
return true;
|
1835
1872
|
}
|
1836
1873
|
|
@@ -1883,12 +1920,13 @@ MaybeObject* Heap::AllocateJSGlobalPropertyCell(Object* value) {
|
|
1883
1920
|
|
1884
1921
|
|
1885
1922
|
MaybeObject* Heap::CreateOddball(const char* to_string,
|
1886
|
-
Object* to_number
|
1923
|
+
Object* to_number,
|
1924
|
+
byte kind) {
|
1887
1925
|
Object* result;
|
1888
1926
|
{ MaybeObject* maybe_result = Allocate(oddball_map(), OLD_DATA_SPACE);
|
1889
1927
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
1890
1928
|
}
|
1891
|
-
return Oddball::cast(result)->Initialize(to_string, to_number);
|
1929
|
+
return Oddball::cast(result)->Initialize(to_string, to_number, kind);
|
1892
1930
|
}
|
1893
1931
|
|
1894
1932
|
|
@@ -1900,7 +1938,7 @@ bool Heap::CreateApiObjects() {
|
|
1900
1938
|
}
|
1901
1939
|
set_neander_map(Map::cast(obj));
|
1902
1940
|
|
1903
|
-
{ MaybeObject* maybe_obj =
|
1941
|
+
{ MaybeObject* maybe_obj = AllocateJSObjectFromMap(neander_map());
|
1904
1942
|
if (!maybe_obj->ToObject(&obj)) return false;
|
1905
1943
|
}
|
1906
1944
|
Object* elements;
|
@@ -1915,20 +1953,6 @@ bool Heap::CreateApiObjects() {
|
|
1915
1953
|
}
|
1916
1954
|
|
1917
1955
|
|
1918
|
-
void Heap::CreateCEntryStub() {
|
1919
|
-
CEntryStub stub(1);
|
1920
|
-
set_c_entry_code(*stub.GetCode());
|
1921
|
-
}
|
1922
|
-
|
1923
|
-
|
1924
|
-
#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
|
1925
|
-
void Heap::CreateRegExpCEntryStub() {
|
1926
|
-
RegExpCEntryStub stub;
|
1927
|
-
set_re_c_entry_code(*stub.GetCode());
|
1928
|
-
}
|
1929
|
-
#endif
|
1930
|
-
|
1931
|
-
|
1932
1956
|
void Heap::CreateJSEntryStub() {
|
1933
1957
|
JSEntryStub stub;
|
1934
1958
|
set_js_entry_code(*stub.GetCode());
|
@@ -1941,14 +1965,6 @@ void Heap::CreateJSConstructEntryStub() {
|
|
1941
1965
|
}
|
1942
1966
|
|
1943
1967
|
|
1944
|
-
#if V8_TARGET_ARCH_ARM
|
1945
|
-
void Heap::CreateDirectCEntryStub() {
|
1946
|
-
DirectCEntryStub stub;
|
1947
|
-
set_direct_c_entry_code(*stub.GetCode());
|
1948
|
-
}
|
1949
|
-
#endif
|
1950
|
-
|
1951
|
-
|
1952
1968
|
void Heap::CreateFixedStubs() {
|
1953
1969
|
// Here we create roots for fixed stubs. They are needed at GC
|
1954
1970
|
// for cooking and uncooking (check out frames.cc).
|
@@ -1956,22 +1972,15 @@ void Heap::CreateFixedStubs() {
|
|
1956
1972
|
// stub cache for these stubs.
|
1957
1973
|
HandleScope scope;
|
1958
1974
|
// gcc-4.4 has problem generating correct code of following snippet:
|
1959
|
-
// {
|
1960
|
-
//
|
1975
|
+
// { JSEntryStub stub;
|
1976
|
+
// js_entry_code_ = *stub.GetCode();
|
1961
1977
|
// }
|
1962
|
-
// {
|
1963
|
-
//
|
1978
|
+
// { JSConstructEntryStub stub;
|
1979
|
+
// js_construct_entry_code_ = *stub.GetCode();
|
1964
1980
|
// }
|
1965
1981
|
// To workaround the problem, make separate functions without inlining.
|
1966
|
-
Heap::CreateCEntryStub();
|
1967
1982
|
Heap::CreateJSEntryStub();
|
1968
1983
|
Heap::CreateJSConstructEntryStub();
|
1969
|
-
#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
|
1970
|
-
Heap::CreateRegExpCEntryStub();
|
1971
|
-
#endif
|
1972
|
-
#if V8_TARGET_ARCH_ARM
|
1973
|
-
Heap::CreateDirectCEntryStub();
|
1974
|
-
#endif
|
1975
1984
|
}
|
1976
1985
|
|
1977
1986
|
|
@@ -1994,6 +2003,7 @@ bool Heap::CreateInitialObjects() {
|
|
1994
2003
|
if (!maybe_obj->ToObject(&obj)) return false;
|
1995
2004
|
}
|
1996
2005
|
set_undefined_value(obj);
|
2006
|
+
Oddball::cast(obj)->set_kind(Oddball::kUndefined);
|
1997
2007
|
ASSERT(!InNewSpace(undefined_value()));
|
1998
2008
|
|
1999
2009
|
// Allocate initial symbol table.
|
@@ -2013,39 +2023,50 @@ bool Heap::CreateInitialObjects() {
|
|
2013
2023
|
|
2014
2024
|
// Allocate the null_value
|
2015
2025
|
{ MaybeObject* maybe_obj =
|
2016
|
-
Oddball::cast(null_value())->Initialize("null",
|
2026
|
+
Oddball::cast(null_value())->Initialize("null",
|
2027
|
+
Smi::FromInt(0),
|
2028
|
+
Oddball::kNull);
|
2017
2029
|
if (!maybe_obj->ToObject(&obj)) return false;
|
2018
2030
|
}
|
2019
2031
|
|
2020
|
-
{ MaybeObject* maybe_obj = CreateOddball("true",
|
2032
|
+
{ MaybeObject* maybe_obj = CreateOddball("true",
|
2033
|
+
Smi::FromInt(1),
|
2034
|
+
Oddball::kTrue);
|
2021
2035
|
if (!maybe_obj->ToObject(&obj)) return false;
|
2022
2036
|
}
|
2023
2037
|
set_true_value(obj);
|
2024
2038
|
|
2025
|
-
{ MaybeObject* maybe_obj = CreateOddball("false",
|
2039
|
+
{ MaybeObject* maybe_obj = CreateOddball("false",
|
2040
|
+
Smi::FromInt(0),
|
2041
|
+
Oddball::kFalse);
|
2026
2042
|
if (!maybe_obj->ToObject(&obj)) return false;
|
2027
2043
|
}
|
2028
2044
|
set_false_value(obj);
|
2029
2045
|
|
2030
|
-
{ MaybeObject* maybe_obj = CreateOddball("hole",
|
2046
|
+
{ MaybeObject* maybe_obj = CreateOddball("hole",
|
2047
|
+
Smi::FromInt(-1),
|
2048
|
+
Oddball::kTheHole);
|
2031
2049
|
if (!maybe_obj->ToObject(&obj)) return false;
|
2032
2050
|
}
|
2033
2051
|
set_the_hole_value(obj);
|
2034
2052
|
|
2035
2053
|
{ MaybeObject* maybe_obj = CreateOddball("arguments_marker",
|
2036
|
-
Smi::FromInt(-4)
|
2054
|
+
Smi::FromInt(-4),
|
2055
|
+
Oddball::kArgumentMarker);
|
2037
2056
|
if (!maybe_obj->ToObject(&obj)) return false;
|
2038
2057
|
}
|
2039
2058
|
set_arguments_marker(obj);
|
2040
2059
|
|
2041
|
-
{ MaybeObject* maybe_obj =
|
2042
|
-
|
2060
|
+
{ MaybeObject* maybe_obj = CreateOddball("no_interceptor_result_sentinel",
|
2061
|
+
Smi::FromInt(-2),
|
2062
|
+
Oddball::kOther);
|
2043
2063
|
if (!maybe_obj->ToObject(&obj)) return false;
|
2044
2064
|
}
|
2045
2065
|
set_no_interceptor_result_sentinel(obj);
|
2046
2066
|
|
2047
|
-
{ MaybeObject* maybe_obj =
|
2048
|
-
|
2067
|
+
{ MaybeObject* maybe_obj = CreateOddball("termination_exception",
|
2068
|
+
Smi::FromInt(-3),
|
2069
|
+
Oddball::kOther);
|
2049
2070
|
if (!maybe_obj->ToObject(&obj)) return false;
|
2050
2071
|
}
|
2051
2072
|
set_termination_exception(obj);
|
@@ -2107,7 +2128,8 @@ bool Heap::CreateInitialObjects() {
|
|
2107
2128
|
{ MaybeObject* maybe_obj = StringDictionary::Allocate(Runtime::kNumFunctions);
|
2108
2129
|
if (!maybe_obj->ToObject(&obj)) return false;
|
2109
2130
|
}
|
2110
|
-
{ MaybeObject* maybe_obj = Runtime::InitializeIntrinsicFunctionNames(
|
2131
|
+
{ MaybeObject* maybe_obj = Runtime::InitializeIntrinsicFunctionNames(this,
|
2132
|
+
obj);
|
2111
2133
|
if (!maybe_obj->ToObject(&obj)) return false;
|
2112
2134
|
}
|
2113
2135
|
set_intrinsic_function_names(StringDictionary::cast(obj));
|
@@ -2127,20 +2149,20 @@ bool Heap::CreateInitialObjects() {
|
|
2127
2149
|
}
|
2128
2150
|
set_natives_source_cache(FixedArray::cast(obj));
|
2129
2151
|
|
2130
|
-
// Handling of script id generation is in
|
2152
|
+
// Handling of script id generation is in FACTORY->NewScript.
|
2131
2153
|
set_last_script_id(undefined_value());
|
2132
2154
|
|
2133
2155
|
// Initialize keyed lookup cache.
|
2134
|
-
|
2156
|
+
isolate_->keyed_lookup_cache()->Clear();
|
2135
2157
|
|
2136
2158
|
// Initialize context slot cache.
|
2137
|
-
|
2159
|
+
isolate_->context_slot_cache()->Clear();
|
2138
2160
|
|
2139
2161
|
// Initialize descriptor cache.
|
2140
|
-
|
2162
|
+
isolate_->descriptor_lookup_cache()->Clear();
|
2141
2163
|
|
2142
2164
|
// Initialize compilation cache.
|
2143
|
-
|
2165
|
+
isolate_->compilation_cache()->Clear();
|
2144
2166
|
|
2145
2167
|
return true;
|
2146
2168
|
}
|
@@ -2164,7 +2186,7 @@ void Heap::FlushNumberStringCache() {
|
|
2164
2186
|
// Flush the number to string cache.
|
2165
2187
|
int len = number_string_cache()->length();
|
2166
2188
|
for (int i = 0; i < len; i++) {
|
2167
|
-
number_string_cache()->set_undefined(i);
|
2189
|
+
number_string_cache()->set_undefined(this, i);
|
2168
2190
|
}
|
2169
2191
|
}
|
2170
2192
|
|
@@ -2216,7 +2238,7 @@ void Heap::SetNumberStringCache(Object* number, String* string) {
|
|
2216
2238
|
|
2217
2239
|
MaybeObject* Heap::NumberToString(Object* number,
|
2218
2240
|
bool check_number_string_cache) {
|
2219
|
-
|
2241
|
+
isolate_->counters()->number_to_string_runtime()->Increment();
|
2220
2242
|
if (check_number_string_cache) {
|
2221
2243
|
Object* cached = GetNumberStringCache(number);
|
2222
2244
|
if (cached != undefined_value()) {
|
@@ -2266,6 +2288,8 @@ Heap::RootListIndex Heap::RootIndexForExternalArrayType(
|
|
2266
2288
|
return kExternalUnsignedIntArrayMapRootIndex;
|
2267
2289
|
case kExternalFloatArray:
|
2268
2290
|
return kExternalFloatArrayMapRootIndex;
|
2291
|
+
case kExternalPixelArray:
|
2292
|
+
return kExternalPixelArrayMapRootIndex;
|
2269
2293
|
default:
|
2270
2294
|
UNREACHABLE();
|
2271
2295
|
return kUndefinedValueRootIndex;
|
@@ -2317,10 +2341,11 @@ MaybeObject* Heap::AllocateSharedFunctionInfo(Object* name) {
|
|
2317
2341
|
|
2318
2342
|
SharedFunctionInfo* share = SharedFunctionInfo::cast(result);
|
2319
2343
|
share->set_name(name);
|
2320
|
-
Code* illegal =
|
2344
|
+
Code* illegal = isolate_->builtins()->builtin(Builtins::kIllegal);
|
2321
2345
|
share->set_code(illegal);
|
2322
2346
|
share->set_scope_info(SerializedScopeInfo::Empty());
|
2323
|
-
Code* construct_stub =
|
2347
|
+
Code* construct_stub = isolate_->builtins()->builtin(
|
2348
|
+
Builtins::kJSConstructStubGeneric);
|
2324
2349
|
share->set_construct_stub(construct_stub);
|
2325
2350
|
share->set_expected_nof_properties(0);
|
2326
2351
|
share->set_length(0);
|
@@ -2378,20 +2403,21 @@ static inline bool Between(uint32_t character, uint32_t from, uint32_t to) {
|
|
2378
2403
|
|
2379
2404
|
|
2380
2405
|
MUST_USE_RESULT static inline MaybeObject* MakeOrFindTwoCharacterString(
|
2406
|
+
Heap* heap,
|
2381
2407
|
uint32_t c1,
|
2382
2408
|
uint32_t c2) {
|
2383
2409
|
String* symbol;
|
2384
2410
|
// Numeric strings have a different hash algorithm not known by
|
2385
2411
|
// LookupTwoCharsSymbolIfExists, so we skip this step for such strings.
|
2386
2412
|
if ((!Between(c1, '0', '9') || !Between(c2, '0', '9')) &&
|
2387
|
-
|
2413
|
+
heap->symbol_table()->LookupTwoCharsSymbolIfExists(c1, c2, &symbol)) {
|
2388
2414
|
return symbol;
|
2389
2415
|
// Now we know the length is 2, we might as well make use of that fact
|
2390
2416
|
// when building the new string.
|
2391
2417
|
} else if ((c1 | c2) <= String::kMaxAsciiCharCodeU) { // We can do this
|
2392
2418
|
ASSERT(IsPowerOf2(String::kMaxAsciiCharCodeU + 1)); // because of this.
|
2393
2419
|
Object* result;
|
2394
|
-
{ MaybeObject* maybe_result =
|
2420
|
+
{ MaybeObject* maybe_result = heap->AllocateRawAsciiString(2);
|
2395
2421
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
2396
2422
|
}
|
2397
2423
|
char* dest = SeqAsciiString::cast(result)->GetChars();
|
@@ -2400,7 +2426,7 @@ MUST_USE_RESULT static inline MaybeObject* MakeOrFindTwoCharacterString(
|
|
2400
2426
|
return result;
|
2401
2427
|
} else {
|
2402
2428
|
Object* result;
|
2403
|
-
{ MaybeObject* maybe_result =
|
2429
|
+
{ MaybeObject* maybe_result = heap->AllocateRawTwoByteString(2);
|
2404
2430
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
2405
2431
|
}
|
2406
2432
|
uc16* dest = SeqTwoByteString::cast(result)->GetChars();
|
@@ -2430,7 +2456,7 @@ MaybeObject* Heap::AllocateConsString(String* first, String* second) {
|
|
2430
2456
|
if (length == 2) {
|
2431
2457
|
unsigned c1 = first->Get(0);
|
2432
2458
|
unsigned c2 = second->Get(0);
|
2433
|
-
return MakeOrFindTwoCharacterString(c1, c2);
|
2459
|
+
return MakeOrFindTwoCharacterString(this, c1, c2);
|
2434
2460
|
}
|
2435
2461
|
|
2436
2462
|
bool first_is_ascii = first->IsAsciiRepresentation();
|
@@ -2440,7 +2466,7 @@ MaybeObject* Heap::AllocateConsString(String* first, String* second) {
|
|
2440
2466
|
// Make sure that an out of memory exception is thrown if the length
|
2441
2467
|
// of the new cons string is too large.
|
2442
2468
|
if (length > String::kMaxLength || length < 0) {
|
2443
|
-
|
2469
|
+
isolate()->context()->mark_out_of_memory();
|
2444
2470
|
return Failure::OutOfMemoryException();
|
2445
2471
|
}
|
2446
2472
|
|
@@ -2452,7 +2478,7 @@ MaybeObject* Heap::AllocateConsString(String* first, String* second) {
|
|
2452
2478
|
is_ascii_data_in_two_byte_string =
|
2453
2479
|
first->HasOnlyAsciiChars() && second->HasOnlyAsciiChars();
|
2454
2480
|
if (is_ascii_data_in_two_byte_string) {
|
2455
|
-
|
2481
|
+
isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment();
|
2456
2482
|
}
|
2457
2483
|
}
|
2458
2484
|
|
@@ -2493,6 +2519,7 @@ MaybeObject* Heap::AllocateConsString(String* first, String* second) {
|
|
2493
2519
|
char* dest = SeqAsciiString::cast(result)->GetChars();
|
2494
2520
|
String::WriteToFlat(first, dest, 0, first_length);
|
2495
2521
|
String::WriteToFlat(second, dest + first_length, 0, second_length);
|
2522
|
+
isolate_->counters()->string_add_runtime_ext_to_ascii()->Increment();
|
2496
2523
|
return result;
|
2497
2524
|
}
|
2498
2525
|
|
@@ -2534,15 +2561,14 @@ MaybeObject* Heap::AllocateSubString(String* buffer,
|
|
2534
2561
|
int length = end - start;
|
2535
2562
|
|
2536
2563
|
if (length == 1) {
|
2537
|
-
return
|
2538
|
-
buffer->Get(start));
|
2564
|
+
return LookupSingleCharacterStringFromCode(buffer->Get(start));
|
2539
2565
|
} else if (length == 2) {
|
2540
2566
|
// Optimization for 2-byte strings often used as keys in a decompression
|
2541
2567
|
// dictionary. Check whether we already have the string in the symbol
|
2542
2568
|
// table to prevent creation of many unneccesary strings.
|
2543
2569
|
unsigned c1 = buffer->Get(start);
|
2544
2570
|
unsigned c2 = buffer->Get(start + 1);
|
2545
|
-
return MakeOrFindTwoCharacterString(c1, c2);
|
2571
|
+
return MakeOrFindTwoCharacterString(this, c1, c2);
|
2546
2572
|
}
|
2547
2573
|
|
2548
2574
|
// Make an attempt to flatten the buffer to reduce access time.
|
@@ -2574,7 +2600,7 @@ MaybeObject* Heap::AllocateExternalStringFromAscii(
|
|
2574
2600
|
ExternalAsciiString::Resource* resource) {
|
2575
2601
|
size_t length = resource->length();
|
2576
2602
|
if (length > static_cast<size_t>(String::kMaxLength)) {
|
2577
|
-
|
2603
|
+
isolate()->context()->mark_out_of_memory();
|
2578
2604
|
return Failure::OutOfMemoryException();
|
2579
2605
|
}
|
2580
2606
|
|
@@ -2597,7 +2623,7 @@ MaybeObject* Heap::AllocateExternalStringFromTwoByte(
|
|
2597
2623
|
ExternalTwoByteString::Resource* resource) {
|
2598
2624
|
size_t length = resource->length();
|
2599
2625
|
if (length > static_cast<size_t>(String::kMaxLength)) {
|
2600
|
-
|
2626
|
+
isolate()->context()->mark_out_of_memory();
|
2601
2627
|
return Failure::OutOfMemoryException();
|
2602
2628
|
}
|
2603
2629
|
|
@@ -2607,7 +2633,7 @@ MaybeObject* Heap::AllocateExternalStringFromTwoByte(
|
|
2607
2633
|
bool is_ascii = length <= kAsciiCheckLengthLimit &&
|
2608
2634
|
String::IsAscii(resource->data(), static_cast<int>(length));
|
2609
2635
|
Map* map = is_ascii ?
|
2610
|
-
|
2636
|
+
external_string_with_ascii_data_map() : external_string_map();
|
2611
2637
|
Object* result;
|
2612
2638
|
{ MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
|
2613
2639
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
@@ -2624,8 +2650,8 @@ MaybeObject* Heap::AllocateExternalStringFromTwoByte(
|
|
2624
2650
|
|
2625
2651
|
MaybeObject* Heap::LookupSingleCharacterStringFromCode(uint16_t code) {
|
2626
2652
|
if (code <= String::kMaxAsciiCharCode) {
|
2627
|
-
Object* value =
|
2628
|
-
if (value !=
|
2653
|
+
Object* value = single_character_string_cache()->get(code);
|
2654
|
+
if (value != undefined_value()) return value;
|
2629
2655
|
|
2630
2656
|
char buffer[1];
|
2631
2657
|
buffer[0] = static_cast<char>(code);
|
@@ -2633,12 +2659,12 @@ MaybeObject* Heap::LookupSingleCharacterStringFromCode(uint16_t code) {
|
|
2633
2659
|
MaybeObject* maybe_result = LookupSymbol(Vector<const char>(buffer, 1));
|
2634
2660
|
|
2635
2661
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
2636
|
-
|
2662
|
+
single_character_string_cache()->set(code, result);
|
2637
2663
|
return result;
|
2638
2664
|
}
|
2639
2665
|
|
2640
2666
|
Object* result;
|
2641
|
-
{ MaybeObject* maybe_result =
|
2667
|
+
{ MaybeObject* maybe_result = AllocateRawTwoByteString(1);
|
2642
2668
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
2643
2669
|
}
|
2644
2670
|
String* answer = String::cast(result);
|
@@ -2700,24 +2726,6 @@ void Heap::CreateFillerObjectAt(Address addr, int size) {
|
|
2700
2726
|
}
|
2701
2727
|
|
2702
2728
|
|
2703
|
-
MaybeObject* Heap::AllocatePixelArray(int length,
|
2704
|
-
uint8_t* external_pointer,
|
2705
|
-
PretenureFlag pretenure) {
|
2706
|
-
AllocationSpace space = (pretenure == TENURED) ? OLD_DATA_SPACE : NEW_SPACE;
|
2707
|
-
Object* result;
|
2708
|
-
{ MaybeObject* maybe_result =
|
2709
|
-
AllocateRaw(PixelArray::kAlignedSize, space, OLD_DATA_SPACE);
|
2710
|
-
if (!maybe_result->ToObject(&result)) return maybe_result;
|
2711
|
-
}
|
2712
|
-
|
2713
|
-
reinterpret_cast<PixelArray*>(result)->set_map(pixel_array_map());
|
2714
|
-
reinterpret_cast<PixelArray*>(result)->set_length(length);
|
2715
|
-
reinterpret_cast<PixelArray*>(result)->set_external_pointer(external_pointer);
|
2716
|
-
|
2717
|
-
return result;
|
2718
|
-
}
|
2719
|
-
|
2720
|
-
|
2721
2729
|
MaybeObject* Heap::AllocateExternalArray(int length,
|
2722
2730
|
ExternalArrayType array_type,
|
2723
2731
|
void* external_pointer,
|
@@ -2742,7 +2750,8 @@ MaybeObject* Heap::AllocateExternalArray(int length,
|
|
2742
2750
|
|
2743
2751
|
MaybeObject* Heap::CreateCode(const CodeDesc& desc,
|
2744
2752
|
Code::Flags flags,
|
2745
|
-
Handle<Object> self_reference
|
2753
|
+
Handle<Object> self_reference,
|
2754
|
+
bool immovable) {
|
2746
2755
|
// Allocate ByteArray before the Code object, so that we do not risk
|
2747
2756
|
// leaving uninitialized Code object (and breaking the heap).
|
2748
2757
|
Object* reloc_info;
|
@@ -2750,12 +2759,14 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc,
|
|
2750
2759
|
if (!maybe_reloc_info->ToObject(&reloc_info)) return maybe_reloc_info;
|
2751
2760
|
}
|
2752
2761
|
|
2753
|
-
// Compute size
|
2762
|
+
// Compute size.
|
2754
2763
|
int body_size = RoundUp(desc.instr_size, kObjectAlignment);
|
2755
2764
|
int obj_size = Code::SizeFor(body_size);
|
2756
2765
|
ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment));
|
2757
2766
|
MaybeObject* maybe_result;
|
2758
|
-
|
2767
|
+
// Large code objects and code objects which should stay at a fixed address
|
2768
|
+
// are allocated in large object space.
|
2769
|
+
if (obj_size > MaxObjectSizeInPagedSpace() || immovable) {
|
2759
2770
|
maybe_result = lo_space_->AllocateRawCode(obj_size);
|
2760
2771
|
} else {
|
2761
2772
|
maybe_result = code_space_->AllocateRaw(obj_size);
|
@@ -2767,7 +2778,8 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc,
|
|
2767
2778
|
// Initialize the object
|
2768
2779
|
HeapObject::cast(result)->set_map(code_map());
|
2769
2780
|
Code* code = Code::cast(result);
|
2770
|
-
ASSERT(!
|
2781
|
+
ASSERT(!isolate_->code_range()->exists() ||
|
2782
|
+
isolate_->code_range()->contains(code->address()));
|
2771
2783
|
code->set_instruction_size(desc.instr_size);
|
2772
2784
|
code->set_relocation_info(ByteArray::cast(reloc_info));
|
2773
2785
|
code->set_flags(flags);
|
@@ -2813,7 +2825,8 @@ MaybeObject* Heap::CopyCode(Code* code) {
|
|
2813
2825
|
CopyBlock(new_addr, old_addr, obj_size);
|
2814
2826
|
// Relocate the copy.
|
2815
2827
|
Code* new_code = Code::cast(result);
|
2816
|
-
ASSERT(!
|
2828
|
+
ASSERT(!isolate_->code_range()->exists() ||
|
2829
|
+
isolate_->code_range()->contains(code->address()));
|
2817
2830
|
new_code->Relocate(new_addr - old_addr);
|
2818
2831
|
return new_code;
|
2819
2832
|
}
|
@@ -2862,7 +2875,8 @@ MaybeObject* Heap::CopyCode(Code* code, Vector<byte> reloc_info) {
|
|
2862
2875
|
memcpy(new_code->relocation_start(), reloc_info.start(), reloc_info.length());
|
2863
2876
|
|
2864
2877
|
// Relocate the copy.
|
2865
|
-
ASSERT(!
|
2878
|
+
ASSERT(!isolate_->code_range()->exists() ||
|
2879
|
+
isolate_->code_range()->contains(code->address()));
|
2866
2880
|
new_code->Relocate(new_addr - old_addr);
|
2867
2881
|
|
2868
2882
|
#ifdef DEBUG
|
@@ -2886,7 +2900,7 @@ MaybeObject* Heap::Allocate(Map* map, AllocationSpace space) {
|
|
2886
2900
|
}
|
2887
2901
|
HeapObject::cast(result)->set_map(map);
|
2888
2902
|
#ifdef ENABLE_LOGGING_AND_PROFILING
|
2889
|
-
|
2903
|
+
isolate_->producer_heap_profile()->RecordJSObjectAllocation(result);
|
2890
2904
|
#endif
|
2891
2905
|
return result;
|
2892
2906
|
}
|
@@ -2948,22 +2962,34 @@ MaybeObject* Heap::AllocateArgumentsObject(Object* callee, int length) {
|
|
2948
2962
|
// To get fast allocation and map sharing for arguments objects we
|
2949
2963
|
// allocate them based on an arguments boilerplate.
|
2950
2964
|
|
2965
|
+
JSObject* boilerplate;
|
2966
|
+
int arguments_object_size;
|
2967
|
+
bool strict_mode_callee = callee->IsJSFunction() &&
|
2968
|
+
JSFunction::cast(callee)->shared()->strict_mode();
|
2969
|
+
if (strict_mode_callee) {
|
2970
|
+
boilerplate =
|
2971
|
+
isolate()->context()->global_context()->
|
2972
|
+
strict_mode_arguments_boilerplate();
|
2973
|
+
arguments_object_size = kArgumentsObjectSizeStrict;
|
2974
|
+
} else {
|
2975
|
+
boilerplate =
|
2976
|
+
isolate()->context()->global_context()->arguments_boilerplate();
|
2977
|
+
arguments_object_size = kArgumentsObjectSize;
|
2978
|
+
}
|
2979
|
+
|
2951
2980
|
// This calls Copy directly rather than using Heap::AllocateRaw so we
|
2952
2981
|
// duplicate the check here.
|
2953
2982
|
ASSERT(allocation_allowed_ && gc_state_ == NOT_IN_GC);
|
2954
2983
|
|
2955
|
-
JSObject* boilerplate =
|
2956
|
-
Top::context()->global_context()->arguments_boilerplate();
|
2957
|
-
|
2958
2984
|
// Check that the size of the boilerplate matches our
|
2959
2985
|
// expectations. The ArgumentsAccessStub::GenerateNewObject relies
|
2960
2986
|
// on the size being a known constant.
|
2961
|
-
ASSERT(
|
2987
|
+
ASSERT(arguments_object_size == boilerplate->map()->instance_size());
|
2962
2988
|
|
2963
2989
|
// Do the allocation.
|
2964
2990
|
Object* result;
|
2965
2991
|
{ MaybeObject* maybe_result =
|
2966
|
-
AllocateRaw(
|
2992
|
+
AllocateRaw(arguments_object_size, NEW_SPACE, OLD_POINTER_SPACE);
|
2967
2993
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
2968
2994
|
}
|
2969
2995
|
|
@@ -2972,14 +2998,17 @@ MaybeObject* Heap::AllocateArgumentsObject(Object* callee, int length) {
|
|
2972
2998
|
// barrier here.
|
2973
2999
|
CopyBlock(HeapObject::cast(result)->address(),
|
2974
3000
|
boilerplate->address(),
|
2975
|
-
|
3001
|
+
JSObject::kHeaderSize);
|
2976
3002
|
|
2977
|
-
// Set the
|
2978
|
-
JSObject::cast(result)->InObjectPropertyAtPut(
|
2979
|
-
callee);
|
2980
|
-
JSObject::cast(result)->InObjectPropertyAtPut(arguments_length_index,
|
3003
|
+
// Set the length property.
|
3004
|
+
JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsLengthIndex,
|
2981
3005
|
Smi::FromInt(length),
|
2982
3006
|
SKIP_WRITE_BARRIER);
|
3007
|
+
// Set the callee property for non-strict mode arguments object only.
|
3008
|
+
if (!strict_mode_callee) {
|
3009
|
+
JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsCalleeIndex,
|
3010
|
+
callee);
|
3011
|
+
}
|
2983
3012
|
|
2984
3013
|
// Check the state of the object
|
2985
3014
|
ASSERT(JSObject::cast(result)->HasFastProperties());
|
@@ -3011,8 +3040,7 @@ MaybeObject* Heap::AllocateInitialMap(JSFunction* fun) {
|
|
3011
3040
|
int instance_size = fun->shared()->CalculateInstanceSize();
|
3012
3041
|
int in_object_properties = fun->shared()->CalculateInObjectProperties();
|
3013
3042
|
Object* map_obj;
|
3014
|
-
{ MaybeObject* maybe_map_obj =
|
3015
|
-
Heap::AllocateMap(JS_OBJECT_TYPE, instance_size);
|
3043
|
+
{ MaybeObject* maybe_map_obj = AllocateMap(JS_OBJECT_TYPE, instance_size);
|
3016
3044
|
if (!maybe_map_obj->ToObject(&map_obj)) return maybe_map_obj;
|
3017
3045
|
}
|
3018
3046
|
|
@@ -3208,7 +3236,7 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) {
|
|
3208
3236
|
PropertyDetails d =
|
3209
3237
|
PropertyDetails(details.attributes(), CALLBACKS, details.index());
|
3210
3238
|
Object* value = descs->GetCallbacksObject(i);
|
3211
|
-
{ MaybeObject* maybe_value =
|
3239
|
+
{ MaybeObject* maybe_value = AllocateJSGlobalPropertyCell(value);
|
3212
3240
|
if (!maybe_value->ToObject(&value)) return maybe_value;
|
3213
3241
|
}
|
3214
3242
|
|
@@ -3234,7 +3262,7 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) {
|
|
3234
3262
|
|
3235
3263
|
// Setup the global object as a normalized object.
|
3236
3264
|
global->set_map(new_map);
|
3237
|
-
global->map()->set_instance_descriptors(
|
3265
|
+
global->map()->set_instance_descriptors(empty_descriptor_array());
|
3238
3266
|
global->set_properties(dictionary);
|
3239
3267
|
|
3240
3268
|
// Make sure result is a global object with properties in dictionary.
|
@@ -3273,7 +3301,7 @@ MaybeObject* Heap::CopyJSObject(JSObject* source) {
|
|
3273
3301
|
{ MaybeObject* maybe_clone = new_space_.AllocateRaw(object_size);
|
3274
3302
|
if (!maybe_clone->ToObject(&clone)) return maybe_clone;
|
3275
3303
|
}
|
3276
|
-
ASSERT(
|
3304
|
+
ASSERT(InNewSpace(clone));
|
3277
3305
|
// Since we know the clone is allocated in new space, we can copy
|
3278
3306
|
// the contents without worrying about updating the write barrier.
|
3279
3307
|
CopyBlock(HeapObject::cast(clone)->address(),
|
@@ -3303,7 +3331,7 @@ MaybeObject* Heap::CopyJSObject(JSObject* source) {
|
|
3303
3331
|
}
|
3304
3332
|
// Return the new clone.
|
3305
3333
|
#ifdef ENABLE_LOGGING_AND_PROFILING
|
3306
|
-
|
3334
|
+
isolate_->producer_heap_profile()->RecordJSObjectAllocation(clone);
|
3307
3335
|
#endif
|
3308
3336
|
return clone;
|
3309
3337
|
}
|
@@ -3359,7 +3387,7 @@ MaybeObject* Heap::AllocateStringFromUtf8Slow(Vector<const char> string,
|
|
3359
3387
|
// Count the number of characters in the UTF-8 string and check if
|
3360
3388
|
// it is an ASCII string.
|
3361
3389
|
Access<ScannerConstants::Utf8Decoder>
|
3362
|
-
decoder(
|
3390
|
+
decoder(isolate_->scanner_constants()->utf8_decoder());
|
3363
3391
|
decoder->Reset(string.start(), string.length());
|
3364
3392
|
int chars = 0;
|
3365
3393
|
while (decoder->has_more()) {
|
@@ -3412,12 +3440,24 @@ Map* Heap::SymbolMapForString(String* string) {
|
|
3412
3440
|
|
3413
3441
|
// Find the corresponding symbol map for strings.
|
3414
3442
|
Map* map = string->map();
|
3415
|
-
if (map == ascii_string_map())
|
3416
|
-
|
3417
|
-
|
3418
|
-
if (map ==
|
3419
|
-
|
3420
|
-
|
3443
|
+
if (map == ascii_string_map()) {
|
3444
|
+
return ascii_symbol_map();
|
3445
|
+
}
|
3446
|
+
if (map == string_map()) {
|
3447
|
+
return symbol_map();
|
3448
|
+
}
|
3449
|
+
if (map == cons_string_map()) {
|
3450
|
+
return cons_symbol_map();
|
3451
|
+
}
|
3452
|
+
if (map == cons_ascii_string_map()) {
|
3453
|
+
return cons_ascii_symbol_map();
|
3454
|
+
}
|
3455
|
+
if (map == external_string_map()) {
|
3456
|
+
return external_symbol_map();
|
3457
|
+
}
|
3458
|
+
if (map == external_ascii_string_map()) {
|
3459
|
+
return external_ascii_symbol_map();
|
3460
|
+
}
|
3421
3461
|
if (map == external_string_with_ascii_data_map()) {
|
3422
3462
|
return external_symbol_with_ascii_data_map();
|
3423
3463
|
}
|
@@ -3591,7 +3631,7 @@ MaybeObject* Heap::CopyFixedArrayWithMap(FixedArray* src, Map* map) {
|
|
3591
3631
|
{ MaybeObject* maybe_obj = AllocateRawFixedArray(len);
|
3592
3632
|
if (!maybe_obj->ToObject(&obj)) return maybe_obj;
|
3593
3633
|
}
|
3594
|
-
if (
|
3634
|
+
if (InNewSpace(obj)) {
|
3595
3635
|
HeapObject* dst = HeapObject::cast(obj);
|
3596
3636
|
dst->set_map(map);
|
3597
3637
|
CopyBlock(dst->address() + kPointerSize,
|
@@ -3623,7 +3663,7 @@ MaybeObject* Heap::AllocateFixedArray(int length) {
|
|
3623
3663
|
array->set_map(fixed_array_map());
|
3624
3664
|
array->set_length(length);
|
3625
3665
|
// Initialize body.
|
3626
|
-
ASSERT(!
|
3666
|
+
ASSERT(!InNewSpace(undefined_value()));
|
3627
3667
|
MemsetPointer(array->data_start(), undefined_value(), length);
|
3628
3668
|
return result;
|
3629
3669
|
}
|
@@ -3654,20 +3694,21 @@ MaybeObject* Heap::AllocateRawFixedArray(int length, PretenureFlag pretenure) {
|
|
3654
3694
|
|
3655
3695
|
|
3656
3696
|
MUST_USE_RESULT static MaybeObject* AllocateFixedArrayWithFiller(
|
3697
|
+
Heap* heap,
|
3657
3698
|
int length,
|
3658
3699
|
PretenureFlag pretenure,
|
3659
3700
|
Object* filler) {
|
3660
3701
|
ASSERT(length >= 0);
|
3661
|
-
ASSERT(
|
3662
|
-
if (length == 0) return
|
3702
|
+
ASSERT(heap->empty_fixed_array()->IsFixedArray());
|
3703
|
+
if (length == 0) return heap->empty_fixed_array();
|
3663
3704
|
|
3664
|
-
ASSERT(!
|
3705
|
+
ASSERT(!heap->InNewSpace(filler));
|
3665
3706
|
Object* result;
|
3666
|
-
{ MaybeObject* maybe_result =
|
3707
|
+
{ MaybeObject* maybe_result = heap->AllocateRawFixedArray(length, pretenure);
|
3667
3708
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
3668
3709
|
}
|
3669
3710
|
|
3670
|
-
HeapObject::cast(result)->set_map(
|
3711
|
+
HeapObject::cast(result)->set_map(heap->fixed_array_map());
|
3671
3712
|
FixedArray* array = FixedArray::cast(result);
|
3672
3713
|
array->set_length(length);
|
3673
3714
|
MemsetPointer(array->data_start(), filler, length);
|
@@ -3676,13 +3717,19 @@ MUST_USE_RESULT static MaybeObject* AllocateFixedArrayWithFiller(
|
|
3676
3717
|
|
3677
3718
|
|
3678
3719
|
MaybeObject* Heap::AllocateFixedArray(int length, PretenureFlag pretenure) {
|
3679
|
-
return AllocateFixedArrayWithFiller(
|
3720
|
+
return AllocateFixedArrayWithFiller(this,
|
3721
|
+
length,
|
3722
|
+
pretenure,
|
3723
|
+
undefined_value());
|
3680
3724
|
}
|
3681
3725
|
|
3682
3726
|
|
3683
3727
|
MaybeObject* Heap::AllocateFixedArrayWithHoles(int length,
|
3684
3728
|
PretenureFlag pretenure) {
|
3685
|
-
return AllocateFixedArrayWithFiller(
|
3729
|
+
return AllocateFixedArrayWithFiller(this,
|
3730
|
+
length,
|
3731
|
+
pretenure,
|
3732
|
+
the_hole_value());
|
3686
3733
|
}
|
3687
3734
|
|
3688
3735
|
|
@@ -3702,7 +3749,7 @@ MaybeObject* Heap::AllocateUninitializedFixedArray(int length) {
|
|
3702
3749
|
|
3703
3750
|
MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) {
|
3704
3751
|
Object* result;
|
3705
|
-
{ MaybeObject* maybe_result =
|
3752
|
+
{ MaybeObject* maybe_result = AllocateFixedArray(length, pretenure);
|
3706
3753
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
3707
3754
|
}
|
3708
3755
|
reinterpret_cast<HeapObject*>(result)->set_map(hash_table_map());
|
@@ -3714,7 +3761,7 @@ MaybeObject* Heap::AllocateHashTable(int length, PretenureFlag pretenure) {
|
|
3714
3761
|
MaybeObject* Heap::AllocateGlobalContext() {
|
3715
3762
|
Object* result;
|
3716
3763
|
{ MaybeObject* maybe_result =
|
3717
|
-
|
3764
|
+
AllocateFixedArray(Context::GLOBAL_CONTEXT_SLOTS);
|
3718
3765
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
3719
3766
|
}
|
3720
3767
|
Context* context = reinterpret_cast<Context*>(result);
|
@@ -3728,7 +3775,7 @@ MaybeObject* Heap::AllocateGlobalContext() {
|
|
3728
3775
|
MaybeObject* Heap::AllocateFunctionContext(int length, JSFunction* function) {
|
3729
3776
|
ASSERT(length >= Context::MIN_CONTEXT_SLOTS);
|
3730
3777
|
Object* result;
|
3731
|
-
{ MaybeObject* maybe_result =
|
3778
|
+
{ MaybeObject* maybe_result = AllocateFixedArray(length);
|
3732
3779
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
3733
3780
|
}
|
3734
3781
|
Context* context = reinterpret_cast<Context*>(result);
|
@@ -3749,12 +3796,12 @@ MaybeObject* Heap::AllocateWithContext(Context* previous,
|
|
3749
3796
|
JSObject* extension,
|
3750
3797
|
bool is_catch_context) {
|
3751
3798
|
Object* result;
|
3752
|
-
{ MaybeObject* maybe_result =
|
3753
|
-
Heap::AllocateFixedArray(Context::MIN_CONTEXT_SLOTS);
|
3799
|
+
{ MaybeObject* maybe_result = AllocateFixedArray(Context::MIN_CONTEXT_SLOTS);
|
3754
3800
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
3755
3801
|
}
|
3756
3802
|
Context* context = reinterpret_cast<Context*>(result);
|
3757
|
-
context->set_map(is_catch_context ? catch_context_map() :
|
3803
|
+
context->set_map(is_catch_context ? catch_context_map() :
|
3804
|
+
context_map());
|
3758
3805
|
context->set_closure(previous->closure());
|
3759
3806
|
context->set_fcontext(previous->fcontext());
|
3760
3807
|
context->set_previous(previous);
|
@@ -3770,7 +3817,8 @@ MaybeObject* Heap::AllocateWithContext(Context* previous,
|
|
3770
3817
|
MaybeObject* Heap::AllocateStruct(InstanceType type) {
|
3771
3818
|
Map* map;
|
3772
3819
|
switch (type) {
|
3773
|
-
#define MAKE_CASE(NAME, Name, name)
|
3820
|
+
#define MAKE_CASE(NAME, Name, name) \
|
3821
|
+
case NAME##_TYPE: map = name##_map(); break;
|
3774
3822
|
STRUCT_LIST(MAKE_CASE)
|
3775
3823
|
#undef MAKE_CASE
|
3776
3824
|
default:
|
@@ -3781,7 +3829,7 @@ STRUCT_LIST(MAKE_CASE)
|
|
3781
3829
|
AllocationSpace space =
|
3782
3830
|
(size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : OLD_POINTER_SPACE;
|
3783
3831
|
Object* result;
|
3784
|
-
{ MaybeObject* maybe_result =
|
3832
|
+
{ MaybeObject* maybe_result = Allocate(map, space);
|
3785
3833
|
if (!maybe_result->ToObject(&result)) return maybe_result;
|
3786
3834
|
}
|
3787
3835
|
Struct::cast(result)->InitializeBody(size);
|
@@ -3795,8 +3843,11 @@ bool Heap::IdleNotification() {
|
|
3795
3843
|
static const int kIdlesBeforeMarkCompact = 8;
|
3796
3844
|
static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1;
|
3797
3845
|
static const unsigned int kGCsBetweenCleanup = 4;
|
3798
|
-
|
3799
|
-
|
3846
|
+
|
3847
|
+
if (!last_idle_notification_gc_count_init_) {
|
3848
|
+
last_idle_notification_gc_count_ = gc_count_;
|
3849
|
+
last_idle_notification_gc_count_init_ = true;
|
3850
|
+
}
|
3800
3851
|
|
3801
3852
|
bool uncommit = true;
|
3802
3853
|
bool finished = false;
|
@@ -3805,56 +3856,56 @@ bool Heap::IdleNotification() {
|
|
3805
3856
|
// GCs have taken place. This allows another round of cleanup based
|
3806
3857
|
// on idle notifications if enough work has been carried out to
|
3807
3858
|
// provoke a number of garbage collections.
|
3808
|
-
if (gc_count_ -
|
3809
|
-
|
3810
|
-
Min(
|
3859
|
+
if (gc_count_ - last_idle_notification_gc_count_ < kGCsBetweenCleanup) {
|
3860
|
+
number_idle_notifications_ =
|
3861
|
+
Min(number_idle_notifications_ + 1, kMaxIdleCount);
|
3811
3862
|
} else {
|
3812
|
-
|
3813
|
-
|
3863
|
+
number_idle_notifications_ = 0;
|
3864
|
+
last_idle_notification_gc_count_ = gc_count_;
|
3814
3865
|
}
|
3815
3866
|
|
3816
|
-
if (
|
3867
|
+
if (number_idle_notifications_ == kIdlesBeforeScavenge) {
|
3817
3868
|
if (contexts_disposed_ > 0) {
|
3818
|
-
HistogramTimerScope scope(
|
3869
|
+
HistogramTimerScope scope(isolate_->counters()->gc_context());
|
3819
3870
|
CollectAllGarbage(false);
|
3820
3871
|
} else {
|
3821
3872
|
CollectGarbage(NEW_SPACE);
|
3822
3873
|
}
|
3823
3874
|
new_space_.Shrink();
|
3824
|
-
|
3825
|
-
} else if (
|
3875
|
+
last_idle_notification_gc_count_ = gc_count_;
|
3876
|
+
} else if (number_idle_notifications_ == kIdlesBeforeMarkSweep) {
|
3826
3877
|
// Before doing the mark-sweep collections we clear the
|
3827
3878
|
// compilation cache to avoid hanging on to source code and
|
3828
3879
|
// generated code for cached functions.
|
3829
|
-
|
3880
|
+
isolate_->compilation_cache()->Clear();
|
3830
3881
|
|
3831
3882
|
CollectAllGarbage(false);
|
3832
3883
|
new_space_.Shrink();
|
3833
|
-
|
3884
|
+
last_idle_notification_gc_count_ = gc_count_;
|
3834
3885
|
|
3835
|
-
} else if (
|
3886
|
+
} else if (number_idle_notifications_ == kIdlesBeforeMarkCompact) {
|
3836
3887
|
CollectAllGarbage(true);
|
3837
3888
|
new_space_.Shrink();
|
3838
|
-
|
3889
|
+
last_idle_notification_gc_count_ = gc_count_;
|
3890
|
+
number_idle_notifications_ = 0;
|
3839
3891
|
finished = true;
|
3840
|
-
|
3841
3892
|
} else if (contexts_disposed_ > 0) {
|
3842
3893
|
if (FLAG_expose_gc) {
|
3843
3894
|
contexts_disposed_ = 0;
|
3844
3895
|
} else {
|
3845
|
-
HistogramTimerScope scope(
|
3896
|
+
HistogramTimerScope scope(isolate_->counters()->gc_context());
|
3846
3897
|
CollectAllGarbage(false);
|
3847
|
-
|
3898
|
+
last_idle_notification_gc_count_ = gc_count_;
|
3848
3899
|
}
|
3849
3900
|
// If this is the first idle notification, we reset the
|
3850
3901
|
// notification count to avoid letting idle notifications for
|
3851
3902
|
// context disposal garbage collections start a potentially too
|
3852
3903
|
// aggressive idle GC cycle.
|
3853
|
-
if (
|
3854
|
-
|
3904
|
+
if (number_idle_notifications_ <= 1) {
|
3905
|
+
number_idle_notifications_ = 0;
|
3855
3906
|
uncommit = false;
|
3856
3907
|
}
|
3857
|
-
} else if (
|
3908
|
+
} else if (number_idle_notifications_ > kIdlesBeforeMarkCompact) {
|
3858
3909
|
// If we have received more than kIdlesBeforeMarkCompact idle
|
3859
3910
|
// notifications we do not perform any cleanup because we don't
|
3860
3911
|
// expect to gain much by doing so.
|
@@ -3864,7 +3915,7 @@ bool Heap::IdleNotification() {
|
|
3864
3915
|
// Make sure that we have no pending context disposals and
|
3865
3916
|
// conditionally uncommit from space.
|
3866
3917
|
ASSERT(contexts_disposed_ == 0);
|
3867
|
-
if (uncommit)
|
3918
|
+
if (uncommit) UncommitFromSpace();
|
3868
3919
|
return finished;
|
3869
3920
|
}
|
3870
3921
|
|
@@ -3873,7 +3924,7 @@ bool Heap::IdleNotification() {
|
|
3873
3924
|
|
3874
3925
|
void Heap::Print() {
|
3875
3926
|
if (!HasBeenSetup()) return;
|
3876
|
-
|
3927
|
+
isolate()->PrintStack();
|
3877
3928
|
AllSpaces spaces;
|
3878
3929
|
for (Space* space = spaces.next(); space != NULL; space = spaces.next())
|
3879
3930
|
space->Print();
|
@@ -3906,11 +3957,11 @@ void Heap::ReportHeapStatistics(const char* title) {
|
|
3906
3957
|
|
3907
3958
|
PrintF("\n");
|
3908
3959
|
PrintF("Number of handles : %d\n", HandleScope::NumberOfHandles());
|
3909
|
-
|
3960
|
+
isolate_->global_handles()->PrintStats();
|
3910
3961
|
PrintF("\n");
|
3911
3962
|
|
3912
3963
|
PrintF("Heap statistics : ");
|
3913
|
-
|
3964
|
+
isolate_->memory_allocator()->ReportStatistics();
|
3914
3965
|
PrintF("To space : ");
|
3915
3966
|
new_space_.ReportStatistics();
|
3916
3967
|
PrintF("Old pointer space : ");
|
@@ -3993,7 +4044,7 @@ static void VerifyPointersUnderWatermark(
|
|
3993
4044
|
Address start = page->ObjectAreaStart();
|
3994
4045
|
Address end = page->AllocationWatermark();
|
3995
4046
|
|
3996
|
-
|
4047
|
+
HEAP->IterateDirtyRegions(Page::kAllRegionsDirtyMarks,
|
3997
4048
|
start,
|
3998
4049
|
end,
|
3999
4050
|
visit_dirty_region,
|
@@ -4014,7 +4065,7 @@ static void VerifyPointersUnderWatermark(LargeObjectSpace* space) {
|
|
4014
4065
|
// When we are not in GC the Heap::InNewSpace() predicate
|
4015
4066
|
// checks that pointers which satisfy predicate point into
|
4016
4067
|
// the active semispace.
|
4017
|
-
|
4068
|
+
HEAP->InNewSpace(*slot);
|
4018
4069
|
slot_address += kPointerSize;
|
4019
4070
|
}
|
4020
4071
|
}
|
@@ -4135,7 +4186,8 @@ void Heap::ZapFromSpace() {
|
|
4135
4186
|
#endif // DEBUG
|
4136
4187
|
|
4137
4188
|
|
4138
|
-
bool Heap::IteratePointersInDirtyRegion(
|
4189
|
+
bool Heap::IteratePointersInDirtyRegion(Heap* heap,
|
4190
|
+
Address start,
|
4139
4191
|
Address end,
|
4140
4192
|
ObjectSlotCallback copy_object_func) {
|
4141
4193
|
Address slot_address = start;
|
@@ -4143,10 +4195,10 @@ bool Heap::IteratePointersInDirtyRegion(Address start,
|
|
4143
4195
|
|
4144
4196
|
while (slot_address < end) {
|
4145
4197
|
Object** slot = reinterpret_cast<Object**>(slot_address);
|
4146
|
-
if (
|
4198
|
+
if (heap->InNewSpace(*slot)) {
|
4147
4199
|
ASSERT((*slot)->IsHeapObject());
|
4148
4200
|
copy_object_func(reinterpret_cast<HeapObject**>(slot));
|
4149
|
-
if (
|
4201
|
+
if (heap->InNewSpace(*slot)) {
|
4150
4202
|
ASSERT((*slot)->IsHeapObject());
|
4151
4203
|
pointers_to_new_space_found = true;
|
4152
4204
|
}
|
@@ -4180,14 +4232,16 @@ static bool IteratePointersInDirtyMaps(Address start,
|
|
4180
4232
|
Address map_address = start;
|
4181
4233
|
bool pointers_to_new_space_found = false;
|
4182
4234
|
|
4235
|
+
Heap* heap = HEAP;
|
4183
4236
|
while (map_address < end) {
|
4184
|
-
ASSERT(!
|
4237
|
+
ASSERT(!heap->InNewSpace(Memory::Object_at(map_address)));
|
4185
4238
|
ASSERT(Memory::Object_at(map_address)->IsMap());
|
4186
4239
|
|
4187
4240
|
Address pointer_fields_start = map_address + Map::kPointerFieldsBeginOffset;
|
4188
4241
|
Address pointer_fields_end = map_address + Map::kPointerFieldsEndOffset;
|
4189
4242
|
|
4190
|
-
if (Heap::IteratePointersInDirtyRegion(
|
4243
|
+
if (Heap::IteratePointersInDirtyRegion(heap,
|
4244
|
+
pointer_fields_start,
|
4191
4245
|
pointer_fields_end,
|
4192
4246
|
copy_object_func)) {
|
4193
4247
|
pointers_to_new_space_found = true;
|
@@ -4201,6 +4255,7 @@ static bool IteratePointersInDirtyMaps(Address start,
|
|
4201
4255
|
|
4202
4256
|
|
4203
4257
|
bool Heap::IteratePointersInDirtyMapsRegion(
|
4258
|
+
Heap* heap,
|
4204
4259
|
Address start,
|
4205
4260
|
Address end,
|
4206
4261
|
ObjectSlotCallback copy_object_func) {
|
@@ -4220,7 +4275,8 @@ bool Heap::IteratePointersInDirtyMapsRegion(
|
|
4220
4275
|
Min(prev_map + Map::kPointerFieldsEndOffset, end);
|
4221
4276
|
|
4222
4277
|
contains_pointers_to_new_space =
|
4223
|
-
IteratePointersInDirtyRegion(
|
4278
|
+
IteratePointersInDirtyRegion(heap,
|
4279
|
+
pointer_fields_start,
|
4224
4280
|
pointer_fields_end,
|
4225
4281
|
copy_object_func)
|
4226
4282
|
|| contains_pointers_to_new_space;
|
@@ -4242,7 +4298,8 @@ bool Heap::IteratePointersInDirtyMapsRegion(
|
|
4242
4298
|
Min(end, map_aligned_end + Map::kPointerFieldsEndOffset);
|
4243
4299
|
|
4244
4300
|
contains_pointers_to_new_space =
|
4245
|
-
IteratePointersInDirtyRegion(
|
4301
|
+
IteratePointersInDirtyRegion(heap,
|
4302
|
+
pointer_fields_start,
|
4246
4303
|
pointer_fields_end,
|
4247
4304
|
copy_object_func)
|
4248
4305
|
|| contains_pointers_to_new_space;
|
@@ -4262,10 +4319,10 @@ void Heap::IterateAndMarkPointersToFromSpace(Address start,
|
|
4262
4319
|
|
4263
4320
|
while (slot_address < end) {
|
4264
4321
|
Object** slot = reinterpret_cast<Object**>(slot_address);
|
4265
|
-
if (
|
4322
|
+
if (InFromSpace(*slot)) {
|
4266
4323
|
ASSERT((*slot)->IsHeapObject());
|
4267
4324
|
callback(reinterpret_cast<HeapObject**>(slot));
|
4268
|
-
if (
|
4325
|
+
if (InNewSpace(*slot)) {
|
4269
4326
|
ASSERT((*slot)->IsHeapObject());
|
4270
4327
|
marks |= page->GetRegionMaskForAddress(slot_address);
|
4271
4328
|
}
|
@@ -4304,7 +4361,7 @@ uint32_t Heap::IterateDirtyRegions(
|
|
4304
4361
|
Address region_end = Min(second_region, area_end);
|
4305
4362
|
|
4306
4363
|
if (marks & mask) {
|
4307
|
-
if (visit_dirty_region(region_start, region_end, copy_object_func)) {
|
4364
|
+
if (visit_dirty_region(this, region_start, region_end, copy_object_func)) {
|
4308
4365
|
newmarks |= mask;
|
4309
4366
|
}
|
4310
4367
|
}
|
@@ -4316,7 +4373,10 @@ uint32_t Heap::IterateDirtyRegions(
|
|
4316
4373
|
|
4317
4374
|
while (region_end <= area_end) {
|
4318
4375
|
if (marks & mask) {
|
4319
|
-
if (visit_dirty_region(
|
4376
|
+
if (visit_dirty_region(this,
|
4377
|
+
region_start,
|
4378
|
+
region_end,
|
4379
|
+
copy_object_func)) {
|
4320
4380
|
newmarks |= mask;
|
4321
4381
|
}
|
4322
4382
|
}
|
@@ -4332,7 +4392,7 @@ uint32_t Heap::IterateDirtyRegions(
|
|
4332
4392
|
// with region end. Check whether region covering last part of area is
|
4333
4393
|
// dirty.
|
4334
4394
|
if (marks & mask) {
|
4335
|
-
if (visit_dirty_region(region_start, area_end, copy_object_func)) {
|
4395
|
+
if (visit_dirty_region(this, region_start, area_end, copy_object_func)) {
|
4336
4396
|
newmarks |= mask;
|
4337
4397
|
}
|
4338
4398
|
}
|
@@ -4398,7 +4458,7 @@ void Heap::IterateWeakRoots(ObjectVisitor* v, VisitMode mode) {
|
|
4398
4458
|
v->Synchronize("symbol_table");
|
4399
4459
|
if (mode != VISIT_ALL_IN_SCAVENGE) {
|
4400
4460
|
// Scavenge collections have special processing for this.
|
4401
|
-
|
4461
|
+
external_string_table_.Iterate(v);
|
4402
4462
|
}
|
4403
4463
|
v->Synchronize("external_string_table");
|
4404
4464
|
}
|
@@ -4411,42 +4471,42 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
|
|
4411
4471
|
v->VisitPointer(BitCast<Object**>(&hidden_symbol_));
|
4412
4472
|
v->Synchronize("symbol");
|
4413
4473
|
|
4414
|
-
|
4474
|
+
isolate_->bootstrapper()->Iterate(v);
|
4415
4475
|
v->Synchronize("bootstrapper");
|
4416
|
-
|
4476
|
+
isolate_->Iterate(v);
|
4417
4477
|
v->Synchronize("top");
|
4418
4478
|
Relocatable::Iterate(v);
|
4419
4479
|
v->Synchronize("relocatable");
|
4420
4480
|
|
4421
4481
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
4422
|
-
|
4482
|
+
isolate_->debug()->Iterate(v);
|
4423
4483
|
#endif
|
4424
4484
|
v->Synchronize("debug");
|
4425
|
-
|
4485
|
+
isolate_->compilation_cache()->Iterate(v);
|
4426
4486
|
v->Synchronize("compilationcache");
|
4427
4487
|
|
4428
4488
|
// Iterate over local handles in handle scopes.
|
4429
|
-
|
4489
|
+
isolate_->handle_scope_implementer()->Iterate(v);
|
4430
4490
|
v->Synchronize("handlescope");
|
4431
4491
|
|
4432
4492
|
// Iterate over the builtin code objects and code stubs in the
|
4433
4493
|
// heap. Note that it is not necessary to iterate over code objects
|
4434
4494
|
// on scavenge collections.
|
4435
4495
|
if (mode != VISIT_ALL_IN_SCAVENGE) {
|
4436
|
-
|
4496
|
+
isolate_->builtins()->IterateBuiltins(v);
|
4437
4497
|
}
|
4438
4498
|
v->Synchronize("builtins");
|
4439
4499
|
|
4440
4500
|
// Iterate over global handles.
|
4441
4501
|
if (mode == VISIT_ONLY_STRONG) {
|
4442
|
-
|
4502
|
+
isolate_->global_handles()->IterateStrongRoots(v);
|
4443
4503
|
} else {
|
4444
|
-
|
4504
|
+
isolate_->global_handles()->IterateAllRoots(v);
|
4445
4505
|
}
|
4446
4506
|
v->Synchronize("globalhandles");
|
4447
4507
|
|
4448
4508
|
// Iterate over pointers being held by inactive threads.
|
4449
|
-
|
4509
|
+
isolate_->thread_manager()->Iterate(v);
|
4450
4510
|
v->Synchronize("threadmanager");
|
4451
4511
|
|
4452
4512
|
// Iterate over the pointers the Serialization/Deserialization code is
|
@@ -4465,10 +4525,6 @@ void Heap::IterateStrongRoots(ObjectVisitor* v, VisitMode mode) {
|
|
4465
4525
|
}
|
4466
4526
|
|
4467
4527
|
|
4468
|
-
// Flag is set when the heap has been configured. The heap can be repeatedly
|
4469
|
-
// configured through the API until it is setup.
|
4470
|
-
static bool heap_configured = false;
|
4471
|
-
|
4472
4528
|
// TODO(1236194): Since the heap size is configurable on the command line
|
4473
4529
|
// and through the API, we should gracefully handle the case that the heap
|
4474
4530
|
// size is not big enough to fit all the initial objects.
|
@@ -4515,7 +4571,7 @@ bool Heap::ConfigureHeap(int max_semispace_size,
|
|
4515
4571
|
// The old generation is paged.
|
4516
4572
|
max_old_generation_size_ = RoundUp(max_old_generation_size_, Page::kPageSize);
|
4517
4573
|
|
4518
|
-
|
4574
|
+
configured_ = true;
|
4519
4575
|
return true;
|
4520
4576
|
}
|
4521
4577
|
|
@@ -4543,11 +4599,13 @@ void Heap::RecordStats(HeapStats* stats, bool take_snapshot) {
|
|
4543
4599
|
*stats->cell_space_size = cell_space_->Size();
|
4544
4600
|
*stats->cell_space_capacity = cell_space_->Capacity();
|
4545
4601
|
*stats->lo_space_size = lo_space_->Size();
|
4546
|
-
|
4547
|
-
*stats->memory_allocator_size =
|
4602
|
+
isolate_->global_handles()->RecordStats(stats);
|
4603
|
+
*stats->memory_allocator_size = isolate()->memory_allocator()->Size();
|
4548
4604
|
*stats->memory_allocator_capacity =
|
4549
|
-
|
4605
|
+
isolate()->memory_allocator()->Size() +
|
4606
|
+
isolate()->memory_allocator()->Available();
|
4550
4607
|
*stats->os_error = OS::GetLastError();
|
4608
|
+
isolate()->memory_allocator()->Available();
|
4551
4609
|
if (take_snapshot) {
|
4552
4610
|
HeapIterator iterator(HeapIterator::kFilterFreeListNodes);
|
4553
4611
|
for (HeapObject* obj = iterator.next();
|
@@ -4579,8 +4637,177 @@ int Heap::PromotedExternalMemorySize() {
|
|
4579
4637
|
- amount_of_external_allocated_memory_at_last_global_gc_;
|
4580
4638
|
}
|
4581
4639
|
|
4640
|
+
#ifdef DEBUG
|
4641
|
+
|
4642
|
+
// Tags 0, 1, and 3 are used. Use 2 for marking visited HeapObject.
|
4643
|
+
static const int kMarkTag = 2;
|
4644
|
+
|
4645
|
+
|
4646
|
+
class HeapDebugUtils {
|
4647
|
+
public:
|
4648
|
+
explicit HeapDebugUtils(Heap* heap)
|
4649
|
+
: search_for_any_global_(false),
|
4650
|
+
search_target_(NULL),
|
4651
|
+
found_target_(false),
|
4652
|
+
object_stack_(20),
|
4653
|
+
heap_(heap) {
|
4654
|
+
}
|
4655
|
+
|
4656
|
+
class MarkObjectVisitor : public ObjectVisitor {
|
4657
|
+
public:
|
4658
|
+
explicit MarkObjectVisitor(HeapDebugUtils* utils) : utils_(utils) { }
|
4659
|
+
|
4660
|
+
void VisitPointers(Object** start, Object** end) {
|
4661
|
+
// Copy all HeapObject pointers in [start, end)
|
4662
|
+
for (Object** p = start; p < end; p++) {
|
4663
|
+
if ((*p)->IsHeapObject())
|
4664
|
+
utils_->MarkObjectRecursively(p);
|
4665
|
+
}
|
4666
|
+
}
|
4667
|
+
|
4668
|
+
HeapDebugUtils* utils_;
|
4669
|
+
};
|
4670
|
+
|
4671
|
+
void MarkObjectRecursively(Object** p) {
|
4672
|
+
if (!(*p)->IsHeapObject()) return;
|
4673
|
+
|
4674
|
+
HeapObject* obj = HeapObject::cast(*p);
|
4675
|
+
|
4676
|
+
Object* map = obj->map();
|
4677
|
+
|
4678
|
+
if (!map->IsHeapObject()) return; // visited before
|
4679
|
+
|
4680
|
+
if (found_target_) return; // stop if target found
|
4681
|
+
object_stack_.Add(obj);
|
4682
|
+
if ((search_for_any_global_ && obj->IsJSGlobalObject()) ||
|
4683
|
+
(!search_for_any_global_ && (obj == search_target_))) {
|
4684
|
+
found_target_ = true;
|
4685
|
+
return;
|
4686
|
+
}
|
4687
|
+
|
4688
|
+
// not visited yet
|
4689
|
+
Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map));
|
4690
|
+
|
4691
|
+
Address map_addr = map_p->address();
|
4692
|
+
|
4693
|
+
obj->set_map(reinterpret_cast<Map*>(map_addr + kMarkTag));
|
4694
|
+
|
4695
|
+
MarkObjectRecursively(&map);
|
4696
|
+
|
4697
|
+
MarkObjectVisitor mark_visitor(this);
|
4698
|
+
|
4699
|
+
obj->IterateBody(map_p->instance_type(), obj->SizeFromMap(map_p),
|
4700
|
+
&mark_visitor);
|
4701
|
+
|
4702
|
+
if (!found_target_) // don't pop if found the target
|
4703
|
+
object_stack_.RemoveLast();
|
4704
|
+
}
|
4705
|
+
|
4706
|
+
|
4707
|
+
class UnmarkObjectVisitor : public ObjectVisitor {
|
4708
|
+
public:
|
4709
|
+
explicit UnmarkObjectVisitor(HeapDebugUtils* utils) : utils_(utils) { }
|
4710
|
+
|
4711
|
+
void VisitPointers(Object** start, Object** end) {
|
4712
|
+
// Copy all HeapObject pointers in [start, end)
|
4713
|
+
for (Object** p = start; p < end; p++) {
|
4714
|
+
if ((*p)->IsHeapObject())
|
4715
|
+
utils_->UnmarkObjectRecursively(p);
|
4716
|
+
}
|
4717
|
+
}
|
4718
|
+
|
4719
|
+
HeapDebugUtils* utils_;
|
4720
|
+
};
|
4721
|
+
|
4722
|
+
|
4723
|
+
void UnmarkObjectRecursively(Object** p) {
|
4724
|
+
if (!(*p)->IsHeapObject()) return;
|
4725
|
+
|
4726
|
+
HeapObject* obj = HeapObject::cast(*p);
|
4727
|
+
|
4728
|
+
Object* map = obj->map();
|
4729
|
+
|
4730
|
+
if (map->IsHeapObject()) return; // unmarked already
|
4731
|
+
|
4732
|
+
Address map_addr = reinterpret_cast<Address>(map);
|
4733
|
+
|
4734
|
+
map_addr -= kMarkTag;
|
4735
|
+
|
4736
|
+
ASSERT_TAG_ALIGNED(map_addr);
|
4737
|
+
|
4738
|
+
HeapObject* map_p = HeapObject::FromAddress(map_addr);
|
4739
|
+
|
4740
|
+
obj->set_map(reinterpret_cast<Map*>(map_p));
|
4741
|
+
|
4742
|
+
UnmarkObjectRecursively(reinterpret_cast<Object**>(&map_p));
|
4743
|
+
|
4744
|
+
UnmarkObjectVisitor unmark_visitor(this);
|
4745
|
+
|
4746
|
+
obj->IterateBody(Map::cast(map_p)->instance_type(),
|
4747
|
+
obj->SizeFromMap(Map::cast(map_p)),
|
4748
|
+
&unmark_visitor);
|
4749
|
+
}
|
4750
|
+
|
4751
|
+
|
4752
|
+
void MarkRootObjectRecursively(Object** root) {
|
4753
|
+
if (search_for_any_global_) {
|
4754
|
+
ASSERT(search_target_ == NULL);
|
4755
|
+
} else {
|
4756
|
+
ASSERT(search_target_->IsHeapObject());
|
4757
|
+
}
|
4758
|
+
found_target_ = false;
|
4759
|
+
object_stack_.Clear();
|
4760
|
+
|
4761
|
+
MarkObjectRecursively(root);
|
4762
|
+
UnmarkObjectRecursively(root);
|
4763
|
+
|
4764
|
+
if (found_target_) {
|
4765
|
+
PrintF("=====================================\n");
|
4766
|
+
PrintF("==== Path to object ====\n");
|
4767
|
+
PrintF("=====================================\n\n");
|
4768
|
+
|
4769
|
+
ASSERT(!object_stack_.is_empty());
|
4770
|
+
for (int i = 0; i < object_stack_.length(); i++) {
|
4771
|
+
if (i > 0) PrintF("\n |\n |\n V\n\n");
|
4772
|
+
Object* obj = object_stack_[i];
|
4773
|
+
obj->Print();
|
4774
|
+
}
|
4775
|
+
PrintF("=====================================\n");
|
4776
|
+
}
|
4777
|
+
}
|
4778
|
+
|
4779
|
+
// Helper class for visiting HeapObjects recursively.
|
4780
|
+
class MarkRootVisitor: public ObjectVisitor {
|
4781
|
+
public:
|
4782
|
+
explicit MarkRootVisitor(HeapDebugUtils* utils) : utils_(utils) { }
|
4783
|
+
|
4784
|
+
void VisitPointers(Object** start, Object** end) {
|
4785
|
+
// Visit all HeapObject pointers in [start, end)
|
4786
|
+
for (Object** p = start; p < end; p++) {
|
4787
|
+
if ((*p)->IsHeapObject())
|
4788
|
+
utils_->MarkRootObjectRecursively(p);
|
4789
|
+
}
|
4790
|
+
}
|
4791
|
+
|
4792
|
+
HeapDebugUtils* utils_;
|
4793
|
+
};
|
4794
|
+
|
4795
|
+
bool search_for_any_global_;
|
4796
|
+
Object* search_target_;
|
4797
|
+
bool found_target_;
|
4798
|
+
List<Object*> object_stack_;
|
4799
|
+
Heap* heap_;
|
4800
|
+
|
4801
|
+
friend class Heap;
|
4802
|
+
};
|
4803
|
+
|
4804
|
+
#endif
|
4582
4805
|
|
4583
4806
|
bool Heap::Setup(bool create_heap_objects) {
|
4807
|
+
#ifdef DEBUG
|
4808
|
+
debug_utils_ = new HeapDebugUtils(this);
|
4809
|
+
#endif
|
4810
|
+
|
4584
4811
|
// Initialize heap spaces and initial maps and objects. Whenever something
|
4585
4812
|
// goes wrong, just return false. The caller should check the results and
|
4586
4813
|
// call Heap::TearDown() to release allocated memory.
|
@@ -4589,13 +4816,19 @@ bool Heap::Setup(bool create_heap_objects) {
|
|
4589
4816
|
// Configuration is based on the flags new-space-size (really the semispace
|
4590
4817
|
// size) and old-space-size if set or the initial values of semispace_size_
|
4591
4818
|
// and old_generation_size_ otherwise.
|
4592
|
-
if (!
|
4819
|
+
if (!configured_) {
|
4593
4820
|
if (!ConfigureHeapDefault()) return false;
|
4594
4821
|
}
|
4595
4822
|
|
4596
|
-
|
4597
|
-
|
4598
|
-
|
4823
|
+
gc_initializer_mutex->Lock();
|
4824
|
+
static bool initialized_gc = false;
|
4825
|
+
if (!initialized_gc) {
|
4826
|
+
initialized_gc = true;
|
4827
|
+
InitializeScavengingVisitorsTables();
|
4828
|
+
NewSpaceScavenger::Initialize();
|
4829
|
+
MarkCompactCollector::Initialize();
|
4830
|
+
}
|
4831
|
+
gc_initializer_mutex->Unlock();
|
4599
4832
|
|
4600
4833
|
MarkMapPointersAsEncoded(false);
|
4601
4834
|
|
@@ -4603,9 +4836,11 @@ bool Heap::Setup(bool create_heap_objects) {
|
|
4603
4836
|
// space. The chunk is double the size of the requested reserved
|
4604
4837
|
// new space size to ensure that we can find a pair of semispaces that
|
4605
4838
|
// are contiguous and aligned to their size.
|
4606
|
-
if (!
|
4839
|
+
if (!isolate_->memory_allocator()->Setup(MaxReserved(), MaxExecutableSize()))
|
4840
|
+
return false;
|
4607
4841
|
void* chunk =
|
4608
|
-
|
4842
|
+
isolate_->memory_allocator()->ReserveInitialChunk(
|
4843
|
+
4 * reserved_semispace_size_);
|
4609
4844
|
if (chunk == NULL) return false;
|
4610
4845
|
|
4611
4846
|
// Align the pair of semispaces to their size, which must be a power
|
@@ -4618,13 +4853,19 @@ bool Heap::Setup(bool create_heap_objects) {
|
|
4618
4853
|
|
4619
4854
|
// Initialize old pointer space.
|
4620
4855
|
old_pointer_space_ =
|
4621
|
-
new OldSpace(
|
4856
|
+
new OldSpace(this,
|
4857
|
+
max_old_generation_size_,
|
4858
|
+
OLD_POINTER_SPACE,
|
4859
|
+
NOT_EXECUTABLE);
|
4622
4860
|
if (old_pointer_space_ == NULL) return false;
|
4623
4861
|
if (!old_pointer_space_->Setup(NULL, 0)) return false;
|
4624
4862
|
|
4625
4863
|
// Initialize old data space.
|
4626
4864
|
old_data_space_ =
|
4627
|
-
new OldSpace(
|
4865
|
+
new OldSpace(this,
|
4866
|
+
max_old_generation_size_,
|
4867
|
+
OLD_DATA_SPACE,
|
4868
|
+
NOT_EXECUTABLE);
|
4628
4869
|
if (old_data_space_ == NULL) return false;
|
4629
4870
|
if (!old_data_space_->Setup(NULL, 0)) return false;
|
4630
4871
|
|
@@ -4633,18 +4874,18 @@ bool Heap::Setup(bool create_heap_objects) {
|
|
4633
4874
|
// On 64-bit platform(s), we put all code objects in a 2 GB range of
|
4634
4875
|
// virtual address space, so that they can call each other with near calls.
|
4635
4876
|
if (code_range_size_ > 0) {
|
4636
|
-
if (!
|
4877
|
+
if (!isolate_->code_range()->Setup(code_range_size_)) {
|
4637
4878
|
return false;
|
4638
4879
|
}
|
4639
4880
|
}
|
4640
4881
|
|
4641
4882
|
code_space_ =
|
4642
|
-
new OldSpace(max_old_generation_size_, CODE_SPACE, EXECUTABLE);
|
4883
|
+
new OldSpace(this, max_old_generation_size_, CODE_SPACE, EXECUTABLE);
|
4643
4884
|
if (code_space_ == NULL) return false;
|
4644
4885
|
if (!code_space_->Setup(NULL, 0)) return false;
|
4645
4886
|
|
4646
4887
|
// Initialize map space.
|
4647
|
-
map_space_ = new MapSpace(FLAG_use_big_map_space
|
4888
|
+
map_space_ = new MapSpace(this, FLAG_use_big_map_space
|
4648
4889
|
? max_old_generation_size_
|
4649
4890
|
: MapSpace::kMaxMapPageIndex * Page::kPageSize,
|
4650
4891
|
FLAG_max_map_space_pages,
|
@@ -4653,14 +4894,14 @@ bool Heap::Setup(bool create_heap_objects) {
|
|
4653
4894
|
if (!map_space_->Setup(NULL, 0)) return false;
|
4654
4895
|
|
4655
4896
|
// Initialize global property cell space.
|
4656
|
-
cell_space_ = new CellSpace(max_old_generation_size_, CELL_SPACE);
|
4897
|
+
cell_space_ = new CellSpace(this, max_old_generation_size_, CELL_SPACE);
|
4657
4898
|
if (cell_space_ == NULL) return false;
|
4658
4899
|
if (!cell_space_->Setup(NULL, 0)) return false;
|
4659
4900
|
|
4660
4901
|
// The large object code space may contain code or data. We set the memory
|
4661
4902
|
// to be non-executable here for safety, but this means we need to enable it
|
4662
4903
|
// explicitly when allocating large code objects.
|
4663
|
-
lo_space_ = new LargeObjectSpace(LO_SPACE);
|
4904
|
+
lo_space_ = new LargeObjectSpace(this, LO_SPACE);
|
4664
4905
|
if (lo_space_ == NULL) return false;
|
4665
4906
|
if (!lo_space_->Setup()) return false;
|
4666
4907
|
|
@@ -4675,12 +4916,12 @@ bool Heap::Setup(bool create_heap_objects) {
|
|
4675
4916
|
global_contexts_list_ = undefined_value();
|
4676
4917
|
}
|
4677
4918
|
|
4678
|
-
LOG(IntPtrTEvent("heap-capacity", Capacity()));
|
4679
|
-
LOG(IntPtrTEvent("heap-available", Available()));
|
4919
|
+
LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
|
4920
|
+
LOG(isolate_, IntPtrTEvent("heap-available", Available()));
|
4680
4921
|
|
4681
4922
|
#ifdef ENABLE_LOGGING_AND_PROFILING
|
4682
4923
|
// This should be called only after initial objects have been created.
|
4683
|
-
|
4924
|
+
isolate_->producer_heap_profile()->Setup();
|
4684
4925
|
#endif
|
4685
4926
|
|
4686
4927
|
return true;
|
@@ -4688,6 +4929,8 @@ bool Heap::Setup(bool create_heap_objects) {
|
|
4688
4929
|
|
4689
4930
|
|
4690
4931
|
void Heap::SetStackLimits() {
|
4932
|
+
ASSERT(isolate_ != NULL);
|
4933
|
+
ASSERT(isolate_ == isolate());
|
4691
4934
|
// On 64 bit machines, pointers are generally out of range of Smis. We write
|
4692
4935
|
// something that looks like an out of range Smi to the GC.
|
4693
4936
|
|
@@ -4695,10 +4938,10 @@ void Heap::SetStackLimits() {
|
|
4695
4938
|
// These are actually addresses, but the tag makes the GC ignore it.
|
4696
4939
|
roots_[kStackLimitRootIndex] =
|
4697
4940
|
reinterpret_cast<Object*>(
|
4698
|
-
(
|
4941
|
+
(isolate_->stack_guard()->jslimit() & ~kSmiTagMask) | kSmiTag);
|
4699
4942
|
roots_[kRealStackLimitRootIndex] =
|
4700
4943
|
reinterpret_cast<Object*>(
|
4701
|
-
(
|
4944
|
+
(isolate_->stack_guard()->real_jslimit() & ~kSmiTagMask) | kSmiTag);
|
4702
4945
|
}
|
4703
4946
|
|
4704
4947
|
|
@@ -4708,16 +4951,16 @@ void Heap::TearDown() {
|
|
4708
4951
|
PrintF("gc_count=%d ", gc_count_);
|
4709
4952
|
PrintF("mark_sweep_count=%d ", ms_count_);
|
4710
4953
|
PrintF("mark_compact_count=%d ", mc_count_);
|
4711
|
-
PrintF("max_gc_pause=%d ",
|
4712
|
-
PrintF("min_in_mutator=%d ",
|
4954
|
+
PrintF("max_gc_pause=%d ", get_max_gc_pause());
|
4955
|
+
PrintF("min_in_mutator=%d ", get_min_in_mutator());
|
4713
4956
|
PrintF("max_alive_after_gc=%" V8_PTR_PREFIX "d ",
|
4714
|
-
|
4957
|
+
get_max_alive_after_gc());
|
4715
4958
|
PrintF("\n\n");
|
4716
4959
|
}
|
4717
4960
|
|
4718
|
-
|
4961
|
+
isolate_->global_handles()->TearDown();
|
4719
4962
|
|
4720
|
-
|
4963
|
+
external_string_table_.TearDown();
|
4721
4964
|
|
4722
4965
|
new_space_.TearDown();
|
4723
4966
|
|
@@ -4757,7 +5000,12 @@ void Heap::TearDown() {
|
|
4757
5000
|
lo_space_ = NULL;
|
4758
5001
|
}
|
4759
5002
|
|
4760
|
-
|
5003
|
+
isolate_->memory_allocator()->TearDown();
|
5004
|
+
|
5005
|
+
#ifdef DEBUG
|
5006
|
+
delete debug_utils_;
|
5007
|
+
debug_utils_ = NULL;
|
5008
|
+
#endif
|
4761
5009
|
}
|
4762
5010
|
|
4763
5011
|
|
@@ -4846,7 +5094,7 @@ class PrintHandleVisitor: public ObjectVisitor {
|
|
4846
5094
|
void Heap::PrintHandles() {
|
4847
5095
|
PrintF("Handles:\n");
|
4848
5096
|
PrintHandleVisitor v;
|
4849
|
-
|
5097
|
+
isolate_->handle_scope_implementer()->Iterate(&v);
|
4850
5098
|
}
|
4851
5099
|
|
4852
5100
|
#endif
|
@@ -4855,19 +5103,19 @@ void Heap::PrintHandles() {
|
|
4855
5103
|
Space* AllSpaces::next() {
|
4856
5104
|
switch (counter_++) {
|
4857
5105
|
case NEW_SPACE:
|
4858
|
-
return
|
5106
|
+
return HEAP->new_space();
|
4859
5107
|
case OLD_POINTER_SPACE:
|
4860
|
-
return
|
5108
|
+
return HEAP->old_pointer_space();
|
4861
5109
|
case OLD_DATA_SPACE:
|
4862
|
-
return
|
5110
|
+
return HEAP->old_data_space();
|
4863
5111
|
case CODE_SPACE:
|
4864
|
-
return
|
5112
|
+
return HEAP->code_space();
|
4865
5113
|
case MAP_SPACE:
|
4866
|
-
return
|
5114
|
+
return HEAP->map_space();
|
4867
5115
|
case CELL_SPACE:
|
4868
|
-
return
|
5116
|
+
return HEAP->cell_space();
|
4869
5117
|
case LO_SPACE:
|
4870
|
-
return
|
5118
|
+
return HEAP->lo_space();
|
4871
5119
|
default:
|
4872
5120
|
return NULL;
|
4873
5121
|
}
|
@@ -4877,15 +5125,15 @@ Space* AllSpaces::next() {
|
|
4877
5125
|
PagedSpace* PagedSpaces::next() {
|
4878
5126
|
switch (counter_++) {
|
4879
5127
|
case OLD_POINTER_SPACE:
|
4880
|
-
return
|
5128
|
+
return HEAP->old_pointer_space();
|
4881
5129
|
case OLD_DATA_SPACE:
|
4882
|
-
return
|
5130
|
+
return HEAP->old_data_space();
|
4883
5131
|
case CODE_SPACE:
|
4884
|
-
return
|
5132
|
+
return HEAP->code_space();
|
4885
5133
|
case MAP_SPACE:
|
4886
|
-
return
|
5134
|
+
return HEAP->map_space();
|
4887
5135
|
case CELL_SPACE:
|
4888
|
-
return
|
5136
|
+
return HEAP->cell_space();
|
4889
5137
|
default:
|
4890
5138
|
return NULL;
|
4891
5139
|
}
|
@@ -4896,11 +5144,11 @@ PagedSpace* PagedSpaces::next() {
|
|
4896
5144
|
OldSpace* OldSpaces::next() {
|
4897
5145
|
switch (counter_++) {
|
4898
5146
|
case OLD_POINTER_SPACE:
|
4899
|
-
return
|
5147
|
+
return HEAP->old_pointer_space();
|
4900
5148
|
case OLD_DATA_SPACE:
|
4901
|
-
return
|
5149
|
+
return HEAP->old_data_space();
|
4902
5150
|
case CODE_SPACE:
|
4903
|
-
return
|
5151
|
+
return HEAP->code_space();
|
4904
5152
|
default:
|
4905
5153
|
return NULL;
|
4906
5154
|
}
|
@@ -4955,25 +5203,25 @@ ObjectIterator* SpaceIterator::CreateIterator() {
|
|
4955
5203
|
|
4956
5204
|
switch (current_space_) {
|
4957
5205
|
case NEW_SPACE:
|
4958
|
-
iterator_ = new SemiSpaceIterator(
|
5206
|
+
iterator_ = new SemiSpaceIterator(HEAP->new_space(), size_func_);
|
4959
5207
|
break;
|
4960
5208
|
case OLD_POINTER_SPACE:
|
4961
|
-
iterator_ = new HeapObjectIterator(
|
5209
|
+
iterator_ = new HeapObjectIterator(HEAP->old_pointer_space(), size_func_);
|
4962
5210
|
break;
|
4963
5211
|
case OLD_DATA_SPACE:
|
4964
|
-
iterator_ = new HeapObjectIterator(
|
5212
|
+
iterator_ = new HeapObjectIterator(HEAP->old_data_space(), size_func_);
|
4965
5213
|
break;
|
4966
5214
|
case CODE_SPACE:
|
4967
|
-
iterator_ = new HeapObjectIterator(
|
5215
|
+
iterator_ = new HeapObjectIterator(HEAP->code_space(), size_func_);
|
4968
5216
|
break;
|
4969
5217
|
case MAP_SPACE:
|
4970
|
-
iterator_ = new HeapObjectIterator(
|
5218
|
+
iterator_ = new HeapObjectIterator(HEAP->map_space(), size_func_);
|
4971
5219
|
break;
|
4972
5220
|
case CELL_SPACE:
|
4973
|
-
iterator_ = new HeapObjectIterator(
|
5221
|
+
iterator_ = new HeapObjectIterator(HEAP->cell_space(), size_func_);
|
4974
5222
|
break;
|
4975
5223
|
case LO_SPACE:
|
4976
|
-
iterator_ = new LargeObjectIterator(
|
5224
|
+
iterator_ = new LargeObjectIterator(HEAP->lo_space(), size_func_);
|
4977
5225
|
break;
|
4978
5226
|
}
|
4979
5227
|
|
@@ -5007,16 +5255,17 @@ class FreeListNodesFilter : public HeapObjectsFilter {
|
|
5007
5255
|
|
5008
5256
|
private:
|
5009
5257
|
void MarkFreeListNodes() {
|
5010
|
-
Heap
|
5011
|
-
|
5012
|
-
|
5013
|
-
|
5014
|
-
|
5258
|
+
Heap* heap = HEAP;
|
5259
|
+
heap->old_pointer_space()->MarkFreeListNodes();
|
5260
|
+
heap->old_data_space()->MarkFreeListNodes();
|
5261
|
+
MarkCodeSpaceFreeListNodes(heap);
|
5262
|
+
heap->map_space()->MarkFreeListNodes();
|
5263
|
+
heap->cell_space()->MarkFreeListNodes();
|
5015
5264
|
}
|
5016
5265
|
|
5017
|
-
void MarkCodeSpaceFreeListNodes() {
|
5266
|
+
void MarkCodeSpaceFreeListNodes(Heap* heap) {
|
5018
5267
|
// For code space, using FreeListNode::IsFreeListNode is OK.
|
5019
|
-
HeapObjectIterator iter(
|
5268
|
+
HeapObjectIterator iter(heap->code_space());
|
5020
5269
|
for (HeapObject* obj = iter.next_object();
|
5021
5270
|
obj != NULL;
|
5022
5271
|
obj = iter.next_object()) {
|
@@ -5078,7 +5327,7 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
|
|
5078
5327
|
obj->SetMark();
|
5079
5328
|
}
|
5080
5329
|
UnmarkingVisitor visitor;
|
5081
|
-
|
5330
|
+
HEAP->IterateRoots(&visitor, VISIT_ALL);
|
5082
5331
|
while (visitor.can_process())
|
5083
5332
|
visitor.ProcessNext();
|
5084
5333
|
}
|
@@ -5336,7 +5585,11 @@ void PathTracer::ProcessResults() {
|
|
5336
5585
|
for (int i = 0; i < object_stack_.length(); i++) {
|
5337
5586
|
if (i > 0) PrintF("\n |\n |\n V\n\n");
|
5338
5587
|
Object* obj = object_stack_[i];
|
5588
|
+
#ifdef OBJECT_PRINT
|
5339
5589
|
obj->Print();
|
5590
|
+
#else
|
5591
|
+
obj->ShortPrint();
|
5592
|
+
#endif
|
5340
5593
|
}
|
5341
5594
|
PrintF("=====================================\n");
|
5342
5595
|
}
|
@@ -5377,7 +5630,7 @@ static intptr_t CountTotalHolesSize() {
|
|
5377
5630
|
}
|
5378
5631
|
|
5379
5632
|
|
5380
|
-
GCTracer::GCTracer()
|
5633
|
+
GCTracer::GCTracer(Heap* heap)
|
5381
5634
|
: start_time_(0.0),
|
5382
5635
|
start_size_(0),
|
5383
5636
|
gc_count_(0),
|
@@ -5386,14 +5639,16 @@ GCTracer::GCTracer()
|
|
5386
5639
|
marked_count_(0),
|
5387
5640
|
allocated_since_last_gc_(0),
|
5388
5641
|
spent_in_mutator_(0),
|
5389
|
-
promoted_objects_size_(0)
|
5642
|
+
promoted_objects_size_(0),
|
5643
|
+
heap_(heap) {
|
5390
5644
|
// These two fields reflect the state of the previous full collection.
|
5391
5645
|
// Set them before they are changed by the collector.
|
5392
|
-
previous_has_compacted_ =
|
5393
|
-
previous_marked_count_ =
|
5646
|
+
previous_has_compacted_ = heap_->mark_compact_collector_.HasCompacted();
|
5647
|
+
previous_marked_count_ =
|
5648
|
+
heap_->mark_compact_collector_.previous_marked_count();
|
5394
5649
|
if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
|
5395
5650
|
start_time_ = OS::TimeCurrentMillis();
|
5396
|
-
start_size_ =
|
5651
|
+
start_size_ = heap_->SizeOfObjects();
|
5397
5652
|
|
5398
5653
|
for (int i = 0; i < Scope::kNumberOfScopes; i++) {
|
5399
5654
|
scopes_[i] = 0;
|
@@ -5401,10 +5656,11 @@ GCTracer::GCTracer()
|
|
5401
5656
|
|
5402
5657
|
in_free_list_or_wasted_before_gc_ = CountTotalHolesSize();
|
5403
5658
|
|
5404
|
-
allocated_since_last_gc_ =
|
5659
|
+
allocated_since_last_gc_ =
|
5660
|
+
heap_->SizeOfObjects() - heap_->alive_after_last_gc_;
|
5405
5661
|
|
5406
|
-
if (last_gc_end_timestamp_ > 0) {
|
5407
|
-
spent_in_mutator_ = Max(start_time_ - last_gc_end_timestamp_, 0.0);
|
5662
|
+
if (heap_->last_gc_end_timestamp_ > 0) {
|
5663
|
+
spent_in_mutator_ = Max(start_time_ - heap_->last_gc_end_timestamp_, 0.0);
|
5408
5664
|
}
|
5409
5665
|
}
|
5410
5666
|
|
@@ -5413,20 +5669,21 @@ GCTracer::~GCTracer() {
|
|
5413
5669
|
// Printf ONE line iff flag is set.
|
5414
5670
|
if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
|
5415
5671
|
|
5416
|
-
bool first_gc = (last_gc_end_timestamp_ == 0);
|
5672
|
+
bool first_gc = (heap_->last_gc_end_timestamp_ == 0);
|
5417
5673
|
|
5418
|
-
alive_after_last_gc_ =
|
5419
|
-
last_gc_end_timestamp_ = OS::TimeCurrentMillis();
|
5674
|
+
heap_->alive_after_last_gc_ = heap_->SizeOfObjects();
|
5675
|
+
heap_->last_gc_end_timestamp_ = OS::TimeCurrentMillis();
|
5420
5676
|
|
5421
|
-
int time = static_cast<int>(last_gc_end_timestamp_ - start_time_);
|
5677
|
+
int time = static_cast<int>(heap_->last_gc_end_timestamp_ - start_time_);
|
5422
5678
|
|
5423
5679
|
// Update cumulative GC statistics if required.
|
5424
5680
|
if (FLAG_print_cumulative_gc_stat) {
|
5425
|
-
max_gc_pause_ = Max(max_gc_pause_, time);
|
5426
|
-
max_alive_after_gc_ = Max(max_alive_after_gc_,
|
5681
|
+
heap_->max_gc_pause_ = Max(heap_->max_gc_pause_, time);
|
5682
|
+
heap_->max_alive_after_gc_ = Max(heap_->max_alive_after_gc_,
|
5683
|
+
heap_->alive_after_last_gc_);
|
5427
5684
|
if (!first_gc) {
|
5428
|
-
min_in_mutator_ = Min(min_in_mutator_,
|
5429
|
-
|
5685
|
+
heap_->min_in_mutator_ = Min(heap_->min_in_mutator_,
|
5686
|
+
static_cast<int>(spent_in_mutator_));
|
5430
5687
|
}
|
5431
5688
|
}
|
5432
5689
|
|
@@ -5451,7 +5708,8 @@ GCTracer::~GCTracer() {
|
|
5451
5708
|
PrintF("s");
|
5452
5709
|
break;
|
5453
5710
|
case MARK_COMPACTOR:
|
5454
|
-
PrintF(
|
5711
|
+
PrintF("%s",
|
5712
|
+
heap_->mark_compact_collector_.HasCompacted() ? "mc" : "ms");
|
5455
5713
|
break;
|
5456
5714
|
default:
|
5457
5715
|
UNREACHABLE();
|
@@ -5465,7 +5723,7 @@ GCTracer::~GCTracer() {
|
|
5465
5723
|
PrintF("compact=%d ", static_cast<int>(scopes_[Scope::MC_COMPACT]));
|
5466
5724
|
|
5467
5725
|
PrintF("total_size_before=%" V8_PTR_PREFIX "d ", start_size_);
|
5468
|
-
PrintF("total_size_after=%" V8_PTR_PREFIX "d ",
|
5726
|
+
PrintF("total_size_after=%" V8_PTR_PREFIX "d ", heap_->SizeOfObjects());
|
5469
5727
|
PrintF("holes_size_before=%" V8_PTR_PREFIX "d ",
|
5470
5728
|
in_free_list_or_wasted_before_gc_);
|
5471
5729
|
PrintF("holes_size_after=%" V8_PTR_PREFIX "d ", CountTotalHolesSize());
|
@@ -5477,7 +5735,7 @@ GCTracer::~GCTracer() {
|
|
5477
5735
|
}
|
5478
5736
|
|
5479
5737
|
#if defined(ENABLE_LOGGING_AND_PROFILING)
|
5480
|
-
|
5738
|
+
heap_->PrintShortHeapStatistics();
|
5481
5739
|
#endif
|
5482
5740
|
}
|
5483
5741
|
|
@@ -5487,8 +5745,8 @@ const char* GCTracer::CollectorString() {
|
|
5487
5745
|
case SCAVENGER:
|
5488
5746
|
return "Scavenge";
|
5489
5747
|
case MARK_COMPACTOR:
|
5490
|
-
return
|
5491
|
-
|
5748
|
+
return heap_->mark_compact_collector_.HasCompacted() ? "Mark-compact"
|
5749
|
+
: "Mark-sweep";
|
5492
5750
|
}
|
5493
5751
|
return "Unknown GC";
|
5494
5752
|
}
|
@@ -5508,13 +5766,13 @@ int KeyedLookupCache::Lookup(Map* map, String* name) {
|
|
5508
5766
|
if ((key.map == map) && key.name->Equals(name)) {
|
5509
5767
|
return field_offsets_[index];
|
5510
5768
|
}
|
5511
|
-
return
|
5769
|
+
return kNotFound;
|
5512
5770
|
}
|
5513
5771
|
|
5514
5772
|
|
5515
5773
|
void KeyedLookupCache::Update(Map* map, String* name, int field_offset) {
|
5516
5774
|
String* symbol;
|
5517
|
-
if (
|
5775
|
+
if (HEAP->LookupSymbolIfExists(name, &symbol)) {
|
5518
5776
|
int index = Hash(map, symbol);
|
5519
5777
|
Key& key = keys_[index];
|
5520
5778
|
key.map = map;
|
@@ -5529,35 +5787,24 @@ void KeyedLookupCache::Clear() {
|
|
5529
5787
|
}
|
5530
5788
|
|
5531
5789
|
|
5532
|
-
KeyedLookupCache::Key KeyedLookupCache::keys_[KeyedLookupCache::kLength];
|
5533
|
-
|
5534
|
-
|
5535
|
-
int KeyedLookupCache::field_offsets_[KeyedLookupCache::kLength];
|
5536
|
-
|
5537
|
-
|
5538
5790
|
void DescriptorLookupCache::Clear() {
|
5539
5791
|
for (int index = 0; index < kLength; index++) keys_[index].array = NULL;
|
5540
5792
|
}
|
5541
5793
|
|
5542
5794
|
|
5543
|
-
DescriptorLookupCache::Key
|
5544
|
-
DescriptorLookupCache::keys_[DescriptorLookupCache::kLength];
|
5545
|
-
|
5546
|
-
int DescriptorLookupCache::results_[DescriptorLookupCache::kLength];
|
5547
|
-
|
5548
|
-
|
5549
5795
|
#ifdef DEBUG
|
5550
5796
|
void Heap::GarbageCollectionGreedyCheck() {
|
5551
5797
|
ASSERT(FLAG_gc_greedy);
|
5552
|
-
if (
|
5798
|
+
if (isolate_->bootstrapper()->IsActive()) return;
|
5553
5799
|
if (disallow_allocation_failure()) return;
|
5554
5800
|
CollectGarbage(NEW_SPACE);
|
5555
5801
|
}
|
5556
5802
|
#endif
|
5557
5803
|
|
5558
5804
|
|
5559
|
-
TranscendentalCache::
|
5560
|
-
: type_(t)
|
5805
|
+
TranscendentalCache::SubCache::SubCache(Type t)
|
5806
|
+
: type_(t),
|
5807
|
+
isolate_(Isolate::Current()) {
|
5561
5808
|
uint32_t in0 = 0xffffffffu; // Bit-pattern for a NaN that isn't
|
5562
5809
|
uint32_t in1 = 0xffffffffu; // generated by the FPU.
|
5563
5810
|
for (int i = 0; i < kCacheSize; i++) {
|
@@ -5568,9 +5815,6 @@ TranscendentalCache::TranscendentalCache(TranscendentalCache::Type t)
|
|
5568
5815
|
}
|
5569
5816
|
|
5570
5817
|
|
5571
|
-
TranscendentalCache* TranscendentalCache::caches_[kNumberOfCaches];
|
5572
|
-
|
5573
|
-
|
5574
5818
|
void TranscendentalCache::Clear() {
|
5575
5819
|
for (int i = 0; i < kNumberOfCaches; i++) {
|
5576
5820
|
if (caches_[i] != NULL) {
|
@@ -5584,8 +5828,8 @@ void TranscendentalCache::Clear() {
|
|
5584
5828
|
void ExternalStringTable::CleanUp() {
|
5585
5829
|
int last = 0;
|
5586
5830
|
for (int i = 0; i < new_space_strings_.length(); ++i) {
|
5587
|
-
if (new_space_strings_[i] ==
|
5588
|
-
if (
|
5831
|
+
if (new_space_strings_[i] == heap_->raw_unchecked_null_value()) continue;
|
5832
|
+
if (heap_->InNewSpace(new_space_strings_[i])) {
|
5589
5833
|
new_space_strings_[last++] = new_space_strings_[i];
|
5590
5834
|
} else {
|
5591
5835
|
old_space_strings_.Add(new_space_strings_[i]);
|
@@ -5594,8 +5838,8 @@ void ExternalStringTable::CleanUp() {
|
|
5594
5838
|
new_space_strings_.Rewind(last);
|
5595
5839
|
last = 0;
|
5596
5840
|
for (int i = 0; i < old_space_strings_.length(); ++i) {
|
5597
|
-
if (old_space_strings_[i] ==
|
5598
|
-
ASSERT(!
|
5841
|
+
if (old_space_strings_[i] == heap_->raw_unchecked_null_value()) continue;
|
5842
|
+
ASSERT(!heap_->InNewSpace(old_space_strings_[i]));
|
5599
5843
|
old_space_strings_[last++] = old_space_strings_[i];
|
5600
5844
|
}
|
5601
5845
|
old_space_strings_.Rewind(last);
|
@@ -5609,7 +5853,4 @@ void ExternalStringTable::TearDown() {
|
|
5609
5853
|
}
|
5610
5854
|
|
5611
5855
|
|
5612
|
-
List<Object*> ExternalStringTable::new_space_strings_;
|
5613
|
-
List<Object*> ExternalStringTable::old_space_strings_;
|
5614
|
-
|
5615
5856
|
} } // namespace v8::internal
|