libv8 3.11.8.17 → 3.16.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -2
- data/Gemfile +1 -1
- data/Rakefile +6 -7
- data/lib/libv8/version.rb +1 -1
- data/vendor/v8/.gitignore +24 -3
- data/vendor/v8/AUTHORS +7 -0
- data/vendor/v8/ChangeLog +839 -0
- data/vendor/v8/DEPS +1 -1
- data/vendor/v8/Makefile.android +92 -0
- data/vendor/v8/OWNERS +11 -0
- data/vendor/v8/PRESUBMIT.py +71 -0
- data/vendor/v8/SConstruct +34 -39
- data/vendor/v8/build/android.gypi +56 -37
- data/vendor/v8/build/common.gypi +112 -30
- data/vendor/v8/build/gyp_v8 +1 -1
- data/vendor/v8/build/standalone.gypi +15 -11
- data/vendor/v8/include/v8-debug.h +9 -1
- data/vendor/v8/include/v8-preparser.h +4 -3
- data/vendor/v8/include/v8-profiler.h +25 -25
- data/vendor/v8/include/v8-testing.h +4 -3
- data/vendor/v8/include/v8.h +994 -540
- data/vendor/v8/preparser/preparser-process.cc +3 -3
- data/vendor/v8/samples/lineprocessor.cc +20 -27
- data/vendor/v8/samples/process.cc +18 -14
- data/vendor/v8/samples/shell.cc +16 -15
- data/vendor/v8/src/SConscript +15 -14
- data/vendor/v8/src/accessors.cc +169 -77
- data/vendor/v8/src/accessors.h +4 -0
- data/vendor/v8/src/allocation-inl.h +2 -2
- data/vendor/v8/src/allocation.h +7 -7
- data/vendor/v8/src/api.cc +810 -497
- data/vendor/v8/src/api.h +85 -60
- data/vendor/v8/src/arm/assembler-arm-inl.h +179 -22
- data/vendor/v8/src/arm/assembler-arm.cc +633 -264
- data/vendor/v8/src/arm/assembler-arm.h +264 -197
- data/vendor/v8/src/arm/builtins-arm.cc +117 -27
- data/vendor/v8/src/arm/code-stubs-arm.cc +1241 -700
- data/vendor/v8/src/arm/code-stubs-arm.h +35 -138
- data/vendor/v8/src/arm/codegen-arm.cc +285 -16
- data/vendor/v8/src/arm/codegen-arm.h +22 -0
- data/vendor/v8/src/arm/constants-arm.cc +5 -3
- data/vendor/v8/src/arm/constants-arm.h +24 -11
- data/vendor/v8/src/arm/debug-arm.cc +3 -3
- data/vendor/v8/src/arm/deoptimizer-arm.cc +382 -92
- data/vendor/v8/src/arm/disasm-arm.cc +61 -12
- data/vendor/v8/src/arm/frames-arm.h +0 -14
- data/vendor/v8/src/arm/full-codegen-arm.cc +332 -304
- data/vendor/v8/src/arm/ic-arm.cc +180 -259
- data/vendor/v8/src/arm/lithium-arm.cc +364 -316
- data/vendor/v8/src/arm/lithium-arm.h +512 -275
- data/vendor/v8/src/arm/lithium-codegen-arm.cc +1768 -809
- data/vendor/v8/src/arm/lithium-codegen-arm.h +97 -35
- data/vendor/v8/src/arm/lithium-gap-resolver-arm.cc +12 -5
- data/vendor/v8/src/arm/macro-assembler-arm.cc +439 -228
- data/vendor/v8/src/arm/macro-assembler-arm.h +116 -70
- data/vendor/v8/src/arm/regexp-macro-assembler-arm.cc +54 -44
- data/vendor/v8/src/arm/regexp-macro-assembler-arm.h +3 -10
- data/vendor/v8/src/arm/simulator-arm.cc +272 -238
- data/vendor/v8/src/arm/simulator-arm.h +38 -8
- data/vendor/v8/src/arm/stub-cache-arm.cc +522 -895
- data/vendor/v8/src/array.js +101 -70
- data/vendor/v8/src/assembler.cc +270 -19
- data/vendor/v8/src/assembler.h +110 -15
- data/vendor/v8/src/ast.cc +79 -69
- data/vendor/v8/src/ast.h +255 -301
- data/vendor/v8/src/atomicops.h +7 -1
- data/vendor/v8/src/atomicops_internals_tsan.h +335 -0
- data/vendor/v8/src/bootstrapper.cc +481 -418
- data/vendor/v8/src/bootstrapper.h +4 -4
- data/vendor/v8/src/builtins.cc +498 -311
- data/vendor/v8/src/builtins.h +75 -47
- data/vendor/v8/src/checks.cc +2 -1
- data/vendor/v8/src/checks.h +8 -0
- data/vendor/v8/src/code-stubs-hydrogen.cc +253 -0
- data/vendor/v8/src/code-stubs.cc +249 -84
- data/vendor/v8/src/code-stubs.h +501 -169
- data/vendor/v8/src/codegen.cc +36 -18
- data/vendor/v8/src/codegen.h +25 -3
- data/vendor/v8/src/collection.js +54 -17
- data/vendor/v8/src/compilation-cache.cc +24 -16
- data/vendor/v8/src/compilation-cache.h +15 -6
- data/vendor/v8/src/compiler.cc +497 -195
- data/vendor/v8/src/compiler.h +246 -38
- data/vendor/v8/src/contexts.cc +64 -24
- data/vendor/v8/src/contexts.h +60 -29
- data/vendor/v8/src/conversions-inl.h +24 -14
- data/vendor/v8/src/conversions.h +7 -4
- data/vendor/v8/src/counters.cc +21 -12
- data/vendor/v8/src/counters.h +44 -16
- data/vendor/v8/src/cpu-profiler.h +1 -1
- data/vendor/v8/src/d8-debug.cc +2 -2
- data/vendor/v8/src/d8-readline.cc +13 -2
- data/vendor/v8/src/d8.cc +681 -273
- data/vendor/v8/src/d8.gyp +4 -4
- data/vendor/v8/src/d8.h +38 -18
- data/vendor/v8/src/d8.js +0 -617
- data/vendor/v8/src/data-flow.h +55 -0
- data/vendor/v8/src/date.js +1 -42
- data/vendor/v8/src/dateparser-inl.h +5 -1
- data/vendor/v8/src/debug-agent.cc +10 -15
- data/vendor/v8/src/debug-debugger.js +147 -149
- data/vendor/v8/src/debug.cc +323 -164
- data/vendor/v8/src/debug.h +26 -14
- data/vendor/v8/src/deoptimizer.cc +765 -290
- data/vendor/v8/src/deoptimizer.h +130 -28
- data/vendor/v8/src/disassembler.cc +10 -4
- data/vendor/v8/src/elements-kind.cc +7 -2
- data/vendor/v8/src/elements-kind.h +19 -0
- data/vendor/v8/src/elements.cc +607 -285
- data/vendor/v8/src/elements.h +36 -13
- data/vendor/v8/src/execution.cc +52 -31
- data/vendor/v8/src/execution.h +4 -4
- data/vendor/v8/src/extensions/externalize-string-extension.cc +5 -4
- data/vendor/v8/src/extensions/gc-extension.cc +5 -1
- data/vendor/v8/src/extensions/statistics-extension.cc +153 -0
- data/vendor/v8/src/{inspector.h → extensions/statistics-extension.h} +12 -23
- data/vendor/v8/src/factory.cc +101 -134
- data/vendor/v8/src/factory.h +36 -31
- data/vendor/v8/src/flag-definitions.h +102 -25
- data/vendor/v8/src/flags.cc +9 -5
- data/vendor/v8/src/frames-inl.h +10 -0
- data/vendor/v8/src/frames.cc +116 -26
- data/vendor/v8/src/frames.h +96 -12
- data/vendor/v8/src/full-codegen.cc +219 -74
- data/vendor/v8/src/full-codegen.h +63 -21
- data/vendor/v8/src/func-name-inferrer.cc +8 -7
- data/vendor/v8/src/func-name-inferrer.h +5 -3
- data/vendor/v8/src/gdb-jit.cc +71 -57
- data/vendor/v8/src/global-handles.cc +230 -101
- data/vendor/v8/src/global-handles.h +26 -27
- data/vendor/v8/src/globals.h +17 -19
- data/vendor/v8/src/handles-inl.h +59 -12
- data/vendor/v8/src/handles.cc +180 -200
- data/vendor/v8/src/handles.h +80 -11
- data/vendor/v8/src/hashmap.h +60 -40
- data/vendor/v8/src/heap-inl.h +107 -45
- data/vendor/v8/src/heap-profiler.cc +38 -19
- data/vendor/v8/src/heap-profiler.h +24 -14
- data/vendor/v8/src/heap.cc +1123 -738
- data/vendor/v8/src/heap.h +385 -146
- data/vendor/v8/src/hydrogen-instructions.cc +700 -217
- data/vendor/v8/src/hydrogen-instructions.h +1158 -472
- data/vendor/v8/src/hydrogen.cc +3319 -1662
- data/vendor/v8/src/hydrogen.h +411 -170
- data/vendor/v8/src/ia32/assembler-ia32-inl.h +46 -16
- data/vendor/v8/src/ia32/assembler-ia32.cc +131 -61
- data/vendor/v8/src/ia32/assembler-ia32.h +115 -57
- data/vendor/v8/src/ia32/builtins-ia32.cc +99 -5
- data/vendor/v8/src/ia32/code-stubs-ia32.cc +787 -495
- data/vendor/v8/src/ia32/code-stubs-ia32.h +10 -100
- data/vendor/v8/src/ia32/codegen-ia32.cc +227 -23
- data/vendor/v8/src/ia32/codegen-ia32.h +14 -0
- data/vendor/v8/src/ia32/deoptimizer-ia32.cc +428 -87
- data/vendor/v8/src/ia32/disasm-ia32.cc +28 -1
- data/vendor/v8/src/ia32/frames-ia32.h +6 -16
- data/vendor/v8/src/ia32/full-codegen-ia32.cc +280 -272
- data/vendor/v8/src/ia32/ic-ia32.cc +150 -250
- data/vendor/v8/src/ia32/lithium-codegen-ia32.cc +1600 -517
- data/vendor/v8/src/ia32/lithium-codegen-ia32.h +90 -24
- data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.cc +10 -6
- data/vendor/v8/src/ia32/lithium-gap-resolver-ia32.h +2 -2
- data/vendor/v8/src/ia32/lithium-ia32.cc +405 -302
- data/vendor/v8/src/ia32/lithium-ia32.h +526 -271
- data/vendor/v8/src/ia32/macro-assembler-ia32.cc +378 -119
- data/vendor/v8/src/ia32/macro-assembler-ia32.h +62 -28
- data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.cc +43 -30
- data/vendor/v8/src/ia32/regexp-macro-assembler-ia32.h +2 -10
- data/vendor/v8/src/ia32/stub-cache-ia32.cc +492 -678
- data/vendor/v8/src/ic-inl.h +9 -4
- data/vendor/v8/src/ic.cc +836 -923
- data/vendor/v8/src/ic.h +228 -247
- data/vendor/v8/src/incremental-marking-inl.h +26 -30
- data/vendor/v8/src/incremental-marking.cc +276 -248
- data/vendor/v8/src/incremental-marking.h +29 -37
- data/vendor/v8/src/interface.cc +34 -25
- data/vendor/v8/src/interface.h +69 -25
- data/vendor/v8/src/interpreter-irregexp.cc +2 -2
- data/vendor/v8/src/isolate.cc +382 -76
- data/vendor/v8/src/isolate.h +109 -56
- data/vendor/v8/src/json-parser.h +217 -104
- data/vendor/v8/src/json-stringifier.h +745 -0
- data/vendor/v8/src/json.js +10 -132
- data/vendor/v8/src/jsregexp-inl.h +106 -0
- data/vendor/v8/src/jsregexp.cc +517 -285
- data/vendor/v8/src/jsregexp.h +145 -117
- data/vendor/v8/src/list-inl.h +35 -22
- data/vendor/v8/src/list.h +46 -19
- data/vendor/v8/src/lithium-allocator-inl.h +22 -2
- data/vendor/v8/src/lithium-allocator.cc +85 -70
- data/vendor/v8/src/lithium-allocator.h +21 -39
- data/vendor/v8/src/lithium.cc +259 -5
- data/vendor/v8/src/lithium.h +131 -32
- data/vendor/v8/src/liveedit-debugger.js +52 -3
- data/vendor/v8/src/liveedit.cc +393 -113
- data/vendor/v8/src/liveedit.h +7 -3
- data/vendor/v8/src/log-utils.cc +4 -2
- data/vendor/v8/src/log.cc +170 -140
- data/vendor/v8/src/log.h +62 -11
- data/vendor/v8/src/macro-assembler.h +17 -0
- data/vendor/v8/src/macros.py +2 -0
- data/vendor/v8/src/mark-compact-inl.h +3 -23
- data/vendor/v8/src/mark-compact.cc +801 -830
- data/vendor/v8/src/mark-compact.h +154 -47
- data/vendor/v8/src/marking-thread.cc +85 -0
- data/vendor/v8/src/{inspector.cc → marking-thread.h} +32 -24
- data/vendor/v8/src/math.js +12 -18
- data/vendor/v8/src/messages.cc +18 -8
- data/vendor/v8/src/messages.js +314 -261
- data/vendor/v8/src/mips/assembler-mips-inl.h +58 -6
- data/vendor/v8/src/mips/assembler-mips.cc +92 -75
- data/vendor/v8/src/mips/assembler-mips.h +54 -60
- data/vendor/v8/src/mips/builtins-mips.cc +116 -17
- data/vendor/v8/src/mips/code-stubs-mips.cc +919 -556
- data/vendor/v8/src/mips/code-stubs-mips.h +22 -131
- data/vendor/v8/src/mips/codegen-mips.cc +281 -6
- data/vendor/v8/src/mips/codegen-mips.h +22 -0
- data/vendor/v8/src/mips/constants-mips.cc +2 -0
- data/vendor/v8/src/mips/constants-mips.h +12 -2
- data/vendor/v8/src/mips/deoptimizer-mips.cc +286 -50
- data/vendor/v8/src/mips/disasm-mips.cc +13 -0
- data/vendor/v8/src/mips/full-codegen-mips.cc +297 -284
- data/vendor/v8/src/mips/ic-mips.cc +182 -263
- data/vendor/v8/src/mips/lithium-codegen-mips.cc +1208 -556
- data/vendor/v8/src/mips/lithium-codegen-mips.h +72 -19
- data/vendor/v8/src/mips/lithium-gap-resolver-mips.cc +9 -2
- data/vendor/v8/src/mips/lithium-mips.cc +290 -302
- data/vendor/v8/src/mips/lithium-mips.h +463 -266
- data/vendor/v8/src/mips/macro-assembler-mips.cc +208 -115
- data/vendor/v8/src/mips/macro-assembler-mips.h +67 -24
- data/vendor/v8/src/mips/regexp-macro-assembler-mips.cc +40 -25
- data/vendor/v8/src/mips/regexp-macro-assembler-mips.h +3 -9
- data/vendor/v8/src/mips/simulator-mips.cc +112 -40
- data/vendor/v8/src/mips/simulator-mips.h +5 -0
- data/vendor/v8/src/mips/stub-cache-mips.cc +502 -884
- data/vendor/v8/src/mirror-debugger.js +157 -30
- data/vendor/v8/src/mksnapshot.cc +88 -14
- data/vendor/v8/src/object-observe.js +235 -0
- data/vendor/v8/src/objects-debug.cc +178 -176
- data/vendor/v8/src/objects-inl.h +1333 -486
- data/vendor/v8/src/objects-printer.cc +125 -43
- data/vendor/v8/src/objects-visiting-inl.h +578 -6
- data/vendor/v8/src/objects-visiting.cc +2 -2
- data/vendor/v8/src/objects-visiting.h +172 -79
- data/vendor/v8/src/objects.cc +3533 -2885
- data/vendor/v8/src/objects.h +1352 -1131
- data/vendor/v8/src/optimizing-compiler-thread.cc +152 -0
- data/vendor/v8/src/optimizing-compiler-thread.h +111 -0
- data/vendor/v8/src/parser.cc +390 -500
- data/vendor/v8/src/parser.h +45 -33
- data/vendor/v8/src/platform-cygwin.cc +10 -21
- data/vendor/v8/src/platform-freebsd.cc +36 -41
- data/vendor/v8/src/platform-linux.cc +160 -124
- data/vendor/v8/src/platform-macos.cc +30 -27
- data/vendor/v8/src/platform-nullos.cc +17 -1
- data/vendor/v8/src/platform-openbsd.cc +19 -50
- data/vendor/v8/src/platform-posix.cc +14 -0
- data/vendor/v8/src/platform-solaris.cc +20 -53
- data/vendor/v8/src/platform-win32.cc +49 -26
- data/vendor/v8/src/platform.h +40 -1
- data/vendor/v8/src/preparser.cc +8 -5
- data/vendor/v8/src/preparser.h +2 -2
- data/vendor/v8/src/prettyprinter.cc +16 -0
- data/vendor/v8/src/prettyprinter.h +2 -0
- data/vendor/v8/src/profile-generator-inl.h +1 -0
- data/vendor/v8/src/profile-generator.cc +209 -147
- data/vendor/v8/src/profile-generator.h +15 -12
- data/vendor/v8/src/property-details.h +46 -31
- data/vendor/v8/src/property.cc +27 -46
- data/vendor/v8/src/property.h +163 -83
- data/vendor/v8/src/proxy.js +7 -2
- data/vendor/v8/src/regexp-macro-assembler-irregexp.cc +4 -13
- data/vendor/v8/src/regexp-macro-assembler-irregexp.h +1 -2
- data/vendor/v8/src/regexp-macro-assembler-tracer.cc +1 -11
- data/vendor/v8/src/regexp-macro-assembler-tracer.h +0 -1
- data/vendor/v8/src/regexp-macro-assembler.cc +31 -14
- data/vendor/v8/src/regexp-macro-assembler.h +14 -11
- data/vendor/v8/src/regexp-stack.cc +1 -0
- data/vendor/v8/src/regexp.js +9 -8
- data/vendor/v8/src/rewriter.cc +18 -7
- data/vendor/v8/src/runtime-profiler.cc +52 -43
- data/vendor/v8/src/runtime-profiler.h +0 -25
- data/vendor/v8/src/runtime.cc +2006 -2023
- data/vendor/v8/src/runtime.h +56 -49
- data/vendor/v8/src/safepoint-table.cc +12 -18
- data/vendor/v8/src/safepoint-table.h +11 -8
- data/vendor/v8/src/scanner.cc +1 -0
- data/vendor/v8/src/scanner.h +4 -10
- data/vendor/v8/src/scopeinfo.cc +35 -9
- data/vendor/v8/src/scopeinfo.h +64 -3
- data/vendor/v8/src/scopes.cc +251 -156
- data/vendor/v8/src/scopes.h +61 -27
- data/vendor/v8/src/serialize.cc +348 -396
- data/vendor/v8/src/serialize.h +125 -114
- data/vendor/v8/src/small-pointer-list.h +11 -11
- data/vendor/v8/src/{smart-array-pointer.h → smart-pointers.h} +64 -15
- data/vendor/v8/src/snapshot-common.cc +64 -15
- data/vendor/v8/src/snapshot-empty.cc +7 -1
- data/vendor/v8/src/snapshot.h +9 -2
- data/vendor/v8/src/spaces-inl.h +17 -0
- data/vendor/v8/src/spaces.cc +477 -183
- data/vendor/v8/src/spaces.h +238 -58
- data/vendor/v8/src/splay-tree-inl.h +8 -7
- data/vendor/v8/src/splay-tree.h +24 -10
- data/vendor/v8/src/store-buffer.cc +12 -5
- data/vendor/v8/src/store-buffer.h +2 -4
- data/vendor/v8/src/string-search.h +22 -6
- data/vendor/v8/src/string-stream.cc +11 -8
- data/vendor/v8/src/string.js +47 -15
- data/vendor/v8/src/stub-cache.cc +461 -224
- data/vendor/v8/src/stub-cache.h +164 -102
- data/vendor/v8/src/sweeper-thread.cc +105 -0
- data/vendor/v8/src/sweeper-thread.h +81 -0
- data/vendor/v8/src/token.h +1 -0
- data/vendor/v8/src/transitions-inl.h +220 -0
- data/vendor/v8/src/transitions.cc +160 -0
- data/vendor/v8/src/transitions.h +207 -0
- data/vendor/v8/src/type-info.cc +182 -181
- data/vendor/v8/src/type-info.h +31 -19
- data/vendor/v8/src/unicode-inl.h +62 -106
- data/vendor/v8/src/unicode.cc +57 -67
- data/vendor/v8/src/unicode.h +45 -91
- data/vendor/v8/src/uri.js +57 -29
- data/vendor/v8/src/utils.h +105 -5
- data/vendor/v8/src/v8-counters.cc +54 -11
- data/vendor/v8/src/v8-counters.h +134 -19
- data/vendor/v8/src/v8.cc +29 -29
- data/vendor/v8/src/v8.h +1 -0
- data/vendor/v8/src/v8conversions.cc +26 -22
- data/vendor/v8/src/v8globals.h +56 -43
- data/vendor/v8/src/v8natives.js +83 -30
- data/vendor/v8/src/v8threads.cc +42 -21
- data/vendor/v8/src/v8threads.h +4 -1
- data/vendor/v8/src/v8utils.cc +9 -93
- data/vendor/v8/src/v8utils.h +37 -33
- data/vendor/v8/src/variables.cc +6 -3
- data/vendor/v8/src/variables.h +6 -13
- data/vendor/v8/src/version.cc +2 -2
- data/vendor/v8/src/vm-state-inl.h +11 -0
- data/vendor/v8/src/x64/assembler-x64-inl.h +39 -8
- data/vendor/v8/src/x64/assembler-x64.cc +78 -64
- data/vendor/v8/src/x64/assembler-x64.h +38 -33
- data/vendor/v8/src/x64/builtins-x64.cc +105 -7
- data/vendor/v8/src/x64/code-stubs-x64.cc +790 -413
- data/vendor/v8/src/x64/code-stubs-x64.h +10 -106
- data/vendor/v8/src/x64/codegen-x64.cc +210 -8
- data/vendor/v8/src/x64/codegen-x64.h +20 -1
- data/vendor/v8/src/x64/deoptimizer-x64.cc +336 -75
- data/vendor/v8/src/x64/disasm-x64.cc +15 -0
- data/vendor/v8/src/x64/frames-x64.h +0 -14
- data/vendor/v8/src/x64/full-codegen-x64.cc +293 -270
- data/vendor/v8/src/x64/ic-x64.cc +153 -251
- data/vendor/v8/src/x64/lithium-codegen-x64.cc +1379 -531
- data/vendor/v8/src/x64/lithium-codegen-x64.h +67 -23
- data/vendor/v8/src/x64/lithium-gap-resolver-x64.cc +2 -2
- data/vendor/v8/src/x64/lithium-x64.cc +349 -289
- data/vendor/v8/src/x64/lithium-x64.h +460 -250
- data/vendor/v8/src/x64/macro-assembler-x64.cc +350 -177
- data/vendor/v8/src/x64/macro-assembler-x64.h +67 -49
- data/vendor/v8/src/x64/regexp-macro-assembler-x64.cc +46 -33
- data/vendor/v8/src/x64/regexp-macro-assembler-x64.h +2 -3
- data/vendor/v8/src/x64/stub-cache-x64.cc +484 -653
- data/vendor/v8/src/zone-inl.h +9 -27
- data/vendor/v8/src/zone.cc +5 -5
- data/vendor/v8/src/zone.h +53 -27
- data/vendor/v8/test/benchmarks/testcfg.py +5 -0
- data/vendor/v8/test/cctest/cctest.cc +4 -0
- data/vendor/v8/test/cctest/cctest.gyp +3 -1
- data/vendor/v8/test/cctest/cctest.h +57 -9
- data/vendor/v8/test/cctest/cctest.status +15 -15
- data/vendor/v8/test/cctest/test-accessors.cc +26 -0
- data/vendor/v8/test/cctest/test-alloc.cc +22 -30
- data/vendor/v8/test/cctest/test-api.cc +1943 -314
- data/vendor/v8/test/cctest/test-assembler-arm.cc +133 -13
- data/vendor/v8/test/cctest/test-assembler-ia32.cc +1 -1
- data/vendor/v8/test/cctest/test-assembler-mips.cc +12 -0
- data/vendor/v8/test/cctest/test-ast.cc +4 -2
- data/vendor/v8/test/cctest/test-compiler.cc +61 -29
- data/vendor/v8/test/cctest/test-dataflow.cc +2 -2
- data/vendor/v8/test/cctest/test-debug.cc +212 -33
- data/vendor/v8/test/cctest/test-decls.cc +257 -11
- data/vendor/v8/test/cctest/test-dictionary.cc +24 -10
- data/vendor/v8/test/cctest/test-disasm-arm.cc +118 -1
- data/vendor/v8/test/cctest/test-disasm-ia32.cc +3 -2
- data/vendor/v8/test/cctest/test-flags.cc +14 -1
- data/vendor/v8/test/cctest/test-func-name-inference.cc +7 -4
- data/vendor/v8/test/cctest/test-global-object.cc +51 -0
- data/vendor/v8/test/cctest/test-hashing.cc +32 -23
- data/vendor/v8/test/cctest/test-heap-profiler.cc +131 -77
- data/vendor/v8/test/cctest/test-heap.cc +1084 -143
- data/vendor/v8/test/cctest/test-list.cc +1 -1
- data/vendor/v8/test/cctest/test-liveedit.cc +3 -2
- data/vendor/v8/test/cctest/test-lockers.cc +12 -13
- data/vendor/v8/test/cctest/test-log.cc +10 -8
- data/vendor/v8/test/cctest/test-macro-assembler-x64.cc +2 -2
- data/vendor/v8/test/cctest/test-mark-compact.cc +44 -22
- data/vendor/v8/test/cctest/test-object-observe.cc +434 -0
- data/vendor/v8/test/cctest/test-parsing.cc +86 -39
- data/vendor/v8/test/cctest/test-platform-linux.cc +6 -0
- data/vendor/v8/test/cctest/test-platform-win32.cc +7 -0
- data/vendor/v8/test/cctest/test-random.cc +5 -4
- data/vendor/v8/test/cctest/test-regexp.cc +137 -101
- data/vendor/v8/test/cctest/test-serialize.cc +150 -230
- data/vendor/v8/test/cctest/test-sockets.cc +1 -1
- data/vendor/v8/test/cctest/test-spaces.cc +139 -0
- data/vendor/v8/test/cctest/test-strings.cc +736 -74
- data/vendor/v8/test/cctest/test-thread-termination.cc +10 -11
- data/vendor/v8/test/cctest/test-threads.cc +4 -4
- data/vendor/v8/test/cctest/test-utils.cc +16 -0
- data/vendor/v8/test/cctest/test-weakmaps.cc +7 -3
- data/vendor/v8/test/cctest/testcfg.py +64 -5
- data/vendor/v8/test/es5conform/testcfg.py +5 -0
- data/vendor/v8/test/message/message.status +1 -1
- data/vendor/v8/test/message/overwritten-builtins.out +3 -0
- data/vendor/v8/test/message/testcfg.py +89 -8
- data/vendor/v8/test/message/try-catch-finally-no-message.out +26 -26
- data/vendor/v8/test/mjsunit/accessor-map-sharing.js +18 -2
- data/vendor/v8/test/mjsunit/allocation-site-info.js +126 -0
- data/vendor/v8/test/mjsunit/array-bounds-check-removal.js +62 -1
- data/vendor/v8/test/mjsunit/array-iteration.js +1 -1
- data/vendor/v8/test/mjsunit/array-literal-transitions.js +2 -0
- data/vendor/v8/test/mjsunit/array-natives-elements.js +317 -0
- data/vendor/v8/test/mjsunit/array-reduce.js +8 -8
- data/vendor/v8/test/mjsunit/array-slice.js +12 -0
- data/vendor/v8/test/mjsunit/array-store-and-grow.js +4 -1
- data/vendor/v8/test/mjsunit/assert-opt-and-deopt.js +1 -1
- data/vendor/v8/test/mjsunit/bugs/bug-2337.js +53 -0
- data/vendor/v8/test/mjsunit/compare-known-objects-slow.js +69 -0
- data/vendor/v8/test/mjsunit/compiler/alloc-object-huge.js +3 -1
- data/vendor/v8/test/mjsunit/compiler/inline-accessors.js +368 -0
- data/vendor/v8/test/mjsunit/compiler/inline-arguments.js +87 -1
- data/vendor/v8/test/mjsunit/compiler/inline-closures.js +49 -0
- data/vendor/v8/test/mjsunit/compiler/inline-construct.js +55 -43
- data/vendor/v8/test/mjsunit/compiler/inline-literals.js +39 -0
- data/vendor/v8/test/mjsunit/compiler/multiply-add.js +69 -0
- data/vendor/v8/test/mjsunit/compiler/optimized-closures.js +57 -0
- data/vendor/v8/test/mjsunit/compiler/parallel-proto-change.js +44 -0
- data/vendor/v8/test/mjsunit/compiler/property-static.js +69 -0
- data/vendor/v8/test/mjsunit/compiler/proto-chain-constant.js +55 -0
- data/vendor/v8/test/mjsunit/compiler/proto-chain-load.js +44 -0
- data/vendor/v8/test/mjsunit/compiler/regress-gvn.js +3 -2
- data/vendor/v8/test/mjsunit/compiler/regress-or.js +6 -2
- data/vendor/v8/test/mjsunit/compiler/rotate.js +224 -0
- data/vendor/v8/test/mjsunit/compiler/uint32.js +173 -0
- data/vendor/v8/test/mjsunit/count-based-osr.js +2 -1
- data/vendor/v8/test/mjsunit/d8-os.js +3 -3
- data/vendor/v8/test/mjsunit/date-parse.js +3 -0
- data/vendor/v8/test/mjsunit/date.js +22 -0
- data/vendor/v8/test/mjsunit/debug-break-inline.js +1 -0
- data/vendor/v8/test/mjsunit/debug-evaluate-locals-optimized-double.js +22 -12
- data/vendor/v8/test/mjsunit/debug-evaluate-locals-optimized.js +21 -10
- data/vendor/v8/test/mjsunit/debug-liveedit-compile-error.js +60 -0
- data/vendor/v8/test/mjsunit/debug-liveedit-double-call.js +142 -0
- data/vendor/v8/test/mjsunit/debug-liveedit-literals.js +94 -0
- data/vendor/v8/test/mjsunit/debug-liveedit-restart-frame.js +153 -0
- data/vendor/v8/test/mjsunit/debug-multiple-breakpoints.js +1 -1
- data/vendor/v8/test/mjsunit/debug-script-breakpoints-closure.js +67 -0
- data/vendor/v8/test/mjsunit/debug-script-breakpoints-nested.js +82 -0
- data/vendor/v8/test/mjsunit/debug-script.js +4 -2
- data/vendor/v8/test/mjsunit/debug-set-variable-value.js +308 -0
- data/vendor/v8/test/mjsunit/debug-stepout-scope-part1.js +190 -0
- data/vendor/v8/test/mjsunit/debug-stepout-scope-part2.js +83 -0
- data/vendor/v8/test/mjsunit/debug-stepout-scope-part3.js +80 -0
- data/vendor/v8/test/mjsunit/debug-stepout-scope-part4.js +80 -0
- data/vendor/v8/test/mjsunit/debug-stepout-scope-part5.js +77 -0
- data/vendor/v8/test/mjsunit/debug-stepout-scope-part6.js +79 -0
- data/vendor/v8/test/mjsunit/debug-stepout-scope-part7.js +79 -0
- data/vendor/v8/test/mjsunit/{debug-stepout-scope.js → debug-stepout-scope-part8.js} +0 -189
- data/vendor/v8/test/mjsunit/delete-non-configurable.js +74 -0
- data/vendor/v8/test/mjsunit/deopt-minus-zero.js +56 -0
- data/vendor/v8/test/mjsunit/elements-kind.js +6 -4
- data/vendor/v8/test/mjsunit/elements-length-no-holey.js +33 -0
- data/vendor/v8/test/mjsunit/elements-transition-hoisting.js +46 -19
- data/vendor/v8/test/mjsunit/error-accessors.js +54 -0
- data/vendor/v8/test/mjsunit/error-constructors.js +1 -14
- data/vendor/v8/test/mjsunit/error-tostring.js +8 -0
- data/vendor/v8/test/mjsunit/eval-stack-trace.js +204 -0
- data/vendor/v8/test/mjsunit/external-array.js +364 -1
- data/vendor/v8/test/mjsunit/fast-array-length.js +37 -0
- data/vendor/v8/test/mjsunit/fast-non-keyed.js +113 -0
- data/vendor/v8/test/mjsunit/fast-prototype.js +117 -0
- data/vendor/v8/test/mjsunit/function-call.js +14 -18
- data/vendor/v8/test/mjsunit/fuzz-natives-part1.js +230 -0
- data/vendor/v8/test/mjsunit/fuzz-natives-part2.js +229 -0
- data/vendor/v8/test/mjsunit/fuzz-natives-part3.js +229 -0
- data/vendor/v8/test/mjsunit/{fuzz-natives.js → fuzz-natives-part4.js} +12 -2
- data/vendor/v8/test/mjsunit/generated-transition-stub.js +218 -0
- data/vendor/v8/test/mjsunit/greedy.js +1 -1
- data/vendor/v8/test/mjsunit/harmony/block-conflicts.js +2 -1
- data/vendor/v8/test/mjsunit/harmony/block-let-crankshaft.js +1 -1
- data/vendor/v8/test/mjsunit/harmony/collections.js +69 -11
- data/vendor/v8/test/mjsunit/harmony/debug-blockscopes.js +2 -2
- data/vendor/v8/test/mjsunit/harmony/module-linking.js +180 -3
- data/vendor/v8/test/mjsunit/harmony/module-parsing.js +31 -0
- data/vendor/v8/test/mjsunit/harmony/module-recompile.js +87 -0
- data/vendor/v8/test/mjsunit/harmony/module-resolution.js +15 -2
- data/vendor/v8/test/mjsunit/harmony/object-observe.js +1056 -0
- data/vendor/v8/test/mjsunit/harmony/proxies-json.js +178 -0
- data/vendor/v8/test/mjsunit/harmony/proxies.js +25 -10
- data/vendor/v8/test/mjsunit/json-parser-recursive.js +33 -0
- data/vendor/v8/test/mjsunit/json-stringify-recursive.js +52 -0
- data/vendor/v8/test/mjsunit/json.js +38 -2
- data/vendor/v8/test/mjsunit/json2.js +153 -0
- data/vendor/v8/test/mjsunit/limit-locals.js +5 -4
- data/vendor/v8/test/mjsunit/manual-parallel-recompile.js +79 -0
- data/vendor/v8/test/mjsunit/math-exp-precision.js +64 -0
- data/vendor/v8/test/mjsunit/math-floor-negative.js +59 -0
- data/vendor/v8/test/mjsunit/math-floor-of-div-minus-zero.js +41 -0
- data/vendor/v8/test/mjsunit/math-floor-of-div-nosudiv.js +288 -0
- data/vendor/v8/test/mjsunit/math-floor-of-div.js +81 -9
- data/vendor/v8/test/mjsunit/{math-floor.js → math-floor-part1.js} +1 -72
- data/vendor/v8/test/mjsunit/math-floor-part2.js +76 -0
- data/vendor/v8/test/mjsunit/math-floor-part3.js +78 -0
- data/vendor/v8/test/mjsunit/math-floor-part4.js +76 -0
- data/vendor/v8/test/mjsunit/mirror-object.js +43 -9
- data/vendor/v8/test/mjsunit/mjsunit.js +1 -1
- data/vendor/v8/test/mjsunit/mjsunit.status +52 -27
- data/vendor/v8/test/mjsunit/mul-exhaustive-part1.js +491 -0
- data/vendor/v8/test/mjsunit/mul-exhaustive-part10.js +470 -0
- data/vendor/v8/test/mjsunit/mul-exhaustive-part2.js +525 -0
- data/vendor/v8/test/mjsunit/mul-exhaustive-part3.js +532 -0
- data/vendor/v8/test/mjsunit/mul-exhaustive-part4.js +509 -0
- data/vendor/v8/test/mjsunit/mul-exhaustive-part5.js +505 -0
- data/vendor/v8/test/mjsunit/mul-exhaustive-part6.js +554 -0
- data/vendor/v8/test/mjsunit/mul-exhaustive-part7.js +497 -0
- data/vendor/v8/test/mjsunit/mul-exhaustive-part8.js +526 -0
- data/vendor/v8/test/mjsunit/mul-exhaustive-part9.js +533 -0
- data/vendor/v8/test/mjsunit/new-function.js +34 -0
- data/vendor/v8/test/mjsunit/numops-fuzz-part1.js +1172 -0
- data/vendor/v8/test/mjsunit/numops-fuzz-part2.js +1178 -0
- data/vendor/v8/test/mjsunit/numops-fuzz-part3.js +1178 -0
- data/vendor/v8/test/mjsunit/numops-fuzz-part4.js +1177 -0
- data/vendor/v8/test/mjsunit/object-define-property.js +107 -2
- data/vendor/v8/test/mjsunit/override-read-only-property.js +6 -4
- data/vendor/v8/test/mjsunit/packed-elements.js +2 -2
- data/vendor/v8/test/mjsunit/parse-int-float.js +4 -4
- data/vendor/v8/test/mjsunit/pixel-array-rounding.js +1 -1
- data/vendor/v8/test/mjsunit/readonly.js +228 -0
- data/vendor/v8/test/mjsunit/regexp-capture-3.js +16 -18
- data/vendor/v8/test/mjsunit/regexp-capture.js +2 -0
- data/vendor/v8/test/mjsunit/regexp-global.js +122 -0
- data/vendor/v8/test/mjsunit/regexp-results-cache.js +78 -0
- data/vendor/v8/test/mjsunit/regress/regress-1117.js +12 -3
- data/vendor/v8/test/mjsunit/regress/regress-1118.js +1 -1
- data/vendor/v8/test/mjsunit/regress/regress-115100.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-1199637.js +1 -3
- data/vendor/v8/test/mjsunit/regress/regress-121407.js +1 -1
- data/vendor/v8/test/mjsunit/regress/regress-131923.js +30 -0
- data/vendor/v8/test/mjsunit/regress/regress-131994.js +70 -0
- data/vendor/v8/test/mjsunit/regress/regress-133211.js +35 -0
- data/vendor/v8/test/mjsunit/regress/regress-133211b.js +39 -0
- data/vendor/v8/test/mjsunit/regress/regress-136048.js +34 -0
- data/vendor/v8/test/mjsunit/regress/regress-137768.js +73 -0
- data/vendor/v8/test/mjsunit/regress/regress-143967.js +34 -0
- data/vendor/v8/test/mjsunit/regress/regress-145201.js +107 -0
- data/vendor/v8/test/mjsunit/regress/regress-147497.js +45 -0
- data/vendor/v8/test/mjsunit/regress/regress-148378.js +38 -0
- data/vendor/v8/test/mjsunit/regress/regress-1563.js +1 -1
- data/vendor/v8/test/mjsunit/regress/regress-1591.js +48 -0
- data/vendor/v8/test/mjsunit/regress/regress-164442.js +45 -0
- data/vendor/v8/test/mjsunit/regress/regress-165637.js +61 -0
- data/vendor/v8/test/mjsunit/regress/regress-166379.js +39 -0
- data/vendor/v8/test/mjsunit/regress/regress-166553.js +33 -0
- data/vendor/v8/test/mjsunit/regress/regress-1692.js +1 -1
- data/vendor/v8/test/mjsunit/regress/regress-171641.js +40 -0
- data/vendor/v8/test/mjsunit/regress/regress-1980.js +1 -1
- data/vendor/v8/test/mjsunit/regress/regress-2073.js +99 -0
- data/vendor/v8/test/mjsunit/regress/regress-2119.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-2156.js +39 -0
- data/vendor/v8/test/mjsunit/regress/regress-2163.js +70 -0
- data/vendor/v8/test/mjsunit/regress/regress-2170.js +58 -0
- data/vendor/v8/test/mjsunit/regress/regress-2172.js +35 -0
- data/vendor/v8/test/mjsunit/regress/regress-2185-2.js +145 -0
- data/vendor/v8/test/mjsunit/regress/regress-2185.js +38 -0
- data/vendor/v8/test/mjsunit/regress/regress-2186.js +49 -0
- data/vendor/v8/test/mjsunit/regress/regress-2193.js +58 -0
- data/vendor/v8/test/mjsunit/regress/regress-2219.js +32 -0
- data/vendor/v8/test/mjsunit/regress/regress-2225.js +65 -0
- data/vendor/v8/test/mjsunit/regress/regress-2226.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-2234.js +41 -0
- data/vendor/v8/test/mjsunit/regress/regress-2243.js +31 -0
- data/vendor/v8/test/mjsunit/regress/regress-2249.js +33 -0
- data/vendor/v8/test/mjsunit/regress/regress-2250.js +68 -0
- data/vendor/v8/test/mjsunit/regress/regress-2261.js +113 -0
- data/vendor/v8/test/mjsunit/regress/regress-2263.js +30 -0
- data/vendor/v8/test/mjsunit/regress/regress-2284.js +32 -0
- data/vendor/v8/test/mjsunit/regress/regress-2285.js +32 -0
- data/vendor/v8/test/mjsunit/regress/regress-2286.js +32 -0
- data/vendor/v8/test/mjsunit/regress/regress-2289.js +34 -0
- data/vendor/v8/test/mjsunit/regress/regress-2291.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-2294.js +70 -0
- data/vendor/v8/test/mjsunit/regress/regress-2296.js +40 -0
- data/vendor/v8/test/mjsunit/regress/regress-2315.js +40 -0
- data/vendor/v8/test/mjsunit/regress/regress-2318.js +66 -0
- data/vendor/v8/test/mjsunit/regress/regress-2322.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-2326.js +54 -0
- data/vendor/v8/test/mjsunit/regress/regress-2336.js +53 -0
- data/vendor/v8/test/mjsunit/regress/regress-2339.js +59 -0
- data/vendor/v8/test/mjsunit/regress/regress-2346.js +123 -0
- data/vendor/v8/test/mjsunit/regress/regress-2373.js +29 -0
- data/vendor/v8/test/mjsunit/regress/regress-2374.js +33 -0
- data/vendor/v8/test/mjsunit/regress/regress-2398.js +41 -0
- data/vendor/v8/test/mjsunit/regress/regress-2410.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-2416.js +75 -0
- data/vendor/v8/test/mjsunit/regress/regress-2419.js +37 -0
- data/vendor/v8/test/mjsunit/regress/regress-2433.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-2437.js +156 -0
- data/vendor/v8/test/mjsunit/regress/regress-2438.js +52 -0
- data/vendor/v8/test/mjsunit/regress/regress-2443.js +129 -0
- data/vendor/v8/test/mjsunit/regress/regress-2444.js +120 -0
- data/vendor/v8/test/mjsunit/regress/regress-2489.js +50 -0
- data/vendor/v8/test/mjsunit/regress/regress-2499.js +40 -0
- data/vendor/v8/test/mjsunit/regress/regress-334.js +1 -1
- data/vendor/v8/test/mjsunit/regress/regress-492.js +39 -1
- data/vendor/v8/test/mjsunit/regress/regress-builtin-array-op.js +38 -0
- data/vendor/v8/test/mjsunit/regress/regress-cnlt-elements.js +43 -0
- data/vendor/v8/test/mjsunit/regress/regress-cnlt-enum-indices.js +45 -0
- data/vendor/v8/test/mjsunit/regress/regress-cntl-descriptors-enum.js +46 -0
- data/vendor/v8/test/mjsunit/regress/regress-convert-enum.js +60 -0
- data/vendor/v8/test/mjsunit/regress/regress-convert-enum2.js +46 -0
- data/vendor/v8/test/mjsunit/regress/regress-convert-transition.js +40 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-119926.js +3 -1
- data/vendor/v8/test/mjsunit/regress/regress-crbug-125148.js +90 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-134055.js +63 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-134609.js +59 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-135008.js +45 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-135066.js +55 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-137689.js +47 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-138887.js +48 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-140083.js +44 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-142087.js +38 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-142218.js +44 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-145961.js +39 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-146910.js +33 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-147475.js +48 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-148376.js +35 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-150545.js +53 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-150729.js +39 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-157019.js +54 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-157520.js +38 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-158185.js +39 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-160010.js +35 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-162085.js +71 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-168545.js +34 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-170856.js +33 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-172345.js +34 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-173974.js +36 -0
- data/vendor/v8/test/mjsunit/regress/regress-crbug-18639.js +9 -5
- data/vendor/v8/test/mjsunit/regress/regress-debug-code-recompilation.js +2 -1
- data/vendor/v8/test/mjsunit/regress/regress-deep-proto.js +45 -0
- data/vendor/v8/test/mjsunit/regress/regress-delete-empty-double.js +40 -0
- data/vendor/v8/test/mjsunit/regress/regress-iteration-order.js +42 -0
- data/vendor/v8/test/mjsunit/regress/regress-json-stringify-gc.js +41 -0
- data/vendor/v8/test/mjsunit/regress/regress-latin-1.js +78 -0
- data/vendor/v8/test/mjsunit/regress/regress-load-elements.js +49 -0
- data/vendor/v8/test/mjsunit/regress/regress-observe-empty-double-array.js +38 -0
- data/vendor/v8/test/mjsunit/regress/regress-undefined-store-keyed-fast-element.js +37 -0
- data/vendor/v8/test/mjsunit/shift-for-integer-div.js +59 -0
- data/vendor/v8/test/mjsunit/stack-traces-gc.js +119 -0
- data/vendor/v8/test/mjsunit/stack-traces-overflow.js +122 -0
- data/vendor/v8/test/mjsunit/stack-traces.js +39 -1
- data/vendor/v8/test/mjsunit/str-to-num.js +7 -2
- data/vendor/v8/test/mjsunit/strict-mode.js +36 -11
- data/vendor/v8/test/mjsunit/string-charcodeat.js +3 -0
- data/vendor/v8/test/mjsunit/string-natives.js +72 -0
- data/vendor/v8/test/mjsunit/string-split.js +17 -0
- data/vendor/v8/test/mjsunit/testcfg.py +76 -6
- data/vendor/v8/test/mjsunit/tools/tickprocessor.js +4 -1
- data/vendor/v8/test/mjsunit/try-finally-continue.js +72 -0
- data/vendor/v8/test/mjsunit/typed-array-slice.js +61 -0
- data/vendor/v8/test/mjsunit/unbox-double-arrays.js +2 -0
- data/vendor/v8/test/mjsunit/uri.js +12 -0
- data/vendor/v8/test/mjsunit/with-readonly.js +4 -2
- data/vendor/v8/test/mozilla/mozilla.status +19 -113
- data/vendor/v8/test/mozilla/testcfg.py +122 -3
- data/vendor/v8/test/preparser/preparser.status +5 -0
- data/vendor/v8/test/preparser/strict-identifiers.pyt +1 -1
- data/vendor/v8/test/preparser/testcfg.py +101 -5
- data/vendor/v8/test/sputnik/sputnik.status +1 -1
- data/vendor/v8/test/sputnik/testcfg.py +5 -0
- data/vendor/v8/test/test262/README +2 -2
- data/vendor/v8/test/test262/test262.status +13 -36
- data/vendor/v8/test/test262/testcfg.py +102 -8
- data/vendor/v8/tools/android-build.sh +0 -0
- data/vendor/v8/tools/android-ll-prof.sh +69 -0
- data/vendor/v8/tools/android-run.py +109 -0
- data/vendor/v8/tools/android-sync.sh +105 -0
- data/vendor/v8/tools/bash-completion.sh +0 -0
- data/vendor/v8/tools/check-static-initializers.sh +0 -0
- data/vendor/v8/tools/common-includes.sh +15 -22
- data/vendor/v8/tools/disasm.py +4 -4
- data/vendor/v8/tools/fuzz-harness.sh +0 -0
- data/vendor/v8/tools/gen-postmortem-metadata.py +6 -8
- data/vendor/v8/tools/grokdump.py +404 -129
- data/vendor/v8/tools/gyp/v8.gyp +105 -43
- data/vendor/v8/tools/linux-tick-processor +5 -5
- data/vendor/v8/tools/ll_prof.py +75 -15
- data/vendor/v8/tools/merge-to-branch.sh +2 -2
- data/vendor/v8/tools/plot-timer-events +70 -0
- data/vendor/v8/tools/plot-timer-events.js +510 -0
- data/vendor/v8/tools/presubmit.py +1 -0
- data/vendor/v8/tools/push-to-trunk.sh +14 -4
- data/vendor/v8/tools/run-llprof.sh +69 -0
- data/vendor/v8/tools/run-tests.py +372 -0
- data/vendor/v8/tools/run-valgrind.py +1 -1
- data/vendor/v8/tools/status-file-converter.py +39 -0
- data/vendor/v8/tools/test-server.py +224 -0
- data/vendor/v8/tools/test-wrapper-gypbuild.py +13 -16
- data/vendor/v8/tools/test.py +10 -19
- data/vendor/v8/tools/testrunner/README +174 -0
- data/vendor/v8/tools/testrunner/__init__.py +26 -0
- data/vendor/v8/tools/testrunner/local/__init__.py +26 -0
- data/vendor/v8/tools/testrunner/local/commands.py +153 -0
- data/vendor/v8/tools/testrunner/local/execution.py +182 -0
- data/vendor/v8/tools/testrunner/local/old_statusfile.py +460 -0
- data/vendor/v8/tools/testrunner/local/progress.py +238 -0
- data/vendor/v8/tools/testrunner/local/statusfile.py +145 -0
- data/vendor/v8/tools/testrunner/local/testsuite.py +187 -0
- data/vendor/v8/tools/testrunner/local/utils.py +108 -0
- data/vendor/v8/tools/testrunner/local/verbose.py +99 -0
- data/vendor/v8/tools/testrunner/network/__init__.py +26 -0
- data/vendor/v8/tools/testrunner/network/distro.py +90 -0
- data/vendor/v8/tools/testrunner/network/endpoint.py +124 -0
- data/vendor/v8/tools/testrunner/network/network_execution.py +253 -0
- data/vendor/v8/tools/testrunner/network/perfdata.py +120 -0
- data/vendor/v8/tools/testrunner/objects/__init__.py +26 -0
- data/vendor/v8/tools/testrunner/objects/context.py +50 -0
- data/vendor/v8/tools/testrunner/objects/output.py +60 -0
- data/vendor/v8/tools/testrunner/objects/peer.py +80 -0
- data/vendor/v8/tools/testrunner/objects/testcase.py +83 -0
- data/vendor/v8/tools/testrunner/objects/workpacket.py +90 -0
- data/vendor/v8/tools/testrunner/server/__init__.py +26 -0
- data/vendor/v8/tools/testrunner/server/compression.py +111 -0
- data/vendor/v8/tools/testrunner/server/constants.py +51 -0
- data/vendor/v8/tools/testrunner/server/daemon.py +147 -0
- data/vendor/v8/tools/testrunner/server/local_handler.py +119 -0
- data/vendor/v8/tools/testrunner/server/main.py +245 -0
- data/vendor/v8/tools/testrunner/server/presence_handler.py +120 -0
- data/vendor/v8/tools/testrunner/server/signatures.py +63 -0
- data/vendor/v8/tools/testrunner/server/status_handler.py +112 -0
- data/vendor/v8/tools/testrunner/server/work_handler.py +150 -0
- data/vendor/v8/tools/tick-processor.html +168 -0
- data/vendor/v8/tools/tickprocessor-driver.js +5 -3
- data/vendor/v8/tools/tickprocessor.js +58 -15
- metadata +534 -30
- data/patches/add-freebsd9-and-freebsd10-to-gyp-GetFlavor.patch +0 -11
- data/patches/do-not-imply-vfp3-and-armv7.patch +0 -44
- data/patches/fPIC-on-x64.patch +0 -14
- data/vendor/v8/src/liveobjectlist-inl.h +0 -126
- data/vendor/v8/src/liveobjectlist.cc +0 -2631
- data/vendor/v8/src/liveobjectlist.h +0 -319
- data/vendor/v8/test/mjsunit/mul-exhaustive.js +0 -4629
- data/vendor/v8/test/mjsunit/numops-fuzz.js +0 -4609
- data/vendor/v8/test/mjsunit/regress/regress-1969.js +0 -5045
data/vendor/v8/src/ic-inl.h
CHANGED
@@ -40,10 +40,11 @@ namespace internal {
|
|
40
40
|
|
41
41
|
Address IC::address() const {
|
42
42
|
// Get the address of the call.
|
43
|
-
Address result = pc()
|
43
|
+
Address result = Assembler::target_address_from_return_address(pc());
|
44
44
|
|
45
45
|
#ifdef ENABLE_DEBUGGER_SUPPORT
|
46
|
-
|
46
|
+
ASSERT(Isolate::Current() == isolate());
|
47
|
+
Debug* debug = isolate()->debug();
|
47
48
|
// First check if any break points are active if not just return the address
|
48
49
|
// of the call.
|
49
50
|
if (!debug->has_break_points()) return result;
|
@@ -79,6 +80,7 @@ Code* IC::GetTargetAtAddress(Address address) {
|
|
79
80
|
|
80
81
|
void IC::SetTargetAtAddress(Address address, Code* target) {
|
81
82
|
ASSERT(target->is_inline_cache_stub() || target->is_compare_ic_stub());
|
83
|
+
Heap* heap = target->GetHeap();
|
82
84
|
Code* old_target = GetTargetAtAddress(address);
|
83
85
|
#ifdef DEBUG
|
84
86
|
// STORE_IC and KEYED_STORE_IC use Code::extra_ic_state() to mark
|
@@ -90,8 +92,11 @@ void IC::SetTargetAtAddress(Address address, Code* target) {
|
|
90
92
|
}
|
91
93
|
#endif
|
92
94
|
Assembler::set_target_address_at(address, target->instruction_start());
|
93
|
-
|
94
|
-
|
95
|
+
if (heap->gc_state() == Heap::MARK_COMPACT) {
|
96
|
+
heap->mark_compact_collector()->RecordCodeTargetPatch(address, target);
|
97
|
+
} else {
|
98
|
+
heap->incremental_marking()->RecordCodeTargetPatch(address, target);
|
99
|
+
}
|
95
100
|
PostPatching(address, target, old_target);
|
96
101
|
}
|
97
102
|
|
data/vendor/v8/src/ic.cc
CHANGED
@@ -43,16 +43,17 @@ namespace internal {
|
|
43
43
|
char IC::TransitionMarkFromState(IC::State state) {
|
44
44
|
switch (state) {
|
45
45
|
case UNINITIALIZED: return '0';
|
46
|
-
case PREMONOMORPHIC: return '
|
46
|
+
case PREMONOMORPHIC: return '.';
|
47
47
|
case MONOMORPHIC: return '1';
|
48
48
|
case MONOMORPHIC_PROTOTYPE_FAILURE: return '^';
|
49
|
-
case
|
49
|
+
case POLYMORPHIC: return 'P';
|
50
|
+
case MEGAMORPHIC: return 'N';
|
51
|
+
case GENERIC: return 'G';
|
50
52
|
|
51
53
|
// We never see the debugger states here, because the state is
|
52
54
|
// computed from the original code - not the patched code. Let
|
53
55
|
// these cases fall through to the unreachable code below.
|
54
|
-
case
|
55
|
-
case DEBUG_PREPARE_STEP_IN: break;
|
56
|
+
case DEBUG_STUB: break;
|
56
57
|
}
|
57
58
|
UNREACHABLE();
|
58
59
|
return 0;
|
@@ -110,18 +111,17 @@ void IC::TraceIC(const char* type,
|
|
110
111
|
ASSERT((TraceIC(type, name, old_state, new_target), true))
|
111
112
|
|
112
113
|
IC::IC(FrameDepth depth, Isolate* isolate) : isolate_(isolate) {
|
113
|
-
|
114
|
-
//
|
115
|
-
// a
|
116
|
-
// ~35% speedup when running DeltaBlue with the '--nouse-ic' flag.
|
114
|
+
// To improve the performance of the (much used) IC code, we unfold a few
|
115
|
+
// levels of the stack frame iteration code. This yields a ~35% speedup when
|
116
|
+
// running DeltaBlue and a ~25% speedup of gbemu with the '--nouse-ic' flag.
|
117
117
|
const Address entry =
|
118
118
|
Isolate::c_entry_fp(isolate->thread_local_top());
|
119
119
|
Address* pc_address =
|
120
120
|
reinterpret_cast<Address*>(entry + ExitFrameConstants::kCallerPCOffset);
|
121
121
|
Address fp = Memory::Address_at(entry + ExitFrameConstants::kCallerFPOffset);
|
122
|
-
// If there's another JavaScript frame on the stack
|
123
|
-
// one frame further down the stack to
|
124
|
-
// the return address stack slot.
|
122
|
+
// If there's another JavaScript frame on the stack or a
|
123
|
+
// StubFailureTrampoline, we need to look one frame further down the stack to
|
124
|
+
// find the frame pointer and the return address stack slot.
|
125
125
|
if (depth == EXTRA_CALL_FRAME) {
|
126
126
|
const int kCallerPCOffset = StandardFrameConstants::kCallerPCOffset;
|
127
127
|
pc_address = reinterpret_cast<Address*>(fp + kCallerPCOffset);
|
@@ -158,7 +158,7 @@ Address IC::OriginalCodeAddress() const {
|
|
158
158
|
// Get the address of the call site in the active code. This is the
|
159
159
|
// place where the call to DebugBreakXXX is and where the IC
|
160
160
|
// normally would be.
|
161
|
-
Address addr = pc()
|
161
|
+
Address addr = Assembler::target_address_from_return_address(pc());
|
162
162
|
// Return the address in the original code. This is the place where
|
163
163
|
// the call which has been overwritten by the DebugBreakXXX resides
|
164
164
|
// and the place where the inline cache system should look.
|
@@ -169,26 +169,6 @@ Address IC::OriginalCodeAddress() const {
|
|
169
169
|
#endif
|
170
170
|
|
171
171
|
|
172
|
-
static bool HasNormalObjectsInPrototypeChain(Isolate* isolate,
|
173
|
-
LookupResult* lookup,
|
174
|
-
Object* receiver) {
|
175
|
-
Object* end = lookup->IsProperty()
|
176
|
-
? lookup->holder() : Object::cast(isolate->heap()->null_value());
|
177
|
-
for (Object* current = receiver;
|
178
|
-
current != end;
|
179
|
-
current = current->GetPrototype()) {
|
180
|
-
if (current->IsJSObject() &&
|
181
|
-
!JSObject::cast(current)->HasFastProperties() &&
|
182
|
-
!current->IsJSGlobalProxy() &&
|
183
|
-
!current->IsJSGlobalObject()) {
|
184
|
-
return true;
|
185
|
-
}
|
186
|
-
}
|
187
|
-
|
188
|
-
return false;
|
189
|
-
}
|
190
|
-
|
191
|
-
|
192
172
|
static bool TryRemoveInvalidPrototypeDependentStub(Code* target,
|
193
173
|
Object* receiver,
|
194
174
|
Object* name) {
|
@@ -273,7 +253,7 @@ RelocInfo::Mode IC::ComputeMode() {
|
|
273
253
|
if (info->pc() == addr) return info->rmode();
|
274
254
|
}
|
275
255
|
UNREACHABLE();
|
276
|
-
return RelocInfo::
|
256
|
+
return RelocInfo::NONE32;
|
277
257
|
}
|
278
258
|
|
279
259
|
|
@@ -310,7 +290,8 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) {
|
|
310
290
|
if (FLAG_type_info_threshold == 0 && !FLAG_watch_ic_patching) {
|
311
291
|
return;
|
312
292
|
}
|
313
|
-
|
293
|
+
Isolate* isolate = target->GetHeap()->isolate();
|
294
|
+
Code* host = isolate->
|
314
295
|
inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
|
315
296
|
if (host->kind() != Code::FUNCTION) return;
|
316
297
|
|
@@ -320,16 +301,20 @@ void IC::PostPatching(Address address, Code* target, Code* old_target) {
|
|
320
301
|
int delta = ComputeTypeInfoCountDelta(old_target->ic_state(),
|
321
302
|
target->ic_state());
|
322
303
|
// Not all Code objects have TypeFeedbackInfo.
|
323
|
-
if (
|
304
|
+
if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) {
|
324
305
|
TypeFeedbackInfo* info =
|
325
306
|
TypeFeedbackInfo::cast(host->type_feedback_info());
|
326
|
-
info->
|
327
|
-
info->ic_with_type_info_count() + delta);
|
307
|
+
info->change_ic_with_type_info_count(delta);
|
328
308
|
}
|
329
309
|
}
|
310
|
+
if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
|
311
|
+
TypeFeedbackInfo* info =
|
312
|
+
TypeFeedbackInfo::cast(host->type_feedback_info());
|
313
|
+
info->change_own_type_change_checksum();
|
314
|
+
}
|
330
315
|
if (FLAG_watch_ic_patching) {
|
331
316
|
host->set_profiler_ticks(0);
|
332
|
-
|
317
|
+
isolate->runtime_profiler()->NotifyICChanged();
|
333
318
|
}
|
334
319
|
// TODO(2029): When an optimized function is patched, it would
|
335
320
|
// be nice to propagate the corresponding type information to its
|
@@ -341,15 +326,13 @@ void IC::Clear(Address address) {
|
|
341
326
|
Code* target = GetTargetAtAddress(address);
|
342
327
|
|
343
328
|
// Don't clear debug break inline cache as it will remove the break point.
|
344
|
-
if (target->
|
329
|
+
if (target->is_debug_break()) return;
|
345
330
|
|
346
331
|
switch (target->kind()) {
|
347
332
|
case Code::LOAD_IC: return LoadIC::Clear(address, target);
|
348
|
-
case Code::KEYED_LOAD_IC:
|
349
|
-
return KeyedLoadIC::Clear(address, target);
|
333
|
+
case Code::KEYED_LOAD_IC: return KeyedLoadIC::Clear(address, target);
|
350
334
|
case Code::STORE_IC: return StoreIC::Clear(address, target);
|
351
|
-
case Code::KEYED_STORE_IC:
|
352
|
-
return KeyedStoreIC::Clear(address, target);
|
335
|
+
case Code::KEYED_STORE_IC: return KeyedStoreIC::Clear(address, target);
|
353
336
|
case Code::CALL_IC: return CallIC::Clear(address, target);
|
354
337
|
case Code::KEYED_CALL_IC: return KeyedCallIC::Clear(address, target);
|
355
338
|
case Code::COMPARE_IC: return CompareIC::Clear(address, target);
|
@@ -381,13 +364,13 @@ void KeyedLoadIC::Clear(Address address, Code* target) {
|
|
381
364
|
// Make sure to also clear the map used in inline fast cases. If we
|
382
365
|
// do not clear these maps, cached code can keep objects alive
|
383
366
|
// through the embedded maps.
|
384
|
-
SetTargetAtAddress(address, initialize_stub());
|
367
|
+
SetTargetAtAddress(address, *initialize_stub());
|
385
368
|
}
|
386
369
|
|
387
370
|
|
388
371
|
void LoadIC::Clear(Address address, Code* target) {
|
389
372
|
if (target->ic_state() == UNINITIALIZED) return;
|
390
|
-
SetTargetAtAddress(address, initialize_stub());
|
373
|
+
SetTargetAtAddress(address, *initialize_stub());
|
391
374
|
}
|
392
375
|
|
393
376
|
|
@@ -395,8 +378,8 @@ void StoreIC::Clear(Address address, Code* target) {
|
|
395
378
|
if (target->ic_state() == UNINITIALIZED) return;
|
396
379
|
SetTargetAtAddress(address,
|
397
380
|
(Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
|
398
|
-
? initialize_stub_strict()
|
399
|
-
: initialize_stub());
|
381
|
+
? *initialize_stub_strict()
|
382
|
+
: *initialize_stub());
|
400
383
|
}
|
401
384
|
|
402
385
|
|
@@ -404,17 +387,19 @@ void KeyedStoreIC::Clear(Address address, Code* target) {
|
|
404
387
|
if (target->ic_state() == UNINITIALIZED) return;
|
405
388
|
SetTargetAtAddress(address,
|
406
389
|
(Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
|
407
|
-
? initialize_stub_strict()
|
408
|
-
: initialize_stub());
|
390
|
+
? *initialize_stub_strict()
|
391
|
+
: *initialize_stub());
|
409
392
|
}
|
410
393
|
|
411
394
|
|
412
395
|
void CompareIC::Clear(Address address, Code* target) {
|
413
|
-
|
414
|
-
|
396
|
+
ASSERT(target->major_key() == CodeStub::CompareIC);
|
397
|
+
CompareIC::State handler_state;
|
398
|
+
Token::Value op;
|
399
|
+
ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL,
|
400
|
+
&handler_state, &op);
|
415
401
|
// Only clear CompareICs that can retain objects.
|
416
|
-
if (
|
417
|
-
Token::Value op = CompareIC::ComputeOperation(target);
|
402
|
+
if (handler_state != KNOWN_OBJECTS) return;
|
418
403
|
SetTargetAtAddress(address, GetRawUninitialized(op));
|
419
404
|
PatchInlinedSmiCode(address, DISABLE_INLINED_SMI_CHECK);
|
420
405
|
}
|
@@ -435,9 +420,7 @@ static void LookupForRead(Handle<Object> object,
|
|
435
420
|
// Besides normal conditions (property not found or it's not
|
436
421
|
// an interceptor), bail out if lookup is not cacheable: we won't
|
437
422
|
// be able to IC it anyway and regular lookup should work fine.
|
438
|
-
if (!lookup->
|
439
|
-
|| (lookup->type() != INTERCEPTOR)
|
440
|
-
|| !lookup->IsCacheable()) {
|
423
|
+
if (!lookup->IsInterceptor() || !lookup->IsCacheable()) {
|
441
424
|
return;
|
442
425
|
}
|
443
426
|
|
@@ -447,14 +430,14 @@ static void LookupForRead(Handle<Object> object,
|
|
447
430
|
}
|
448
431
|
|
449
432
|
holder->LocalLookupRealNamedProperty(*name, lookup);
|
450
|
-
if (lookup->
|
451
|
-
ASSERT(lookup->
|
433
|
+
if (lookup->IsFound()) {
|
434
|
+
ASSERT(!lookup->IsInterceptor());
|
452
435
|
return;
|
453
436
|
}
|
454
437
|
|
455
438
|
Handle<Object> proto(holder->GetPrototype());
|
456
439
|
if (proto->IsNull()) {
|
457
|
-
lookup->
|
440
|
+
ASSERT(!lookup->IsFound());
|
458
441
|
return;
|
459
442
|
}
|
460
443
|
|
@@ -535,10 +518,10 @@ MaybeObject* CallICBase::LoadFunction(State state,
|
|
535
518
|
LookupResult lookup(isolate());
|
536
519
|
LookupForRead(object, name, &lookup);
|
537
520
|
|
538
|
-
if (!lookup.
|
521
|
+
if (!lookup.IsFound()) {
|
539
522
|
// If the object does not have the requested property, check which
|
540
523
|
// exception we need to throw.
|
541
|
-
return
|
524
|
+
return IsUndeclaredGlobal(object)
|
542
525
|
? ReferenceError("not_defined", name)
|
543
526
|
: TypeError("undefined_method", object, name);
|
544
527
|
}
|
@@ -554,10 +537,10 @@ MaybeObject* CallICBase::LoadFunction(State state,
|
|
554
537
|
Object::GetProperty(object, object, &lookup, name, &attr);
|
555
538
|
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
556
539
|
|
557
|
-
if (lookup.
|
540
|
+
if (lookup.IsInterceptor() && attr == ABSENT) {
|
558
541
|
// If the object does not have the requested property, check which
|
559
542
|
// exception we need to throw.
|
560
|
-
return
|
543
|
+
return IsUndeclaredGlobal(object)
|
561
544
|
? ReferenceError("not_defined", name)
|
562
545
|
: TypeError("undefined_method", object, name);
|
563
546
|
}
|
@@ -644,7 +627,7 @@ Handle<Code> CallICBase::ComputeMonomorphicStub(LookupResult* lookup,
|
|
644
627
|
Handle<JSObject> holder(lookup->holder());
|
645
628
|
switch (lookup->type()) {
|
646
629
|
case FIELD: {
|
647
|
-
|
630
|
+
PropertyIndex index = lookup->GetFieldIndex();
|
648
631
|
return isolate()->stub_cache()->ComputeCallField(
|
649
632
|
argc, kind_, extra_state, name, object, holder, index);
|
650
633
|
}
|
@@ -697,17 +680,8 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
|
|
697
680
|
// Bail out if we didn't find a result.
|
698
681
|
if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
|
699
682
|
|
700
|
-
if (lookup->holder() != *object &&
|
701
|
-
HasNormalObjectsInPrototypeChain(
|
702
|
-
isolate(), lookup, object->GetPrototype())) {
|
703
|
-
// Suppress optimization for prototype chains with slow properties objects
|
704
|
-
// in the middle.
|
705
|
-
return;
|
706
|
-
}
|
707
|
-
|
708
683
|
// Compute the number of arguments.
|
709
684
|
int argc = target()->arguments_count();
|
710
|
-
bool had_proto_failure = false;
|
711
685
|
Handle<Code> code;
|
712
686
|
if (state == UNINITIALIZED) {
|
713
687
|
// This is the first time we execute this inline cache.
|
@@ -724,7 +698,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
|
|
724
698
|
TryRemoveInvalidPrototypeDependentStub(target(),
|
725
699
|
*object,
|
726
700
|
*name)) {
|
727
|
-
|
701
|
+
state = MONOMORPHIC_PROTOTYPE_FAILURE;
|
728
702
|
code = ComputeMonomorphicStub(lookup, state, extra_ic_state,
|
729
703
|
object, name);
|
730
704
|
} else {
|
@@ -740,22 +714,39 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
|
|
740
714
|
if (code.is_null()) return;
|
741
715
|
|
742
716
|
// Patch the call site depending on the state of the cache.
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
717
|
+
switch (state) {
|
718
|
+
case UNINITIALIZED:
|
719
|
+
case MONOMORPHIC_PROTOTYPE_FAILURE:
|
720
|
+
case PREMONOMORPHIC:
|
721
|
+
set_target(*code);
|
722
|
+
break;
|
723
|
+
case MONOMORPHIC:
|
724
|
+
if (code->ic_state() != MONOMORPHIC) {
|
725
|
+
Map* map = target()->FindFirstMap();
|
726
|
+
if (map != NULL) {
|
727
|
+
UpdateMegamorphicCache(map, *name, target());
|
728
|
+
}
|
729
|
+
}
|
730
|
+
set_target(*code);
|
731
|
+
break;
|
732
|
+
case MEGAMORPHIC: {
|
733
|
+
// Cache code holding map should be consistent with
|
734
|
+
// GenerateMonomorphicCacheProbe. It is not the map which holds the stub.
|
735
|
+
Handle<JSObject> cache_object = object->IsJSObject()
|
736
|
+
? Handle<JSObject>::cast(object)
|
737
|
+
: Handle<JSObject>(JSObject::cast(object->GetPrototype()));
|
738
|
+
// Update the stub cache.
|
739
|
+
UpdateMegamorphicCache(cache_object->map(), *name, *code);
|
740
|
+
break;
|
741
|
+
}
|
742
|
+
case DEBUG_STUB:
|
743
|
+
break;
|
744
|
+
case POLYMORPHIC:
|
745
|
+
case GENERIC:
|
746
|
+
UNREACHABLE();
|
747
|
+
break;
|
748
|
+
}
|
749
|
+
|
759
750
|
TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
|
760
751
|
name, state, target());
|
761
752
|
}
|
@@ -775,22 +766,23 @@ MaybeObject* KeyedCallIC::LoadFunction(State state,
|
|
775
766
|
return TypeError("non_object_property_call", object, key);
|
776
767
|
}
|
777
768
|
|
778
|
-
|
769
|
+
bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
|
770
|
+
ASSERT(!(use_ic && object->IsJSGlobalProxy()));
|
771
|
+
|
772
|
+
if (use_ic && state != MEGAMORPHIC) {
|
779
773
|
int argc = target()->arguments_count();
|
780
|
-
Handle<
|
781
|
-
|
782
|
-
if (object->IsJSObject()
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
} else if (!object->IsAccessCheckNeeded()) {
|
789
|
-
Handle<Code> code = isolate()->stub_cache()->ComputeCallMegamorphic(
|
790
|
-
argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
|
791
|
-
set_target(*code);
|
792
|
-
TRACE_IC("KeyedCallIC", key, state, target());
|
774
|
+
Handle<Code> stub = isolate()->stub_cache()->ComputeCallMegamorphic(
|
775
|
+
argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
|
776
|
+
if (object->IsJSObject()) {
|
777
|
+
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
778
|
+
if (receiver->elements()->map() ==
|
779
|
+
isolate()->heap()->non_strict_arguments_elements_map()) {
|
780
|
+
stub = isolate()->stub_cache()->ComputeCallArguments(argc);
|
781
|
+
}
|
793
782
|
}
|
783
|
+
ASSERT(!stub.is_null());
|
784
|
+
set_target(*stub);
|
785
|
+
TRACE_IC("KeyedCallIC", key, state, target());
|
794
786
|
}
|
795
787
|
|
796
788
|
Handle<Object> result = GetProperty(object, key);
|
@@ -829,12 +821,13 @@ MaybeObject* LoadIC::Load(State state,
|
|
829
821
|
if (state == UNINITIALIZED) {
|
830
822
|
stub = pre_monomorphic_stub();
|
831
823
|
} else if (state == PREMONOMORPHIC) {
|
832
|
-
|
833
|
-
|
834
|
-
: isolate()->builtins()->LoadIC_StringWrapperLength();
|
824
|
+
StringLengthStub string_length_stub(kind(), !object->IsString());
|
825
|
+
stub = string_length_stub.GetCode();
|
835
826
|
} else if (state == MONOMORPHIC && object->IsStringWrapper()) {
|
836
|
-
|
827
|
+
StringLengthStub string_length_stub(kind(), true);
|
828
|
+
stub = string_length_stub.GetCode();
|
837
829
|
} else if (state != MEGAMORPHIC) {
|
830
|
+
ASSERT(state != GENERIC);
|
838
831
|
stub = megamorphic_stub();
|
839
832
|
}
|
840
833
|
if (!stub.is_null()) {
|
@@ -857,8 +850,10 @@ MaybeObject* LoadIC::Load(State state,
|
|
857
850
|
if (state == UNINITIALIZED) {
|
858
851
|
stub = pre_monomorphic_stub();
|
859
852
|
} else if (state == PREMONOMORPHIC) {
|
860
|
-
|
853
|
+
ArrayLengthStub array_length_stub(kind());
|
854
|
+
stub = array_length_stub.GetCode();
|
861
855
|
} else if (state != MEGAMORPHIC) {
|
856
|
+
ASSERT(state != GENERIC);
|
862
857
|
stub = megamorphic_stub();
|
863
858
|
}
|
864
859
|
if (!stub.is_null()) {
|
@@ -878,8 +873,10 @@ MaybeObject* LoadIC::Load(State state,
|
|
878
873
|
if (state == UNINITIALIZED) {
|
879
874
|
stub = pre_monomorphic_stub();
|
880
875
|
} else if (state == PREMONOMORPHIC) {
|
881
|
-
|
876
|
+
FunctionPrototypeStub function_prototype_stub(kind());
|
877
|
+
stub = function_prototype_stub.GetCode();
|
882
878
|
} else if (state != MEGAMORPHIC) {
|
879
|
+
ASSERT(state != GENERIC);
|
883
880
|
stub = megamorphic_stub();
|
884
881
|
}
|
885
882
|
if (!stub.is_null()) {
|
@@ -893,17 +890,21 @@ MaybeObject* LoadIC::Load(State state,
|
|
893
890
|
}
|
894
891
|
|
895
892
|
// Check if the name is trivially convertible to an index and get
|
896
|
-
// the element if so.
|
893
|
+
// the element or char if so.
|
897
894
|
uint32_t index;
|
898
|
-
if (name->AsArrayIndex(&index))
|
895
|
+
if (kind() == Code::KEYED_LOAD_IC && name->AsArrayIndex(&index)) {
|
896
|
+
// Rewrite to the generic keyed load stub.
|
897
|
+
if (FLAG_use_ic) set_target(*generic_stub());
|
898
|
+
return Runtime::GetElementOrCharAt(isolate(), object, index);
|
899
|
+
}
|
899
900
|
|
900
901
|
// Named lookup in the object.
|
901
902
|
LookupResult lookup(isolate());
|
902
903
|
LookupForRead(object, name, &lookup);
|
903
904
|
|
904
905
|
// If we did not find a property, check if we need to throw an exception.
|
905
|
-
if (!lookup.
|
906
|
-
if (
|
906
|
+
if (!lookup.IsFound()) {
|
907
|
+
if (IsUndeclaredGlobal(object)) {
|
907
908
|
return ReferenceError("not_defined", name);
|
908
909
|
}
|
909
910
|
LOG(isolate(), SuspectReadEvent(*name, *object));
|
@@ -915,15 +916,14 @@ MaybeObject* LoadIC::Load(State state,
|
|
915
916
|
}
|
916
917
|
|
917
918
|
PropertyAttributes attr;
|
918
|
-
if (lookup.
|
919
|
-
(lookup.type() == INTERCEPTOR || lookup.type() == HANDLER)) {
|
919
|
+
if (lookup.IsInterceptor() || lookup.IsHandler()) {
|
920
920
|
// Get the property.
|
921
921
|
Handle<Object> result =
|
922
922
|
Object::GetProperty(object, object, &lookup, name, &attr);
|
923
923
|
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
924
924
|
// If the property is not present, check if we need to throw an
|
925
925
|
// exception.
|
926
|
-
if (attr == ABSENT &&
|
926
|
+
if (attr == ABSENT && IsUndeclaredGlobal(object)) {
|
927
927
|
return ReferenceError("not_defined", name);
|
928
928
|
}
|
929
929
|
return *result;
|
@@ -934,6 +934,56 @@ MaybeObject* LoadIC::Load(State state,
|
|
934
934
|
}
|
935
935
|
|
936
936
|
|
937
|
+
void IC::PatchCache(State state,
|
938
|
+
StrictModeFlag strict_mode,
|
939
|
+
Handle<JSObject> receiver,
|
940
|
+
Handle<String> name,
|
941
|
+
Handle<Code> code) {
|
942
|
+
switch (state) {
|
943
|
+
case UNINITIALIZED:
|
944
|
+
case PREMONOMORPHIC:
|
945
|
+
case MONOMORPHIC_PROTOTYPE_FAILURE:
|
946
|
+
set_target(*code);
|
947
|
+
break;
|
948
|
+
case MONOMORPHIC:
|
949
|
+
// Only move to megamorphic if the target changes.
|
950
|
+
if (target() != *code) {
|
951
|
+
// We are transitioning from monomorphic to megamorphic case.
|
952
|
+
// Place the current monomorphic stub and stub compiled for
|
953
|
+
// the receiver into stub cache.
|
954
|
+
Map* map = target()->FindFirstMap();
|
955
|
+
if (map != NULL) {
|
956
|
+
UpdateMegamorphicCache(map, *name, target());
|
957
|
+
}
|
958
|
+
UpdateMegamorphicCache(receiver->map(), *name, *code);
|
959
|
+
set_target((strict_mode == kStrictMode)
|
960
|
+
? *megamorphic_stub_strict()
|
961
|
+
: *megamorphic_stub());
|
962
|
+
}
|
963
|
+
break;
|
964
|
+
case MEGAMORPHIC:
|
965
|
+
// Update the stub cache.
|
966
|
+
UpdateMegamorphicCache(receiver->map(), *name, *code);
|
967
|
+
break;
|
968
|
+
case POLYMORPHIC:
|
969
|
+
// When trying to patch a polymorphic stub with anything other than
|
970
|
+
// another polymorphic stub, go generic.
|
971
|
+
// TODO(verwaest): Currently we always go generic since no polymorphic
|
972
|
+
// stubs enter this code path. Replace with proper updating once named
|
973
|
+
// load/store can also be polymorphic.
|
974
|
+
set_target((strict_mode == kStrictMode)
|
975
|
+
? *generic_stub_strict()
|
976
|
+
: *generic_stub());
|
977
|
+
break;
|
978
|
+
case DEBUG_STUB:
|
979
|
+
break;
|
980
|
+
case GENERIC:
|
981
|
+
UNREACHABLE();
|
982
|
+
break;
|
983
|
+
}
|
984
|
+
}
|
985
|
+
|
986
|
+
|
937
987
|
void LoadIC::UpdateCaches(LookupResult* lookup,
|
938
988
|
State state,
|
939
989
|
Handle<Object> object,
|
@@ -944,122 +994,91 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
|
|
944
994
|
// Loading properties from values is not common, so don't try to
|
945
995
|
// deal with non-JS objects here.
|
946
996
|
if (!object->IsJSObject()) return;
|
947
|
-
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
948
997
|
|
949
|
-
|
950
|
-
|
951
|
-
// Compute the code stub for this load.
|
998
|
+
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
952
999
|
Handle<Code> code;
|
953
1000
|
if (state == UNINITIALIZED) {
|
954
1001
|
// This is the first time we execute this inline cache.
|
955
1002
|
// Set the target to the pre monomorphic stub to delay
|
956
1003
|
// setting the monomorphic state.
|
957
1004
|
code = pre_monomorphic_stub();
|
958
|
-
} else if (!lookup->IsProperty()) {
|
959
|
-
// Nonexistent property. The result is undefined.
|
960
|
-
code = isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver);
|
961
1005
|
} else {
|
962
|
-
|
963
|
-
|
964
|
-
switch (lookup->type()) {
|
965
|
-
case FIELD:
|
966
|
-
code = isolate()->stub_cache()->ComputeLoadField(
|
967
|
-
name, receiver, holder, lookup->GetFieldIndex());
|
968
|
-
break;
|
969
|
-
case CONSTANT_FUNCTION: {
|
970
|
-
Handle<JSFunction> constant(lookup->GetConstantFunction());
|
971
|
-
code = isolate()->stub_cache()->ComputeLoadConstant(
|
972
|
-
name, receiver, holder, constant);
|
973
|
-
break;
|
974
|
-
}
|
975
|
-
case NORMAL:
|
976
|
-
if (holder->IsGlobalObject()) {
|
977
|
-
Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
|
978
|
-
Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
|
979
|
-
code = isolate()->stub_cache()->ComputeLoadGlobal(
|
980
|
-
name, receiver, global, cell, lookup->IsDontDelete());
|
981
|
-
} else {
|
982
|
-
// There is only one shared stub for loading normalized
|
983
|
-
// properties. It does not traverse the prototype chain, so the
|
984
|
-
// property must be found in the receiver for the stub to be
|
985
|
-
// applicable.
|
986
|
-
if (!holder.is_identical_to(receiver)) return;
|
987
|
-
code = isolate()->stub_cache()->ComputeLoadNormal();
|
988
|
-
}
|
989
|
-
break;
|
990
|
-
case CALLBACKS: {
|
991
|
-
Handle<Object> callback_object(lookup->GetCallbackObject());
|
992
|
-
if (!callback_object->IsAccessorInfo()) return;
|
993
|
-
Handle<AccessorInfo> callback =
|
994
|
-
Handle<AccessorInfo>::cast(callback_object);
|
995
|
-
if (v8::ToCData<Address>(callback->getter()) == 0) return;
|
996
|
-
code = isolate()->stub_cache()->ComputeLoadCallback(
|
997
|
-
name, receiver, holder, callback);
|
998
|
-
break;
|
999
|
-
}
|
1000
|
-
case INTERCEPTOR:
|
1001
|
-
ASSERT(HasInterceptorGetter(*holder));
|
1002
|
-
code = isolate()->stub_cache()->ComputeLoadInterceptor(
|
1003
|
-
name, receiver, holder);
|
1004
|
-
break;
|
1005
|
-
default:
|
1006
|
-
return;
|
1007
|
-
}
|
1008
|
-
}
|
1009
|
-
|
1010
|
-
// Patch the call site depending on the state of the cache.
|
1011
|
-
if (state == UNINITIALIZED ||
|
1012
|
-
state == PREMONOMORPHIC ||
|
1013
|
-
state == MONOMORPHIC_PROTOTYPE_FAILURE) {
|
1014
|
-
set_target(*code);
|
1015
|
-
} else if (state == MONOMORPHIC) {
|
1016
|
-
// We are transitioning from monomorphic to megamorphic case.
|
1017
|
-
// Place the current monomorphic stub and stub compiled for
|
1018
|
-
// the receiver into stub cache.
|
1019
|
-
Map* map = target()->FindFirstMap();
|
1020
|
-
if (map != NULL) {
|
1021
|
-
isolate()->stub_cache()->Set(*name, map, target());
|
1022
|
-
}
|
1023
|
-
isolate()->stub_cache()->Set(*name, receiver->map(), *code);
|
1024
|
-
|
1025
|
-
set_target(*megamorphic_stub());
|
1026
|
-
} else if (state == MEGAMORPHIC) {
|
1027
|
-
// Cache code holding map should be consistent with
|
1028
|
-
// GenerateMonomorphicCacheProbe.
|
1029
|
-
isolate()->stub_cache()->Set(*name, receiver->map(), *code);
|
1006
|
+
code = ComputeLoadMonomorphic(lookup, receiver, name);
|
1007
|
+
if (code.is_null()) return;
|
1030
1008
|
}
|
1031
1009
|
|
1010
|
+
PatchCache(state, kNonStrictMode, receiver, name, code);
|
1032
1011
|
TRACE_IC("LoadIC", name, state, target());
|
1033
1012
|
}
|
1034
1013
|
|
1035
1014
|
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
ASSERT(grow_mode == DO_NOT_ALLOW_JSARRAY_GROWTH);
|
1041
|
-
return KeyedLoadElementStub(elements_kind).GetCode();
|
1015
|
+
void IC::UpdateMegamorphicCache(Map* map, String* name, Code* code) {
|
1016
|
+
// Cache code holding map should be consistent with
|
1017
|
+
// GenerateMonomorphicCacheProbe.
|
1018
|
+
isolate()->stub_cache()->Set(name, map, code);
|
1042
1019
|
}
|
1043
1020
|
|
1044
1021
|
|
1045
|
-
Handle<Code>
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
Handle<Map> receiver_map = receiver_maps->at(i);
|
1052
|
-
Handle<Code> cached_stub = ComputeMonomorphicStubWithoutMapCheck(
|
1053
|
-
receiver_map, strict_mode, growth_mode);
|
1054
|
-
handler_ics.Add(cached_stub);
|
1022
|
+
Handle<Code> LoadIC::ComputeLoadMonomorphic(LookupResult* lookup,
|
1023
|
+
Handle<JSObject> receiver,
|
1024
|
+
Handle<String> name) {
|
1025
|
+
if (!lookup->IsProperty()) {
|
1026
|
+
// Nonexistent property. The result is undefined.
|
1027
|
+
return isolate()->stub_cache()->ComputeLoadNonexistent(name, receiver);
|
1055
1028
|
}
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1029
|
+
|
1030
|
+
// Compute monomorphic stub.
|
1031
|
+
Handle<JSObject> holder(lookup->holder());
|
1032
|
+
switch (lookup->type()) {
|
1033
|
+
case FIELD:
|
1034
|
+
return isolate()->stub_cache()->ComputeLoadField(
|
1035
|
+
name, receiver, holder, lookup->GetFieldIndex());
|
1036
|
+
case CONSTANT_FUNCTION: {
|
1037
|
+
Handle<JSFunction> constant(lookup->GetConstantFunction());
|
1038
|
+
return isolate()->stub_cache()->ComputeLoadConstant(
|
1039
|
+
name, receiver, holder, constant);
|
1040
|
+
}
|
1041
|
+
case NORMAL:
|
1042
|
+
if (holder->IsGlobalObject()) {
|
1043
|
+
Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
|
1044
|
+
Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
|
1045
|
+
return isolate()->stub_cache()->ComputeLoadGlobal(
|
1046
|
+
name, receiver, global, cell, lookup->IsDontDelete());
|
1047
|
+
}
|
1048
|
+
// There is only one shared stub for loading normalized
|
1049
|
+
// properties. It does not traverse the prototype chain, so the
|
1050
|
+
// property must be found in the receiver for the stub to be
|
1051
|
+
// applicable.
|
1052
|
+
if (!holder.is_identical_to(receiver)) break;
|
1053
|
+
return isolate()->stub_cache()->ComputeLoadNormal();
|
1054
|
+
case CALLBACKS: {
|
1055
|
+
Handle<Object> callback(lookup->GetCallbackObject());
|
1056
|
+
if (callback->IsAccessorInfo()) {
|
1057
|
+
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
|
1058
|
+
if (v8::ToCData<Address>(info->getter()) == 0) break;
|
1059
|
+
if (!info->IsCompatibleReceiver(*receiver)) break;
|
1060
|
+
return isolate()->stub_cache()->ComputeLoadCallback(
|
1061
|
+
name, receiver, holder, info);
|
1062
|
+
} else if (callback->IsAccessorPair()) {
|
1063
|
+
Handle<Object> getter(Handle<AccessorPair>::cast(callback)->getter());
|
1064
|
+
if (!getter->IsJSFunction()) break;
|
1065
|
+
if (holder->IsGlobalObject()) break;
|
1066
|
+
if (!holder->HasFastProperties()) break;
|
1067
|
+
return isolate()->stub_cache()->ComputeLoadViaGetter(
|
1068
|
+
name, receiver, holder, Handle<JSFunction>::cast(getter));
|
1069
|
+
}
|
1070
|
+
ASSERT(callback->IsForeign());
|
1071
|
+
// No IC support for old-style native accessors.
|
1072
|
+
break;
|
1073
|
+
}
|
1074
|
+
case INTERCEPTOR:
|
1075
|
+
ASSERT(HasInterceptorGetter(*holder));
|
1076
|
+
return isolate()->stub_cache()->ComputeLoadInterceptor(
|
1077
|
+
name, receiver, holder);
|
1078
|
+
default:
|
1079
|
+
break;
|
1080
|
+
}
|
1081
|
+
return Handle<Code>::null();
|
1063
1082
|
}
|
1064
1083
|
|
1065
1084
|
|
@@ -1083,111 +1102,139 @@ static Handle<Object> TryConvertKey(Handle<Object> key, Isolate* isolate) {
|
|
1083
1102
|
}
|
1084
1103
|
|
1085
1104
|
|
1086
|
-
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
if (key->IsSymbol()) {
|
1095
|
-
Handle<String> name = Handle<String>::cast(key);
|
1096
|
-
|
1097
|
-
// If the object is undefined or null it's illegal to try to get any
|
1098
|
-
// of its properties; throw a TypeError in that case.
|
1099
|
-
if (object->IsUndefined() || object->IsNull()) {
|
1100
|
-
return TypeError("non_object_property_load", object, name);
|
1105
|
+
static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
|
1106
|
+
Handle<Map> new_receiver_map) {
|
1107
|
+
ASSERT(!new_receiver_map.is_null());
|
1108
|
+
for (int current = 0; current < receiver_maps->length(); ++current) {
|
1109
|
+
if (!receiver_maps->at(current).is_null() &&
|
1110
|
+
receiver_maps->at(current).is_identical_to(new_receiver_map)) {
|
1111
|
+
return false;
|
1101
1112
|
}
|
1113
|
+
}
|
1114
|
+
receiver_maps->Add(new_receiver_map);
|
1115
|
+
return true;
|
1116
|
+
}
|
1102
1117
|
|
1103
|
-
if (FLAG_use_ic) {
|
1104
|
-
// TODO(1073): don't ignore the current stub state.
|
1105
|
-
|
1106
|
-
// Use specialized code for getting the length of strings.
|
1107
|
-
if (object->IsString() &&
|
1108
|
-
name->Equals(isolate()->heap()->length_symbol())) {
|
1109
|
-
Handle<String> string = Handle<String>::cast(object);
|
1110
|
-
Handle<Code> code =
|
1111
|
-
isolate()->stub_cache()->ComputeKeyedLoadStringLength(name, string);
|
1112
|
-
ASSERT(!code.is_null());
|
1113
|
-
set_target(*code);
|
1114
|
-
TRACE_IC("KeyedLoadIC", name, state, target());
|
1115
|
-
return Smi::FromInt(string->length());
|
1116
|
-
}
|
1117
1118
|
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
return array->length();
|
1119
|
+
static void GetReceiverMapsForStub(Handle<Code> stub,
|
1120
|
+
MapHandleList* result) {
|
1121
|
+
ASSERT(stub->is_inline_cache_stub());
|
1122
|
+
ASSERT(stub->is_keyed_load_stub() || stub->is_keyed_store_stub());
|
1123
|
+
switch (stub->ic_state()) {
|
1124
|
+
case MONOMORPHIC: {
|
1125
|
+
Map* map = stub->FindFirstMap();
|
1126
|
+
if (map != NULL) {
|
1127
|
+
result->Add(Handle<Map>(map));
|
1128
1128
|
}
|
1129
|
-
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1138
|
-
|
1139
|
-
set_target(*code);
|
1140
|
-
TRACE_IC("KeyedLoadIC", name, state, target());
|
1141
|
-
return Accessors::FunctionGetPrototype(*object, 0);
|
1129
|
+
break;
|
1130
|
+
}
|
1131
|
+
case POLYMORPHIC: {
|
1132
|
+
AssertNoAllocation no_allocation;
|
1133
|
+
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
|
1134
|
+
for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
|
1135
|
+
RelocInfo* info = it.rinfo();
|
1136
|
+
Handle<Object> object(info->target_object());
|
1137
|
+
ASSERT(object->IsMap());
|
1138
|
+
AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
|
1142
1139
|
}
|
1140
|
+
break;
|
1143
1141
|
}
|
1142
|
+
case MEGAMORPHIC:
|
1143
|
+
break;
|
1144
|
+
case UNINITIALIZED:
|
1145
|
+
case PREMONOMORPHIC:
|
1146
|
+
case MONOMORPHIC_PROTOTYPE_FAILURE:
|
1147
|
+
case GENERIC:
|
1148
|
+
case DEBUG_STUB:
|
1149
|
+
UNREACHABLE();
|
1150
|
+
break;
|
1151
|
+
}
|
1152
|
+
}
|
1144
1153
|
|
1145
|
-
// Check if the name is trivially convertible to an index and get
|
1146
|
-
// the element or char if so.
|
1147
|
-
uint32_t index = 0;
|
1148
|
-
if (name->AsArrayIndex(&index)) {
|
1149
|
-
// Rewrite to the generic keyed load stub.
|
1150
|
-
if (FLAG_use_ic) set_target(*generic_stub());
|
1151
|
-
return Runtime::GetElementOrCharAt(isolate(), object, index);
|
1152
|
-
}
|
1153
1154
|
|
1154
|
-
|
1155
|
-
|
1156
|
-
LookupForRead(object, name, &lookup);
|
1155
|
+
Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
|
1156
|
+
State ic_state = target()->ic_state();
|
1157
1157
|
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1158
|
+
// Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
|
1159
|
+
// via megamorphic stubs, since they don't have a map in their relocation info
|
1160
|
+
// and so the stubs can't be harvested for the object needed for a map check.
|
1161
|
+
if (target()->type() != Code::NORMAL) {
|
1162
|
+
TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type");
|
1163
|
+
return generic_stub();
|
1164
|
+
}
|
1162
1165
|
|
1163
|
-
|
1164
|
-
|
1165
|
-
|
1166
|
+
Handle<Map> receiver_map(receiver->map());
|
1167
|
+
MapHandleList target_receiver_maps;
|
1168
|
+
if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
|
1169
|
+
// Optimistically assume that ICs that haven't reached the MONOMORPHIC state
|
1170
|
+
// yet will do so and stay there.
|
1171
|
+
return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
|
1172
|
+
}
|
1166
1173
|
|
1167
|
-
|
1168
|
-
|
1169
|
-
|
1170
|
-
|
1171
|
-
|
1172
|
-
|
1173
|
-
// If the property is not present, check if we need to throw an
|
1174
|
-
// exception.
|
1175
|
-
if (attr == ABSENT && IsContextual(object)) {
|
1176
|
-
return ReferenceError("not_defined", name);
|
1177
|
-
}
|
1178
|
-
return *result;
|
1174
|
+
if (target() == *string_stub()) {
|
1175
|
+
target_receiver_maps.Add(isolate()->factory()->string_map());
|
1176
|
+
} else {
|
1177
|
+
GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
|
1178
|
+
if (target_receiver_maps.length() == 0) {
|
1179
|
+
return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
|
1179
1180
|
}
|
1181
|
+
}
|
1182
|
+
|
1183
|
+
// The first time a receiver is seen that is a transitioned version of the
|
1184
|
+
// previous monomorphic receiver type, assume the new ElementsKind is the
|
1185
|
+
// monomorphic type. This benefits global arrays that only transition
|
1186
|
+
// once, and all call sites accessing them are faster if they remain
|
1187
|
+
// monomorphic. If this optimistic assumption is not true, the IC will
|
1188
|
+
// miss again and it will become polymorphic and support both the
|
1189
|
+
// untransitioned and transitioned maps.
|
1190
|
+
if (ic_state == MONOMORPHIC &&
|
1191
|
+
IsMoreGeneralElementsKindTransition(
|
1192
|
+
target_receiver_maps.at(0)->elements_kind(),
|
1193
|
+
receiver->GetElementsKind())) {
|
1194
|
+
return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
|
1195
|
+
}
|
1196
|
+
|
1197
|
+
ASSERT(ic_state != GENERIC);
|
1198
|
+
|
1199
|
+
// Determine the list of receiver maps that this call site has seen,
|
1200
|
+
// adding the map that was just encountered.
|
1201
|
+
if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
|
1202
|
+
// If the miss wasn't due to an unseen map, a polymorphic stub
|
1203
|
+
// won't help, use the generic stub.
|
1204
|
+
TRACE_GENERIC_IC("KeyedIC", "same map added twice");
|
1205
|
+
return generic_stub();
|
1206
|
+
}
|
1180
1207
|
|
1181
|
-
|
1208
|
+
// If the maximum number of receiver maps has been exceeded, use the generic
|
1209
|
+
// version of the IC.
|
1210
|
+
if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
|
1211
|
+
TRACE_GENERIC_IC("KeyedIC", "max polymorph exceeded");
|
1212
|
+
return generic_stub();
|
1213
|
+
}
|
1214
|
+
|
1215
|
+
return isolate()->stub_cache()->ComputeLoadElementPolymorphic(
|
1216
|
+
&target_receiver_maps);
|
1217
|
+
}
|
1218
|
+
|
1219
|
+
|
1220
|
+
MaybeObject* KeyedLoadIC::Load(State state,
|
1221
|
+
Handle<Object> object,
|
1222
|
+
Handle<Object> key,
|
1223
|
+
ICMissMode miss_mode) {
|
1224
|
+
// Check for values that can be converted into a symbol directly or
|
1225
|
+
// is representable as a smi.
|
1226
|
+
key = TryConvertKey(key, isolate());
|
1227
|
+
|
1228
|
+
if (key->IsSymbol()) {
|
1229
|
+
return LoadIC::Load(state, object, Handle<String>::cast(key));
|
1182
1230
|
}
|
1183
1231
|
|
1184
|
-
// Do not use ICs for objects that require access checks (including
|
1185
|
-
// the global object).
|
1186
1232
|
bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
|
1233
|
+
ASSERT(!(use_ic && object->IsJSGlobalProxy()));
|
1187
1234
|
|
1188
1235
|
if (use_ic) {
|
1189
1236
|
Handle<Code> stub = generic_stub();
|
1190
|
-
if (
|
1237
|
+
if (miss_mode != MISS_FORCE_GENERIC) {
|
1191
1238
|
if (object->IsString() && key->IsNumber()) {
|
1192
1239
|
if (state == UNINITIALIZED) {
|
1193
1240
|
stub = string_stub();
|
@@ -1200,103 +1247,74 @@ MaybeObject* KeyedLoadIC::Load(State state,
|
|
1200
1247
|
} else if (receiver->HasIndexedInterceptor()) {
|
1201
1248
|
stub = indexed_interceptor_stub();
|
1202
1249
|
} else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
|
1203
|
-
stub =
|
1250
|
+
stub = LoadElementStub(receiver);
|
1204
1251
|
}
|
1205
1252
|
}
|
1206
1253
|
} else {
|
1207
1254
|
TRACE_GENERIC_IC("KeyedLoadIC", "force generic");
|
1208
1255
|
}
|
1209
|
-
|
1256
|
+
ASSERT(!stub.is_null());
|
1257
|
+
set_target(*stub);
|
1258
|
+
TRACE_IC("KeyedLoadIC", key, state, target());
|
1210
1259
|
}
|
1211
1260
|
|
1212
|
-
TRACE_IC("KeyedLoadIC", key, state, target());
|
1213
1261
|
|
1214
|
-
// Get the property.
|
1215
1262
|
return Runtime::GetObjectProperty(isolate(), object, key);
|
1216
1263
|
}
|
1217
1264
|
|
1218
1265
|
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
Handle<String> name) {
|
1266
|
+
Handle<Code> KeyedLoadIC::ComputeLoadMonomorphic(LookupResult* lookup,
|
1267
|
+
Handle<JSObject> receiver,
|
1268
|
+
Handle<String> name) {
|
1223
1269
|
// Bail out if we didn't find a result.
|
1224
|
-
if (!lookup->IsProperty()
|
1225
|
-
|
1226
|
-
if (!object->IsJSObject()) return;
|
1227
|
-
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
1228
|
-
|
1229
|
-
if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
|
1230
|
-
|
1231
|
-
// Compute the code stub for this load.
|
1232
|
-
Handle<Code> code;
|
1270
|
+
if (!lookup->IsProperty()) return Handle<Code>::null();
|
1233
1271
|
|
1234
|
-
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
|
1240
|
-
|
1241
|
-
|
1242
|
-
|
1243
|
-
|
1244
|
-
code = isolate()->stub_cache()->ComputeKeyedLoadField(
|
1245
|
-
name, receiver, holder, lookup->GetFieldIndex());
|
1246
|
-
break;
|
1247
|
-
case CONSTANT_FUNCTION: {
|
1248
|
-
Handle<JSFunction> constant(lookup->GetConstantFunction());
|
1249
|
-
code = isolate()->stub_cache()->ComputeKeyedLoadConstant(
|
1250
|
-
name, receiver, holder, constant);
|
1251
|
-
break;
|
1252
|
-
}
|
1253
|
-
case CALLBACKS: {
|
1254
|
-
Handle<Object> callback_object(lookup->GetCallbackObject());
|
1255
|
-
if (!callback_object->IsAccessorInfo()) return;
|
1256
|
-
Handle<AccessorInfo> callback =
|
1257
|
-
Handle<AccessorInfo>::cast(callback_object);
|
1258
|
-
if (v8::ToCData<Address>(callback->getter()) == 0) return;
|
1259
|
-
code = isolate()->stub_cache()->ComputeKeyedLoadCallback(
|
1260
|
-
name, receiver, holder, callback);
|
1261
|
-
break;
|
1262
|
-
}
|
1263
|
-
case INTERCEPTOR:
|
1264
|
-
ASSERT(HasInterceptorGetter(lookup->holder()));
|
1265
|
-
code = isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
|
1266
|
-
name, receiver, holder);
|
1267
|
-
break;
|
1268
|
-
default:
|
1269
|
-
// Always rewrite to the generic case so that we do not
|
1270
|
-
// repeatedly try to rewrite.
|
1271
|
-
code = generic_stub();
|
1272
|
-
break;
|
1272
|
+
// Compute a monomorphic stub.
|
1273
|
+
Handle<JSObject> holder(lookup->holder());
|
1274
|
+
switch (lookup->type()) {
|
1275
|
+
case FIELD:
|
1276
|
+
return isolate()->stub_cache()->ComputeKeyedLoadField(
|
1277
|
+
name, receiver, holder, lookup->GetFieldIndex());
|
1278
|
+
case CONSTANT_FUNCTION: {
|
1279
|
+
Handle<JSFunction> constant(lookup->GetConstantFunction());
|
1280
|
+
return isolate()->stub_cache()->ComputeKeyedLoadConstant(
|
1281
|
+
name, receiver, holder, constant);
|
1273
1282
|
}
|
1283
|
+
case CALLBACKS: {
|
1284
|
+
Handle<Object> callback_object(lookup->GetCallbackObject());
|
1285
|
+
if (!callback_object->IsAccessorInfo()) break;
|
1286
|
+
Handle<AccessorInfo> callback =
|
1287
|
+
Handle<AccessorInfo>::cast(callback_object);
|
1288
|
+
if (v8::ToCData<Address>(callback->getter()) == 0) break;
|
1289
|
+
if (!callback->IsCompatibleReceiver(*receiver)) break;
|
1290
|
+
return isolate()->stub_cache()->ComputeKeyedLoadCallback(
|
1291
|
+
name, receiver, holder, callback);
|
1292
|
+
}
|
1293
|
+
case INTERCEPTOR:
|
1294
|
+
ASSERT(HasInterceptorGetter(lookup->holder()));
|
1295
|
+
return isolate()->stub_cache()->ComputeKeyedLoadInterceptor(
|
1296
|
+
name, receiver, holder);
|
1297
|
+
default:
|
1298
|
+
// Always rewrite to the generic case so that we do not
|
1299
|
+
// repeatedly try to rewrite.
|
1300
|
+
return generic_stub();
|
1274
1301
|
}
|
1275
|
-
|
1276
|
-
// Patch the call site depending on the state of the cache. Make
|
1277
|
-
// sure to always rewrite from monomorphic to megamorphic.
|
1278
|
-
ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
|
1279
|
-
if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
|
1280
|
-
set_target(*code);
|
1281
|
-
} else if (state == MONOMORPHIC) {
|
1282
|
-
set_target(*megamorphic_stub());
|
1283
|
-
}
|
1284
|
-
|
1285
|
-
TRACE_IC("KeyedLoadIC", name, state, target());
|
1302
|
+
return Handle<Code>::null();
|
1286
1303
|
}
|
1287
1304
|
|
1288
1305
|
|
1289
1306
|
static bool StoreICableLookup(LookupResult* lookup) {
|
1290
1307
|
// Bail out if we didn't find a result.
|
1291
|
-
if (!lookup->IsFound()
|
1308
|
+
if (!lookup->IsFound()) return false;
|
1292
1309
|
|
1293
1310
|
// Bail out if inline caching is not allowed.
|
1294
1311
|
if (!lookup->IsCacheable()) return false;
|
1295
1312
|
|
1296
1313
|
// If the property is read-only, we leave the IC in its current state.
|
1297
|
-
if (lookup->
|
1298
|
-
|
1299
|
-
|
1314
|
+
if (lookup->IsTransition()) {
|
1315
|
+
return !lookup->GetTransitionDetails().IsReadOnly();
|
1316
|
+
}
|
1317
|
+
return !lookup->IsReadOnly();
|
1300
1318
|
}
|
1301
1319
|
|
1302
1320
|
|
@@ -1304,11 +1322,16 @@ static bool LookupForWrite(Handle<JSObject> receiver,
|
|
1304
1322
|
Handle<String> name,
|
1305
1323
|
LookupResult* lookup) {
|
1306
1324
|
receiver->LocalLookup(*name, lookup);
|
1325
|
+
if (!lookup->IsFound()) {
|
1326
|
+
receiver->map()->LookupTransition(*receiver, *name, lookup);
|
1327
|
+
}
|
1307
1328
|
if (!StoreICableLookup(lookup)) {
|
1308
|
-
|
1329
|
+
// 2nd chance: There can be accessors somewhere in the prototype chain.
|
1330
|
+
receiver->Lookup(*name, lookup);
|
1331
|
+
return lookup->IsPropertyCallbacks() && StoreICableLookup(lookup);
|
1309
1332
|
}
|
1310
1333
|
|
1311
|
-
if (lookup->
|
1334
|
+
if (lookup->IsInterceptor() &&
|
1312
1335
|
receiver->GetNamedInterceptor()->setter()->IsUndefined()) {
|
1313
1336
|
receiver->LocalLookupRealNamedProperty(*name, lookup);
|
1314
1337
|
return StoreICableLookup(lookup);
|
@@ -1322,30 +1345,30 @@ MaybeObject* StoreIC::Store(State state,
|
|
1322
1345
|
StrictModeFlag strict_mode,
|
1323
1346
|
Handle<Object> object,
|
1324
1347
|
Handle<String> name,
|
1325
|
-
Handle<Object> value
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1348
|
+
Handle<Object> value,
|
1349
|
+
JSReceiver::StoreFromKeyed store_mode) {
|
1350
|
+
// Handle proxies.
|
1351
|
+
if (object->IsJSProxy()) {
|
1352
|
+
return JSProxy::cast(*object)->
|
1353
|
+
SetProperty(*name, *value, NONE, strict_mode);
|
1354
|
+
}
|
1332
1355
|
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
|
1356
|
+
// If the object is undefined or null it's illegal to try to set any
|
1357
|
+
// properties on it; throw a TypeError in that case.
|
1358
|
+
if (object->IsUndefined() || object->IsNull()) {
|
1359
|
+
return TypeError("non_object_property_store", object, name);
|
1360
|
+
}
|
1338
1361
|
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
}
|
1344
|
-
// Ignore other stores where the receiver is not a JSObject.
|
1345
|
-
// TODO(1475): Must check prototype chains of object wrappers.
|
1346
|
-
return *value;
|
1362
|
+
// The length property of string values is read-only. Throw in strict mode.
|
1363
|
+
if (strict_mode == kStrictMode && object->IsString() &&
|
1364
|
+
name->Equals(isolate()->heap()->length_symbol())) {
|
1365
|
+
return TypeError("strict_read_only_property", object, name);
|
1347
1366
|
}
|
1348
1367
|
|
1368
|
+
// Ignore other stores where the receiver is not a JSObject.
|
1369
|
+
// TODO(1475): Must check prototype chains of object wrappers.
|
1370
|
+
if (!object->IsJSObject()) return *value;
|
1371
|
+
|
1349
1372
|
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
1350
1373
|
|
1351
1374
|
// Check if the given name is an array index.
|
@@ -1357,58 +1380,52 @@ MaybeObject* StoreIC::Store(State state,
|
|
1357
1380
|
return *value;
|
1358
1381
|
}
|
1359
1382
|
|
1383
|
+
// Observed objects are always modified through the runtime.
|
1384
|
+
if (FLAG_harmony_observation && receiver->map()->is_observed()) {
|
1385
|
+
return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
|
1386
|
+
}
|
1387
|
+
|
1360
1388
|
// Use specialized code for setting the length of arrays with fast
|
1361
|
-
// properties.
|
1362
|
-
//
|
1363
|
-
if (
|
1389
|
+
// properties. Slow properties might indicate redefinition of the length
|
1390
|
+
// property.
|
1391
|
+
if (FLAG_use_ic &&
|
1392
|
+
receiver->IsJSArray() &&
|
1364
1393
|
name->Equals(isolate()->heap()->length_symbol()) &&
|
1365
1394
|
Handle<JSArray>::cast(receiver)->AllowsSetElementsLength() &&
|
1366
1395
|
receiver->HasFastProperties()) {
|
1367
|
-
|
1368
|
-
if (FLAG_trace_ic) PrintF("[StoreIC : +#length /array]\n");
|
1369
|
-
#endif
|
1370
|
-
Handle<Code> stub = (strict_mode == kStrictMode)
|
1371
|
-
? isolate()->builtins()->StoreIC_ArrayLength_Strict()
|
1372
|
-
: isolate()->builtins()->StoreIC_ArrayLength();
|
1396
|
+
Handle<Code> stub = StoreArrayLengthStub(kind(), strict_mode).GetCode();
|
1373
1397
|
set_target(*stub);
|
1374
|
-
|
1398
|
+
TRACE_IC("StoreIC", name, state, *stub);
|
1399
|
+
return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
|
1375
1400
|
}
|
1376
1401
|
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1383
|
-
|
1384
|
-
|
1385
|
-
|
1386
|
-
// or an assignment to a read only property.
|
1387
|
-
if (strict_mode == kStrictMode) {
|
1388
|
-
if (lookup.IsProperty() && lookup.IsReadOnly()) {
|
1389
|
-
return TypeError("strict_read_only_property", object, name);
|
1390
|
-
} else if (IsContextual(object)) {
|
1391
|
-
return ReferenceError("not_defined", name);
|
1392
|
-
}
|
1393
|
-
}
|
1402
|
+
if (receiver->IsJSGlobalProxy()) {
|
1403
|
+
if (FLAG_use_ic && kind() != Code::KEYED_STORE_IC) {
|
1404
|
+
// Generate a generic stub that goes to the runtime when we see a global
|
1405
|
+
// proxy as receiver.
|
1406
|
+
Handle<Code> stub = (strict_mode == kStrictMode)
|
1407
|
+
? global_proxy_stub_strict()
|
1408
|
+
: global_proxy_stub();
|
1409
|
+
set_target(*stub);
|
1410
|
+
TRACE_IC("StoreIC", name, state, *stub);
|
1394
1411
|
}
|
1412
|
+
return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
|
1395
1413
|
}
|
1396
1414
|
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1401
|
-
Handle<Code> stub = (strict_mode == kStrictMode)
|
1402
|
-
? global_proxy_stub_strict()
|
1403
|
-
: global_proxy_stub();
|
1404
|
-
if (target() != *stub) {
|
1405
|
-
set_target(*stub);
|
1406
|
-
TRACE_IC("StoreIC", name, state, target());
|
1415
|
+
LookupResult lookup(isolate());
|
1416
|
+
if (LookupForWrite(receiver, name, &lookup)) {
|
1417
|
+
if (FLAG_use_ic) {
|
1418
|
+
UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
|
1407
1419
|
}
|
1420
|
+
} else if (strict_mode == kStrictMode &&
|
1421
|
+
!(lookup.IsProperty() && lookup.IsReadOnly()) &&
|
1422
|
+
IsUndeclaredGlobal(object)) {
|
1423
|
+
// Strict mode doesn't allow setting non-existent global property.
|
1424
|
+
return ReferenceError("not_defined", name);
|
1408
1425
|
}
|
1409
1426
|
|
1410
1427
|
// Set the property.
|
1411
|
-
return receiver->SetProperty(*name, *value, NONE, strict_mode);
|
1428
|
+
return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
|
1412
1429
|
}
|
1413
1430
|
|
1414
1431
|
|
@@ -1420,36 +1437,30 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
|
|
1420
1437
|
Handle<Object> value) {
|
1421
1438
|
ASSERT(!receiver->IsJSGlobalProxy());
|
1422
1439
|
ASSERT(StoreICableLookup(lookup));
|
1440
|
+
ASSERT(lookup->IsFound());
|
1441
|
+
|
1423
1442
|
// These are not cacheable, so we never see such LookupResults here.
|
1424
|
-
ASSERT(lookup->
|
1425
|
-
// We get only called for properties or transitions, see StoreICableLookup.
|
1426
|
-
ASSERT(lookup->type() != NULL_DESCRIPTOR);
|
1443
|
+
ASSERT(!lookup->IsHandler());
|
1427
1444
|
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
PropertyType type = lookup->type();
|
1445
|
+
Handle<Code> code =
|
1446
|
+
ComputeStoreMonomorphic(lookup, strict_mode, receiver, name);
|
1447
|
+
if (code.is_null()) return;
|
1432
1448
|
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1449
|
+
PatchCache(state, strict_mode, receiver, name, code);
|
1450
|
+
TRACE_IC("StoreIC", name, state, target());
|
1451
|
+
}
|
1452
|
+
|
1453
|
+
|
1454
|
+
Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
|
1455
|
+
StrictModeFlag strict_mode,
|
1456
|
+
Handle<JSObject> receiver,
|
1457
|
+
Handle<String> name) {
|
1458
|
+
Handle<JSObject> holder(lookup->holder());
|
1459
|
+
switch (lookup->type()) {
|
1438
1460
|
case FIELD:
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
Handle<Map>::null(),
|
1443
|
-
strict_mode);
|
1444
|
-
break;
|
1445
|
-
case MAP_TRANSITION: {
|
1446
|
-
if (lookup->GetAttributes() != NONE) return;
|
1447
|
-
Handle<Map> transition(lookup->GetTransitionMap());
|
1448
|
-
int index = transition->PropertyIndexFor(*name);
|
1449
|
-
code = isolate()->stub_cache()->ComputeStoreField(
|
1450
|
-
name, receiver, index, transition, strict_mode);
|
1451
|
-
break;
|
1452
|
-
}
|
1461
|
+
return isolate()->stub_cache()->ComputeStoreField(
|
1462
|
+
name, receiver, lookup->GetFieldIndex().field_index(),
|
1463
|
+
Handle<Map>::null(), strict_mode);
|
1453
1464
|
case NORMAL:
|
1454
1465
|
if (receiver->IsGlobalObject()) {
|
1455
1466
|
// The stub generated for the global object picks the value directly
|
@@ -1457,98 +1468,64 @@ void StoreIC::UpdateCaches(LookupResult* lookup,
|
|
1457
1468
|
// global object.
|
1458
1469
|
Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
|
1459
1470
|
Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
|
1460
|
-
|
1471
|
+
return isolate()->stub_cache()->ComputeStoreGlobal(
|
1461
1472
|
name, global, cell, strict_mode);
|
1462
|
-
} else {
|
1463
|
-
if (lookup->holder() != *receiver) return;
|
1464
|
-
code = isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
|
1465
1473
|
}
|
1466
|
-
break;
|
1474
|
+
if (!holder.is_identical_to(receiver)) break;
|
1475
|
+
return isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
|
1467
1476
|
case CALLBACKS: {
|
1468
|
-
Handle<Object>
|
1469
|
-
if (
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1477
|
+
Handle<Object> callback(lookup->GetCallbackObject());
|
1478
|
+
if (callback->IsAccessorInfo()) {
|
1479
|
+
Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
|
1480
|
+
if (v8::ToCData<Address>(info->setter()) == 0) break;
|
1481
|
+
if (!holder->HasFastProperties()) break;
|
1482
|
+
if (!info->IsCompatibleReceiver(*receiver)) break;
|
1483
|
+
return isolate()->stub_cache()->ComputeStoreCallback(
|
1484
|
+
name, receiver, holder, info, strict_mode);
|
1485
|
+
} else if (callback->IsAccessorPair()) {
|
1486
|
+
Handle<Object> setter(Handle<AccessorPair>::cast(callback)->setter());
|
1487
|
+
if (!setter->IsJSFunction()) break;
|
1488
|
+
if (holder->IsGlobalObject()) break;
|
1489
|
+
if (!holder->HasFastProperties()) break;
|
1490
|
+
return isolate()->stub_cache()->ComputeStoreViaSetter(
|
1491
|
+
name, receiver, holder, Handle<JSFunction>::cast(setter),
|
1492
|
+
strict_mode);
|
1493
|
+
}
|
1494
|
+
ASSERT(callback->IsForeign());
|
1495
|
+
// No IC support for old-style native accessors.
|
1475
1496
|
break;
|
1476
1497
|
}
|
1477
1498
|
case INTERCEPTOR:
|
1478
1499
|
ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined());
|
1479
|
-
|
1500
|
+
return isolate()->stub_cache()->ComputeStoreInterceptor(
|
1480
1501
|
name, receiver, strict_mode);
|
1481
|
-
break;
|
1482
1502
|
case CONSTANT_FUNCTION:
|
1483
|
-
|
1484
|
-
case
|
1485
|
-
|
1486
|
-
|
1487
|
-
case NULL_DESCRIPTOR:
|
1488
|
-
UNREACHABLE();
|
1489
|
-
return;
|
1490
|
-
}
|
1491
|
-
|
1492
|
-
// Patch the call site depending on the state of the cache.
|
1493
|
-
if (state == UNINITIALIZED || state == MONOMORPHIC_PROTOTYPE_FAILURE) {
|
1494
|
-
set_target(*code);
|
1495
|
-
} else if (state == MONOMORPHIC) {
|
1496
|
-
// Only move to megamorphic if the target changes.
|
1497
|
-
if (target() != *code) {
|
1498
|
-
set_target((strict_mode == kStrictMode)
|
1499
|
-
? megamorphic_stub_strict()
|
1500
|
-
: megamorphic_stub());
|
1501
|
-
}
|
1502
|
-
} else if (state == MEGAMORPHIC) {
|
1503
|
-
// Update the stub cache.
|
1504
|
-
isolate()->stub_cache()->Set(*name, receiver->map(), *code);
|
1505
|
-
}
|
1503
|
+
break;
|
1504
|
+
case TRANSITION: {
|
1505
|
+
Handle<Map> transition(lookup->GetTransitionTarget());
|
1506
|
+
int descriptor = transition->LastAdded();
|
1506
1507
|
|
1507
|
-
|
1508
|
-
|
1508
|
+
DescriptorArray* target_descriptors = transition->instance_descriptors();
|
1509
|
+
PropertyDetails details = target_descriptors->GetDetails(descriptor);
|
1509
1510
|
|
1511
|
+
if (details.type() != FIELD || details.attributes() != NONE) break;
|
1510
1512
|
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
for (int current = 0; current < receiver_maps->length(); ++current) {
|
1515
|
-
if (!receiver_maps->at(current).is_null() &&
|
1516
|
-
receiver_maps->at(current).is_identical_to(new_receiver_map)) {
|
1517
|
-
return false;
|
1518
|
-
}
|
1519
|
-
}
|
1520
|
-
receiver_maps->Add(new_receiver_map);
|
1521
|
-
return true;
|
1522
|
-
}
|
1523
|
-
|
1524
|
-
|
1525
|
-
void KeyedIC::GetReceiverMapsForStub(Handle<Code> stub,
|
1526
|
-
MapHandleList* result) {
|
1527
|
-
ASSERT(stub->is_inline_cache_stub());
|
1528
|
-
if (!string_stub().is_null() && stub.is_identical_to(string_stub())) {
|
1529
|
-
return result->Add(isolate()->factory()->string_map());
|
1530
|
-
} else if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) {
|
1531
|
-
if (stub->ic_state() == MONOMORPHIC) {
|
1532
|
-
result->Add(Handle<Map>(stub->FindFirstMap()));
|
1533
|
-
} else {
|
1534
|
-
ASSERT(stub->ic_state() == MEGAMORPHIC);
|
1535
|
-
AssertNoAllocation no_allocation;
|
1536
|
-
int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
|
1537
|
-
for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
|
1538
|
-
RelocInfo* info = it.rinfo();
|
1539
|
-
Handle<Object> object(info->target_object());
|
1540
|
-
ASSERT(object->IsMap());
|
1541
|
-
AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
|
1542
|
-
}
|
1513
|
+
int field_index = target_descriptors->GetFieldIndex(descriptor);
|
1514
|
+
return isolate()->stub_cache()->ComputeStoreField(
|
1515
|
+
name, receiver, field_index, transition, strict_mode);
|
1543
1516
|
}
|
1517
|
+
case NONEXISTENT:
|
1518
|
+
case HANDLER:
|
1519
|
+
UNREACHABLE();
|
1520
|
+
break;
|
1544
1521
|
}
|
1522
|
+
return Handle<Code>::null();
|
1545
1523
|
}
|
1546
1524
|
|
1547
1525
|
|
1548
|
-
Handle<Code>
|
1549
|
-
|
1550
|
-
|
1551
|
-
Handle<Code> generic_stub) {
|
1526
|
+
Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
|
1527
|
+
StubKind stub_kind,
|
1528
|
+
StrictModeFlag strict_mode) {
|
1552
1529
|
State ic_state = target()->ic_state();
|
1553
1530
|
KeyedAccessGrowMode grow_mode = IsGrowStubKind(stub_kind)
|
1554
1531
|
? ALLOW_JSARRAY_GROWTH
|
@@ -1557,62 +1534,70 @@ Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver,
|
|
1557
1534
|
// Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
|
1558
1535
|
// via megamorphic stubs, since they don't have a map in their relocation info
|
1559
1536
|
// and so the stubs can't be harvested for the object needed for a map check.
|
1560
|
-
if (target()->type() != NORMAL) {
|
1537
|
+
if (target()->type() != Code::NORMAL) {
|
1561
1538
|
TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type");
|
1562
|
-
return generic_stub;
|
1539
|
+
return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
|
1563
1540
|
}
|
1564
1541
|
|
1565
|
-
|
1542
|
+
Handle<Map> receiver_map(receiver->map());
|
1566
1543
|
MapHandleList target_receiver_maps;
|
1567
|
-
if (ic_state
|
1568
|
-
|
1569
|
-
|
1570
|
-
|
1571
|
-
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1544
|
+
if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
|
1545
|
+
// Optimistically assume that ICs that haven't reached the MONOMORPHIC state
|
1546
|
+
// yet will do so and stay there.
|
1547
|
+
stub_kind = GetNoTransitionStubKind(stub_kind);
|
1548
|
+
return isolate()->stub_cache()->ComputeKeyedStoreElement(
|
1549
|
+
receiver_map, stub_kind, strict_mode, grow_mode);
|
1550
|
+
}
|
1551
|
+
|
1552
|
+
GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
|
1553
|
+
if (target_receiver_maps.length() == 0) {
|
1554
|
+
// Optimistically assume that ICs that haven't reached the MONOMORPHIC state
|
1555
|
+
// yet will do so and stay there.
|
1556
|
+
stub_kind = GetNoTransitionStubKind(stub_kind);
|
1557
|
+
return isolate()->stub_cache()->ComputeKeyedStoreElement(
|
1558
|
+
receiver_map, stub_kind, strict_mode, grow_mode);
|
1559
|
+
}
|
1560
|
+
// The first time a receiver is seen that is a transitioned version of the
|
1561
|
+
// previous monomorphic receiver type, assume the new ElementsKind is the
|
1562
|
+
// monomorphic type. This benefits global arrays that only transition
|
1563
|
+
// once, and all call sites accessing them are faster if they remain
|
1564
|
+
// monomorphic. If this optimistic assumption is not true, the IC will
|
1565
|
+
// miss again and it will become polymorphic and support both the
|
1566
|
+
// untransitioned and transitioned maps.
|
1567
|
+
if (ic_state == MONOMORPHIC &&
|
1568
|
+
IsTransitionStubKind(stub_kind) &&
|
1569
|
+
IsMoreGeneralElementsKindTransition(
|
1570
|
+
target_receiver_maps.at(0)->elements_kind(),
|
1571
|
+
receiver->GetElementsKind())) {
|
1572
|
+
Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, stub_kind);
|
1573
|
+
ASSERT(*monomorphic_map != *receiver_map);
|
1574
|
+
stub_kind = GetNoTransitionStubKind(stub_kind);
|
1575
|
+
return isolate()->stub_cache()->ComputeKeyedStoreElement(
|
1576
|
+
monomorphic_map, stub_kind, strict_mode, grow_mode);
|
1577
|
+
}
|
1578
|
+
|
1579
|
+
ASSERT(ic_state != GENERIC);
|
1594
1580
|
|
1595
|
-
// Determine the list of receiver maps that this call site has seen,
|
1596
|
-
// adding the map that was just encountered.
|
1597
|
-
Handle<Map> receiver_map(receiver->map());
|
1598
1581
|
bool map_added =
|
1599
1582
|
AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
|
1583
|
+
|
1600
1584
|
if (IsTransitionStubKind(stub_kind)) {
|
1601
1585
|
Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind);
|
1602
1586
|
map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map);
|
1603
1587
|
}
|
1588
|
+
|
1604
1589
|
if (!map_added) {
|
1605
1590
|
// If the miss wasn't due to an unseen map, a polymorphic stub
|
1606
1591
|
// won't help, use the generic stub.
|
1607
1592
|
TRACE_GENERIC_IC("KeyedIC", "same map added twice");
|
1608
|
-
return generic_stub;
|
1593
|
+
return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
|
1609
1594
|
}
|
1610
1595
|
|
1611
1596
|
// If the maximum number of receiver maps has been exceeded, use the generic
|
1612
1597
|
// version of the IC.
|
1613
1598
|
if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
|
1614
1599
|
TRACE_GENERIC_IC("KeyedIC", "max polymorph exceeded");
|
1615
|
-
return generic_stub;
|
1600
|
+
return strict_mode == kStrictMode ? generic_stub_strict() : generic_stub();
|
1616
1601
|
}
|
1617
1602
|
|
1618
1603
|
if ((Code::GetKeyedAccessGrowMode(target()->extra_ic_state()) ==
|
@@ -1620,81 +1605,34 @@ Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver,
|
|
1620
1605
|
grow_mode = ALLOW_JSARRAY_GROWTH;
|
1621
1606
|
}
|
1622
1607
|
|
1623
|
-
|
1624
|
-
|
1625
|
-
Code::ExtraICState extra_state = Code::ComputeExtraICState(grow_mode,
|
1626
|
-
strict_mode);
|
1627
|
-
Code::Flags flags = Code::ComputeFlags(kind(), MEGAMORPHIC, extra_state);
|
1628
|
-
Handle<Object> probe = cache->Lookup(&target_receiver_maps, flags);
|
1629
|
-
if (probe->IsCode()) return Handle<Code>::cast(probe);
|
1630
|
-
|
1631
|
-
Handle<Code> stub =
|
1632
|
-
ComputePolymorphicStub(&target_receiver_maps, strict_mode, grow_mode);
|
1633
|
-
PolymorphicCodeCache::Update(cache, &target_receiver_maps, flags, stub);
|
1634
|
-
return stub;
|
1608
|
+
return isolate()->stub_cache()->ComputeStoreElementPolymorphic(
|
1609
|
+
&target_receiver_maps, grow_mode, strict_mode);
|
1635
1610
|
}
|
1636
1611
|
|
1637
1612
|
|
1638
|
-
Handle<
|
1639
|
-
|
1640
|
-
StrictModeFlag strict_mode,
|
1641
|
-
KeyedAccessGrowMode grow_mode) {
|
1642
|
-
if ((receiver_map->instance_type() & kNotStringTag) == 0) {
|
1643
|
-
ASSERT(!string_stub().is_null());
|
1644
|
-
return string_stub();
|
1645
|
-
} else {
|
1646
|
-
ASSERT(receiver_map->has_dictionary_elements() ||
|
1647
|
-
receiver_map->has_fast_smi_or_object_elements() ||
|
1648
|
-
receiver_map->has_fast_double_elements() ||
|
1649
|
-
receiver_map->has_external_array_elements());
|
1650
|
-
bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
|
1651
|
-
return GetElementStubWithoutMapCheck(is_js_array,
|
1652
|
-
receiver_map->elements_kind(),
|
1653
|
-
grow_mode);
|
1654
|
-
}
|
1655
|
-
}
|
1656
|
-
|
1657
|
-
|
1658
|
-
Handle<Code> KeyedIC::ComputeMonomorphicStub(Handle<JSObject> receiver,
|
1659
|
-
StubKind stub_kind,
|
1660
|
-
StrictModeFlag strict_mode,
|
1661
|
-
Handle<Code> generic_stub) {
|
1662
|
-
if (receiver->HasFastSmiOrObjectElements() ||
|
1663
|
-
receiver->HasExternalArrayElements() ||
|
1664
|
-
receiver->HasFastDoubleElements() ||
|
1665
|
-
receiver->HasDictionaryElements()) {
|
1666
|
-
return isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement(
|
1667
|
-
receiver, stub_kind, strict_mode);
|
1668
|
-
} else {
|
1669
|
-
return generic_stub;
|
1670
|
-
}
|
1671
|
-
}
|
1672
|
-
|
1673
|
-
|
1674
|
-
Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver,
|
1675
|
-
StubKind stub_kind) {
|
1613
|
+
Handle<Map> KeyedStoreIC::ComputeTransitionedMap(Handle<JSObject> receiver,
|
1614
|
+
StubKind stub_kind) {
|
1676
1615
|
switch (stub_kind) {
|
1677
|
-
case
|
1678
|
-
case
|
1679
|
-
case
|
1680
|
-
case
|
1616
|
+
case STORE_TRANSITION_SMI_TO_OBJECT:
|
1617
|
+
case STORE_TRANSITION_DOUBLE_TO_OBJECT:
|
1618
|
+
case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT:
|
1619
|
+
case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT:
|
1681
1620
|
return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS);
|
1682
|
-
case
|
1683
|
-
case
|
1621
|
+
case STORE_TRANSITION_SMI_TO_DOUBLE:
|
1622
|
+
case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE:
|
1684
1623
|
return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS);
|
1685
|
-
case
|
1686
|
-
case
|
1687
|
-
case
|
1688
|
-
case
|
1624
|
+
case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT:
|
1625
|
+
case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
|
1626
|
+
case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT:
|
1627
|
+
case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT:
|
1689
1628
|
return JSObject::GetElementsTransitionMap(receiver,
|
1690
1629
|
FAST_HOLEY_ELEMENTS);
|
1691
|
-
case
|
1692
|
-
case
|
1630
|
+
case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE:
|
1631
|
+
case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE:
|
1693
1632
|
return JSObject::GetElementsTransitionMap(receiver,
|
1694
1633
|
FAST_HOLEY_DOUBLE_ELEMENTS);
|
1695
|
-
case
|
1696
|
-
case
|
1697
|
-
case KeyedIC::STORE_AND_GROW_NO_TRANSITION:
|
1634
|
+
case STORE_NO_TRANSITION:
|
1635
|
+
case STORE_AND_GROW_NO_TRANSITION:
|
1698
1636
|
UNREACHABLE();
|
1699
1637
|
break;
|
1700
1638
|
}
|
@@ -1702,54 +1640,9 @@ Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver,
|
|
1702
1640
|
}
|
1703
1641
|
|
1704
1642
|
|
1705
|
-
Handle<
|
1706
|
-
|
1707
|
-
|
1708
|
-
KeyedAccessGrowMode grow_mode) {
|
1709
|
-
return KeyedStoreElementStub(is_js_array, elements_kind, grow_mode).GetCode();
|
1710
|
-
}
|
1711
|
-
|
1712
|
-
|
1713
|
-
Handle<Code> KeyedStoreIC::ComputePolymorphicStub(
|
1714
|
-
MapHandleList* receiver_maps,
|
1715
|
-
StrictModeFlag strict_mode,
|
1716
|
-
KeyedAccessGrowMode grow_mode) {
|
1717
|
-
// Collect MONOMORPHIC stubs for all target_receiver_maps.
|
1718
|
-
CodeHandleList handler_ics(receiver_maps->length());
|
1719
|
-
MapHandleList transitioned_maps(receiver_maps->length());
|
1720
|
-
for (int i = 0; i < receiver_maps->length(); ++i) {
|
1721
|
-
Handle<Map> receiver_map(receiver_maps->at(i));
|
1722
|
-
Handle<Code> cached_stub;
|
1723
|
-
Handle<Map> transitioned_map =
|
1724
|
-
receiver_map->FindTransitionedMap(receiver_maps);
|
1725
|
-
if (!transitioned_map.is_null()) {
|
1726
|
-
cached_stub = ElementsTransitionAndStoreStub(
|
1727
|
-
receiver_map->elements_kind(), // original elements_kind
|
1728
|
-
transitioned_map->elements_kind(),
|
1729
|
-
receiver_map->instance_type() == JS_ARRAY_TYPE, // is_js_array
|
1730
|
-
strict_mode, grow_mode).GetCode();
|
1731
|
-
} else {
|
1732
|
-
cached_stub = ComputeMonomorphicStubWithoutMapCheck(receiver_map,
|
1733
|
-
strict_mode,
|
1734
|
-
grow_mode);
|
1735
|
-
}
|
1736
|
-
ASSERT(!cached_stub.is_null());
|
1737
|
-
handler_ics.Add(cached_stub);
|
1738
|
-
transitioned_maps.Add(transitioned_map);
|
1739
|
-
}
|
1740
|
-
KeyedStoreStubCompiler compiler(isolate(), strict_mode, grow_mode);
|
1741
|
-
Handle<Code> code = compiler.CompileStorePolymorphic(
|
1742
|
-
receiver_maps, &handler_ics, &transitioned_maps);
|
1743
|
-
isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
|
1744
|
-
PROFILE(isolate(),
|
1745
|
-
CodeCreateEvent(Logger::KEYED_STORE_MEGAMORPHIC_IC_TAG, *code, 0));
|
1746
|
-
return code;
|
1747
|
-
}
|
1748
|
-
|
1749
|
-
|
1750
|
-
KeyedIC::StubKind KeyedStoreIC::GetStubKind(Handle<JSObject> receiver,
|
1751
|
-
Handle<Object> key,
|
1752
|
-
Handle<Object> value) {
|
1643
|
+
KeyedStoreIC::StubKind KeyedStoreIC::GetStubKind(Handle<JSObject> receiver,
|
1644
|
+
Handle<Object> key,
|
1645
|
+
Handle<Object> value) {
|
1753
1646
|
ASSERT(key->IsSmi());
|
1754
1647
|
int index = Smi::cast(*key)->value();
|
1755
1648
|
bool allow_growth = receiver->IsJSArray() &&
|
@@ -1818,155 +1711,94 @@ MaybeObject* KeyedStoreIC::Store(State state,
|
|
1818
1711
|
Handle<Object> object,
|
1819
1712
|
Handle<Object> key,
|
1820
1713
|
Handle<Object> value,
|
1821
|
-
|
1714
|
+
ICMissMode miss_mode) {
|
1822
1715
|
// Check for values that can be converted into a symbol directly or
|
1823
1716
|
// is representable as a smi.
|
1824
1717
|
key = TryConvertKey(key, isolate());
|
1825
1718
|
|
1826
1719
|
if (key->IsSymbol()) {
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
}
|
1834
|
-
|
1835
|
-
// If the object is undefined or null it's illegal to try to set any
|
1836
|
-
// properties on it; throw a TypeError in that case.
|
1837
|
-
if (object->IsUndefined() || object->IsNull()) {
|
1838
|
-
return TypeError("non_object_property_store", object, name);
|
1839
|
-
}
|
1840
|
-
|
1841
|
-
// Ignore stores where the receiver is not a JSObject.
|
1842
|
-
if (!object->IsJSObject()) return *value;
|
1843
|
-
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
1844
|
-
|
1845
|
-
// Check if the given name is an array index.
|
1846
|
-
uint32_t index;
|
1847
|
-
if (name->AsArrayIndex(&index)) {
|
1848
|
-
Handle<Object> result =
|
1849
|
-
JSObject::SetElement(receiver, index, value, NONE, strict_mode);
|
1850
|
-
RETURN_IF_EMPTY_HANDLE(isolate(), result);
|
1851
|
-
return *value;
|
1852
|
-
}
|
1853
|
-
|
1854
|
-
// Update inline cache and stub cache.
|
1855
|
-
if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) {
|
1856
|
-
LookupResult lookup(isolate());
|
1857
|
-
if (LookupForWrite(receiver, name, &lookup)) {
|
1858
|
-
UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
|
1859
|
-
}
|
1860
|
-
}
|
1861
|
-
|
1862
|
-
// Set the property.
|
1863
|
-
return receiver->SetProperty(*name, *value, NONE, strict_mode);
|
1720
|
+
return StoreIC::Store(state,
|
1721
|
+
strict_mode,
|
1722
|
+
object,
|
1723
|
+
Handle<String>::cast(key),
|
1724
|
+
value,
|
1725
|
+
JSReceiver::MAY_BE_STORE_FROM_KEYED);
|
1864
1726
|
}
|
1865
1727
|
|
1866
|
-
|
1867
|
-
|
1868
|
-
|
1728
|
+
bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded() &&
|
1729
|
+
!(FLAG_harmony_observation && object->IsJSObject() &&
|
1730
|
+
JSObject::cast(*object)->map()->is_observed());
|
1869
1731
|
ASSERT(!(use_ic && object->IsJSGlobalProxy()));
|
1870
1732
|
|
1871
1733
|
if (use_ic) {
|
1872
1734
|
Handle<Code> stub = (strict_mode == kStrictMode)
|
1873
1735
|
? generic_stub_strict()
|
1874
1736
|
: generic_stub();
|
1875
|
-
if (
|
1876
|
-
|
1877
|
-
|
1878
|
-
|
1879
|
-
|
1880
|
-
|
1881
|
-
if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
|
1737
|
+
if (miss_mode != MISS_FORCE_GENERIC) {
|
1738
|
+
if (object->IsJSObject()) {
|
1739
|
+
Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
1740
|
+
if (receiver->elements()->map() ==
|
1741
|
+
isolate()->heap()->non_strict_arguments_elements_map()) {
|
1742
|
+
stub = non_strict_arguments_stub();
|
1743
|
+
} else if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
|
1882
1744
|
StubKind stub_kind = GetStubKind(receiver, key, value);
|
1883
|
-
stub =
|
1745
|
+
stub = StoreElementStub(receiver, stub_kind, strict_mode);
|
1884
1746
|
}
|
1885
|
-
} else {
|
1886
|
-
TRACE_GENERIC_IC("KeyedStoreIC", "force generic");
|
1887
1747
|
}
|
1748
|
+
} else {
|
1749
|
+
TRACE_GENERIC_IC("KeyedStoreIC", "force generic");
|
1888
1750
|
}
|
1889
|
-
|
1751
|
+
ASSERT(!stub.is_null());
|
1752
|
+
set_target(*stub);
|
1753
|
+
TRACE_IC("KeyedStoreIC", key, state, target());
|
1890
1754
|
}
|
1891
1755
|
|
1892
|
-
TRACE_IC("KeyedStoreIC", key, state, target());
|
1893
|
-
|
1894
|
-
// Set the property.
|
1895
1756
|
return Runtime::SetObjectProperty(
|
1896
1757
|
isolate(), object , key, value, NONE, strict_mode);
|
1897
1758
|
}
|
1898
1759
|
|
1899
1760
|
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
Handle<String> name,
|
1905
|
-
Handle<Object> value) {
|
1906
|
-
ASSERT(!receiver->IsJSGlobalProxy());
|
1907
|
-
ASSERT(StoreICableLookup(lookup));
|
1908
|
-
// These are not cacheable, so we never see such LookupResults here.
|
1909
|
-
ASSERT(lookup->type() != HANDLER);
|
1910
|
-
// We get only called for properties or transitions, see StoreICableLookup.
|
1911
|
-
ASSERT(lookup->type() != NULL_DESCRIPTOR);
|
1912
|
-
|
1761
|
+
Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
|
1762
|
+
StrictModeFlag strict_mode,
|
1763
|
+
Handle<JSObject> receiver,
|
1764
|
+
Handle<String> name) {
|
1913
1765
|
// If the property has a non-field type allowing map transitions
|
1914
1766
|
// where there is extra room in the object, we leave the IC in its
|
1915
1767
|
// current state.
|
1916
|
-
|
1917
|
-
|
1918
|
-
// Compute the code stub for this store; used for rewriting to
|
1919
|
-
// monomorphic state and making sure that the code stub is in the
|
1920
|
-
// stub cache.
|
1921
|
-
Handle<Code> code;
|
1922
|
-
|
1923
|
-
switch (type) {
|
1768
|
+
switch (lookup->type()) {
|
1924
1769
|
case FIELD:
|
1925
|
-
|
1926
|
-
name, receiver, lookup->GetFieldIndex(),
|
1770
|
+
return isolate()->stub_cache()->ComputeKeyedStoreField(
|
1771
|
+
name, receiver, lookup->GetFieldIndex().field_index(),
|
1927
1772
|
Handle<Map>::null(), strict_mode);
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1773
|
+
case TRANSITION: {
|
1774
|
+
Handle<Map> transition(lookup->GetTransitionTarget());
|
1775
|
+
int descriptor = transition->LastAdded();
|
1776
|
+
|
1777
|
+
DescriptorArray* target_descriptors = transition->instance_descriptors();
|
1778
|
+
PropertyDetails details = target_descriptors->GetDetails(descriptor);
|
1779
|
+
|
1780
|
+
if (details.type() == FIELD && details.attributes() == NONE) {
|
1781
|
+
int field_index = target_descriptors->GetFieldIndex(descriptor);
|
1782
|
+
return isolate()->stub_cache()->ComputeKeyedStoreField(
|
1783
|
+
name, receiver, field_index, transition, strict_mode);
|
1936
1784
|
}
|
1937
1785
|
// fall through.
|
1786
|
+
}
|
1938
1787
|
case NORMAL:
|
1939
1788
|
case CONSTANT_FUNCTION:
|
1940
1789
|
case CALLBACKS:
|
1941
1790
|
case INTERCEPTOR:
|
1942
|
-
case CONSTANT_TRANSITION:
|
1943
|
-
case ELEMENTS_TRANSITION:
|
1944
1791
|
// Always rewrite to the generic case so that we do not
|
1945
1792
|
// repeatedly try to rewrite.
|
1946
|
-
|
1793
|
+
return (strict_mode == kStrictMode)
|
1947
1794
|
? generic_stub_strict()
|
1948
1795
|
: generic_stub();
|
1949
|
-
break;
|
1950
1796
|
case HANDLER:
|
1951
|
-
case
|
1797
|
+
case NONEXISTENT:
|
1952
1798
|
UNREACHABLE();
|
1953
|
-
|
1954
|
-
}
|
1955
|
-
|
1956
|
-
ASSERT(!code.is_null());
|
1957
|
-
|
1958
|
-
// Patch the call site depending on the state of the cache. Make
|
1959
|
-
// sure to always rewrite from monomorphic to megamorphic.
|
1960
|
-
ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
|
1961
|
-
if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
|
1962
|
-
set_target(*code);
|
1963
|
-
} else if (state == MONOMORPHIC) {
|
1964
|
-
set_target((strict_mode == kStrictMode)
|
1965
|
-
? *megamorphic_stub_strict()
|
1966
|
-
: *megamorphic_stub());
|
1799
|
+
break;
|
1967
1800
|
}
|
1968
|
-
|
1969
|
-
TRACE_IC("KeyedStoreIC", name, state, target());
|
1801
|
+
return Handle<Code>::null();
|
1970
1802
|
}
|
1971
1803
|
|
1972
1804
|
|
@@ -1988,13 +1820,12 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
|
|
1988
1820
|
extra_ic_state,
|
1989
1821
|
args.at<Object>(0),
|
1990
1822
|
args.at<String>(1));
|
1991
|
-
|
1992
|
-
JSFunction* raw_function = NULL;
|
1823
|
+
JSFunction* raw_function;
|
1993
1824
|
if (!maybe_result->To(&raw_function)) return maybe_result;
|
1994
1825
|
|
1995
1826
|
// The first time the inline cache is updated may be the first time the
|
1996
|
-
// function it references gets called.
|
1997
|
-
// then the first call will trigger a compilation.
|
1827
|
+
// function it references gets called. If the function is lazily compiled
|
1828
|
+
// then the first call will trigger a compilation. We check for this case
|
1998
1829
|
// and we do the compilation immediately, instead of waiting for the stub
|
1999
1830
|
// currently attached to the JSFunction object to trigger compilation.
|
2000
1831
|
if (raw_function->is_compiled()) return raw_function;
|
@@ -2029,7 +1860,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
|
|
2029
1860
|
RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) {
|
2030
1861
|
HandleScope scope(isolate);
|
2031
1862
|
ASSERT(args.length() == 2);
|
2032
|
-
LoadIC ic(isolate);
|
1863
|
+
LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
|
2033
1864
|
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
2034
1865
|
return ic.Load(state, args.at<Object>(0), args.at<String>(1));
|
2035
1866
|
}
|
@@ -2039,18 +1870,30 @@ RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) {
|
|
2039
1870
|
RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_Miss) {
|
2040
1871
|
HandleScope scope(isolate);
|
2041
1872
|
ASSERT(args.length() == 2);
|
2042
|
-
KeyedLoadIC ic(isolate);
|
1873
|
+
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
|
2043
1874
|
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
2044
|
-
return ic.Load(state, args.at<Object>(0), args.at<Object>(1),
|
1875
|
+
return ic.Load(state, args.at<Object>(0), args.at<Object>(1), MISS);
|
1876
|
+
}
|
1877
|
+
|
1878
|
+
|
1879
|
+
RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissFromStubFailure) {
|
1880
|
+
HandleScope scope(isolate);
|
1881
|
+
ASSERT(args.length() == 2);
|
1882
|
+
KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate);
|
1883
|
+
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
1884
|
+
return ic.Load(state, args.at<Object>(0), args.at<Object>(1), MISS);
|
2045
1885
|
}
|
2046
1886
|
|
2047
1887
|
|
2048
1888
|
RUNTIME_FUNCTION(MaybeObject*, KeyedLoadIC_MissForceGeneric) {
|
2049
1889
|
HandleScope scope(isolate);
|
2050
1890
|
ASSERT(args.length() == 2);
|
2051
|
-
KeyedLoadIC ic(isolate);
|
1891
|
+
KeyedLoadIC ic(IC::NO_EXTRA_FRAME, isolate);
|
2052
1892
|
IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
|
2053
|
-
return ic.Load(state,
|
1893
|
+
return ic.Load(state,
|
1894
|
+
args.at<Object>(0),
|
1895
|
+
args.at<Object>(1),
|
1896
|
+
MISS_FORCE_GENERIC);
|
2054
1897
|
}
|
2055
1898
|
|
2056
1899
|
|
@@ -2083,13 +1926,13 @@ RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
|
|
2083
1926
|
// The length property has to be a writable callback property.
|
2084
1927
|
LookupResult debug_lookup(isolate);
|
2085
1928
|
receiver->LocalLookup(isolate->heap()->length_symbol(), &debug_lookup);
|
2086
|
-
ASSERT(debug_lookup.
|
1929
|
+
ASSERT(debug_lookup.IsPropertyCallbacks() && !debug_lookup.IsReadOnly());
|
2087
1930
|
#endif
|
2088
1931
|
|
2089
1932
|
Object* result;
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
1933
|
+
MaybeObject* maybe_result = receiver->SetElementsLength(len);
|
1934
|
+
if (!maybe_result->To(&result)) return maybe_result;
|
1935
|
+
|
2093
1936
|
return len;
|
2094
1937
|
}
|
2095
1938
|
|
@@ -2142,7 +1985,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) {
|
|
2142
1985
|
args.at<Object>(0),
|
2143
1986
|
args.at<Object>(1),
|
2144
1987
|
args.at<Object>(2),
|
2145
|
-
|
1988
|
+
MISS);
|
2146
1989
|
}
|
2147
1990
|
|
2148
1991
|
|
@@ -2175,7 +2018,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) {
|
|
2175
2018
|
args.at<Object>(0),
|
2176
2019
|
args.at<Object>(1),
|
2177
2020
|
args.at<Object>(2),
|
2178
|
-
|
2021
|
+
MISS_FORCE_GENERIC);
|
2179
2022
|
}
|
2180
2023
|
|
2181
2024
|
|
@@ -2203,7 +2046,7 @@ UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) {
|
|
2203
2046
|
case HEAP_NUMBER:
|
2204
2047
|
return MONOMORPHIC;
|
2205
2048
|
case GENERIC:
|
2206
|
-
return
|
2049
|
+
return ::v8::internal::GENERIC;
|
2207
2050
|
}
|
2208
2051
|
UNREACHABLE();
|
2209
2052
|
return ::v8::internal::UNINITIALIZED;
|
@@ -2253,11 +2096,10 @@ const char* BinaryOpIC::GetName(TypeInfo type_info) {
|
|
2253
2096
|
switch (type_info) {
|
2254
2097
|
case UNINITIALIZED: return "Uninitialized";
|
2255
2098
|
case SMI: return "SMI";
|
2256
|
-
case INT32: return "
|
2257
|
-
case HEAP_NUMBER: return "
|
2099
|
+
case INT32: return "Int32";
|
2100
|
+
case HEAP_NUMBER: return "HeapNumber";
|
2258
2101
|
case ODDBALL: return "Oddball";
|
2259
|
-
case
|
2260
|
-
case STRING: return "Strings";
|
2102
|
+
case STRING: return "String";
|
2261
2103
|
case GENERIC: return "Generic";
|
2262
2104
|
default: return "Invalid";
|
2263
2105
|
}
|
@@ -2272,69 +2114,16 @@ BinaryOpIC::State BinaryOpIC::ToState(TypeInfo type_info) {
|
|
2272
2114
|
case INT32:
|
2273
2115
|
case HEAP_NUMBER:
|
2274
2116
|
case ODDBALL:
|
2275
|
-
case BOTH_STRING:
|
2276
2117
|
case STRING:
|
2277
2118
|
return MONOMORPHIC;
|
2278
2119
|
case GENERIC:
|
2279
|
-
return
|
2120
|
+
return ::v8::internal::GENERIC;
|
2280
2121
|
}
|
2281
2122
|
UNREACHABLE();
|
2282
2123
|
return ::v8::internal::UNINITIALIZED;
|
2283
2124
|
}
|
2284
2125
|
|
2285
2126
|
|
2286
|
-
BinaryOpIC::TypeInfo BinaryOpIC::JoinTypes(BinaryOpIC::TypeInfo x,
|
2287
|
-
BinaryOpIC::TypeInfo y) {
|
2288
|
-
if (x == UNINITIALIZED) return y;
|
2289
|
-
if (y == UNINITIALIZED) return x;
|
2290
|
-
if (x == y) return x;
|
2291
|
-
if (x == BOTH_STRING && y == STRING) return STRING;
|
2292
|
-
if (x == STRING && y == BOTH_STRING) return STRING;
|
2293
|
-
if (x == STRING || x == BOTH_STRING || y == STRING || y == BOTH_STRING) {
|
2294
|
-
return GENERIC;
|
2295
|
-
}
|
2296
|
-
if (x > y) return x;
|
2297
|
-
return y;
|
2298
|
-
}
|
2299
|
-
|
2300
|
-
|
2301
|
-
BinaryOpIC::TypeInfo BinaryOpIC::GetTypeInfo(Handle<Object> left,
|
2302
|
-
Handle<Object> right) {
|
2303
|
-
::v8::internal::TypeInfo left_type =
|
2304
|
-
::v8::internal::TypeInfo::TypeFromValue(left);
|
2305
|
-
::v8::internal::TypeInfo right_type =
|
2306
|
-
::v8::internal::TypeInfo::TypeFromValue(right);
|
2307
|
-
|
2308
|
-
if (left_type.IsSmi() && right_type.IsSmi()) {
|
2309
|
-
return SMI;
|
2310
|
-
}
|
2311
|
-
|
2312
|
-
if (left_type.IsInteger32() && right_type.IsInteger32()) {
|
2313
|
-
// Platforms with 32-bit Smis have no distinct INT32 type.
|
2314
|
-
if (kSmiValueSize == 32) return SMI;
|
2315
|
-
return INT32;
|
2316
|
-
}
|
2317
|
-
|
2318
|
-
if (left_type.IsNumber() && right_type.IsNumber()) {
|
2319
|
-
return HEAP_NUMBER;
|
2320
|
-
}
|
2321
|
-
|
2322
|
-
// Patching for fast string ADD makes sense even if only one of the
|
2323
|
-
// arguments is a string.
|
2324
|
-
if (left_type.IsString()) {
|
2325
|
-
return right_type.IsString() ? BOTH_STRING : STRING;
|
2326
|
-
} else if (right_type.IsString()) {
|
2327
|
-
return STRING;
|
2328
|
-
}
|
2329
|
-
|
2330
|
-
// Check for oddball objects.
|
2331
|
-
if (left->IsUndefined() && right->IsNumber()) return ODDBALL;
|
2332
|
-
if (left->IsNumber() && right->IsUndefined()) return ODDBALL;
|
2333
|
-
|
2334
|
-
return GENERIC;
|
2335
|
-
}
|
2336
|
-
|
2337
|
-
|
2338
2127
|
RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
|
2339
2128
|
ASSERT(args.length() == 4);
|
2340
2129
|
|
@@ -2352,10 +2141,13 @@ RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
|
|
2352
2141
|
Handle<Code> code = stub.GetCode();
|
2353
2142
|
if (!code.is_null()) {
|
2354
2143
|
if (FLAG_trace_ic) {
|
2355
|
-
PrintF("[UnaryOpIC
|
2144
|
+
PrintF("[UnaryOpIC in ");
|
2145
|
+
JavaScriptFrame::PrintTop(stdout, false, true);
|
2146
|
+
PrintF(" (%s->%s)#%s @ %p]\n",
|
2356
2147
|
UnaryOpIC::GetName(previous_type),
|
2357
2148
|
UnaryOpIC::GetName(type),
|
2358
|
-
Token::Name(op)
|
2149
|
+
Token::Name(op),
|
2150
|
+
static_cast<void*>(*code));
|
2359
2151
|
}
|
2360
2152
|
UnaryOpIC ic(isolate);
|
2361
2153
|
ic.patch(*code);
|
@@ -2386,25 +2178,72 @@ RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
|
|
2386
2178
|
return *result;
|
2387
2179
|
}
|
2388
2180
|
|
2181
|
+
|
2182
|
+
static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value,
|
2183
|
+
Token::Value op) {
|
2184
|
+
::v8::internal::TypeInfo type =
|
2185
|
+
::v8::internal::TypeInfo::TypeFromValue(value);
|
2186
|
+
if (type.IsSmi()) return BinaryOpIC::SMI;
|
2187
|
+
if (type.IsInteger32()) {
|
2188
|
+
if (kSmiValueSize == 32) return BinaryOpIC::SMI;
|
2189
|
+
return BinaryOpIC::INT32;
|
2190
|
+
}
|
2191
|
+
if (type.IsNumber()) return BinaryOpIC::HEAP_NUMBER;
|
2192
|
+
if (type.IsString()) return BinaryOpIC::STRING;
|
2193
|
+
if (value->IsUndefined()) {
|
2194
|
+
if (op == Token::BIT_AND ||
|
2195
|
+
op == Token::BIT_OR ||
|
2196
|
+
op == Token::BIT_XOR ||
|
2197
|
+
op == Token::SAR ||
|
2198
|
+
op == Token::SHL ||
|
2199
|
+
op == Token::SHR) {
|
2200
|
+
if (kSmiValueSize == 32) return BinaryOpIC::SMI;
|
2201
|
+
return BinaryOpIC::INT32;
|
2202
|
+
}
|
2203
|
+
return BinaryOpIC::ODDBALL;
|
2204
|
+
}
|
2205
|
+
return BinaryOpIC::GENERIC;
|
2206
|
+
}
|
2207
|
+
|
2208
|
+
|
2209
|
+
static BinaryOpIC::TypeInfo InputState(BinaryOpIC::TypeInfo old_type,
|
2210
|
+
Handle<Object> value,
|
2211
|
+
Token::Value op) {
|
2212
|
+
BinaryOpIC::TypeInfo new_type = TypeInfoFromValue(value, op);
|
2213
|
+
if (old_type == BinaryOpIC::STRING) {
|
2214
|
+
if (new_type == BinaryOpIC::STRING) return new_type;
|
2215
|
+
return BinaryOpIC::GENERIC;
|
2216
|
+
}
|
2217
|
+
return Max(old_type, new_type);
|
2218
|
+
}
|
2219
|
+
|
2220
|
+
|
2389
2221
|
RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
|
2390
|
-
ASSERT(args.length() ==
|
2222
|
+
ASSERT(args.length() == 3);
|
2391
2223
|
|
2392
2224
|
HandleScope scope(isolate);
|
2393
2225
|
Handle<Object> left = args.at<Object>(0);
|
2394
2226
|
Handle<Object> right = args.at<Object>(1);
|
2395
2227
|
int key = args.smi_at(2);
|
2396
|
-
Token::Value op =
|
2397
|
-
BinaryOpIC::TypeInfo
|
2398
|
-
|
2228
|
+
Token::Value op = BinaryOpStub::decode_op_from_minor_key(key);
|
2229
|
+
BinaryOpIC::TypeInfo previous_left, previous_right, unused_previous_result;
|
2230
|
+
BinaryOpStub::decode_types_from_minor_key(
|
2231
|
+
key, &previous_left, &previous_right, &unused_previous_result);
|
2399
2232
|
|
2400
|
-
BinaryOpIC::TypeInfo
|
2401
|
-
|
2233
|
+
BinaryOpIC::TypeInfo new_left = InputState(previous_left, left, op);
|
2234
|
+
BinaryOpIC::TypeInfo new_right = InputState(previous_right, right, op);
|
2402
2235
|
BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED;
|
2403
|
-
|
2236
|
+
|
2237
|
+
// STRING is only used for ADD operations.
|
2238
|
+
if ((new_left == BinaryOpIC::STRING || new_right == BinaryOpIC::STRING) &&
|
2404
2239
|
op != Token::ADD) {
|
2405
|
-
|
2240
|
+
new_left = new_right = BinaryOpIC::GENERIC;
|
2406
2241
|
}
|
2407
|
-
|
2242
|
+
|
2243
|
+
BinaryOpIC::TypeInfo new_overall = Max(new_left, new_right);
|
2244
|
+
BinaryOpIC::TypeInfo previous_overall = Max(previous_left, previous_right);
|
2245
|
+
|
2246
|
+
if (new_overall == BinaryOpIC::SMI && previous_overall == BinaryOpIC::SMI) {
|
2408
2247
|
if (op == Token::DIV ||
|
2409
2248
|
op == Token::MUL ||
|
2410
2249
|
op == Token::SHR ||
|
@@ -2419,26 +2258,35 @@ RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
|
|
2419
2258
|
result_type = BinaryOpIC::INT32;
|
2420
2259
|
}
|
2421
2260
|
}
|
2422
|
-
if (
|
2423
|
-
|
2424
|
-
|
2261
|
+
if (new_overall == BinaryOpIC::INT32 &&
|
2262
|
+
previous_overall == BinaryOpIC::INT32) {
|
2263
|
+
if (new_left == previous_left && new_right == previous_right) {
|
2264
|
+
result_type = BinaryOpIC::HEAP_NUMBER;
|
2265
|
+
}
|
2425
2266
|
}
|
2426
2267
|
|
2427
|
-
BinaryOpStub stub(key,
|
2268
|
+
BinaryOpStub stub(key, new_left, new_right, result_type);
|
2428
2269
|
Handle<Code> code = stub.GetCode();
|
2429
2270
|
if (!code.is_null()) {
|
2271
|
+
#ifdef DEBUG
|
2430
2272
|
if (FLAG_trace_ic) {
|
2431
|
-
PrintF("[BinaryOpIC
|
2432
|
-
|
2433
|
-
|
2273
|
+
PrintF("[BinaryOpIC in ");
|
2274
|
+
JavaScriptFrame::PrintTop(stdout, false, true);
|
2275
|
+
PrintF(" ((%s+%s)->((%s+%s)->%s))#%s @ %p]\n",
|
2276
|
+
BinaryOpIC::GetName(previous_left),
|
2277
|
+
BinaryOpIC::GetName(previous_right),
|
2278
|
+
BinaryOpIC::GetName(new_left),
|
2279
|
+
BinaryOpIC::GetName(new_right),
|
2434
2280
|
BinaryOpIC::GetName(result_type),
|
2435
|
-
Token::Name(op)
|
2281
|
+
Token::Name(op),
|
2282
|
+
static_cast<void*>(*code));
|
2436
2283
|
}
|
2284
|
+
#endif
|
2437
2285
|
BinaryOpIC ic(isolate);
|
2438
2286
|
ic.patch(*code);
|
2439
2287
|
|
2440
2288
|
// Activate inlined smi code.
|
2441
|
-
if (
|
2289
|
+
if (previous_overall == BinaryOpIC::UNINITIALIZED) {
|
2442
2290
|
PatchInlinedSmiCode(ic.address(), ENABLE_INLINED_SMI_CHECK);
|
2443
2291
|
}
|
2444
2292
|
}
|
@@ -2501,42 +2349,28 @@ RUNTIME_FUNCTION(MaybeObject*, BinaryOp_Patch) {
|
|
2501
2349
|
|
2502
2350
|
|
2503
2351
|
Code* CompareIC::GetRawUninitialized(Token::Value op) {
|
2504
|
-
ICCompareStub stub(op, UNINITIALIZED);
|
2352
|
+
ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
|
2505
2353
|
Code* code = NULL;
|
2506
|
-
CHECK(stub.FindCodeInCache(&code));
|
2354
|
+
CHECK(stub.FindCodeInCache(&code, Isolate::Current()));
|
2507
2355
|
return code;
|
2508
2356
|
}
|
2509
2357
|
|
2510
2358
|
|
2511
2359
|
Handle<Code> CompareIC::GetUninitialized(Token::Value op) {
|
2512
|
-
ICCompareStub stub(op, UNINITIALIZED);
|
2360
|
+
ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
|
2513
2361
|
return stub.GetCode();
|
2514
2362
|
}
|
2515
2363
|
|
2516
2364
|
|
2517
|
-
CompareIC::State CompareIC::ComputeState(Code* target) {
|
2518
|
-
int key = target->major_key();
|
2519
|
-
if (key == CodeStub::Compare) return GENERIC;
|
2520
|
-
ASSERT(key == CodeStub::CompareIC);
|
2521
|
-
return static_cast<State>(target->compare_state());
|
2522
|
-
}
|
2523
|
-
|
2524
|
-
|
2525
|
-
Token::Value CompareIC::ComputeOperation(Code* target) {
|
2526
|
-
ASSERT(target->major_key() == CodeStub::CompareIC);
|
2527
|
-
return static_cast<Token::Value>(target->compare_operation());
|
2528
|
-
}
|
2529
|
-
|
2530
|
-
|
2531
2365
|
const char* CompareIC::GetStateName(State state) {
|
2532
2366
|
switch (state) {
|
2533
2367
|
case UNINITIALIZED: return "UNINITIALIZED";
|
2534
|
-
case
|
2535
|
-
case
|
2536
|
-
case
|
2537
|
-
case KNOWN_OBJECTS: return "
|
2538
|
-
case
|
2539
|
-
case
|
2368
|
+
case SMI: return "SMI";
|
2369
|
+
case HEAP_NUMBER: return "HEAP_NUMBER";
|
2370
|
+
case OBJECT: return "OBJECTS";
|
2371
|
+
case KNOWN_OBJECTS: return "KNOWN_OBJECTS";
|
2372
|
+
case SYMBOL: return "SYMBOL";
|
2373
|
+
case STRING: return "STRING";
|
2540
2374
|
case GENERIC: return "GENERIC";
|
2541
2375
|
default:
|
2542
2376
|
UNREACHABLE();
|
@@ -2545,28 +2379,67 @@ const char* CompareIC::GetStateName(State state) {
|
|
2545
2379
|
}
|
2546
2380
|
|
2547
2381
|
|
2548
|
-
CompareIC::State CompareIC::
|
2382
|
+
static CompareIC::State InputState(CompareIC::State old_state,
|
2383
|
+
Handle<Object> value) {
|
2384
|
+
switch (old_state) {
|
2385
|
+
case CompareIC::UNINITIALIZED:
|
2386
|
+
if (value->IsSmi()) return CompareIC::SMI;
|
2387
|
+
if (value->IsHeapNumber()) return CompareIC::HEAP_NUMBER;
|
2388
|
+
if (value->IsSymbol()) return CompareIC::SYMBOL;
|
2389
|
+
if (value->IsString()) return CompareIC::STRING;
|
2390
|
+
if (value->IsJSObject()) return CompareIC::OBJECT;
|
2391
|
+
break;
|
2392
|
+
case CompareIC::SMI:
|
2393
|
+
if (value->IsSmi()) return CompareIC::SMI;
|
2394
|
+
if (value->IsHeapNumber()) return CompareIC::HEAP_NUMBER;
|
2395
|
+
break;
|
2396
|
+
case CompareIC::HEAP_NUMBER:
|
2397
|
+
if (value->IsNumber()) return CompareIC::HEAP_NUMBER;
|
2398
|
+
break;
|
2399
|
+
case CompareIC::SYMBOL:
|
2400
|
+
if (value->IsSymbol()) return CompareIC::SYMBOL;
|
2401
|
+
if (value->IsString()) return CompareIC::STRING;
|
2402
|
+
break;
|
2403
|
+
case CompareIC::STRING:
|
2404
|
+
if (value->IsSymbol() || value->IsString()) return CompareIC::STRING;
|
2405
|
+
break;
|
2406
|
+
case CompareIC::OBJECT:
|
2407
|
+
if (value->IsJSObject()) return CompareIC::OBJECT;
|
2408
|
+
break;
|
2409
|
+
case CompareIC::GENERIC:
|
2410
|
+
break;
|
2411
|
+
case CompareIC::KNOWN_OBJECTS:
|
2412
|
+
UNREACHABLE();
|
2413
|
+
break;
|
2414
|
+
}
|
2415
|
+
return CompareIC::GENERIC;
|
2416
|
+
}
|
2417
|
+
|
2418
|
+
|
2419
|
+
CompareIC::State CompareIC::TargetState(State old_state,
|
2420
|
+
State old_left,
|
2421
|
+
State old_right,
|
2549
2422
|
bool has_inlined_smi_code,
|
2550
2423
|
Handle<Object> x,
|
2551
2424
|
Handle<Object> y) {
|
2552
|
-
switch (
|
2425
|
+
switch (old_state) {
|
2553
2426
|
case UNINITIALIZED:
|
2554
|
-
if (x->IsSmi() && y->IsSmi()) return
|
2555
|
-
if (x->IsNumber() && y->IsNumber()) return
|
2427
|
+
if (x->IsSmi() && y->IsSmi()) return SMI;
|
2428
|
+
if (x->IsNumber() && y->IsNumber()) return HEAP_NUMBER;
|
2556
2429
|
if (Token::IsOrderedRelationalCompareOp(op_)) {
|
2557
2430
|
// Ordered comparisons treat undefined as NaN, so the
|
2558
2431
|
// HEAP_NUMBER stub will do the right thing.
|
2559
2432
|
if ((x->IsNumber() && y->IsUndefined()) ||
|
2560
2433
|
(y->IsNumber() && x->IsUndefined())) {
|
2561
|
-
return
|
2434
|
+
return HEAP_NUMBER;
|
2562
2435
|
}
|
2563
2436
|
}
|
2564
2437
|
if (x->IsSymbol() && y->IsSymbol()) {
|
2565
2438
|
// We compare symbols as strings if we need to determine
|
2566
2439
|
// the order in a non-equality compare.
|
2567
|
-
return Token::IsEqualityOp(op_) ?
|
2440
|
+
return Token::IsEqualityOp(op_) ? SYMBOL : STRING;
|
2568
2441
|
}
|
2569
|
-
if (x->IsString() && y->IsString()) return
|
2442
|
+
if (x->IsString() && y->IsString()) return STRING;
|
2570
2443
|
if (!Token::IsEqualityOp(op_)) return GENERIC;
|
2571
2444
|
if (x->IsJSObject() && y->IsJSObject()) {
|
2572
2445
|
if (Handle<JSObject>::cast(x)->map() ==
|
@@ -2574,30 +2447,70 @@ CompareIC::State CompareIC::TargetState(State state,
|
|
2574
2447
|
Token::IsEqualityOp(op_)) {
|
2575
2448
|
return KNOWN_OBJECTS;
|
2576
2449
|
} else {
|
2577
|
-
return
|
2450
|
+
return OBJECT;
|
2578
2451
|
}
|
2579
2452
|
}
|
2580
2453
|
return GENERIC;
|
2581
|
-
case
|
2582
|
-
return
|
2583
|
-
?
|
2454
|
+
case SMI:
|
2455
|
+
return x->IsNumber() && y->IsNumber()
|
2456
|
+
? HEAP_NUMBER
|
2584
2457
|
: GENERIC;
|
2585
|
-
case
|
2458
|
+
case SYMBOL:
|
2586
2459
|
ASSERT(Token::IsEqualityOp(op_));
|
2587
|
-
return x->IsString() && y->IsString() ?
|
2588
|
-
case
|
2589
|
-
|
2590
|
-
|
2460
|
+
return x->IsString() && y->IsString() ? STRING : GENERIC;
|
2461
|
+
case HEAP_NUMBER:
|
2462
|
+
if (old_left == SMI && x->IsHeapNumber()) return HEAP_NUMBER;
|
2463
|
+
if (old_right == SMI && y->IsHeapNumber()) return HEAP_NUMBER;
|
2464
|
+
case STRING:
|
2465
|
+
case OBJECT:
|
2591
2466
|
case KNOWN_OBJECTS:
|
2592
2467
|
case GENERIC:
|
2593
2468
|
return GENERIC;
|
2594
2469
|
}
|
2595
2470
|
UNREACHABLE();
|
2596
|
-
return GENERIC;
|
2471
|
+
return GENERIC; // Make the compiler happy.
|
2472
|
+
}
|
2473
|
+
|
2474
|
+
|
2475
|
+
void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
|
2476
|
+
HandleScope scope;
|
2477
|
+
State previous_left, previous_right, previous_state;
|
2478
|
+
ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left,
|
2479
|
+
&previous_right, &previous_state, NULL);
|
2480
|
+
State new_left = InputState(previous_left, x);
|
2481
|
+
State new_right = InputState(previous_right, y);
|
2482
|
+
State state = TargetState(previous_state, previous_left, previous_right,
|
2483
|
+
HasInlinedSmiCode(address()), x, y);
|
2484
|
+
ICCompareStub stub(op_, new_left, new_right, state);
|
2485
|
+
if (state == KNOWN_OBJECTS) {
|
2486
|
+
stub.set_known_map(Handle<Map>(Handle<JSObject>::cast(x)->map()));
|
2487
|
+
}
|
2488
|
+
set_target(*stub.GetCode());
|
2489
|
+
|
2490
|
+
#ifdef DEBUG
|
2491
|
+
if (FLAG_trace_ic) {
|
2492
|
+
PrintF("[CompareIC in ");
|
2493
|
+
JavaScriptFrame::PrintTop(stdout, false, true);
|
2494
|
+
PrintF(" ((%s+%s=%s)->(%s+%s=%s))#%s @ %p]\n",
|
2495
|
+
GetStateName(previous_left),
|
2496
|
+
GetStateName(previous_right),
|
2497
|
+
GetStateName(previous_state),
|
2498
|
+
GetStateName(new_left),
|
2499
|
+
GetStateName(new_right),
|
2500
|
+
GetStateName(state),
|
2501
|
+
Token::Name(op_),
|
2502
|
+
static_cast<void*>(*stub.GetCode()));
|
2503
|
+
}
|
2504
|
+
#endif
|
2505
|
+
|
2506
|
+
// Activate inlined smi code.
|
2507
|
+
if (previous_state == UNINITIALIZED) {
|
2508
|
+
PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
|
2509
|
+
}
|
2597
2510
|
}
|
2598
2511
|
|
2599
2512
|
|
2600
|
-
// Used from
|
2513
|
+
// Used from ICCompareStub::GenerateMiss in code-stubs-<arch>.cc.
|
2601
2514
|
RUNTIME_FUNCTION(Code*, CompareIC_Miss) {
|
2602
2515
|
NoHandleAllocation na;
|
2603
2516
|
ASSERT(args.length() == 3);
|